FreeRTOS-CortexM4-相关函数说明
生活随笔
收集整理的這篇文章主要介紹了
FreeRTOS-CortexM4-相关函数说明
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
目錄
- 0. FreeRTOS配置
- 1. void prvStartFirstTask( void )
- 2. void vPortSVCHandler( void )
- 3. void xPortPendSVHandler( void )
- 4. StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
- 5. void xPortSysTickHandler( void )
正文
0. FreeRTOS配置
- (1) FreeRTOS版本v8.1.2,以下介紹的函數與當前較新的10.1.1版本并無太多變化。
- (2) 未開啟FPU
1. prvStartFirstTask()
__asm void prvStartFirstTask( void ) {PRESERVE8 /* 堆棧的8字節對齊,參考8_DUI0473Marmasm_user_guide.pdf及AAPCS *//* Use the NVIC offset register to locate the stack. */ldr r0, =0xE000ED08 /* SCB->VTOR,向量表偏移地址寄存器*/ldr r0, [r0] /* 從向量表偏移地址寄存器中取出起始地址(0x08000000) */ldr r0, [r0] /* 取出STACK起始地址并初始化到MSP *//* Set the msp back to the start of the stack. */msr msp, r0 /* Globally enable interrupts. */cpsie i /* 使能中斷 */cpsie fdsb /* 數據和指令同步隔離,將流水線中的數據和指令全部執行完畢 */isb/* Call SVC to start the first task. */svc 0 /* 生成svc中斷 */nopnop }2. vPortSVCHandler()
__asm void vPortSVCHandler( void ) {PRESERVE8/* Get the location of the current TCB. */ldr r3, =pxCurrentTCB /* 獲取當前任務的句柄,并獲取任務的堆棧地址給r0 */ldr r1, [r3]ldr r0, [r1]/* Pop the core registers. */ldmia r0!, {r4-r11, r14} /* 從CurrentTCB的任務棧中恢復出各個寄存器,這里的r14出棧后就被恢復為了0xFFFFFFFD(詳見pxPortInitialiseStack()),即當退出SVC中斷后返回到ThreadMode且使用PSP */msr psp, r0isbmov r0, #0 /* 放開中斷限制 */msr basepri, r0bx r14 }3. xPortPendSVHandler()
__asm void xPortPendSVHandler( void ) {extern uxCriticalNesting;extern pxCurrentTCB;extern vTaskSwitchContext;PRESERVE8mrs r0, psp /* 獲取當前任務棧指針PSP到r0 */isb /* 指令同步隔離,將流水線中的指令全部執行完畢 *//* Get the location of the current TCB. */ldr r3, =pxCurrentTCB /* 獲取pxCurrentTCB的地址到r3 */ldr r2, [r3] /* 獲取pxCurrentTCB到r2 *//* Is the task using the FPU context? If so, push high vfp registers. */tst r14, #0x10it eqvstmdbeq r0!, {s16-s31}/* Save the core registers. */stmdb r0!, {r4-r11, r14} /* 將r14,r11-r4依次入任務棧,棧指針為r0指向的地址(保存現場) *//* Save the new top of stack into the first member of the TCB. */str r0, [r2] /* 更新當前任務TCB的棧頂指針pxTopOfStack */stmdb sp!, {r0, r3} /* 將r3(pxCurrentTCB的地址)和r0(當前任務棧指針棧頂)的內容保存至主任務堆棧 */mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITYmsr basepri, r0 /* 屏蔽優先級低于configMAX_SYSCALL_INTERRUPT_PRIORITY的中斷,防止產生意外 */dsb /* 數據同步隔離,將流水線中的數據全部執行完畢 */isb /* 指令同步隔離,將流水線中的指令全部執行完畢 */bl vTaskSwitchContext /* 調用上下文切換函數,找出最高優先級的任務并將指針放入pxCurrentTCB */mov r0, #0 /* 取消屏蔽優先級低于configMAX_SYSCALL_INTERRUPT_PRIORITY的中斷 */msr basepri, r0ldmia sp!, {r0, r3} /* 從主棧恢復出TCB的任務棧棧頂和&pCurrentTCB分別到r0,r3 *//* The first item in pxCurrentTCB is the task top of stack. */ldr r1, [r3] /* 加載pxCurrentTCB到r1 */ldr r0, [r1] /* 加載pxCurrentTCB任務的棧頂到r0 *//* Pop the core registers. */ldmia r0!, {r4-r11, r14} /* 從新的任務棧恢復進入PendSV中斷前的現場 *//* Is the task using the FPU context? If so, pop the high vfp registerstoo. */tst r14, #0x10it eqvldmiaeq r0!, {s16-s31}msr psp, r0 /* 更新PSP */isb#ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata */#if WORKAROUND_PMU_CM001 == 1push { r14 }pop { pc }nop#endif#endifbx r14 /* 退出 */ }
4. pxPortInitialiseStack()
5.?xPortSysTickHandler()
void xPortSysTickHandler( void )/* */ {/* The SysTick runs at the lowest interrupt priority, so when this interruptexecutes all interrupts must be unmasked. There is therefore no need tosave and then restore the interrupt mask value as its value is alreadyknown. *//*SysTick中斷的優先級是系統中最低的,因此如果已經進入了這個中斷中,那么就可以判斷當前系統中的所有中斷都是未屏蔽的。因此沒有必要保存中斷屏蔽值,因為其已知。 */( void ) portSET_INTERRUPT_MASK_FROM_ISR(); /* 屏蔽優先級低于configMAX_SYSCALL_INTERRUPT_PRIORITY的中斷,防止使用FreeRTOS API的程序對下面產生影響 */{/* Increment the RTOS tick. */if( xTaskIncrementTick() != pdFALSE ) /* 檢查等待列表pxDelayedTaskList看是否有到期的、比當前執行的任務優先級更高的Task */{/* A context switch is required. Context switching is performed inthe PendSV interrupt. Pend the PendSV interrupt. */portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;}}portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 ); /* 已完成關鍵操作,放開中斷屏蔽 */ }?
總結
以上是生活随笔為你收集整理的FreeRTOS-CortexM4-相关函数说明的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux守护进程设计规范及python
- 下一篇: 9. 代码生成