chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Cortex-M裸機(jī)環(huán)境下臨界區(qū)保護(hù)的三種實(shí)現(xiàn)

strongerHuang ? 來(lái)源:痞子衡嵌入式 ? 作者:痞子衡 ? 2021-09-08 09:23 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

今天給大家分享的是Cortex-M裸機(jī)環(huán)境下臨界區(qū)保護(hù)的三種實(shí)現(xiàn)。

嵌入式玩過(guò) RTOS 的朋友想必都對(duì) OS_ENTER_CRITICAL()、OS_EXIT_CRITICAL() 這個(gè)功能代碼對(duì)特別眼熟,在 RTOS 里常常會(huì)有多任務(wù)(進(jìn)程)處理,有些情況下一些特殊操作(比如 XIP 下 Flash 擦寫、低功耗模式切換)不能被隨意打斷,或者一些共享數(shù)據(jù)區(qū)不能被無(wú)序訪問(wèn)(A 任務(wù)正在讀,B 任務(wù)卻要寫),這時(shí)候就要用到臨界區(qū)保護(hù)策略了。

所謂臨界區(qū)保護(hù)策略,簡(jiǎn)單說(shuō)就是系統(tǒng)中硬件臨界資源或者軟件臨界資源,多個(gè)任務(wù)必須互斥地對(duì)它們進(jìn)行訪問(wèn)。RTOS 環(huán)境下有現(xiàn)成的臨界區(qū)保護(hù)接口函數(shù),而裸機(jī)系統(tǒng)里其實(shí)也有這種需求。在裸機(jī)系統(tǒng)里,臨界區(qū)保護(hù)主要就是跟系統(tǒng)全局中斷控制有關(guān)。痞子衡之前寫過(guò)一篇 《嵌入式MCU中通用的三重中斷控制設(shè)計(jì)》,文中介紹的第三重也是最頂層的中斷控制是系統(tǒng)全局中斷控制,今天痞子衡就從這個(gè)系統(tǒng)全局中斷控制使用入手給大家介紹三種臨界區(qū)保護(hù)做法:

一、臨界區(qū)保護(hù)測(cè)試場(chǎng)景

關(guān)于臨界區(qū)保護(hù)的測(cè)試場(chǎng)景無(wú)非兩種。第一種場(chǎng)景是受保護(hù)的多個(gè)任務(wù)間并無(wú)關(guān)聯(lián),也不會(huì)互相嵌套,如下面的代碼所示,task1 和 task2 是按序被保護(hù)的,因此 enter_critical() 和 exit_critical() 這兩個(gè)臨界區(qū)保護(hù)函數(shù)總是嚴(yán)格地成對(duì)執(zhí)行:

void critical_section_test(void)

{

// 進(jìn)入臨界區(qū)

enter_critical();

// 做受保護(hù)的任務(wù)1

do_task1();

// 退出臨界區(qū)

exit_critical();

// 進(jìn)入臨界區(qū)

enter_critical();

// 做受保護(hù)的任務(wù)2,與任務(wù)1無(wú)關(guān)聯(lián)

do_task2();

// 退出臨界區(qū)

exit_critical();

}

第二種場(chǎng)景就是多個(gè)任務(wù)間可能有關(guān)聯(lián),會(huì)存在嵌套情況,如下面的代碼所示,task2 是 task1 的一個(gè)子任務(wù),這種情況下,你會(huì)發(fā)現(xiàn)實(shí)際上是先執(zhí)行兩次 enter_critical(),然后再執(zhí)行兩次 exit_critical()。需要注意的是 task1 里面的子任務(wù) task3 雖然沒(méi)有像子任務(wù) task2 那樣被主動(dòng)加一層保護(hù),但由于主任務(wù) task1 整體是受保護(hù)的,因此子任務(wù) task3 也應(yīng)該是受保護(hù)的。

void do_task1(void)

{

// 進(jìn)入臨界區(qū)

enter_critical();

// 做受保護(hù)的任務(wù)2,是任務(wù)1中的子任務(wù)

do_task2();

// 退出臨界區(qū)

exit_critical();

// 做任務(wù)3

do_task3();

}

