在 eu.org 注册免费域名
eu.org 是一个可以免费注册三级域名的公益组织。
eu.org 是一个可以免费注册三级域名的公益组织。
协同程序是一种特殊的多任务编程方式,多个协同程序之间共用调用栈,且正在运行的协同程序不会被其他协程抢占(可以被任务和中断抢占),正在运行的协同程序只能自己主动让出CPU的使用权。要使用协同程序,需要将FreeRTOSConfig.h中的configUSE_CO_ROUTINES设为1。
FreeRTOS的协同程序采用switch-case实现,函数定义方式如下:
1void CoRoutineTask(CoRoutineHandle_t handle,UBaseType_t uxIndex)
2{
3 //协同程序中变量如果要保证值在下一次运行时仍有效,则必须为static
4 static const TickType_t delay = 1000 / portTICK_PERIOD_MS;
5 FreeRTOS的任务优先级是数值越大,优先级越高,0是最低优先级;而Cortex-M的中断优先级是数值越大,优先级越低,0是最高优先级。
FreeRTOSConfig.h中的宏configLIBRARY_LOWEST_INTERRUPT_PRIORITY表示最低中断优先级,从FreeRTOS的demo中复制出来的这个头文件中这个宏的值是15,即从0到15一共16个优先级。Cortex-M的中断优先级有抢占优先级和子优先级两个,但FreeRTOS中没有提供处理子优先级的功能,只使用抢占优先级。因此需要将STM32的中断优先级组设置为16个抢占优先级、1个子优先级,即第四组中断优先级组。
1//优先级组是STM32中优先级分配方式的选择,"组"这个翻译可能不太合适
2//使用第四组中断优先级组
3NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
4//STM32有0到4共五组优先级组FreeRTOS可以使用事件标志组进行任务同步,一个事件标准组包含多个事件标志位,每一位标志一个事件。当configUSE_16BIT_TICKS为1时,一个事件标志组有8位;当这个宏为0时,一个事件标志组有24位。
创建事件标志组使用xEventGroupCreate。
1#include <event_groups.h>
2EventGroupHandle_t xEventGroupCreate(void);
3//返回事件标志组句柄,失败返回NULLFreeRTOS的内存管理API定义在heep_1.c、heep_2.c、heep_3.c、heep_4.c和heep_5.c中,这五个文件中的内存管理API有所不同。
heep_1.c只能分配内存而不能释放内存。heep_2.c可以分配和释放内存但不能合并空闲内存块。heep_3.c简单的封装了线程安全版的标准C语言malloc和free函数。heep_4.c可以合并相邻的空闲内存块。heep_5.c可以合并相邻的空闲内存块,且可以管理地址不连续的物理内存。分配内存的API是pvPortMalloc,释放内存的API是vPortFree。
1undefined信号量(Semaphore)也是一种任务间通信的常用方式,通常用于任务的同步。
1#include <semphr.h>
2
3BaseType_t xSemaphoreGive(SemaphoreHandle_t xSemaphore);
4//产生一个信号,成功返回pdPASS
5//信号量已满则失败,返回errQUEUE_FULL
6
7BaseType_t xSemaphoreTake(SemaphoreHandle_t xSemaphore,TickType_t xBlockTime);队列(Queue)是一种数据结构,它是一种特殊的线性表,只允许在队列的首端进行删除,尾端进行插入,具有先入先出的特性。是任务间通信的一种常用方式。
xQueueCreate函数创建一个队列,它的第一个参数是队列的长度(元素的个数),第二个参数是每个元素的大小(byte)。
1#include <queue.h>
2QueueHandle_t xQueueCreate(const UBaseType_t uxQueueLength,const UBaseType_t uxItemSize);
3//成功返回队列句柄,失败返回NULL在并行编程中,并行存取共享的资源时,常常会导致意外和错误的结果。例如下面代码task1和task2都通过串口打印消息,但由于任务调度,消息被截断了。
1#include <stm32f4xx.h>
2#include <FreeRTOS.h>
3#include <task.h>
4#include <uart.h>
5
6void task1(void* args);
7void task2(void* args);在xTaskCreate函数创建任务时,即为任务赋予了优先级。可以使用vTaskPrioritySet函数来修改任务的优先级,它的第一个参数是任务句柄、第二个参数是优先级,这个函数必须在调度器启动之后才能调用。相应的,uxTaskPriority函数返回一个任务的优先级。
1#include <task.h>
2void vTaskPrioritySet(TaskHandle_t xTask,UBaseType_t uxNewPriority);
3
4UBaseType_t uxTaskPriorityGet(TaskHandle_t xTask);
5//返回任务的优先级