前言
CW32L010的FLASH存儲(chǔ)器支持安全運(yùn)行庫功能,方案商可將核心算法存儲(chǔ)于安全運(yùn)行庫區(qū)域以供客戶二次開發(fā)時(shí)調(diào)用。使能安全運(yùn)行庫保護(hù)功能后,用戶代碼可正常調(diào)用運(yùn)行安全運(yùn)行庫區(qū)域內(nèi)的函數(shù),但無法通過任何方式(CPU、SWD、ISP)讀出安全運(yùn)行庫區(qū)域的內(nèi)容,只有提供正確的密碼時(shí)才能通過ISP協(xié)議禁止安全運(yùn)行庫保護(hù)功能,同 時(shí)清空安全運(yùn)行庫存儲(chǔ)空間的數(shù)據(jù)。
一、工作原理
通過將要保護(hù)的算法指定存放到FLASH對(duì)應(yīng)的頁面page(0
二、設(shè)置安全運(yùn)行庫的具體步驟
2.1.將算法函數(shù)指定到目標(biāo)頁面
只需要使用__attribute__((section(".ARM.__at_address")))就可以將變量、數(shù)組、函數(shù)指定到FLASH的任意地址。
常見的函數(shù)類型指定地址方法如下:
@font-face{ font-family:"Times New Roman"; } @font-face{ font-family:"宋體"; } @font-face{ font-family:"Calibri"; } p.MsoNormal{ mso-style-name:正文; mso-style-parent:""; margin:0pt; margin-bottom:.0001pt; mso-pagination:none; text-align:justify; text-justify:inter-ideograph; font-family:Calibri; mso-fareast-font-family:宋體; mso-bidi-font-family:'Times New Roman'; font-size:10.5000pt; mso-font-kerning:1.0000pt; } p.MsoFooter{ mso-style-name:頁腳; mso-style-noshow:yes; margin:0pt; margin-bottom:.0001pt; tab-stops:center blank 207.6500pt right blank 415.3000pt ; layout-grid-mode:char; mso-pagination:none; text-align:left; font-family:Calibri; mso-fareast-font-family:宋體; mso-bidi-font-family:'Times New Roman'; font-size:9.0000pt; mso-font-kerning:1.0000pt; } span.msoIns{ mso-style-type:export-only; mso-style-name:""; text-decoration:underline; text-underline:single; color:blue; } span.msoDel{ mso-style-type:export-only; mso-style-name:""; text-decoration:line-through; color:red; } @page{mso-page-border-surround-header:no; mso-page-border-surround-footer:no;}@page Section0{ } div.Section0{page:Section0;} void func1 (void); void func1 (void) __attribute__((section(".ARM.__at_0x0000FE00"))); //指定func函數(shù)的地址為0x0000FE00,所在頁面為127頁 void func2 (uint8_t CNT);void func2 (uint8_t) __attribute__((section(".ARM.__at_0x0000FE50")));//指定func函數(shù)的地址為0x0000FE50,所在頁面為127頁 uint8_t func3 (uint8_t CNT1,uint8_t* p); uint8_t func3 (uint8_t, uint8_t*) __attribute__(( section(".ARM.__at_0x0000FEA4" ))); //指定func函數(shù)的地址為0x0000FEA4,所在頁面為127頁
多個(gè)函數(shù)指定地址儲(chǔ)存時(shí),在指定地址前,需先在KEIL的map文件中找到各個(gè)函數(shù)的大小,免得指定地址時(shí)內(nèi)存沖突。map文件如下:
由此可以得到func1、func2、func3的字節(jié)大小分別是0x50、0x54、0x58,接下來就可以指定函數(shù)的存儲(chǔ)地址了。
注意指定地址時(shí),因?yàn)?2位變量需要4字節(jié)對(duì)齊,也就是地址的最低位得是0、4、8、C才行,所以地址不能出現(xiàn),如:0x0000FE01、0x0000FE02、0x0000FE03、0x0000FE05、0x0000FE06、0x0000FE07、0x0000FE09、0x0000FE0A、0x0000FE0B、0x0000FE0D、0x0000FE0E、0x0000FE0F
接著就可以指定func1的地址為0x0000FE00,func2的地址為0x0000FE00+0x50,func3的地址為0x0000FE00+0x50+0x54,如想指定其它地址,依次類推。
2.2.開啟相應(yīng)頁面的安全運(yùn)行庫
使能安全運(yùn)行庫保護(hù)功能的方法為:在地址0xFFF0~ 0xFFFF 寫入特定控制字,如下表所示:
2.3.參考代碼
文章及視頻中使用到的例程源碼文件:
通過網(wǎng)盤分享的文件:CW32L010 FLASH PROTECT.zip
鏈接: https://pan.baidu.com/s/1d5tj_zz-b1bQGkJkuAgbdQ?pwd=CW32
提取碼: CW32
@font-face{ font-family:"Times New Roman"; } @font-face{ font-family:"宋體"; } @font-face{ font-family:"Calibri"; } p.MsoNormal{ mso-style-name:正文; mso-style-parent:""; margin:0pt; margin-bottom:.0001pt; mso-pagination:none; text-align:justify; text-justify:inter-ideograph; font-family:Calibri; mso-fareast-font-family:宋體; mso-bidi-font-family:'Times New Roman'; font-size:10.5000pt; mso-font-kerning:1.0000pt; } p.MsoFooter{ mso-style-name:頁腳; mso-style-noshow:yes; margin:0pt; margin-bottom:.0001pt; tab-stops:center blank 207.6500pt right blank 415.3000pt ; layout-grid-mode:char; mso-pagination:none; text-align:left; font-family:Calibri; mso-fareast-font-family:宋體; mso-bidi-font-family:'Times New Roman'; font-size:9.0000pt; mso-font-kerning:1.0000pt; } span.msoIns{ mso-style-type:export-only; mso-style-name:""; text-decoration:underline; text-underline:single; color:blue; } span.msoDel{ mso-style-type:export-only; mso-style-name:""; text-decoration:line-through; color:red; } @page{mso-page-border-surround-header:no; mso-page-border-surround-footer:no;}@page Section0{ } div.Section0{page:Section0;} void func1 (void) __attribute__((section(".ARM.__at_0x0000FE00")));//指定func函數(shù)的地址為0x0000FE00,所在頁面為127頁 void func2 (uint8_t ) __attribute__((section(".ARM.__at_0x0000FE50")));//指定func函數(shù)的地址為0x0000FE50,所在頁面為127頁 uint8_t func3 (uint8_t ,uint8_t* ) __attribute__((section(".ARM.__at_0x0000FEA4")));//指定func函數(shù)的地址為0x0000FEA4,所在頁面為127頁 void func1 (void) { //PB03---LED1 推挽輸出 CW_GPIOB->DIR_f.PIN3 = 0; CW_GPIOB->ANALOG_f.PIN3 = 0; uint8_t cnt = 10; while(cnt--) { CW_GPIOB->TOG_f.PIN3 = 1; uint32_t thisCnt = 0X9FFFF; while( thisCnt-- ) { ; } } } void func2 (uint8_t CNT) { //PB03---LED1 推挽輸出 CW_GPIOB->DIR_f.PIN3 = 0; CW_GPIOB->ANALOG_f.PIN3 = 0; uint8_t cnt = CNT; while(cnt--) { CW_GPIOB->TOG_f.PIN3 = 1; uint32_t thisCnt = 0X9FFFF; while( thisCnt-- ) { ; } } } uint8_t func3 (uint8_t CNT1,uint8_t* p) { //PB03---LED1 推挽輸出 CW_GPIOB->DIR_f.PIN3 = 0; CW_GPIOB->ANALOG_f.PIN3 = 0; uint8_t cnt = CNT1 + *p; while(cnt--) { CW_GPIOB->TOG_f.PIN3 = 1; uint32_t thisCnt = 0X9FFFF; while( thisCnt-- ) { ; } } return 0; } int32_t main(void) { uint8_t ret,temp; __SYSCTRL_FLASH_CLK_ENABLE(); __SYSCTRL_CRC_CLK_ENABLE(); __SYSCTRL_GPIOB_CLK_ENABLE(); ret = FLASH_SafetyLibraryEnable(SlibKey, 0x7F, 0x7F); if (ret) { // 開啟安全區(qū)失敗 while(1); } func1(); func2(10); temp = 5; ret = func3(5,&temp); //結(jié)束 while(1) { } }
2.4.函數(shù)調(diào)用
函數(shù)調(diào)用時(shí)需要在指定的地址上加1,因?yàn)閷?duì)于cortex M核的芯片,任何跳轉(zhuǎn)相關(guān)地址的最低位,即BIT0都應(yīng)是1。該位表示將用到的的指令集為Thumb指令。具體調(diào)用方法如下:
@font-face{ font-family:"Times New Roman"; } @font-face{ font-family:"宋體"; } @font-face{ font-family:"Calibri"; } p.MsoNormal{ mso-style-name:正文; mso-style-parent:""; margin:0pt; margin-bottom:.0001pt; mso-pagination:none; text-align:justify; text-justify:inter-ideograph; font-family:Calibri; mso-fareast-font-family:宋體; mso-bidi-font-family:'Times New Roman'; font-size:10.5000pt; mso-font-kerning:1.0000pt; } p.MsoFooter{ mso-style-name:頁腳; mso-style-noshow:yes; margin:0pt; margin-bottom:.0001pt; tab-stops:center blank 207.6500pt right blank 415.3000pt ; layout-grid-mode:char; mso-pagination:none; text-align:left; font-family:Calibri; mso-fareast-font-family:宋體; mso-bidi-font-family:'Times New Roman'; font-size:9.0000pt; mso-font-kerning:1.0000pt; } span.msoIns{ mso-style-type:export-only; mso-style-name:""; text-decoration:underline; text-underline:single; color:blue; } span.msoDel{ mso-style-type:export-only; mso-style-name:""; text-decoration:line-through; color:red; } @page{mso-page-border-surround-header:no; mso-page-border-surround-footer:no;}@page Section0{ } div.Section0{page:Section0;} #define Slib_Led_Blink1 ((void (*)())(0x0000FE00UL + 1)) #define Slib_Led_Blink2 ((void (*)(uint8_t))(0x0000FE50UL + 1)) #define Slib_Led_Blink3 ((uint8_t (*)(uint8_t,uint8_t*))(0x0000FEA4UL + 1)) int32_t main(void) { SYSCTRL_HSI_Enable(SYSCTRL_HSIOSC_DIV12); __SYSCTRL_GPIOB_CLK_ENABLE(); Slib_Led_Blink1();//方法一:宏調(diào)用 ((void (*)())(0x0000FE00UL + 1))();//方法二:直接調(diào)用 void (*ppp1) ();//方法三;函數(shù)指針調(diào)用 ppp1 = (void (*) ())(0xFE00 + 1); ppp1(); Slib_Led_Blink2(10);//方法一:宏調(diào)用 ((void (*)(uint8_t))(0x0000FE50UL + 1))(10);//方法二:直接調(diào)用 void (*ppp2)(uint8_t);//方法三;函數(shù)指針調(diào)用 ppp2 = ((void (*)(uint8_t))(0x0000FE50UL + 1)); ppp2(10); uint8_t xx = 5; uint8_t temp = Slib_Led_Blink3(5,&xx);//方法一:宏調(diào)用 ((uint8_t (*)(uint8_t,uint8_t*))(0x0000FEA4UL + 1))(5,&xx);//方法二:直接調(diào)用 uint8_t (*ppp3)(uint8_t,uint8_t*);//方法三;函數(shù)指針調(diào)用 ppp3 = (uint8_t (*)(uint8_t,uint8_t*))(0x0000FEA4+1); ppp3(5,&xx); while (1) { } }
2.5.擦除安全運(yùn)行庫
禁止安全運(yùn)行庫保護(hù)功能共有兩種方法:
(1).通過ISP協(xié)議執(zhí)行片擦操作:芯片接收到片擦指令及正確的安全運(yùn)行庫密碼時(shí),將自動(dòng)擦除本芯片的所有數(shù)據(jù)并禁止安全運(yùn)行庫保護(hù)功能;。
需要用到上位機(jī)CW-Programmmer,具體連線請(qǐng)按上位機(jī)提示進(jìn)行連接,上位機(jī)配置需按下圖配置:
填寫SDK區(qū)域密碼時(shí),需按16進(jìn)制來填寫密碼,如:十進(jìn)制1,0xF,'_','!','@','*','A','1',填寫時(shí)為它們對(duì)應(yīng)ascii值的16進(jìn)制,分別是0x01、0x0F、0x5F、0x21、0x40、0x2A、0x41、0x31,所以密碼應(yīng)該填寫010F5F21402A4131。
填寫完密碼后,點(diǎn)擊在線編程,即可擦除安全運(yùn)行庫。
(2).在RAM中對(duì)芯片執(zhí)行片擦操作:配置編譯器參數(shù),使片擦操作從RAM中執(zhí)行。片擦操作完成后,本芯片的所有數(shù)據(jù)均被擦除并禁止安全運(yùn)行庫保護(hù)功能。
2.6.注意事項(xiàng)
(1).指定算法函數(shù)的地址不要太靠前,否則會(huì)與下載的代碼起沖突,建議選擇FLASH靠后的頁面。
(2).儲(chǔ)存在安全運(yùn)行庫頁面里的函數(shù),不可調(diào)用安全區(qū)外的函數(shù)。
(3).安全運(yùn)行庫代碼下載到MCU后,要進(jìn)行上電復(fù)位才能生效。
三、現(xiàn)象演示
將安全運(yùn)行庫的代碼下載到CW32L010F8P6 StartKit REV01板子中后,斷電后重新上電,DEBUG頁面的memory中,127頁顯示不可讀,全0,表示127頁已經(jīng)受到保護(hù)了。
用戶可以在其它工程中調(diào)用儲(chǔ)存在安全運(yùn)行庫頁面的函數(shù),具體調(diào)用方法詳情見2.4函數(shù)調(diào)用章節(jié)。
四、視頻講解
CW32L010黑客區(qū)安全運(yùn)行庫保護(hù)的實(shí)現(xiàn) :1.FLASH及安全庫區(qū)域原理_嗶哩嗶哩_bilibili
CW32L010黑客區(qū)安全運(yùn)行庫保護(hù)的實(shí)現(xiàn) :2.算法編程調(diào)用及注意事項(xiàng)_嗶哩嗶哩_bilibili
CW32L010黑客區(qū)安全運(yùn)行庫保護(hù)的實(shí)現(xiàn) :3. 實(shí)例代碼運(yùn)行講解及FLASH讀取驗(yàn)證_嗶哩嗶哩_bilibili
審核編輯 黃宇
-
RAM
+關(guān)注
關(guān)注
8文章
1396瀏覽量
119195 -
算法
+關(guān)注
關(guān)注
23文章
4737瀏覽量
96686
發(fā)布評(píng)論請(qǐng)先 登錄
基于CW32L010的高性能溫控器方案

基于CW32L010的高性能溫控器方案
CW32L010 MCU在VSCode+GCC+EIDE+JLink下的使用示例

CW32L010 ESC Driver 電機(jī)控制套件快速上手指南
基于CW32L010單片機(jī)的掃振一體電動(dòng)牙刷應(yīng)用方案

基于CW32L010單片機(jī)的掃振一體電動(dòng)牙刷應(yīng)用方案
CW32L010 ESC Driver 電機(jī)控制套件使用
武漢芯源半導(dǎo)體CW32L010在兩輪車儀表的應(yīng)用介紹

武漢芯源半導(dǎo)體CW32L010在兩輪車儀表的應(yīng)用介紹
CW32L010 Motor Control Driver無刷電機(jī)驅(qū)動(dòng)板上手體驗(yàn)

方案介紹|CW32L010安全低功耗MCU:驅(qū)動(dòng)高速風(fēng)筒新力量
【產(chǎn)品方案】基于CW32L010低成本電動(dòng)工具方案

【CW32L010 Mini Board 測(cè)評(píng)】簡介、點(diǎn)燈
CW32L010 新品初體驗(yàn)

評(píng)論