void critical_section_test(void)

{

// 進(jìn)入臨界區(qū)

enter_critical();

// 做受保護(hù)的任務(wù)1

do_task1();

// 退出臨界區(qū)

exit_critical();

}

二、臨界區(qū)保護(hù)三種實(shí)現(xiàn)

上面的臨界區(qū)保護(hù)測(cè)試場(chǎng)景很清楚了,現(xiàn)在到 enter_critical()、exit_critical() 這對(duì)臨界區(qū)保護(hù)函數(shù)的實(shí)現(xiàn)環(huán)節(jié)了:

2.1 入門做法

首先是非常入門的做法,直接就是對(duì)系統(tǒng)全局中斷控制函數(shù) __disable_irq()、__enable_irq() 的封裝?;氐缴弦还?jié)的測(cè)試場(chǎng)景里,這種實(shí)現(xiàn)可以很好地應(yīng)對(duì)非嵌套型任務(wù)的保護(hù),但是對(duì)于互相嵌套的任務(wù)保護(hù)就失效了。上一節(jié)測(cè)試代碼里,task3 應(yīng)該也要受到保護(hù)的,但實(shí)際上并沒(méi)有被保護(hù),因?yàn)榫o接著 task2 后面的 exit_critical() 直接就打開了系統(tǒng)全局中斷。

void enter_critical(void)

{

// 關(guān)閉系統(tǒng)全局中斷

__disable_irq();

}

void exit_critical(void)

{

// 打開系統(tǒng)全局中斷

__enable_irq();

}

2.2 改進(jìn)做法

針對(duì)入門做法,可不可以改進(jìn)呢?當(dāng)然可以,我們只需要加一個(gè)全局變量 s_lockObject 來(lái)實(shí)時(shí)記錄當(dāng)前已進(jìn)入的臨界區(qū)保護(hù)的次數(shù),即如下代碼所示。每調(diào)用一次 enter_critical() 都會(huì)直接關(guān)閉系統(tǒng)全局中斷(保證臨界區(qū)一定是受保護(hù)的),并記錄次數(shù),而調(diào)用 exit_critical() 時(shí)僅當(dāng)當(dāng)前次數(shù)是 1 時(shí)(即當(dāng)前不是臨界區(qū)保護(hù)嵌套情況),才會(huì)打開系統(tǒng)全局中斷,否則只是抵消一次進(jìn)入臨界區(qū)次數(shù)而已。改進(jìn)后的實(shí)現(xiàn)顯然可以保護(hù)上一節(jié)測(cè)試代碼里的 task3 了。

static uint32_t s_lockObject;

void init_critical(void)

{

__disable_irq();

// 清零計(jì)數(shù)器

s_lockObject = 0;

__enable_irq();

}

void enter_critical(void)

{

// 關(guān)閉系統(tǒng)全局中斷

__disable_irq();

// 計(jì)數(shù)器加 1

++s_lockObject;

}

void exit_critical(void)

{

if (s_lockObject 《= 1)

{

// 僅當(dāng)計(jì)數(shù)器不大于 1 時(shí),才打開系統(tǒng)全局中斷,并清零計(jì)數(shù)器

s_lockObject = 0;

__enable_irq();

}

else

{

// 當(dāng)計(jì)數(shù)器大于 1 時(shí),直接計(jì)數(shù)器減 1 即可

--s_lockObject;

}

}

2.3 終極做法

