久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 12014|回復: 0
打印 上一主題 下一主題
收起左側

一個關于MCU讀保護操作后程序不能運行的話題

[復制鏈接]
跳轉到指定樓層
樓主
ID:98618 發表于 2015-12-8 03:04 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
整理:MilerShao

某日,一來自北京的工程師跟我說在使用STM32L151芯片做產品開發,基本功能開發完畢。他欲通過用戶程序對芯片信息塊的相關選項字節進行配置,來完成芯片的讀保護。結果他發現無法利用其用戶程序實現芯片的讀保護加密。

他把涉及芯片讀保護操作的代碼發給我,希望協助查看測試。我簡單測試了下,發現可以實現讀保加密并告知測試結果。他很快反饋說,讀保護加密的確實現了,但程序沒法跑了。因為忙碌,沒做進一步測試,只是讓他再檢查下代碼。

過了個周末,客戶工程師還是充滿憂傷和委屈繼續追問此事。因為我覺得即使他自己寫不來那個讀保護加密代碼也沒關系,交給其它燒錄工具來實現并沒啥不好或不方便。可這哥們訴說他的經理非要它用自己的代碼實現,不停追問結果,折騰好幾天無果。

該工程師是利用ST官方標準固件庫做的,跟我手頭上的一樣,都是STM32L1系列標準固件庫1.3.

隨便搭建了個項目,并在代碼里做讀保護代碼的編寫。編譯生成機器碼,燒錄程序進入STM32L15x所在目標板。復位目標板,發現程序真的無法運行。通過STLINK UTLITY或STVP連接目標板,發現芯片的確已經做了LEVEL 1讀保護加密。

去掉源代碼里相關讀保護的程序代碼,再次編譯、燒錄,程序運行

一切正常。當代碼里加了讀保護代碼后程序無法正常運行,那問題一定出在那段讀保護操作的代碼上。用戶的代碼主要就下面幾句,那最有可能出問題應該在藍色那句。該句函數調用做實質的讀保護操作。

Rdp_Status=FLASH_OB_GetRDP(); //查詢當前芯片讀保護狀態

if(Rdp_Status== RESET)

{

FLASH_Unlock();

FLASH_OB_Unlock();

FLASH_OB_RDPConfig(OB_RDP_Level_1);//做讀保護配置操作

FLASH_OB_Lock();

FLASH_Lock();

FLASH_OB_Launch();

}

*********************************************************************

打開上面藍色語句的函數調用,其具體函數實現代碼如下:

FLASH_Status FLASH_OB_RDPConfig(uint8_t OB_RDP)

{

FLASH_Status status = FLASH_COMPLETE;

uint8_t tmp1 = 0;

uint32_t tmp2 = 0;

/* Check the parameters */

assert_param(IS_OB_RDP(OB_RDP));

status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);

/* calculate the option byte to write */

tmp1=(uint8_t)(~(OB_RDP ));

tmp2=(uint32_t)(((uint32_t)((uint32_t)(tmp1)<<16))|((uint32_t)OB_RDP));

if(status == FLASH_COMPLETE)

{

OB->RDP = tmp2; /* program read protection level */

}

/* Wait for last operation to be completed */

status = FLASH_WaitForLastOperation(FLASH_ER_PRG_TIMEOUT);

/* Return the Read protection operation Status */

return status;

}

上面代碼應該說也很簡單,就幾條賦值語句。目的就是給讀保護相關選項賦予適當的數值。這里代碼有無問題就有必要結合手冊相關部分和相關定義來做解讀。不妨看看RDP操作相關部分。




每個OPTION項都是一個32位字,高16位與低16位必須成互補關系

其中讀保護項是在上面的第一個選項字中配置的,除了 RDP和nRDP外,還有SPRMOD和nSPROMOD,他們共同組成一個完整的、可互補校驗的配置字。

結合上面的原則再過來看上面提到的讀保護配置函數:

FLASH_OB_RDPConfig( uint8_t OB_RDP); 這里OB_RDP為0xBB,目的是為了實現LEVEL 1讀保護加密。 當按照如下代碼換算后:

tmp1 = (uint8_t)(~(OB_RDP ));

tmp2=(uint32_t)(((uint32_t)((uint32_t)(tmp1)<<16))|((uint32_t)OB_RDP));

OB->RDP = tmp2; /* program read protection level */

Tmp2的結果是0x004400BB,然后把它寫給RDP所在的選項字。這樣寫顯然不符合上面的約定:選項字的高16位與低16位應該成互補關系。即使這樣強行寫進去,校驗還是會出錯。這應該就是執行該操作程序無法運行的原因。

將上面代碼的兩個地方簡單修改下,其它不動。

uint8_t tmp1 = 0; ==> uint16_t tmp1 = 0;

tmp1 = (uint8_t)(~(OB_RDP )); ==> tmp1 =(~((uint16_t)(OB_RDP )));

按照上面描述修改后,賦給RDP選項字的值便是0xFF4400BB.將修改過的代碼重新燒錄。斷電、復位等都不出現死機現象,程序運行正常,利用相關工具查看芯片證實已經做了LEVEL 1級別讀保護。

看來導致上面問題的原因可以歸結于ST官方參考庫函數的問題,是個BUG.不過結合芯片參考手冊還是可以發現和調整的。后來我去ST官網找了下有無關于SMT32L15X系列的最新固件庫,發現了1.31版本,比上面提到的版本新一點,特地查看了新版本的相關函數,新版在這個地方已經做了更正

他們修改時跟我上面提到的有些差異,是因為考慮到做RDP調整時不要影響當前各SECTOR讀寫保護狀態的設置。

所以在利用庫函數編程遇到某些感覺很可能非自己軟件代碼原因導致MCU功能異常時,不妨點進相關庫函數結合技術手冊仔細查看確認下,或者找找有無更新版本的固件庫。雖說ST官方庫做得相當不錯了,但BUG或多或少都存在。建議剛著手開發時,盡可能下載最新版本的固件庫和相關技術資料。

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久一久久 | 性做久久久久久免费观看欧美 | 久久免费视频1 | 狠狠操狠狠干 | 欧美日韩精品中文字幕 | 四色成人av永久网址 | 欧美一区二区三区日韩 | 91传媒在线观看 | 一二三区视频 | 欧美日韩综合一区 | 一区二区三区精品视频 | 欧美在线观看一区 | 亚洲综合三区 | 成人欧美一区二区三区在线播放 | 国产69精品久久99不卡免费版 | 亚洲欧美一区二区三区情侣bbw | 国产精品国产三级国产aⅴ中文 | 亚洲国产日本 | 亚洲视频在线看 | 一区二区三区av | 日韩欧美国产精品一区 | 一区二区三区免费 | 青青草国产在线观看 | 观看av| 亚洲综合一区二区三区 | 国产成人99久久亚洲综合精品 | 日韩视频专区 | 久久精品亚洲一区 | 久久久精品一区 | 国产精品视频一区二区三区不卡 | 色天堂影院| 亚洲精品自拍视频 | 久热久 | 日韩在线视频一区 | 成人午夜电影网 | 久久久区 | 国产精品一区二区av | 国产免费播放视频 | 国产精品久久久久久福利一牛影视 | 精品成人免费一区二区在线播放 | 日日操夜夜操天天操 |