日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

FreeRTOS-CortexM4-相关函数说明

發(fā)布時(shí)間:2024/1/8 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 FreeRTOS-CortexM4-相关函数说明 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

目錄

  • 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,以下介紹的函數(shù)與當(dāng)前較新的10.1.1版本并無太多變化。
  • (2) 未開啟FPU

1. prvStartFirstTask()

__asm void prvStartFirstTask( void ) {PRESERVE8 /* 堆棧的8字節(jié)對齊,參考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 /* 數(shù)據(jù)和指令同步隔離,將流水線中的數(shù)據(jù)和指令全部執(zhí)行完畢 */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 /* 獲取當(dāng)前任務(wù)的句柄,并獲取任務(wù)的堆棧地址給r0 */ldr r1, [r3]ldr r0, [r1]/* Pop the core registers. */ldmia r0!, {r4-r11, r14} /* 從CurrentTCB的任務(wù)棧中恢復(fù)出各個(gè)寄存器,這里的r14出棧后就被恢復(fù)為了0xFFFFFFFD(詳見pxPortInitialiseStack()),即當(dāng)退出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 /* 獲取當(dāng)前任務(wù)棧指針PSP到r0 */isb /* 指令同步隔離,將流水線中的指令全部執(zhí)行完畢 *//* 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依次入任務(wù)棧,棧指針為r0指向的地址(保存現(xiàn)場) *//* Save the new top of stack into the first member of the TCB. */str r0, [r2] /* 更新當(dāng)前任務(wù)TCB的棧頂指針pxTopOfStack */stmdb sp!, {r0, r3} /* 將r3(pxCurrentTCB的地址)和r0(當(dāng)前任務(wù)棧指針棧頂)的內(nèi)容保存至主任務(wù)堆棧 */mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITYmsr basepri, r0 /* 屏蔽優(yōu)先級低于configMAX_SYSCALL_INTERRUPT_PRIORITY的中斷,防止產(chǎn)生意外 */dsb /* 數(shù)據(jù)同步隔離,將流水線中的數(shù)據(jù)全部執(zhí)行完畢 */isb /* 指令同步隔離,將流水線中的指令全部執(zhí)行完畢 */bl vTaskSwitchContext /* 調(diào)用上下文切換函數(shù),找出最高優(yōu)先級的任務(wù)并將指針放入pxCurrentTCB */mov r0, #0 /* 取消屏蔽優(yōu)先級低于configMAX_SYSCALL_INTERRUPT_PRIORITY的中斷 */msr basepri, r0ldmia sp!, {r0, r3} /* 從主?;謴?fù)出TCB的任務(wù)棧棧頂和&pCurrentTCB分別到r0,r3 *//* The first item in pxCurrentTCB is the task top of stack. */ldr r1, [r3] /* 加載pxCurrentTCB到r1 */ldr r0, [r1] /* 加載pxCurrentTCB任務(wù)的棧頂?shù)絩0 *//* Pop the core registers. */ldmia r0!, {r4-r11, r14} /* 從新的任務(wù)?;謴?fù)進(jìn)入PendSV中斷前的現(xiàn)場 *//* 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()

StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) {/* Simulate the stack frame as it would be created by a context switchinterrupt. */ /* 模擬中斷后堆棧的棧幀內(nèi)容,初始化各個(gè)任務(wù)的任務(wù)棧 *//* Offset added to account for the way the MCU uses the stack on entry/exitof interrupts, and to ensure alignment. */pxTopOfStack--;*pxTopOfStack = portINITIAL_XPSR; /* xPSR */pxTopOfStack--;*pxTopOfStack = ( StackType_t ) pxCode; /* PC */pxTopOfStack--;*pxTopOfStack = ( StackType_t ) prvTaskExitError; /* LR */ /* 無處返回,出錯(cuò) *//* Save code space by skipping register initialisation. */pxTopOfStack -= 5; /* R12, R3, R2 and R1. */*pxTopOfStack = ( StackType_t ) pvParameters; /* R0 */ /* 傳遞的參數(shù)放入r0中 *//* A save method is being used that requires each task to maintain itsown exec return value. */pxTopOfStack--;*pxTopOfStack = portINITIAL_EXEC_RETURN; /* 0xFFFFFFFD 返回到Thread & 使用PSP */pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */return pxTopOfStack; }

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中斷的優(yōu)先級是系統(tǒng)中最低的,因此如果已經(jīng)進(jìn)入了這個(gè)中斷中,那么就可以判斷當(dāng)前系統(tǒng)中的所有中斷都是未屏蔽的。因此沒有必要保存中斷屏蔽值,因?yàn)槠湟阎?*/( void ) portSET_INTERRUPT_MASK_FROM_ISR(); /* 屏蔽優(yōu)先級低于configMAX_SYSCALL_INTERRUPT_PRIORITY的中斷,防止使用FreeRTOS API的程序?qū)ο旅娈a(chǎn)生影響 */{/* Increment the RTOS tick. */if( xTaskIncrementTick() != pdFALSE ) /* 檢查等待列表pxDelayedTaskList看是否有到期的、比當(dāng)前執(zhí)行的任務(wù)優(yōu)先級更高的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 ); /* 已完成關(guān)鍵操作,放開中斷屏蔽 */ }

?

總結(jié)

以上是生活随笔為你收集整理的FreeRTOS-CortexM4-相关函数说明的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。