上面的改進(jìn)做法雖然解決了臨界區(qū)任務(wù)嵌套保護(hù)的問(wèn)題,但是增加了一個(gè)全局變量和一個(gè)初始化函數(shù),實(shí)現(xiàn)不夠優(yōu)雅,并且嵌入式系統(tǒng)里全局變量極容易被篡改,存在一定風(fēng)險(xiǎn),有沒(méi)有更好的實(shí)現(xiàn)呢?當(dāng)然有,這要借助 Cortex-M 處理器內(nèi)核的特殊屏蔽寄存器 PRIMASK,下面是 PRIMASK 寄存器位定義(取自 ARMv7-M 手冊(cè)),其僅有最低位 PM 是有效的,當(dāng) PRIMASK[PM] 為 1 時(shí),系統(tǒng)全局中斷是關(guān)閉的(將執(zhí)行優(yōu)先級(jí)提高到 0x0/0x80);當(dāng) PRIMASK[PM] 為 0 時(shí),系統(tǒng)全局中斷是打開的(對(duì)執(zhí)行優(yōu)先級(jí)無(wú)影響)。

345fd67a-1018-11ec-8fb8-12bb97331649.png

看到這,你應(yīng)該明白了 __disable_irq()、__enable_irq() 功能其實(shí)就是操作 PRIMASK 寄存器實(shí)現(xiàn)的。既然 PRIMASK 寄存器控制也保存了系統(tǒng)全局中斷的開關(guān)狀態(tài),我們可以通過(guò)獲取 PRIMASK 值來(lái)替代上面改進(jìn)做法里的全局變量 s_lockObject 的功能,代碼實(shí)現(xiàn)如下:

uint32_t enter_critical(void)

{

// 保存當(dāng)前 PRIMASK 值

uint32_t regPrimask = __get_PRIMASK();

// 關(guān)閉系統(tǒng)全局中斷(其實(shí)就是將 PRIMASK 設(shè)為 1)

__disable_irq();

return regPrimask;

}

void exit_critical(uint32_t primask)

{

// 恢復(fù) PRIMASK

__set_PRIMASK(primask);

}

因?yàn)?enter_critical()、exit_critical() 函數(shù)原型有所變化,因此使用上也要相應(yīng)改變下:

void critical_section_test(void)

{

// 進(jìn)入臨界區(qū)

uint32_t primask = enter_critical();

// 做受保護(hù)的任務(wù)

do_task();

// 退出臨界區(qū)

exit_critical(primask);

// 。..

}

附錄、PRIMASK寄存器設(shè)置函數(shù)在各 IDE 下實(shí)現(xiàn)

//////////////////////////////////////////////////////// IAR 環(huán)境下實(shí)現(xiàn)(見 cmsis_iccarm.h 文件)#define __set_PRIMASK(VALUE) (__arm_wsr(“PRIMASK”, (VALUE)))#define __get_PRIMASK() (__arm_rsr(“PRIMASK”))//////////////////////////////////////////////////////// Keil 環(huán)境下實(shí)現(xiàn)(見 cmsis_armclang.h 文件)

__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask)

{

__ASM volatile (“MSR primask, %0” : : “r” (priMask) : “memory”);

}

__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void)

{

uint32_t result;

__ASM volatile (“MRS %0, primask” : “=r” (result) );

return(result);

}

至此,Cortex-M裸機(jī)環(huán)境下臨界區(qū)保護(hù)的三種實(shí)現(xiàn)已經(jīng)講述完畢,你學(xué)廢了嗎?

責(zé)任編輯:haq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 單片機(jī)
    +關(guān)注

    關(guān)注

    6071

    文章

    45259

    瀏覽量

    660160
  • 嵌入式
    +關(guān)注

    關(guān)注

    5175

    文章

    19983

    瀏覽量

    324504
  • RTOS
    +關(guān)注

    關(guān)注

    24

    文章

    856

    瀏覽量

    122209

原文標(biāo)題:?jiǎn)纹瑱C(jī)非RTOS時(shí),臨界區(qū)保護(hù)的實(shí)現(xiàn)辦法

