精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

MM32F5330內存保護單元(MPU)設計

靈動MM32MCU ? 來源:靈動MM32MCU ? 2023-09-07 18:29 ? 次閱讀

1

MM32F5330 MPU簡介

靈動微電子發布了搭載安謀科技“星辰”STAR-MC1處理器的全新高性能 MM32F5 微控制器系列,該系列在內核、總線和外設配置等多個方面進行了創新,內核上更是首次搭載了 Armv8-M 架構的 “星辰” STAR-MC1 處理器。Armv8-M 架構相較于 Armv7-M 架構,除了性能顯著提升以外,其中一項就是更加安全:Armv8-M 架構引入了 TrustZone 技術,并強化了內存保護單元(MPU),讓代碼運行在更安全的環境中。

MPU 在 4GB 地址映射中定義保護區域。Armv8-M 上的MPU 有8個region,每一個region都有起始地址,結束地址,訪問權限和內存屬性,每一個region都有單獨的屬性。和以往Armv7-M 的MPU有所不同,Armv8-M的MPU不支持region overlap,如果一個地址同時出現在兩個不同的region中,會導致HardFault。如果程序訪問被MPU禁止的內存位置,處理器就會生成一個 MemManage異常。

MPU 本質上就是為了保護某一段地址區域不被非授權狀態的程序進行訪問。通常嵌入式操作系統使用MPU進行內存保護,內核可以根據進程動態更新MPU區域設置。MPU 可以讓嵌入式系統更加健壯,以及保護一些加密區域。MPU 具有以下能力可以增加系統的健壯性:

可以阻止用戶去破壞操作系統需要使用的數據

可以防止一個任務去非法訪問其他任務的數據,將任務完全隔離開

可以把關鍵數據區設為只讀,從而不被破壞

檢測其他意外訪問,比如堆棧溢出,數組越界等

2

內存類型

Armv8中將內存分為兩種類型:Normal memory和Device memory。Normal memory適用于系統中的大部分內存,而Device memory則適用于外設所使用的內存。

Normal memory,主要指RAMROM,FLASH等,處理器以及編譯器都可以對程序做優化,處理器還可以增加repeate,reorder,merge的操作。在強制訪問順序的情況下,需要調用內存屏障指令。

Device memory,通常都是外設對應的內存映射。Device類型用于可能有副作用的位置,不可緩存,不允許對標記為Device的區域進行推測性數據訪問。

Device memory屬性:

1) G:Gather,多個內存訪問可以合并

2) R:Reordering,對內存訪問指令進行重排

3) E:Early Write Ack,寫操作的Ack可提前應答

四種Device memory:

1) Device nGnRnE,不允許gather、reorder、early

2) Device nGnRE,允許early

3) Device nGRE,允許reorder、early

4) Device GRE,允許gather、reorder、early

下表顯示了可能的MPU region屬性,包括Shareable和Cacheable屬性。

e8e3478c-4d5e-11ee-a25d-92fbcf53809c.png

Armv8內存類型和屬性還有很多細節,對MPU region屬性配置會涉及到Cache讀寫策略的內容,感興趣的同學可以先查閱相關資料,進行詳細了解。本章節我們著重理解MPU的功能和作用,并進行簡單驗證,關于Cache內容在后續章節中再進行說明。

3

MPU寄存器模組

3.1 MPU主要有以下寄存器

e9168cfa-4d5e-11ee-a25d-92fbcf53809c.png

3.2 MPU_TYPE

MPU_TYPE寄存器用來表示MPU是否存在以及它支持多少個region。

e927ead6-4d5e-11ee-a25d-92fbcf53809c.png

3.3 MPU_CTRL

MPU_CTRL用來使能MPU、使能backgroup map、使能NMI中MPU是否有效。

e9552fd2-4d5e-11ee-a25d-92fbcf53809c.png

3.4 MPU_RNR

MPU_RNR用來選擇region,在訪問MPU_RBAR和MPU_RLAR之前,必須先寫入MPU_RNR來選擇region。

e97777ae-4d5e-11ee-a25d-92fbcf53809c.png

3.5 MPU_RBAR

MPU_RBAR定義了region的起始地址。

e9990fea-4d5e-11ee-a25d-92fbcf53809c.pnge9c59254-4d5e-11ee-a25d-92fbcf53809c.png

3.6 MPU_RLAR

MPU_RLAR定義了region的上限地址以及region屬性選擇。

e9e76eb0-4d5e-11ee-a25d-92fbcf53809c.png

3.7 MPU_MAIR0和MPU_MAIR1

MPU_MAIR0和MPU_MAIR1提供與AttrIndex值對應的內存屬性編碼。

e9fc768e-4d5e-11ee-a25d-92fbcf53809c.png

