標題: ucos到stm32(一) [打印本頁]
作者: 51黑fan 時間: 2016-1-31 01:03
標題: ucos到stm32(一)
/**********************************戰艦版實例**************************************/
P80:μc/osⅡ時鐘 硬件定時器中斷(使用了STM32中的Systick中斷)每產生一次,μc/osⅡ時鐘就會進入一次系統中斷服務程序(OSTickISR()),系統中斷服務程序通過調用OSTimeTick()來完成系統每個時鐘節拍所要完成的工作(包括遍歷每個任務控制塊將其延時參數減1等)。
任哲版教材P87鉤子函數在戰艦的對應源碼:
鉤子函數的使用(以OSTimerTickHook為例):
需要到os_cfg.h中把這兩個宏#define成>0。
P88:OSTimeDly在OSTimeDly中完成OSTCBCur->OSTCBDly(任務延時寄存器)的寫入并進行一次任務切換:
關于 μc/osⅡ的疑難:
·μc/osⅡ的時鐘OSTimeTick()是怎么與STM32的SysTick關聯起來的?
戰艦開發板配套程序中在main()中有delay_init()(delay.c下)函數,其原代碼如下:
void delay_init()
{
#ifdef OS_CRITICAL_METHOD //如果OS_CRITICAL_METHOD定義了,說明使用ucosII了.
u32 reload;
#endif
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //選擇外部時鐘 HCLK/8
fac_us=SystemCoreClock/8000000; //為系統時鐘的1/8
#ifdef OS_CRITICAL_METHOD //如果OS_CRITICAL_METHOD定義了,說明使用ucosII了.
reload=SystemCoreClock/8000000; //每秒鐘的計數次數 單位為K
reload*=1000000/OS_TICKS_PER_SEC;//根據OS_TICKS_PER_SEC設定溢出時間
//reload為24位寄存器,最大值:16777216,在72M下,約合1.86s左右
fac_ms=1000/OS_TICKS_PER_SEC;//代表ucos可以延時的最少單位
SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk; //開啟SYSTICK中斷
SysTick->LOAD=reload; //每1/OS_TICKS_PER_SEC秒中斷一次
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //開啟SYSTICK
#else
fac_ms=(u16)fac_us*1000;//非ucos下,代表每個ms需要的systick時鐘數
#endif
}
可見delay_init()開啟了STM32的SYSTICK中斷,下面繼續找SYSTICK的中斷服務程序(同樣也在delay.c),代碼如下:
void SysTick_Handler(void)
{
OSIntEnter(); //進入中斷,其作僅僅是將判斷中斷層數是否達到255否則OSIntNesting++
OSTimeTick(); //調用ucos的時鐘服務程序
OSIntExit(); //觸發任務切換軟中斷
}
發現OSTimeTick(); 在 SYSTICK的中斷服務程序被調用,現在μc/osⅡ的時鐘OSTimeTick()就與STM32的SysTick關聯了起來。
OSIntExit (void)的作用除了執行了OSIntNesting--之外 還進行了一次中斷級任務調度OSIntCtxSw() 。
·OSIntCtxSw()切換任務的原理:
Step1:SIntCtxSw()觸發了一次軟件中斷,代碼如下
;/**************************************************************************************
;* 函數名稱: OSIntCtxSw
;* 功能描述: 中斷級任務切換(其實是進行了一次軟件中斷)
;* 參 數: None
;* 返 回 值: None
;***************************************************************************************/
OSIntCtxSw
PUSH {R4, R5}
LDR R4, =NVIC_INT_CTRL ;觸發PendSV異常 (causes context switch)
;NVIC_INT_CTRL就是軟件中斷控制寄存器
LDR R5, =NVIC_PENDSVSET ;NVIC_PENDSVSET是觸發軟件中斷的值.
STR R5, [R4] ;將R5中的字數據寫入以R4為地址的存儲器中就發生了PendSV中斷
POP {R4, R5}
BX LR
NOP
Step2:執行完了step后會進入軟件中斷服務函數,代碼(在os_cpu_aasm中)如下
;/**************************************************************************************
;* 函數名稱: OSPendSV
;*
;* 功能描述: 該函數實際上完成了cpu各寄存器的壓棧和新任務堆棧向cpu的進棧;
;* 參 數: None
;*
;* 返 回 值: None
;***************************************************************************************/
PendSV_Handler ;軟件中斷服務函數
CPSID I ; Prevent interruption during context switch
MRS R0, PSP ; PSP is process stack pointer 如果在用PSP堆棧,則可以忽略保存寄存器,參考CM3權威中的雙堆棧-白菜注
CBZ R0, PendSV_Handler_Nosave ; Skip register save the first time
SUBS R0, R0, #0x20 ; Save remaining regs R4-11 on process stack
STM R0, {R4-R11}
LDR R1, =OSTCBCur ; OSTCBCur->OSTCBStkPtr = SP; =OSTCBCur就是取的OSTCBCur
;首地址,即任務控制塊的堆棧。
LDR R1, [R1]
STR R0, [R1] ; R0 is SP of process being switched out
歡迎光臨 (http://www.zg4o1577.cn/bbs/) |
Powered by Discuz! X3.1 |
主站蜘蛛池模板:
亚洲一区二区在线免费观看
|
福利视频二区
|
6080亚洲精品一区二区
|
欧美aaaa视频
|
国产高清一区二区
|
日韩一区二区三区视频
|
91久久综合
|
国产亚洲精品久久久久久牛牛
|
黄色毛片在线播放
|
亚洲欧美中文日韩在线v日本
|
91在线精品播放
|
免费成人午夜
|
欧美一级毛片免费观看
|
国产精品视频在线播放
|
亚洲精品乱码久久久久久按摩
|
国产综合精品一区二区三区
|
综合久久av
|
亚洲精品中文在线观看
|
国产成人精品一区二区在线
|
性在线|
亚洲精品中文在线观看
|
美女天天干天天操
|
一区二区三区四区免费观看
|
亚洲第1页
|
天天久|
国产女人与拘做受视频
|
一区二区三区观看视频
|
国产日韩欧美在线观看
|
免费av在线|
欧美久久一区二区
|
欧美一区二区三区视频在线观看
|
久久久综合久久
|
97成人精品
|
中文二区
|
国产一区二区精品在线观看
|
麻豆成人在线视频
|
亚洲国产成人精
|
可以免费观看的av片
|
99久久精品国产一区二区三区
|
色婷婷久久综合
|
尤物在线
|