文章出處:【微信號(hào):strongerHuang,微信公眾號(hào):strongerHuang】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    rtt使用的軟件i2c庫(kù)進(jìn)行模擬i2c時(shí)序時(shí),不需要加臨界區(qū)保護(hù)嗎?

    這里進(jìn)行模擬i2c時(shí)序,不需要加臨界區(qū)保護(hù)。假如我有一個(gè)低優(yōu)先級(jí)的線程正在進(jìn)行i2c讀寫,這時(shí)候有個(gè)高優(yōu)先級(jí)的線程進(jìn)行搶占,做了一些工作,這個(gè)時(shí)候i2c的時(shí)序就被破壞了吧。還是說(shuō) rtt 不考
    發(fā)表于 09-10 08:09

    請(qǐng)問(wèn)NuMicro? Cortex-M? 系列芯片是否支持 I2C 監(jiān)視器功能?

    NuMicro? Cortex-M? 系列芯片是否支持 I2C 監(jiān)視器功能?
    發(fā)表于 08-21 06:04

    三種SPWM波形生成算法的分析與實(shí)現(xiàn)

    摘要:變頻技術(shù)作為現(xiàn)代電力電子的核心技術(shù),集現(xiàn)代電子、信息和智能技術(shù)于一體。而SPW(正弦波脈寬調(diào)制)波的產(chǎn)生和控制則是變頻技術(shù)的核心之一。本文對(duì)SPI波形生成的三種算法-對(duì)稱規(guī)則采樣法、不對(duì)稱規(guī)則
    發(fā)表于 07-31 13:34

    MEMS中的三種測(cè)溫方式

    在集成MEMS芯片的環(huán)境溫度測(cè)量領(lǐng)域,熱阻、熱電堆和PN結(jié)原理是三種主流技術(shù)。熱阻是利用熱敏電阻,如金屬鉑或注入硅的溫度電阻系數(shù)恒定,即電阻隨溫度線性變化的特性測(cè)溫,電阻變化直接對(duì)應(yīng)絕對(duì)溫度,需恒流源供電。
    的頭像 發(fā)表于 07-16 13:58 ?1098次閱讀
    MEMS中的<b class='flag-5'>三種</b>測(cè)溫方式

    開關(guān)電源三種控制模式:PWM/PFM/PSM

    摘要 本文詳細(xì)介紹了開關(guān)電源的三種主要調(diào)制方式:PWM(脈沖寬度調(diào)制)、PFM(脈沖頻率調(diào)制)和PSM(脈沖跨周期調(diào)制)。PWM通過(guò)調(diào)整脈沖寬度保持恒定頻率,適用于重負(fù)載,但輕負(fù)載效率低。PFM則在
    發(fā)表于 06-09 16:11

    介紹三種常見的MySQL高可用方案

    在生產(chǎn)環(huán)境中,為了確保數(shù)據(jù)庫(kù)系統(tǒng)的連續(xù)可用性、降低故障恢復(fù)時(shí)間以及實(shí)現(xiàn)業(yè)務(wù)的無(wú)縫切換,高可用(High Availability, HA)方案至關(guān)重要。本文將詳細(xì)介紹三種常見的 MySQL 高可用
    的頭像 發(fā)表于 05-28 17:16 ?819次閱讀

    redis三種集群方案詳解

    在Redis中提供的集群方案總共有三種(一般一個(gè)redis節(jié)點(diǎn)不超過(guò)10G內(nèi)存)。
    的頭像 發(fā)表于 03-31 10:46 ?1115次閱讀
    redis<b class='flag-5'>三種</b>集群方案詳解

    DeepSeek企業(yè)級(jí)部署RakSmart裸機(jī)環(huán)境準(zhǔn)備指南

    RakSmart裸機(jī)環(huán)境中部署DeepSeek的企業(yè)級(jí)環(huán)境準(zhǔn)備指南,內(nèi)容涵蓋關(guān)鍵步驟和注意事項(xiàng),主機(jī)推薦小編為您整理發(fā)布DeepSeek企業(yè)級(jí)RakSmart裸機(jī)云部署指南。
    的頭像 發(fā)表于 03-24 10:07 ?618次閱讀

    介紹三種數(shù)據(jù)保護(hù)策略的特點(diǎn)與適用場(chǎng)景

    在企業(yè)IT環(huán)境中,數(shù)據(jù)保護(hù)是不可忽視的重要環(huán)節(jié),而復(fù)制(Replication)、快照(Snapshot)和備份(Backup)是三種常見的策略。它們?cè)跀?shù)據(jù)恢復(fù)、業(yè)務(wù)連續(xù)性以及災(zāi)難恢復(fù)中扮演著不同的角色,但很多企業(yè)在選擇數(shù)據(jù)
    的頭像 發(fā)表于 03-21 11:46 ?1130次閱讀

    瑞薩RA8快速上手指南:Cortex-M85內(nèi)核瑞薩RA8開發(fā)環(huán)境搭建 并點(diǎn)亮一個(gè)LED

    因?yàn)?b class='flag-5'>Cortex-M內(nèi)核,瑞薩RA8系列單片機(jī)支持多種市面上常見的開發(fā)環(huán)境,像Keil MDK、IAR EWARM等,而本文講述的是瑞薩自家官方的IDE(e2 studio)。
    的頭像 發(fā)表于 03-17 14:35 ?1320次閱讀
    瑞薩RA8快速上手指南:<b class='flag-5'>Cortex-M</b>85內(nèi)核瑞薩RA8開發(fā)<b class='flag-5'>環(huán)境</b>搭建 并點(diǎn)亮一個(gè)LED

    GaN、超級(jí)SI、SiC這三種MOS器件的用途區(qū)別

    如果想要說(shuō)明白GaN、超級(jí)SI、SiC這三種MOS器件的用途區(qū)別,首先要做的是搞清楚這三種功率器件的特性,然后再根據(jù)材料特性分析具體應(yīng)用。
    的頭像 發(fā)表于 03-14 18:05 ?1874次閱讀

    示波器的三種觸發(fā)模式

    示波器的觸發(fā)方式不僅影響波形捕捉的時(shí)機(jī),還決定了顯示的波形是否穩(wěn)定。 常見的觸發(fā)模式有三種: 單次觸發(fā) (Single)、 正常觸發(fā) (Normal)和 自動(dòng)觸發(fā) (Auto)。下面將對(duì)這三種觸發(fā)
    的頭像 發(fā)表于 01-07 11:04 ?1.1w次閱讀
    示波器的<b class='flag-5'>三種</b>觸發(fā)模式

    如何使用Ozone分析Cortex-M異常

    Ozone可以幫助用戶快速分析和查找導(dǎo)致CPU故障的軟件bug。本文解釋如何使用Ozone的調(diào)試功能,深入了解Cortex-M架構(gòu)上的這些錯(cuò)誤。
    的頭像 發(fā)表于 11-29 11:14 ?2221次閱讀
    如何使用Ozone分析<b class='flag-5'>Cortex-M</b>異常

    三種封裝形式的400G光模塊概述

    本文主要就三種封裝形式(QSFP-DD、OSFP、QSFP112)的400G光模塊做了簡(jiǎn)單的梳理,從為什么會(huì)有400G光模塊問(wèn)世?400G光模塊在三種封裝形式的各個(gè)具體型號(hào)(以短距離為主,最遠(yuǎn)2km),
    的頭像 發(fā)表于 11-11 11:35 ?1613次閱讀
    <b class='flag-5'>三種</b>封裝形式<b class='flag-5'>下</b>的400G光模塊概述

    I2S有左對(duì)齊,右對(duì)齊跟標(biāo)準(zhǔn)的I2S三種格式,那么這三種格式各有什么優(yōu)點(diǎn)呢?

    大家好,關(guān)于I2S格式,有兩個(gè)疑問(wèn)請(qǐng)教一 我們知道I2S有左對(duì)齊,右對(duì)齊跟標(biāo)準(zhǔn)的I2S三種格式,那么這三種格式各有什么優(yōu)點(diǎn)呢? 而且對(duì)于標(biāo)準(zhǔn)的I2S格式,32FS傳輸16bit的數(shù)據(jù),48fs傳輸24bit的數(shù)據(jù),最低位會(huì)移
    發(fā)表于 10-21 08:23