每一個region屬性MARI_ATTR占8位。

如果MAIR_ATTR[7:4]為0,那么MAIR_ATTR定義如下:

ea49a238-4d5e-11ee-a25d-92fbcf53809c.png

如果MAIR_ATTR[7:4]不為0,那么MAIR_ATTR定義如下:

ea88bd42-4d5e-11ee-a25d-92fbcf53809c.png

4

MPU配置

關于MPU的配置可以參考靈動微電子官網的LibSamples,具體在core_starmc1.h和mpu_armv8.h文件定義了MPU寄存器映射及接口函數,下表中列出部分函數:

ea9f1880-4d5e-11ee-a25d-92fbcf53809c.png

5

MPU測試

5.1 region read/write測試

定義一個指針變量指向地址0x20006000位置,在MPU關閉時,該地址可以正常進行讀寫,通過配置MPU將0x20006000 - 0x20006FFF區域設置為region0只讀,使能MPU后再進行寫訪問,仿真觀測運行情況。測試代碼如下:

voidmpu_readwrite(void)
{
volatileuint32_t*temptr=(volatileuint32_t*)0x20006000UL;
MPU_Cmd(MPU,DISABLE);//DisableMPU
*temptr=0x00;
printf("%x:%x
",(uint32_t)temptr,*temptr);
*temptr=0xA5;
printf("%x:%x
",(uint32_t)temptr,*temptr);

//Enable MPU region0:0x20006000-0x20006FFF
//Read-only,Executionnotpermitted,Devicememory
MPU_SelectRegion(MPU,0);
MPU_SetRegionBase(MPU,0x20006000UL,REGION_NON_SHAREABLE,REGION_RO_ANY,REGION_XN);
MPU_SetRegionLimit(MPU,0x20006FFFUL,0,REGION_EN);
MPU_SetRegionAttr(MPU,0,0);

MPU_HfnmienaCmd(MPU,ENABLE);
MPU_PrivdefenaCmd(MPU,ENABLE);
MPU_Cmd(MPU,ENABLE);

printf("Teststart:
");
//AfterMPUisenabled,checkwhetherthewritepermissionisgranted.
printf("%x:%x
",(uint32_t)temptr,*temptr);
//Thehardfaultwillbetriggeredwhenthecodeisexecutedhere.
*temptr=0x5A;
printf("%x:%x
",(uint32_t)temptr,*temptr);
printf("Testover!
");
}

仿真查看MPU配置和代碼執行預期一致:

eab30dea-4d5e-11ee-a25d-92fbcf53809c.png

串口調試助手打印情況:

eaf6c99a-4d5e-11ee-a25d-92fbcf53809c.png

打印Test start之前的數據可以進行讀寫,使能MPU之后先打印一次數據,即可讀,但是運行到賦值語句*temptr = 0x5A,就進入了HardFault,說明該地址不可寫。

eb051a0e-4d5e-11ee-a25d-92fbcf53809c.png

修改測試代碼設置region0為可讀寫:

MPU_SelectRegion(MPU,0);
MPU_SetRegionBase(MPU,0x20006000UL,REGION_NON_SHAREABLE,REGION_RW_ANY,REGION_XN);
MPU_SetRegionLimit(MPU,0x20006FFFUL,0,REGION_EN);
MPU_SetRegionAttr(MPU,0,0);

仿真查看MPU配置和代碼執行預期一致:

eb4f7860-4d5e-11ee-a25d-92fbcf53809c.png

串口調試助手打印情況:

eb861122-4d5e-11ee-a25d-92fbcf53809c.png

測試代碼得到全部執行,使能MPU之后先打印一次數據,即可讀,運行賦值語句*temptr = 0x5A后,打印該地址的數據是0x5A,說明寫正常。

綜上,MPU可以有效設置區域的讀寫權限。

5.2 region overlap測試

定義一個指針變量指向地址0x20006000位置,在MPU關閉時,該地址可以正常進行讀寫,通過配置MPU將0x20006000 - 0x20006FFF區域設置為region0可讀寫,將0x20005000 - 0x20007FFF區域設置為region1可讀寫,使能MPU后再訪問地址0x20006000,測試代碼如下:

voidmpu_overlap(void)
{
volatileuint32_t*temptr=(volatileuint32_t*)0x20006000UL;

MPU_Cmd(MPU,DISABLE);
*temptr=0x00;
printf("%x:%x
",(uint32_t)temptr,*temptr);
*temptr=0xB9;
printf("%x:%x
",(uint32_t)temptr,*temptr);

//Configure region0:0x20006000-0x20006FFF
//Read/write,Executionnotpermitted,Devicememory
MPU_SelectRegion(MPU,0);
MPU_SetRegionBase(MPU,0x20006000UL,REGION_NON_SHAREABLE,REGION_RW_PRIV_ONLY,REGION_XN);
MPU_SetRegionLimit(MPU,0x20006FFFUL,0,REGION_EN);
MPU_SetRegionAttr(MPU,0,0);

//Configure region1:0x20005000-0x20007FFF
//Read/write,Executionnotpermitted,Devicememory
MPU_SelectRegion(MPU,1);
MPU_SetRegionBase(MPU,0x20005000UL,REGION_NON_SHAREABLE,REGION_RW_PRIV_ONLY,REGION_XN);
MPU_SetRegionLimit(MPU,0x20007FFFUL,1,REGION_EN);
MPU_SetRegionAttr(MPU,0,1);

MPU_HfnmienaCmd(MPU,ENABLE);
MPU_PrivdefenaCmd(MPU,ENABLE);
MPU_Cmd(MPU,ENABLE);

printf("Teststart:
");
//Theaddressofthe0x20006000overlapsinregion0andregion1.
//Accessingtheaddresstriggersahardfault.
printf("%x:%x
",(uint32_t)temptr,*temptr);
printf("Testover!
");
}

仿真查看MPU配置情況和代碼執行預期一致:

eb97d09c-4d5e-11ee-a25d-92fbcf53809c.png

串口調試助手打印情況:

ebbdea16-4d5e-11ee-a25d-92fbcf53809c.png

打印Test start之前的數據可以進行讀寫,使能MPU之后,因為地址0x20006000位于region0和region1的overlap區域,運行打印*temptr 的語句,就進入了HardFault,該位置不可訪問,說明MPU不支持region overlap,否則對overlap區域訪問時會觸發HardFault。

ebcb514c-4d5e-11ee-a25d-92fbcf53809c.png

5.3 region code execute測試

將func()函數定義在指定地址0x08007800位置,在MPU關閉時,程序中調用該函數可以正常執行,通過配置MPU將0x08007800 - 0x080087FF區域設置為region0不可執行,使能MPU后再次運行func()函數,觀察測試情況。測試代碼如下:

voidfunc(void)__attribute__((section(".ARM.__AT_0x08007800")));
voidfunc(void)
{
printf("Executethefunction!
");
}

voidmpu_xn(void)
{
//Injectcodeat0x08007800
typedefvoid(*test_func_t)(void);
test_func_ttest_func=(test_func_t)0x08007801;
test_func();
MPU_Cmd(MPU,DISABLE);

//Enable MPU region0:0x08007800-0x080087FF
//Read-only,Executionnotpermitted,Devicememory
MPU_SelectRegion(MPU,0);
MPU_SetRegionBase(MPU,0x08007800UL,REGION_NON_SHAREABLE,REGION_RO_PRIV_ONLY,REGION_XN);
MPU_SetRegionLimit(MPU,0x080087FFUL,0,REGION_EN);
MPU_SetRegionAttr(MPU,0,0);

MPU_HfnmienaCmd(MPU,ENABLE);
MPU_PrivdefenaCmd(MPU,ENABLE);
MPU_Cmd(MPU,ENABLE);
printf("Teststart:
");
//Thetest_funcof0x08007800cannotbeexecutedafterMPUisenabled.
//Thehardfaultwillbetriggeredwhenthecodeisexecutedhere.
test_func();
printf("Testover!
");
}

仿真查看MPU配置情況和代碼執行預期一致:

ebfd74f6-4d5e-11ee-a25d-92fbcf53809c.png

串口調試助手打印情況:

ec53a59c-4d5e-11ee-a25d-92fbcf53809c.png

打印Test start之前調用func()函數一次,執行正常。使能MPU之后,再次調用func()函數,就進入了HardFault,該代碼不可執行。

ec604914-4d5e-11ee-a25d-92fbcf53809c.png

6

小結

MPU為存儲保護單元,它位于存儲器內部的一個可編程的區域,定義了存儲器的屬性和訪問權限,試圖訪問非法或者不允許的內存地址則會觸發HardFault異常。MPU能夠提高嵌入式系統的健壯性,使得系統更加安全。實際應用中根據具體的項目需要,選擇MPU是默認配置還是需要更改一些配置,這樣才能使應用更加符合要求。






審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 微控制器
    +關注

    關注

    48

    文章

    7487

    瀏覽量

    151042
  • 處理器
    +關注

    關注

    68

    文章

    19159

    瀏覽量

    229112
  • 存儲器
    +關注

    關注

    38

    文章

    7452

    瀏覽量

    163598
  • MPU
    MPU
    +關注

    關注

    0

    文章

    346

    瀏覽量

    48735

原文標題:靈動微課堂 (第269講)|MM32F5330內存保護單元(MPU)

文章出處:【微信號:MindMotion-MMCU,微信公眾號:靈動MM32MCU】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    管理STM32 MCU中的內存保護單元

    本應用筆記介紹如何管理 STM32 產品中的內存保護單元MPU)。MPU 是用于存儲器保護的可選組件。STM32 微控制器(MCU)中嵌入
    發表于 12-23 11:04 ?1032次閱讀

    【安富萊】【μCOS-III教程】第6章 內存保護單元MPU

    第6章內存保護單元MPU本期教程帶領大家學習內存保護單元MPU的使用,在前面的幾期教程中曾多次的
    發表于 01-08 18:04

    主要講armv7-m架構下的MPU內存保護單元

    簡介MPU(Memory Protection Unit) 內存保護單元。 本文主要講 armv7-m 架構 架構下的 MPU。在 armv7-m 架構下,Cortex-M3 和 Co
    發表于 04-08 11:00

    如何為MPC5744P配置內存保護單元

    我想知道更多關于如何為 MPC5744P 配置內存保護單元,我需要知道如何使用這個配置器。
    發表于 04-04 09:03

    Armv8-M內存模型與內存保護用戶指南

    本指南概述了Armv8-M內存模型和內存保護單元(MPU)在Cortex-M處理器中實現。本指南使用示例來幫助解釋這些概念 它介紹了。 本章概述以下主題: ?
    發表于 08-02 08:12

    如何管理STM32產品中的內存保護單元MPU

    本應用筆記介紹如何管理 STM32 產品中的內存保護單元MPU)。MPU 是用于存儲器保護的可選組件。STM32 微控制器(MCU)中嵌入
    發表于 09-07 06:23

    Cortex-M內核的MPU內存保護單元

    講講Cortex-M內核的MPU內存保護單元
    的頭像 發表于 03-04 11:17 ?3615次閱讀
    Cortex-M內核的<b class='flag-5'>MPU</b><b class='flag-5'>內存保護</b><b class='flag-5'>單元</b>

    Cortex-M內核的MPU內存保護單元

    的選配件,拿STM32F1來說,STM32F10X_XL系列的芯片才具有這個MPU存儲保護單元,而其他STM32
    發表于 12-01 12:21 ?9次下載
    Cortex-M內核的<b class='flag-5'>MPU</b><b class='flag-5'>內存保護</b><b class='flag-5'>單元</b>

    為什么要使用MPUMPU如何實現內存保護

    如果你開發的嵌入式項目,因內存溢出,或者內存故障等一些原因,造成了重大經濟損失,或者造成了重大事故,你就能體會為什么要使用內存保護單元MPU
    的頭像 發表于 07-05 17:38 ?6661次閱讀
    為什么要使用<b class='flag-5'>MPU</b>?<b class='flag-5'>MPU</b>如何實現<b class='flag-5'>內存保護</b>?

    管理 STM32 MCU 中的內存保護單元

    管理 STM32 MCU 中的內存保護單元
    發表于 11-21 08:11 ?4次下載
    管理 STM32 MCU 中的<b class='flag-5'>內存保護</b><b class='flag-5'>單元</b>

    AN4838 管理STM32 MCU中的內存保護單元

    AN4838 管理STM32 MCU中的內存保護單元
    發表于 11-21 17:07 ?0次下載
    AN4838 管理STM32 MCU中的<b class='flag-5'>內存保護</b><b class='flag-5'>單元</b>

    應用筆記|管理STM32 MCU中的內存保護單元

    內存保護單元MPU)。MPU 是用于存儲器保護的可選組件。STM32 微控制器(MCU)中嵌入 MP
    的頭像 發表于 12-21 21:05 ?986次閱讀

    為什么要使用MPUMPU如何實現內存保護

    如果你開發的嵌入式項目,因內存溢出,或者內存故障等一些原因,造成了重大經濟損失,或者造成了重大事故,你就能體會為什么要使用內存保護單元MPU
    的頭像 發表于 02-24 11:59 ?2615次閱讀

    什么是MPUMPU在哪些方面保護內存安全?

    內存保護單元(MPU)是一種硬件機制,通過只允許代碼訪問需要的內存和外設來提高嵌入式設備的安全性。
    的頭像 發表于 06-12 09:06 ?1.1w次閱讀
    什么是<b class='flag-5'>MPU</b>?<b class='flag-5'>MPU</b>在哪些方面<b class='flag-5'>保護</b><b class='flag-5'>內存</b>安全?

    如何管理STM32產品中的內存保護單元(MPU)

    電子發燒友網站提供《如何管理STM32產品中的內存保護單元(MPU).pdf》資料免費下載
    發表于 08-01 09:15 ?0次下載
    如何管理STM32產品中的<b class='flag-5'>內存保護</b><b class='flag-5'>單元</b>(<b class='flag-5'>MPU</b>)