[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4P4MfHnK-1657685391686)(https://www.freertos.org/a00104.html)]
ref: 野火 《FreeRTOS 内核实现与应用开发实战—基于STM32》
可在野火大学堂下载 或 下载链接
FreeRTOS
FreeRTOS
文件夹\FreeRTOSv202112.00\FreeRTOS\Source
的文件拷贝进去portable
中删剩下Keil
, MemMang
, RVDS
|--FreeRTOS_CORE
|--croutine.c
|--event_groups.c
|--list.c
|--queue.c
|--tasks.c
|--timers.c
|--FreeRTOS_PORTABLE
|--port.c
|--heap_4.c
\FreeRTOS\include
和\FreeRTOS\portable\RVDS\ARM_CM3
\FreeRTOSv202112.00\FreeRTOS\Demo\CORTEX_STM32F103_Keil
中找到文件FreeRTOSConfig.h
,拷贝到工程目录的\FreeRTOS\include
中见portmacro.h
FreeRTOSConfig.h: configUSE_16_BIT_TICKS=1
为16位FreeRTOSConfig.h: configUSE_16_BIT_TICKS=01
为32位前缀:类型
前缀:哪个头文件定义
通过节点将离散的数据链接到一起,组成一个表,常规操作:插入&删除, 通常人为规定一个根节点(生产者),还有个节点计数器.
含有n个节点,前一节点有一个箭头指向后一节点,首尾相连. 节点是自定义类型的数据结构,本身含一个结点指针, 指向后一节点, 还携带一些私有信息(单个数据,数组,指针,结构体等).
通常在节点中只包含一个用于指向下一个节点的指针,通过链表存储的数据内嵌一个节点
链表节点数据结构定义
struct xLIST_ITEM
{
TickType_t xItemValue; // 辅助值:帮节点做顺序排列
struct xLIST_ITEM * pxNext; // 指向链表下一个节点
struct xLIST_ITEM * pxPrevious; // 指向链表前一个节点
void * pvOwner; // 指向拥有该节点的内核对象(TCB)
void * pvContainer; // 指向该节点所在链表
};
typedef struct xLIST_ITEM ListItem_t; // 节点数据类型重定义
TaskHandle_t Task1_Handle; // 任务句柄
#define TASK1_STACK_SIZE 128 // 任务栈大小
StackType_t Task1Stack[TASK1_STACK_SIZE]; // 任务栈
TCB_t Task1TCB; // 任务控制块
Task1_Handle = xTaskCreateStatic( (TaskFunction_t)Task1_Entry, /* 任务入口 */
(char *)"Task1", /* 任务名称,字符串形式 */
(uint32_t)TASK1_STACK_SIZE , /* 任务栈大小,单位为字 */
(void *) NULL, /* 任务形参 */
(UBaseType_t) 2, /* 任务优先级,数值越大,优先级越高 */
(StackType_t *)Task1Stack, /* 任务栈起始地址 */
(TCB_t *)&Task1TCB );
FreeRTOSConfig.h
决定SysTick
的中断周期
#define configCPU_CLOCK_HZ ( ( unsigned long ) 25000000 )
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
vTaskDelay( 1 );
pxReadyTasksLists[configMAX_PRIORITIES]
数组存储就绪任务的TCB(的xStateListItem节点), 数组下标越小, 任务优先级越低pxCurrenTCB
: 全局TCB指针, 任务切换时指向优先级最高的就绪任务TCBtaskSELECT_HIGHEST_PRIORITY_TASK
taskSELECT_HIGHEST_PRIORITY_TASK() // 寻找优先级最高的就绪任务 (更新`uxTopReadyPriority`和`pxCurrentTCB`的值)
taskRESET_READY_PRIORITY( uxPriority ) // 将变量uxTopReadyPriority某个位清0
// 实现任务延时列表后, 任务非就绪时, 清零uxTopReadyPriority对应位, 将任务从就绪列表删除
xNextTaskUnblockTime
xNextTaskUnblockTime
= 时基计数器值xTickCount
+ 任务延时xTickToDelay
比较xTickCount
xNextTaskUnblockTime
FreeRTOSConfig.h
#include "stm32f10x.h" //
#include "bsp_usart.h" // 断言操作需要打印
#define xPortPendSVHandler PendSV_Handler // 中断服务函数配置相关
#define vPortSVCHandler SVC_Handler
stm32f10x_it.c
//systick 中断服务函数
void SysTick_Handler(void)
{
#if (INCLUDE_xTaskGetSchedulerState == 1 )
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
#endif /* INCLUDE_xTaskGetSchedulerState */
xPortSysTickHandler();
#if (INCLUDE_xTaskGetSchedulerState == 1 )
}
#endif /* INCLUDE_xTaskGetSchedulerState */
}
vTaskSuspend()
将处于任何状态的任务挂起, 挂起后无cpu使用权, 不参与调度, 用vTaskResume()
解除
vTaskSuspend()
任务挂起函数vTaskResume()
任务恢复函数xTaskResumeFromISR()
恢复被挂起的任务(中断)vTaskSuspendAll()
挂起调度器, 相当于挂起所有任务xTaskResumeAll()
恢复调度器, 用多少次挂起要用多少次恢复vTaskDelete()
任务删除函数vTaskDelay()
相对任务延时函数, 不适用于周期性执行任务的场合vTaskDelayUntil()
绝对延时函数, 实现固定频率定期执行任务xTicksToWait
, 若队列空, 任务保持阻塞态以等待队列数据有效xQueueCreate()
创建消息队列 分配RAM:队列状态+存储区域vQueueDelete()
消息队列删除函数xQueueSend()
向队列尾部发送一个队列消息(不能被中断调用)xQueueSendFromISR()
中断向队列尾部发消息xQueueSendToFront()
向队列队首发一个消息xQueueSendToFrontFromISR()
中断向队列队首发一个消息xQueueGenericSend()
通用消息队列发送函数xQueueGenericSendFromISR()
中断通用消息队列发送xQueueReceive()
接收消息, 将消息从队列删除xQueueReceiveFromISR()
中断接收消息, 将消息从队列删除, 无阻塞xQueuePeed()
接收消息, 不删除消息xQueuePeedFromISR()
中断接收消息, 不删除消息, 无阻塞xQueueGenericReceive()
通用任务从队列读取消息semphr.h
结构体与消息队列结构体一致uxMessagesWaiting
有效信号量个数
uxLength
队列长度
xSemaphoreCreateBinary()
创建二值信号量(空), 要先释放才能获取xSemaphoreCreateCounting()
创建计数信号量vSemaphoreDelete()
删除一个信号量xSemaphoreTake()
任务获取信号量xSemaphoreTakeFromISR()
任务获取信号量xSemaphoreGive()
任务释放信号量xSemaphoreGiveFromISR()
中断释放信号量xSemaphoreCreateMutex()
创建互斥量prvInitialiseMutex()
初始化互斥量xSemaphoreCreateRecursiveMutex()
创建递归互斥量vSemaphoreDelete()
删除互斥量xSemaphoreTake()
获取互斥量xSemaphoreTakeRecursive()
获取递归互斥量, 需先创建xSemaphoreGive()
释放互斥量xSemaphoreGiveRecursive()
释放递归互斥量EventBits_t
24位表示事件: 0:未发生 1:已发生 共24种事件类型xEventGroupCreate()
创建事件vEventGroupDelete()
删除事件xEventGroupSetBits()
置位事件组, 阻塞于该位的任务被解锁xEventGroupSetBitsFromISR()
中断置位事件组, 阻塞于该位的任务被解锁xEventGroupWaitBits()
阻塞等待事件, 获取事件是否已经发生xEventGroupClearBits()
清除事件组指定的位xEventGroupClearBitsFromISR()
中断清除事件组指定的位xTimerCreate()
创建软件定时器xTimerStart()
启动软件定时器xTimerStartFromISR()
中断启动软件定时器xTimerStop()
停止一个已启动的软件定时器xTimerStopFromISR()
中断停止一个已启动的软件定时器xTimerDelete()
删除软件定时器函数xTaskGenericNotify()
发送任务通知函数vTaskNotifyGiveFromISR()
中断发送任务通知函数xTaskNotify()
直接向另一个任务发送一个事件xTaskNotifyFromISR()
中断直接向另一个任务发送一个事件ulTaskNotifyTake()
获取任务通知, 配合Give()xTaskNotifyWait()
等待通知heap_1.c
heap_2.c
heap_4.c
内存堆为一个大数组ucHeap[configTOTAL_HEAP_SIZE]
heap_3.c
封装了c标准库的malloc()
, free()
, 可安全地在嵌入式系统执行heap_5.c
允许用户使用多个非连续内存堆空间, 每个堆起始地址,大小由用户定义heap_1.c
pvPortMalloc()
申请一块用户指定大小的内存空间, 系统管理的空间满足需求则成功heap_2.c
heap_3.c
malloc()
功能和free()
函数, 有保护功能heap_4.c
malloc()
heap_5.c
vPortDefineHeapRegions()
实现系统管理的内存初始化vTaskGetRunTimeStats()
获取任务相关信息vTaskList()
获取CPU使用率信息