用CH552E? 552G 這兩個芯片做了幾個USB開關通訊設備。 出現(xiàn)了flash丟失問題。
測試情況是這樣子的,設備接USB HUB 擴張器 或?設備接臺式機前面的USB口 然后反復拔插就容易flash 出現(xiàn)頻率特別高。?
flash區(qū)被擦寫掉了,代碼中也按照網上提供的方案做了很多判定在穩(wěn)定的情況才會寫入flash。
這種是什么問題呢。求解。
用CH552E? 552G 這兩個芯片做了幾個USB開關通訊設備。 出現(xiàn)了flash丟失問題。
測試情況是這樣子的,設備接USB HUB 擴張器 或?設備接臺式機前面的USB口 然后反復拔插就容易flash 出現(xiàn)頻率特別高。?
flash區(qū)被擦寫掉了,代碼中也按照網上提供的方案做了很多判定在穩(wěn)定的情況才會寫入flash。
這種是什么問題呢。求解。
可以分享一下允許flash操作的邏輯,看是否有漏洞存在。
CH552的Code flash的可擦寫次數(shù)不是特別高,如果有數(shù)據(jù)存儲的需求,優(yōu)先考慮使用Data flash
使用的是 DataFlash? 不是 code flash
是在官方的demo提供的 DataFlash.c 中拿過來做了修改使用的。
官方原生的也經常出現(xiàn)丟失問題, 后來經過網上有人分享的方案 做了一些判定處理 但是問題還是未能得到解決。
搭車問一下CH552的CodeFlash失效模式是什么?出現(xiàn)什么現(xiàn)象可以認定壽命已經到了。
我手頭有一片開發(fā)用的CH552G,目前燒錄可能已經上百次了,想知道它怎么就算壞了。
4樓的朋友,可以參考下面代碼的全局標志保護。代碼是CH54X上運行的擦除函數(shù),思路是一樣的。
extern UINT8 FLASH_CHECK_BYTE_1;
extern UINT8 FLASH_CHECK_BYTE_2;
UINT8 UserDefFlashErase( UINT16 Addr, UINT16 len )
{
? ? bit e_all;
? ? UINT8 status; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* 返回操作狀態(tài) */
? ? UINT8 FlashType; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /* Flash 類型標志 */
? ? UINT16 addr = Addr+UserDefineFlashAddr;
? ? UINT16 restlen = len;
? ? /* 判斷是否可以正常執(zhí)行FLASH操作 */
? ? if( ( FLASH_CHECK_BYTE_1 != DEF_FLASH_OP_CHECK1 ) && ( FLASH_CHECK_BYTE_2 != DEF_FLASH_OP_CHECK2 ) )
? ? { ? //FLASH_CHECK_BYTE_1和FLASH_CHECK_BYTE_2通常在USB中斷中滿足一定條件置位,或者在GPIO中斷中置位,這個標志的置位來源一定是芯片外部操作實現(xiàn)的,防止自己就擦寫了
? ? ? ? return 0x02;
? ? }
? ? if((addr>=DATA_FLASH_ADDR) && (addr/* DataFlash區(qū)域 */
? ? {
? ? ? ? FlashType = bDATA_WE;
? ? }
? ? else ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /* CodeFlash區(qū)域 */
? ? {
? ? ? ? FlashType = bCODE_WE;
? ? }
? ? SAFE_MOD = 0x55; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /* 進入安全模式 */
? ? SAFE_MOD = 0xAA;
? ? //下面就是FLASH的擦(554以下不需要擦)、寫、讀
? ? //操作結束之后FLASH_CHECK_BYTE_1和FLASH_CHECK_BYTE_2及時復位
? ? GLOBAL_CFG |= FlashType;
? ? ? ? do
? ? ? ? {
? ? ? ? ? ? ROM_ADDR = addr; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /* 寫入目標地址 */
? ? ? ? ? ? ? ? ROM_BUF_MOD = bROM_BUF_BYTE; ? ? ? ? ? ? ? ? ? ? /* 選擇塊擦除模式或單字節(jié)編程模式 */
? ? ? ? ? ? ? ? ROM_DAT_BUF = 0; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /* 擦寫數(shù)據(jù)緩沖區(qū)寄存器為0 */
? ? ? ? ? ? ? ? if ( ROM_STATUS & bROM_ADDR_OK ) ? ? ? ? ? ? ? ? /* 操作地址有效 */
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ROM_CTRL = ROM_CMD_ERASE; ? ? ? ? ? ? ? ? ? ?/* 啟動擦除 */
? ? ? ? ? ? ? ? ? ? ? ? if(ROM_STATUS & bROM_CMD_ERR)
? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? status = 0x02; ? ?/* 未知命令或超時 */
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return status;
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? else
? ? ? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? status = 0x00; ? ?/* 操作成功 */
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? else
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? status = 0x01; ? ?/* 地址無效 */
? ? ? ? ? ? ? ? ? ? ? ? return status;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? addr += 64;
? ? ? ? ? ? ? ? if( restlen >= 64 )
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? restlen -= 64;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? else if( restlen < 64 )
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? restlen = 0;
? ? ? ? ? ? ? ? }
? ? ? ? }while( restlen );
? ? SAFE_MOD = 0x55; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /* 進入安全模式 */
? ? SAFE_MOD = 0xAA;
? ? GLOBAL_CFG &= ~FlashType; ? ? ? ? ? ? ? ? ? ? ? ?/* 開啟寫保護 */
? ? EA = e_all; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* 恢復全局中斷狀態(tài) */
? ? ? ? CH549WDTModeSelect(1); ? ? ? ? ? ? ? ? ? ? ? ? ? /* 啟動看門狗 */
? ? return status;
}
5樓的朋友,當flash的某一些比特位無法被代碼修改的時候,flash就出問題了,可能在ISP工具對芯片進行燒錄的時候會出現(xiàn)失敗的現(xiàn)象。
@7樓的朋友,ISP會報錯就好了,我看一下這個開發(fā)用的CH552G什么會掛掉。
6樓 老哥 你提供的這個 我也是參考過的,修改后就是我4樓貼圖的也是加了全局標識位的? 但是還是被擦寫掉。
全局標志應該有多個,且生效的地方,邏輯都很重要,且在退出函數(shù)的時候應該將全局標志無效。
我們防止的是在上下電過程中程序運行的異常,意外的進入這個函數(shù)執(zhí)行了flash操作,那全局標志的作用應該是只在一通復雜交互邏輯之后才會生效(類似打游戲AAABBBBBXXXXXXYYY開啟隱藏功能),除此之外任何時候調用這個函數(shù)都是無效的。
你截圖的代碼中判斷條件用的是“||”,相信調用這個函數(shù)的地方參數(shù)都是滿足的,要是跑飛到:
jump to this line code;? <----------------------------------------------------------------------
writedataflash(X,X,X);
上面的情況是不是緊接這調用了會傳入正確參數(shù)的flash操作函數(shù)呢?同時READY(應該是個全局標志吧?)也無所謂是什么值。再里面一層判斷條件return i的,意義也不是很大。
好的 感謝。 邏輯上好像是存在一些問題, 我先做下調整 在測試看看。