1. 源码
1.1. task
任务的创建
/* xTaskCreate实际调用xTaskCreatePinnedToCore */
xTaskCreate
xTaskCreatePinnedToCore
/* 任务栈pxStack和任务控制块pxNewTCB创建 */
pvPortMallocStackMem
prvInitialiseNewTask
/* 计算栈顶pxTopOfStack位置 */
/* 存储任务名到TCB */
/* 确定任务优先级 */
/* 初始化列表项 */
vListInitialiseItem
listSET_LIST_ITEM_OWNER
listSET_LIST_ITEM_VALUE
/* 根据芯片架构初始化栈帧 */
pxPortInitialiseStack
sp-->interrupt stack frame
...
prvAddNewTaskToReadyList
prvAddTaskToReadyList
/* 按照任务优先级,添加到对应的pxReadyTasksLists */
vListInsertEnd
/* 新的任务添加到pxIndex的前面,任务列表的遍历是从pxIndex开始,所以认为pxIndex的前面就是尾部 */
开启任务
vTaskStartScheduler
/* 创建空闲任务 prvIdleTask*/
xPortStartScheduler
1.2. 信号量
创建
xSemaphoreCreateCounting=xQueueCreateCountingSemaphore
xQueueCreateCountingSemaphore
xQueueGenericCreate
1.计算所需队列字节数并申请内存
2.初始化新队列
prvInitialiseNewQueue
3.返回新队列指针
4.关键变量值
uxItemSize = queueSEMAPHORE_QUEUE_ITEM_LENGTH = 0;
uxLength = uxMaxCount=3
uxMessagesWaiting = uxInitialCount;
uxQueueType = queueQUEUE_TYPE_COUNTING_SEMAPHORE
释放
xSemaphoreGive = xQueueGenericSend
xQueueGenericSend
prvCopyDataToQueue
判断了一堆,由于uxItemSize==0,最后uxMessagesWaiting+1返回
获取
xSemaphoreTake = xQueueSemaphoreTake
xQueueSemaphoreTake
同样也是在临界区内判断,当前可后去的信号量是否还有,也就是uxMessagesWaiting的值不为0
uxMessagesWaiting-1
执行在等待该信号量的阻塞中的任务(even list)
如果等不到信号,超时,就把当前任务的xEventListItem加到当前信号的xTasksWaitingToSend中(释放也有同样操作)