色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

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

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

3天內不再提示

MCU外設寄存器謹慎賦值法

Dp1040 ? 來源:痞子衡嵌入式 ? 2023-12-12 09:14 ? 次閱讀

今天給大家介紹的是改動i.MXRT1xxx里IOMUXC_GPR寄存器保留位可能會造成系統異常

在群里有一位非常活躍的朋友,前段時間反映了一個在i.MXRT1062應用程序里動態調整FlexRAM導致WDOG模塊工作異常的問題。經過一番排查,發現了i.MXRT芯片系統設計里的一個小秘密,這個秘密警示我們在MCU里應盡量遵循謹慎的外設寄存器賦值法。

這個寄存器謹慎賦值法是什么?這里先賣個關子,文末會揭秘。今天就將這個問題解決過程還原一下,希望對大家有所啟發:

一、重配FlexRAM影響WDOG的表象問題

先交待一下問題背景,這個網友是在i.MXRT1062板子上做的測試,使用的是 SDK_EVK-MIMXRT1060oardsevkmimxrt1060driver_exampleswdogiar 例程(XiP),他對工程啟動文件和主函數改動如下:

9f3ed286-9886-11ee-8b88-92fbcf53809c.png

intmain(void)
{
wdog_config_tconfig;
BOARD_ConfigMPU();
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();

PRINTF("
********System Start********
");

//使能WDOG模塊,設置Timeout時間,不啟用中斷
WDOG_GetDefaultConfig(&config);
//Timeout value is(0xF+1)/2=8 sec.
config.timeoutValue=0xFU;
WDOG_Init(DEMO_WDOG_BASE,&config);
PRINTF("---wdog Init done---
");

while(1)
{
//故意不喂狗,讓WDOG超時復位系統
//WDOG_Refresh(DEMO_WDOG_BASE);
PRINTF("
WDOG has be refreshed!");

/*Delay.*/
delay(SystemCoreClock);
}
}

他在啟動文件 startup_MIMXRT1062.s 里將默認128KB ITCM、128KB DTCM、256KB OCRAM的FlexRAM分配調整成了256KB DTCM、256KB OCRAM(關于FlexRAM基本知識,這種FlexRAM動態調整方式僅適用XiP工程。最終運行結果里看,應用程序似乎僅運行了一次,沒有像預想得那樣重復啟動執行。

9f4d98f2-9886-11ee-8b88-92fbcf53809c.png

如果在 startup_MIMXRT1062.s 里將重配FlexRAM代碼去掉,這個WDOG例程是可以正常工作的,串口助手里可以看到循環打印,所以這很容易讓人推斷出FlexRAM重配功能導致WDOG模塊工作異常了。

9f5151b8-9886-11ee-8b88-92fbcf53809c.png

二、找到程序異常的根本原因

由于這個WDOG例程并不是完全功能異常,至少首次打印是有的,說明重配FlexRAM并沒有對程序堆棧運存等造成實質影響,啟動文件里那段重配FlexRAM代碼本身沒有邏輯問題。而打印輸出在WDOG超時時間到了之后就沒有了,看起來WDOG模塊應該是正常產生了軟復位。

為了最小化代碼去定位問題,我們將這個網友WDOG例程主函數修改如下,去掉WDOG相關代碼,直接用 NVIC_SystemReset() 代替。運行后發現,仍然僅有一次打印,這個實驗的意義是那段重配FlexRAM代碼會導致軟復位后程序沒法再次運行,而跟具體WDOG模塊無關。

intmain(void)
{
BOARD_ConfigMPU();
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();

PRINTF("
********System Start********
");

while(1)
{
NVIC_SystemReset();
}
}

我們現在將焦點放回到重配FlexRAM那段匯編代碼本身,代碼很簡單,就是將i.MXRT芯片內部的IOMUXC_GPR->GPR17(基址0x400ac044)和IOMUXC_GPR->GPR16(基址0x400ac040)分別整體賦值為0x5555aaaa和0x00000007,單純從寄存器有效功能位定義上來看,這樣操作是沒問題的。

  LDR R0,=0x400AC044
  LDR R1,=0x5555aaaa
  STR R1,[R0]
  LDR R0,=0x400AC040
  LDR R1,=0x00000007
  STR R1,[R0]

翻看手冊里關于IOMUXC_GPR->GPR17和IOMUXC_GPR->GPR16寄存器的位定義,發現IOMUXC_GPR->GPR16寄存器中有很多bit是保留位,并且其中bit21保留位默認值是1,與其他保留位默認值0不一樣。顯然 IOMUXC_GPR->GPR16 = 0x00000007 這樣的賦值語句會將其bit21誤清零,并且IOMUXC_GPR寄存器在軟復位后也不會改變其值 。

9f5c3056-9886-11ee-8b88-92fbcf53809c.png

難道問題是由IOMUXC_GPR->GPR16[21]保留位被誤清零導致的?死馬當活馬醫吧,我們修改一下重配FlexRAM代碼如下(兩種方式都行),將IOMUXC_GPR->GPR16[21]保持為默認1。

運行后發現,異常問題解決了,串口助手里可以看到循環打印。現在我們知道了IOMUXC_GPR寄存器即使是保留位也不要輕易當用戶標志位使用,更不要輕易改變其默認值,因為SoC占用了這些位,具體用途未詳述。由此可以推測IOMUXC_GPR->GPR16[21]位跟系統啟動有關,并且其值的設置是在軟復位后才生效的。

#ifdef FLEXRAM_CFG_STANDARD
  LDR R0,=0x400AC044
  MOV32 R1,0x5555aaaa
  STR R1,[R0]
  LDR R0,=0x400AC040
  LDR R1,[R0]
  ORR R1,R1,#4
  STR R1,[R0]
#else
  LDR R0,=0x400AC044
  LDR R1,=0x5555aaaa
  STR R1,[R0]
  LDR R0,=0x400AC040
  LDR R1,=0x00200007
  STR R1,[R0]
#endif

三、MCU外設寄存器謹慎賦值法

現在為大家揭秘文章開頭賣的關子,到底什么是謹慎的外設寄存器賦值法?

其實可以從芯片頭文件定義里去學,假設我們有一個模塊叫PERIPH,模塊內部有一個名為REG的寄存器,這個寄存器中有功能位FUNC(單bit或者多bit),芯片頭文件中通常定義如下:

typedefstruct{
__IOuint32_tREG;
}PERIPH_Type;

#definePERIPH_REG_FUNC_MASK(0x4U)//或者(0xCU)
#definePERIPH_REG_FUNC_SHIFT(2U)
#definePERIPH_REG_FUNC(x)(((uint32_t)(((uint32_t)(x))<

#definePERIPH_BASE(0x400AC000u)
#definePERIPH((PERIPH_Type*)PERIPH_BASE)

謹慎寄存器賦值法的核心要義就是每次操作都只涉及一種功能位,并且不要影響其他功能位的值,就像下面代碼所示。切忌出現 PERIPH->REG = value1 | value2 | ... 這樣的一次性多個不同功能位一起賦值的操作。

謹慎寄存器賦值法既可以避免模塊設計里不同功能位賦值有先后順序的限制問題,也可以防止誤改某些保留位默認值的異常情況發生。當然,這也是有小小代價的,那就是會增加了一些代碼長度。

//如果PERIPH->REG[FUNC]是單bit
PERIPH->REG|=PERIPH_REG_FUNC_MASK;
PERIPH->REG&=~PERIPH_REG_FUNC_MASK;
//如果PERIPH->REG[FUNC]是多bit
PERIPH->REG=(PERIPH->REG&(~PERIPH_REG_FUNC_MASK))|PERIPH_REG_FUNC(value);

至此,改動i.MXRT1xxx里IOMUXC_GPR寄存器保留位可能會造成系統異常便介紹完了。

本文轉載自痞子衡嵌入式公眾號

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

    關注

    455

    文章

    50714

    瀏覽量

    423154
  • mcu
    mcu
    +關注

    關注

    146

    文章

    17123

    瀏覽量

    350992
  • 寄存器
    +關注

    關注

    31

    文章

    5336

    瀏覽量

    120231
  • 應用程序
    +關注

    關注

    37

    文章

    3265

    瀏覽量

    57678

原文標題:什么是MCU里應盡量遵循的寄存器謹慎賦值法?

文章出處:【微信號:玩點嵌入式,微信公眾號:玩點嵌入式】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    為什么SSI通信接口的數據寄存器不能直接賦值

    在學SSI的通信接口,試著通過寄存器直接控制,可是調試時發現,對SSI的數據寄存器直接賦值根本就不能賦值,換句話說賦值是無效的。這是什么情況
    發表于 09-04 06:11

    寄存器,寄存器是什么意思

    寄存器,寄存器是什么意思 寄存器定義  寄存器是中央處理內的組成部分。寄存器是有限存貯容量
    發表于 03-08 14:26 ?2.2w次閱讀

    數據寄存器,數據寄存器是什么意思

    數據寄存器,數據寄存器是什么意思 數據寄存器數據寄存器包括累加AX、基址寄存器BX、計數
    發表于 03-08 14:38 ?1.3w次閱讀

    移位寄存器,移位寄存器是什么意思

    移位寄存器,移位寄存器是什么意思 移位寄存器_
    發表于 03-08 14:50 ?1.8w次閱讀

    ARM寄存器詳解

    ARM有37個寄存器,其中31個通用寄存器,6個狀態寄存器。   這里尤其要注意區別的是ARM自身寄存器和它的一些外設
    發表于 07-10 10:04 ?2956次閱讀

    FPGA 調試 – 外設寄存器視圖

    作為設計者,在 FPGA 設計中您可以訪問眾多外設器件的內部 寄存器 。一旦將FPGA設計下載到目標器件中并且代碼已經運行在相應處理上,與這些寄存器進行交互的典型方法是通過嵌入
    發表于 05-15 11:49 ?3338次閱讀
    FPGA 調試 – <b class='flag-5'>外設</b><b class='flag-5'>寄存器</b>視圖

    STM32寄存器外設驅動x_實驗四

    主要介紹STM32寄存器——外設驅動,圖文詳情,非常合適看
    發表于 02-22 15:46 ?0次下載

    DSP2407片內外設寄存器定義

    DSP2407片內外設寄存器定義,有需要的下來看看
    發表于 05-06 15:29 ?25次下載

    寄存器與移位寄存器

    寄存器與移位寄存器:介紹寄存器原理和移位寄存器的原理及實現。
    發表于 05-20 11:47 ?0次下載

    STM32 BSRR BRR ODR寄存器詳情解析

    BSRR 和 BRR 都是 STM32 系列 MCU 中 GPIO 的寄存器。 BSRR 稱為端口位設置/清楚寄存器,BRR稱為端口位**寄存器
    發表于 11-13 09:54 ?1.2w次閱讀

    STM32系列MCU,寫寄存器Or利用固件庫

    嵌入式的編程,往下說就是操作MCU寄存器。而固件庫就是函數的集合,固件庫函數的作用是向下負責與寄存器直接打交道,向上提供用戶函數調用的接口(API)。相對于固件庫的方式,直接寫寄存器
    的頭像 發表于 08-09 17:22 ?7241次閱讀
    STM32系列<b class='flag-5'>MCU</b>,寫<b class='flag-5'>寄存器</b>Or利用固件庫

    C語言訪問MCU寄存器

    C語言訪問MCU寄存器問題由來://下面這行代碼的意思是直接操作0X020C4068這個寄存器//具體寄存器的作用是通過手冊得到的#define CCM_CCGR0 *((volati
    發表于 10-25 13:21 ?3次下載
    C語言訪問<b class='flag-5'>MCU</b><b class='flag-5'>寄存器</b>

    ---GD32 MCU---SYSCFG相關寄存器無法寫入

    問題描述:客戶在使用中斷時,進行中斷的相關配置,操作SYSCFG的相關寄存器,始終無法寫入往SYSCFG的相關寄存器中寫入非0的數據。原因:GD與ST的操作有差異,GD必須保證先打開外設時鐘才能
    發表于 11-18 16:36 ?2次下載
    ---GD32 <b class='flag-5'>MCU</b>---SYSCFG相關<b class='flag-5'>寄存器</b>無法寫入

    干貨滿滿:ARM的內核寄存器講解

    內核寄存器外設寄存器: 內核寄存器外設寄存器是完全不同的概念。內核
    發表于 04-17 11:47 ?3555次閱讀
    干貨滿滿:ARM的內核<b class='flag-5'>寄存器</b>講解

    寄存器分為基本寄存器和什么兩種

    寄存器是計算機中用于存儲數據的高速存儲單元,它們是CPU內部的重要組成部分。寄存器可以分為基本寄存器和擴展寄存器兩種類型。 一、基本寄存器
    的頭像 發表于 07-12 10:31 ?1322次閱讀
    主站蜘蛛池模板: 一个人在线观看免费视频| 扒开 浓密 毛| 国产看黄网站又黄又爽又色| 米奇影视999| 亚洲成A人片在线观看中文L| a视频免费在线| 精品麻豆一卡2卡三卡4卡乱码| 日夜啪啪一区二区三区| 91久久精一区二区三区大全| 国内精品不卡一区二区三区| 日欧一片内射VA在线影院| 777EY_卡通动漫_1页| 精品人妻伦九区久久AAA片69| 四虎亚洲中文字幕永久在线| ebc5恐怖5a26房间| 久久婷婷色香五月综合激情| 亚洲VA欧美VA天堂V国产综合| 成人免费视频在线| 欧美jizz19性欧美| 2021乱码精品公司| 久久国产精品久久国产精品 | 极品虎白在线观看| 睡觉被偷偷进入magnet| a在线视频免费观看| 久久在精品线影院精品国产| 亚洲精品一区二区在线看片| 国产黄片毛片| 日韩在线av免费视久久| blacked黑人战小美女| 蜜桃成熟时2在线| 在线国产视频观看| 久久精品AV一区二区无码| 亚洲AV久久无码高潮喷水| 国产精品爆乳尤物99精品| 日韩欧美精品有码在线播放免费| 9久爱午夜视频| 免费人成网站在线观看10分钟| 中国女人内谢69xxxxxx直播| 久久久久综合网| 一级毛片全部免| 久久99热狠狠色AV蜜臀|