生活随笔
收集整理的這篇文章主要介紹了
临界区保护
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
1 臨界區(qū)保護(hù)
1.1 問題引入
首先看一下如下問題:
原因分析:
- 根本原因在于讀-改-寫過程中隨時(shí)會(huì)被打斷,再恢復(fù)運(yùn)行時(shí)寫,導(dǎo)致打斷過程中其它寫的效果被覆蓋。
1.2 臨界區(qū)概念
臨界區(qū)的概念如下:
- 臨界區(qū)指的是訪問多個(gè)任務(wù)共享資源的一段代碼。當(dāng)有任務(wù)進(jìn)入臨界區(qū)時(shí),其它任務(wù)必須等待直至該任務(wù)離開臨界區(qū),以確定共享資源的訪問不會(huì)沖突。
由于共享資源的訪問存在于任務(wù)與任務(wù)之間、任務(wù)與中斷ISR之間;那么,只需要防止任務(wù)在訪問共享資源時(shí),切換至其它任務(wù)或防止中斷發(fā)生即可。
1.3 使用關(guān)中斷保護(hù)臨界區(qū)
我們可以使用關(guān)中斷來保護(hù)臨界區(qū),如下:
但是當(dāng)中斷發(fā)生嵌套的時(shí)候就會(huì)出現(xiàn)問題:
所以我們需要采用如下的解決方案:
1.4 設(shè)計(jì)實(shí)現(xiàn)
中斷控制寄存器PRIMASK:
進(jìn)入臨界區(qū):
退出臨界區(qū):
這里只貼一下main.c文件中的內(nèi)容:
#include "tinyOS.h"
#include "ARMCM3.h"
tTask
* currentTask
;
tTask
* nextTask
;
tTask
* idleTask
;
tTask
* taskTable
[2];
uint32_t tickCounter
;
void tTaskInit
(tTask
* task
, void (*entry
)(void *), void *param
, uint32_t
* stack
)
{*(--stack
) = (unsigned long)(1<<24); *(--stack
) = (unsigned long)entry
; *(--stack
) = (unsigned long)0x14; *(--stack
) = (unsigned long)0x12; *(--stack
) = (unsigned long)0x3; *(--stack
) = (unsigned long)0x2; *(--stack
) = (unsigned long)0x1; *(--stack
) = (unsigned long)param
; *(--stack
) = (unsigned long)0x11; *(--stack
) = (unsigned long)0x10; *(--stack
) = (unsigned long)0x9; *(--stack
) = (unsigned long)0x8; *(--stack
) = (unsigned long)0x7; *(--stack
) = (unsigned long)0x6; *(--stack
) = (unsigned long)0x5; *(--stack
) = (unsigned long)0x4; task
->stack
= stack
; task
->delayTicks
= 0;
}
void tTaskSched
()
{ uint32_t status
= tTaskEnterCritical();if (currentTask
== idleTask
) {if (taskTable
[0]->delayTicks
== 0) {nextTask
= taskTable
[0];} else if (taskTable
[1]->delayTicks
== 0) {nextTask
= taskTable
[1];} else {tTaskExitCritical(status
);return;}} else {if (currentTask
== taskTable
[0]) {if (taskTable
[1]->delayTicks
== 0) {nextTask
= taskTable
[1];}else if (currentTask
->delayTicks
!= 0) {nextTask
= idleTask
;} else {tTaskExitCritical(status
);return;}}else if (currentTask
== taskTable
[1]) {if (taskTable
[0]->delayTicks
== 0) {nextTask
= taskTable
[0];}else if (currentTask
->delayTicks
!= 0) {nextTask
= idleTask
;}else {tTaskExitCritical(status
);return;}}}tTaskSwitch(); tTaskExitCritical(status
);
}
void tTaskSystemTickHandler
()
{int i
; uint32_t status
= tTaskEnterCritical();for (i
= 0; i
< 2; i
++) {if (taskTable
[i
]->delayTicks
> 0){taskTable
[i
]->delayTicks
--;}}tickCounter
++;tTaskExitCritical(status
);tTaskSched();
}
void taskDelay
(uint32_t delay
) {uint32_t status
= tTaskEnterCritical();currentTask
->delayTicks
= delay
;tTaskExitCritical(status
);tTaskSched();
}
void tSetSysTickPeriod(uint32_t ms
)
{SysTick
->LOAD
= ms
* SystemCoreClock
/ 1000 - 1;NVIC_SetPriority
(SysTick_IRQn
, (1<<__NVIC_PRIO_BITS
) - 1);SysTick
->VAL
= 0;SysTick
->CTRL
= SysTick_CTRL_CLKSOURCE_Msk
|SysTick_CTRL_TICKINT_Msk
|SysTick_CTRL_ENABLE_Msk
;
}
void SysTick_Handler
()
{tTaskSystemTickHandler();
}
int task1Flag
;
void task1Entry
(void * param
)
{tSetSysTickPeriod(10);for (;;) {task1Flag
= 1;taskDelay(1);task1Flag
= 0;taskDelay(1);}
}int task2Flag
;
void task2Entry
(void * param
)
{for (;;) {uint32_t i
;uint32_t status
= tTaskEnterCritical();uint32_t counter
= tickCounter
;for (i
= 0; i
< 0xFFFF; i
++) {} tickCounter
= counter
+ 1;tTaskExitCritical(status
);task2Flag
= 1;taskDelay(1);task2Flag
= 0;taskDelay(1);}
}
tTask tTask1
;
tTask tTask2
;
tTaskStack task1Env
[1024];
tTaskStack task2Env
[1024];
tTask tTaskIdle
;
tTaskStack idleTaskEnv
[1024];void idleTaskEntry
(void * param
) {for (;;){}
}int main
()
{tTaskInit(&tTask1
, task1Entry
, (void *)0x11111111, &task1Env
[1024]);tTaskInit(&tTask2
, task2Entry
, (void *)0x22222222, &task2Env
[1024]);taskTable
[0] = &tTask1
;taskTable
[1] = &tTask2
;tTaskInit(&tTaskIdle
, idleTaskEntry
, (void *)0, &idleTaskEnv
[1024]);idleTask
= &tTaskIdle
;nextTask
= taskTable
[0];tTaskRunFirst();return 0;
}
參考資料:
【李述銅】從0到1自己動(dòng)手寫嵌入式操作系統(tǒng)
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀
總結(jié)
以上是生活随笔為你收集整理的临界区保护的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。