由FS_Seek()引數錯誤引發的有關定址範圍的思考
平臺:MT2503A
待實現功能:Fota
現象描述:
通過網路(wifi/lan)接收fota的分包並存儲進檔案系統,接收完畢進入bootloader升級後總是不能正常升級,將收到記錄的Fota檔案通過工具讀出並和原始檔案做對比發現許多地方不相同,開始懷疑是接收是出錯,利用debug打印出每一包的校驗資訊發現並沒有出錯,繼續向上檢視處理接收fota封包的函式(拆包後,儲存前),在儲存前做二次校驗,發現也沒有錯誤。由此可以斷定錯誤應該出在儲存過程中。
處理需要寫入的資料步驟:
1. fs_seek()
2. fs_write()
3.fs_fflush()
先將程式碼貼上,大家試試看能不能找到錯誤的地方:
/* MT2503 SDK中自帶函式 */ int FS_Seek(FS_HANDLE FileHandle, int Offset, int Whence) { if (Whence != FS_FILE_BEGIN && Whence != FS_FILE_CURRENT && Whence != FS_FILE_END) { return FS_PARAM_ERROR; } return fs_bl_seek(FileHandle, Offset, Whence); } /* 同事重新封裝一次的程式碼 */ void fota_file_seek(FS_HANDLE handle, hal_uint16 position) { FS_Seek(handle, position, FS_FILE_BEGIN); } void fota_file_writr(FS_HANDLE handle, kal_char *data, kal_uint16 total_len) { ........ write_ret = FS_Write(handle, (kal_uint8 *)(data + len), total_len - len, &size); FS_Commit(handle); ........ } void fota_handle_firmware_package(kal_char *firm_data, kal_uint16 package_id, kal_uint16 package_len) { ........ fota_file_seek(fota_context.kedas_firmware, (package_id-1)*FIRM_WARE_PACKAGE_SIZE); fota_file_write(fota_context.kedas_firmware, firm_data, package_len); ........ }
第一次檢查程式碼時還沒有發現錯誤,所以又去檢視一次檔案比對,發現錯誤總在檔案64kB的地方之後開始出現,隱約覺得是不是MT2503的SDK限制寫入檔案大小,遂打電話給供應商的FAE詢問,檔案系統有沒有限制大小,FAE回答絕不可能出現只能寫了64KB。一般來說只要不超過剩餘flash大小的上限是都可以寫入的。
所以我再次去檢視程式碼,發現了一個很費解的錯誤,同事將fs_seek()函式重新打包了一下,SDK中的fs_seek()需要傳入三個引數分別是:fs_handle(相當於檔案描述符),int型的offset(偏移位置,請注意是int型,2^31定址範圍),int型的whence(表明從頭,從尾查詢),同事二次封裝的fota_file_seek(FS_HANDLE handle, hal_uint16 position) 函式只有兩個引數,相比他是想省一個函式並且讓只在fota的功能中使用,但是注意這個position引數是 hal_uint16 型別
最後,總結一下關於這次debug得出的程式設計經驗:
1. 如果SDK中沒有必要二次封裝的函式就不要封裝了(就是這種你只能省下一個引數,沒有特殊的資料處理),老老實實呼叫就好,
2. 對於系統函式,該傳什麼型別引數就傳什麼。
再留一點地方,有時間把定址範圍推到一下。嘿嘿嘿。