/* System Storage Callback System Callback for Storage Module. @file SysStrg_Exe.c @ingroup mIPRJSYS @note �o���ɮ׭t�d�@��� 1.����Storage Event������ �i�઺event��: STRG_INSERT --- �N���CARD���J ����unmount���e�ݭn�����Ʊ� �I�sFile unmound (NAND), ����mount���e�ݭn�����Ʊ� �I�sFile mount (CARD) STRG_REMOVE --- �N���CARD�ޥX ����unmount���e�ݭn�����Ʊ� �I�sFile unmount (CARD) ����mount���e�ݭn�����Ʊ� �I�sFile_mount (NAND) STRG_ATTACH --- �N��File mount���� ����mount����ݭn�����Ʊ� �o��|�ǤJmount�����Gstatus STRG_DETACH --- �N��File unmount���� ����unmount����ݭn�����Ʊ� �o��|�ǤJunmount�����Gstatus Copyright Novatek Microelectronics Corp. 2010. All rights reserved. */ //////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include "PrjInc.h" #include "PrjCfg.h" #include "sys_storage_partition.h" //////////////////////////////////////////////////////////////////////////////// #include "UIFrameworkExt.h" #include "UICommon.h" #include "dma.h" #include "PStore.h" #if (USE_DCF == ENABLE) #include "DCF.h" #endif //#include "ExifVendor.h" #include "FileSysTsk.h" #include "SysCommon.h" #include "sys_mempool.h" #include "DxType.h" #include "Dx.h" #include "DxApi.h" #include "DxStorage.h" #include #include "FwSrvApi.h" #include "md5/md5.h" #include "GxStrg.h" #include #if (LOGFILE_FUNC==ENABLE) #include "LogFile.h" #endif #if (USERLOG_FUNC == ENABLE) #include "userlog.h" #endif #include "wdt.h" #if (USER_PACK_UPDATE == ENABLE) #include "nvtpack.h" #endif #if (defined(_NVT_ETHREARCAM_TX_)) #include "UIApp/Network/EthCamAppCmd.h" #endif #define MD5_CHECK_ENABLE 0 #define FW_VERSION_CHECK_ENABLE 0 #if (USER_PACK_UPDATE == ENABLE) #define PACK_ITEM_WAV 7 // should be the same as partition table #define PACK_ITEM_EDOG 8 // temporary #define PACK_ITEM_TSR_MODEL 9 // temporary #endif #if defined(_EMBMEM_SPI_NOR_) #define MAX_BLK_PER_SEC 128 #define MAX_SEC_NUM 8 #else #define MAX_BLK_PER_SEC 512 #define MAX_SEC_NUM 64 #endif #define LDC_HEADER_SIZE 16 #define FW_UPD_FW_TMP_MEM_SIZE 0xA00000 #define LOADER_UPD_FW_PATH "A:\\"_BIN_NAME_".BIN" #define FW_DEL_INDIACTION_PATH "A:\\NVTDELFW" //#NT#2018/04/02#Niven Cho -begin //#NT#PARTIAL_COMPRESS, we use last 10MB of APP as working buffer #define FW_PARTIAL_COMPRESS_WORK_BUF_SIZE 0xA00000 //#NT#2018/04/02#Niven Cho -end //global debug level: PRJ_DBG_LVL #include "PrjCfg.h" //local debug level: THIS_DBGLVL #define THIS_DBGLVL 2 // 0=FATAL, 1=ERR, 2=WRN, 3=UNIT, 4=FUNC, 5=IND, 6=MSG, 7=VALUE, 8=USER /////////////////////////////////////////////////////////////////////////////// #define __MODULE__ SysStrgExe #define __DBGLVL__ ((THIS_DBGLVL>=PRJ_DBG_LVL)?THIS_DBGLVL:PRJ_DBG_LVL) #define __DBGFLT__ "*" //*=All, [mark]=CustomClass #include /////////////////////////////////////////////////////////////////////////////// //Check definition options #if defined(_CPU2_ECOS_) #if (LOGFILE_FUNC == ENABLE && ECOS_DBG_MSG_FORCE_UART1_DIRECT == ENABLE) //#error "LOGFILE_FUNC must turn off ECOS_DBG_MSG_FORCE_UART1_DIRECT" #endif #endif #define FW_UPDATE_FILE_LEN 32 #if (FW_VERSION_CHECK_ENABLE) //UINT32 FWBufAddr = 0; UINT32 g_FWBufSize = 0; static char CurVerInfo[] = __DEVICE_VERSION__; static char CurVerInfoType[] = __DEVICE_TYPE__; #endif #if (USER_PACK_UPDATE == ENABLE) DSAPackInfo stNewPackInfo; static BOOL g_bUpdNeedDSAData = FALSE; #endif UINT32 g_FwUpdateType = FW_UPDATE_TYPE_FW; static char uiUpdateFWName[FW_UPDATE_FILE_LEN] = FW_UPDATE_NAME; static BOOL m_bUpdRename = FALSE; static FST_FS_TYPE m_GxStrgType = FST_FS_TYPE_UITRON; static void *mp_fwsrv_work_buf = NULL; void System_SetFwUpdateType(UINT32 type) { g_FwUpdateType = type; } /////////////////////////////////////////////////////////////////////////////// // // EMBMEM // /////////////////////////////////////////////////////////////////////////////// //Caculate FAT Start Addr #if defined(_CPU2_LINUX_) static BOOL xSysStrg_LinuxRun(void); #endif #if defined(_CPU2_ECOS_) static BOOL xSysStrg_eCosRun(void); #endif #if (defined(_DSP1_FREERTOS_) || defined(_DSP2_FREERTOS_)) static BOOL xSysStrg_DspRun(DSP_CORE_ID CoreID); #endif #if (FWS_FUNC == ENABLE) UINT32 System_OnStrgInit_EMBMEM_GetGxStrgType(void) { return m_GxStrgType; } void System_OnStrgInit_EMBMEM(void) { #if defined(_EMBMEM_SPI_NOR_) { //if stoarge is SPI, use ram disk as internal FAT DXSTRG_INIT UserEmbMemInit = {0}; UserEmbMemInit.prt.uiDxClassType = DX_CLASS_STORAGE_EXT | USER_DX_TYPE_EMBMEM_FAT; UserEmbMemInit.buf.addr = mempool_storage_nor; UserEmbMemInit.buf.size = POOL_SIZE_STORAGE_NOR; DX_HANDLE DxNandDev = Dx_GetObject(UserEmbMemInit.prt.uiDxClassType); Dx_Init(DxNandDev, &UserEmbMemInit, 0, STORAGE_VER); } #elif defined( _EMBMEM_EMMC_) //if stoarge is SPI, use ram disk as internal FAT DXSTRG_INIT UserEmbMemInit = {0}; UserEmbMemInit.prt.uiDxClassType = DX_CLASS_STORAGE_EXT | USER_DX_TYPE_EMBMEM_FAT; UserEmbMemInit.buf.addr = mempool_storage_nand; UserEmbMemInit.buf.size = POOL_SIZE_STORAGE_NAND; DX_HANDLE DxNandDev = Dx_GetObject(UserEmbMemInit.prt.uiDxClassType); Dx_Init(DxNandDev, &UserEmbMemInit, 0, STORAGE_VER); #endif } void System_OnStrgExit_EMBMEM(void) { //PHASE-1 : Close Drv or DrvExt } #endif /////////////////////////////////////////////////////////////////////////////// // // EXMEM // /////////////////////////////////////////////////////////////////////////////// //Drv or DrvExt #if (FS_FUNC == ENABLE) DXSTRG_INIT UserSdioInit; #if(COPYCARD2CARD_FUNCTION == ENABLE) DXSTRG_INIT UserSdio2Init; #endif DX_HANDLE DxCardDev1 = 0; typedef enum _BOOT_CARD_STATE { BOOT_CARD_STATE_UNKNOWN, BOOT_CARD_STATE_INSERTED, BOOT_CARD_STATE_REMOVED, ENUM_DUMMY4WORD(BOOT_CARD_STATE) } BOOT_CARD_STATE; static BOOT_CARD_STATE m_BootState_Drive[16] = {BOOT_CARD_STATE_UNKNOWN}; //DriveA, DriveB static UINT32 m_FsDxTypeMap[2] = {FS_DX_TYPE_DRIVE_A, FS_DX_TYPE_DRIVE_B}; void System_OnStrgInit_EXMEM(void) { static BOOL bStrg_init_EXMEM = FALSE; if (bStrg_init_EXMEM) { return; } TM_BOOT_BEGIN("sdio", "init"); #if (FS_DX_TYPE_DRIVE_A >= DX_TYPE_CARD1 && FS_DX_TYPE_DRIVE_A <= DX_TYPE_CARD3) DX_HANDLE DxCardDev1 = Dx_GetObject(DX_CLASS_STORAGE_EXT | FS_DX_TYPE_DRIVE_A); UserSdioInit.buf.addr = mempool_storage_sdio; UserSdioInit.buf.size = POOL_SIZE_STORAGE_SDIO; Dx_Init(DxCardDev1, &UserSdioInit, 0, STORAGE_VER); #endif #if (FS_MULTI_STRG_FUNC && FS_DX_TYPE_DRIVE_B >= DX_TYPE_CARD1 && FS_DX_TYPE_DRIVE_B <= DX_TYPE_CARD3) DX_HANDLE DxCardDev2 = Dx_GetObject(DX_CLASS_STORAGE_EXT | FS_DX_TYPE_DRIVE_B); UserSdio2Init.buf.Addr = OS_GetMempoolAddr(POOL_ID_STORAGE_SDIO2); UserSdio2Init.buf.Size = OS_GetMempoolSize(POOL_ID_STORAGE_SDIO2); Dx_Init(DxCardDev2, &UserSdio2Init, 0, STORAGE_VER); #endif bStrg_init_EXMEM = TRUE; TM_BOOT_END("sdio", "init"); } void System_OnStrgExit_EXMEM(void) { //PHASE-1 : Close Drv or DrvExt } #endif /////////////////////////////////////////////////////////////////////////////// // // FILESYS // /////////////////////////////////////////////////////////////////////////////// //Lib or LibExt #if (FS_FUNC == ENABLE) extern void Strg_CB(UINT32 event, UINT32 param1, UINT32 param2); void Card_DetInsert(void); void Card_DetBusy(void); #if (LOGFILE_FUNC==ENABLE) void System_DetErr(void); #endif #if (SDINSERT_FUNCTION == ENABLE) SX_TIMER_ITEM(Card_DetInsert, Card_DetInsert, 2, FALSE) #endif SX_TIMER_ITEM(System_DetBusy, Card_DetBusy, 25, FALSE) #if (LOGFILE_FUNC==ENABLE) SX_TIMER_ITEM(System_DetErr, System_DetErr,50, FALSE) #endif int SX_TIMER_DET_STRG_ID = -1; int SX_TIMER_DET_SYSTEM_BUSY_ID = -1; #if (LOGFILE_FUNC==ENABLE) int SX_TIMER_DET_SYSTEM_ERROR_ID = -1; #endif #if (LOGFILE_FUNC==ENABLE) _ALIGNED(64) static CHAR gLogFile_Buff[LOGFILE_BUFFER_SIZE]= {0}; #if defined(_CPU2_LINUX_) _ALIGNED(64) static CHAR gLogFile_Buff2[LOGFILE_BUFFER_SIZE]= {0}; #endif #endif void System_OnStrgInit_FS(void) { CHAR mount_path[KFS_LONGNAME_PATH_MAX_LENG] = {0}; TM_BOOT_BEGIN("sdio", "init_fs"); { MEM_RANGE Pool; Pool.addr = mempool_filesys; #if (FS_MULTI_STRG_FUNC == ENABLE) MEM_RANGE Pool2; Pool.Size = POOL_SIZE_FS_BUFFER; GxStrg_SetConfigEx(0, FILE_CFG_BUF, (UINT32)&Pool); Pool2.Addr = Pool.Addr + POOL_SIZE_FS_BUFFER; Pool2.Size = POOL_SIZE_FS_BUFFER; GxStrg_SetConfigEx(1, FILE_CFG_BUF, (UINT32)&Pool2); #if defined(_CPU2_LINUX_) && defined(_EMBMEM_EMMC_) // 3rd is for linux-pstore mounted by filesys MEM_RANGE Pool3; Pool3.Addr = Pool2.Addr + POOL_SIZE_FS_BUFFER; Pool3.Size = POOL_SIZE_FS_BUFFER; GxStrg_SetConfigEx(PST_DEV_ID, FILE_CFG_BUF, (UINT32)&Pool3); #endif #else Pool.size = POOL_SIZE_FILESYS; GxStrg_SetConfigEx(0, FILE_CFG_BUF, (UINT32)&Pool); #endif } //#NT#2017/06/02#Nestor Yang -begin //#NT# Do not link uITRON if not use //GxStrg_SetConfigEx(0, FILE_CFG_FS_TYPE, m_GxStrgType); #if defined(_CPU2_LINUX_) GxStrg_SetConfigEx(0, FILE_CFG_FS_TYPE, FileSys_GetOPS_Linux()); //for FILE_CFG_FS_TYPE, DevID is don't care #else GxStrg_SetConfigEx(0, FILE_CFG_FS_TYPE, FileSys_GetOPS_uITRON()); #endif //#NT#2017/06/02#Nestor Yang -end #if 0 #if (LOGFILE_FUNC==ENABLE) GxStrg_SetConfigEx(0, FILE_CFG_MAX_OPEN_FILE, 6); #endif #if (USERLOG_FUNC == ENABLE) GxStrg_SetConfigEx(0, FILE_CFG_MAX_OPEN_FILE, 6); #endif #if (CURL_FUNC == ENABLE) GxStrg_SetConfigEx(0, FILE_CFG_MAX_OPEN_FILE, 8); #endif #if (IPCAM_FUNC == DISABLE) GxStrg_SetConfigEx(0, FILE_CFG_MAX_OPEN_FILE, 8); #endif #else GxStrg_SetConfigEx(0, FILE_CFG_MAX_OPEN_FILE, 10); #endif // support exFAT GxStrg_SetConfigEx(0, FILE_CFG_SUPPORT_EXFAT, TRUE); // GxStrg_SetConfigEx(0, FILE_CFG_SUPPORT_EXFAT, FALSE); // mount path strncpy(mount_path, "/mnt/sd", sizeof(mount_path) - 1); mount_path[sizeof(mount_path) - 1] = '\0'; GxStrg_SetConfigEx(0, FILE_CFG_MOUNT_PATH, (UINT32)mount_path); //#NT#2018/12/18#Philex Lin - begin // unused now #if 0 // Enable 32MB alignment recording. GxStrg_SetConfigEx(0, FILE_CFG_ALIGNED_SIZE, 32 * 1024 * 1024); #endif //#NT#2018/12/18#Philex Lin - end #if (LOGFILE_FUNC==ENABLE) { LOGFILE_CFG cfg = {0}; #if 0 // only store system error log cfg.ConType = LOGFILE_CON_UART|LOGFILE_CON_MEM; #else // store normal log and system error log #if (defined(_MODEL_565_CARDV_HS880C_)||defined(_MODEL_565_CARDV_HS880CC_)) cfg.ConType = LOGFILE_CON_MEM|LOGFILE_CON_STORE; #else cfg.ConType = LOGFILE_CON_UART|LOGFILE_CON_STORE; #endif #endif cfg.TimeType = LOGFILE_TIME_TYPE_COUNTER; cfg.LogBuffAddr = (UINT32)gLogFile_Buff; cfg.LogBuffSize = sizeof(gLogFile_Buff); #if defined(_CPU2_LINUX_) cfg.LogBuffAddr2 = (UINT32)gLogFile_Buff2; cfg.LogBuffSize2 = sizeof(gLogFile_Buff2); #endif LogFile_Config(&cfg); } #endif GxStrg_RegCB(Strg_CB); //Register CB function of GxStorage (NANR or CARD) { //1.�]�winit�� //FileSys: //2.�]�wCB��, //3.���USxJob�A�� ---------> System Job //4.���USxTimer�A�� ---------> Detect Job #if (SDINSERT_FUNCTION == ENABLE) if (m_GxStrgType == FST_FS_TYPE_UITRON) { SX_TIMER_DET_STRG_ID = SxTimer_AddItem(&Timer_Card_DetInsert); } #endif #if (LOGFILE_FUNC==ENABLE) { SX_TIMER_DET_SYSTEM_ERROR_ID = SxTimer_AddItem(&Timer_System_DetErr); } #endif //SX_TIMER_DET_SYSTEM_BUSY_ID = SxTimer_AddItem(&Timer_System_DetBusy); //5.���USxCmd�A�� ---------> Cmd Function //System_AddSxCmd(Storage_OnCommand); //GxStorage //start scan SxTimer_SetFuncActive(SX_TIMER_DET_STRG_ID, TRUE); SxTimer_SetFuncActive(SX_TIMER_DET_SYSTEM_BUSY_ID, TRUE); } TM_BOOT_END("sdio", "init_fs"); if (m_GxStrgType == FST_FS_TYPE_UITRON) { #if (FS_MULTI_STRG_FUNC) UINT32 uiDxState = 0; DX_HANDLE pStrgDev = Dx_GetObject(DX_CLASS_STORAGE_EXT | FS_DX_TYPE_DRIVE_B); if (Dx_GetState((DX_HANDLE)pStrgDev, STORAGE_STATE_INSERT, &uiDxState) != DX_OK || uiDxState == FALSE) { Ux_PostEvent(NVTEVT_STRG_REMOVE, 1, 1); } else { Ux_PostEvent(NVTEVT_STRG_INSERT, 1, 1); } #endif } #if (USE_DCF == ENABLE) { // init DCF // CHAR pFolderName[9] = {0}; // CHAR pFileName[5] = {0}; // // init DCF FolderID/FileID with RTC data // struct tm tm_cur = hwclock_get_time(TIME_ID_CURRENT); // snprintf(pFolderName, sizeof(pFolderName), "%1d%02d%02d", tm_cur.tm_year % 0x0A, tm_cur.tm_mon, tm_cur.tm_mday); // snprintf(pFileName, sizeof(pFileName), "%02d%02d", tm_cur.tm_hour, tm_cur.tm_min); // //DCF dir-name // DCF_SetDirFreeChars(pFolderName); // //DCF file-name // DCF_SetFileFreeChars(DCF_FILE_TYPE_ANYFORMAT, pFileName); // // //DCF format // DCF_SetParm(DCF_PRMID_SET_VALID_FILE_FMT, DCF_SUPPORT_FORMAT); // DCF_SetParm(DCF_PRMID_SET_DEP_FILE_FMT, DCF_FILE_TYPE_JPG | DCF_FILE_TYPE_WAV | DCF_FILE_TYPE_MPO); // //TODO: [DCF] How to add an new format & its ext? DCF_SetParm(DCF_PRMID_REMOVE_DUPLICATE_FOLDER, TRUE); DCF_SetParm(DCF_PRMID_REMOVE_DUPLICATE_FILE, TRUE); DCF_SetParm(DCF_PRMID_SET_VALID_FILE_FMT, DCF_FILE_TYPE_JPG|DCF_FILE_TYPE_MP4|DCF_FILE_TYPE_MOV); DCF_SetParm(DCF_PRMID_SET_DEP_FILE_FMT, DCF_FILE_TYPE_JPG|DCF_FILE_TYPE_WAV|DCF_FILE_TYPE_MPO); DCF_SetDirFreeChars(DCF_DIR_NAME); DCF_SetFileFreeChars(DCF_FILE_TYPE_ANYFORMAT, DCF_FILE_NAME); } #endif } void System_OnStrgInit_FS2(void) { // update card status again if (GxStrg_GetDeviceCtrl(0, CARD_READONLY)) { System_SetState(SYS_STATE_CARD, CARD_LOCKED); } else if (GxStrg_GetDeviceCtrl(0, CARD_INSERT)) { System_SetState(SYS_STATE_CARD, CARD_INSERTED); } else { System_SetState(SYS_STATE_CARD, CARD_REMOVED); } } void System_OnStrgInit_FS3(void) { static BOOL bFirst = TRUE; if (bFirst) { TM_BOOT_BEGIN("sdio", "fdb_create"); } #if 0 #if(MOVIE_MODE==ENABLE) INT32 iCurrMode = System_GetBootFirstMode(); if (iCurrMode == PRIMARY_MODE_MOVIE) { FlowMovie_FileDBCreate_Fast(); } #endif #endif if (bFirst) { TM_BOOT_END("sdio", "fdb_create"); } bFirst = FALSE; } void System_OnStrgExit_FS(void) { //PHASE-2 : Close Lib or LibExt #if (LOGFILE_FUNC==ENABLE) #if HUNTING_CAMERA_MCU == ENABLE UIMenuStoreInfo *puiPara = sf_ui_para_get(); if(puiPara->DebugMode) { LogFile_Close(); } #else LogFile_Close(); #endif #endif // unmount file system GxStrg_CloseDevice(0); #if (FS_MULTI_STRG_FUNC) GxStrg_CloseDevice(1); #endif } #if (PWR_FUNC == ENABLE) static BOOL FileSys_DetBusy(void) { return (BOOL)((INT32)FileSys_GetParam(FST_PARM_TASK_STS, 0) == FST_STA_BUSY); } #endif void Card_DetInsert(void) { GxStrg_Det(0, Dx_GetObject(DX_CLASS_STORAGE_EXT | FS_DX_TYPE_DRIVE_A)); #if (0)//FS_MULTI_STRG_FUNC) GxStrg_Det(1, Dx_GetObject(DX_CLASS_STORAGE_EXT | FS_DX_TYPE_DRIVE_B)); #endif } void Card_DetBusy(void) { #if (PWR_FUNC == ENABLE) static BOOL bBusyLED = FALSE; if (GxPower_GetControl(GXPWR_CTRL_SLEEP_LEVEL) <= 1 && (!GxPower_GetControl(GXPWR_CTRL_BATTERY_CHARGE_EN))) { if (FileSys_DetBusy()) { if (bBusyLED == FALSE) { DBG_IND("System - busy\r\n"); bBusyLED = TRUE; #if (OUTPUT_FUNC == ENABLE) GxLED_SetCtrl(KEYSCAN_LED_GREEN, SETLED_SPEED, GXLED_1SEC_LED_TOGGLE_CNT / 5); GxLED_SetCtrl(KEYSCAN_LED_GREEN, TURNON_LED, FALSE); GxLED_SetCtrl(KEYSCAN_LED_GREEN, SET_TOGGLE_LED, TRUE); #endif } } else { if (bBusyLED == TRUE) { DBG_IND("System - not busy\r\n"); bBusyLED = FALSE; #if (OUTPUT_FUNC == ENABLE) GxLED_SetCtrl(KEYSCAN_LED_GREEN, SET_TOGGLE_LED, FALSE); GxLED_SetCtrl(KEYSCAN_LED_GREEN, TURNON_LED, FALSE); #endif } } } #endif } INT32 System_OnStrgInsert(VControl *pCtrl, UINT32 paramNum, UINT32 *paramArray) { UINT32 stg_id = paramArray[0]; if (m_BootState_Drive[stg_id] != BOOT_CARD_STATE_UNKNOWN) { if (stg_id == 0) { #if(IPCAM_FUNC==DISABLE && SDHOTPLUG_FUNCTION == DISABLE) System_PowerOff(SYS_POWEROFF_NORMAL); #endif } } else { TM_BOOT_BEGIN("sdio", "mount_fs"); m_BootState_Drive[stg_id] = BOOT_CARD_STATE_INSERTED; } // linux partition as PStore if (stg_id == PST_DEV_ID) { #if defined(_CPU2_LINUX_) if (GxStrg_OpenDevice(stg_id, NULL) != TRUE) { DBG_ERR("Storage mount pstore fail\r\n"); } return NVTEVT_CONSUME; #else DBG_FATAL("stg_id cannot be %d.\r\n", PST_DEV_ID); #endif } #if defined(_EMBMEM_EMMC_) DX_HANDLE pStrgDev = (DX_HANDLE)sdio3_getStorageObject(STRG_OBJ_FAT1); #else DX_HANDLE pStrgDev = (DX_HANDLE)sdio_getStorageObject(STRG_OBJ_FAT1); #endif if (GxStrg_OpenDevice(stg_id, pStrgDev) != TRUE) { char *pDxName = "unknown"; Dx_GetInfo(pStrgDev, DX_INFO_NAME, &pDxName); DBG_ERR("Storage mount %s fail\r\n", pDxName); return NVTEVT_CONSUME; } #if (USE_DCF == ENABLE) { DCF_OPEN_PARM dcfParm = {0}; // Open DCF dcfParm.Drive = (stg_id == 0) ? 'A' : 'B'; #if (FS_MULTI_STRG_FUNC) if (POOL_CNT_DCF_BUFFER !=2) { DBG_FATAL("POOL_CNT_DCF_BUFFER be 2 for FS_MULTI_STRG_FUNC.\r\n"); } else { switch(stg_id) { case 0: dcfParm.WorkbuffAddr = dma_getCacheAddr(OS_GetMempoolAddr(POOL_ID_DCF_BUFFER)); break; case 1: dcfParm.WorkbuffAddr = dma_getCacheAddr(OS_GetMempoolAddr(POOL_ID_DCF_BUFFER)) + POOL_SIZE_DCF_BUFFER; break; default: DBG_ERR("unknown stg_id=%d\r\n", stg_id); dcfParm.WorkbuffAddr = 0; break; } } #else dcfParm.WorkbuffAddr = mempool_dcf;//dma_getCacheAddr(OS_GetMempoolAddr(POOL_ID_DCF_BUFFER)); #endif dcfParm.WorkbuffSize = POOL_SIZE_DCF_BUFFER; DCF_Open(&dcfParm); DCF_ScanObj(); } #endif if (GxStrg_GetDeviceCtrl(stg_id, CARD_READONLY)) { System_SetState(SYS_STATE_CARD, CARD_LOCKED); DBG_IND("Card Locked\r\n"); } else { System_SetState(SYS_STATE_CARD, CARD_INSERTED); DBG_IND("Card inserted\r\n"); } return NVTEVT_CONSUME; } INT32 System_OnStrgRemove(VControl *pCtrl, UINT32 paramNum, UINT32 *paramArray) { UINT32 stg_id = paramArray[0]; if (m_BootState_Drive[stg_id] != BOOT_CARD_STATE_UNKNOWN) { if (stg_id == 0) { #if (LOGFILE_FUNC==ENABLE) #if HUNTING_CAMERA_MCU == ENABLE UIMenuStoreInfo *puiPara = sf_ui_para_get(); if(puiPara->DebugMode) { LogFile_Suspend(); LogFile_Close(); } #else LogFile_Suspend(); LogFile_Close(); #endif #endif #if (USERLOG_FUNC == ENABLE) { userlog_close(); } #endif #if (USE_DCF == ENABLE) //Fix the error "DCF_GetInfoByHandle() Dcf Handle 0 Data may be overwritted" when card plug out/in DCF_Close(0); #endif System_SetState(SYS_STATE_CARD, CARD_REMOVED); GxStrg_CloseDevice(stg_id); #if(IPCAM_FUNC==DISABLE && SDHOTPLUG_FUNCTION == DISABLE) System_PowerOff(SYS_POWEROFF_NORMAL); #endif } } else { TM_BOOT_BEGIN("sdio", "mount_fs"); m_BootState_Drive[stg_id] = BOOT_CARD_STATE_REMOVED; #if (FS_SWITCH_STRG_FUNC == ENABLE) if (stg_id==0) { DX_HANDLE pStrgDev = Dx_GetObject(DX_CLASS_STORAGE_EXT|FS_DX_TYPE_DRIVE_B); if (GxStrg_OpenDevice(stg_id, pStrgDev)!= TRUE) { char* pDxName="unknown"; Dx_GetInfo(pStrgDev, DX_INFO_NAME,&pDxName); DBG_ERR("Storage mount %s fail\r\n",pDxName); return NVTEVT_CONSUME; } System_SetState(SYS_STATE_CARD, CARD_INSERTED); return NVTEVT_CONSUME; } #else // boot without card, send attach to continue UI flow. // because of UserWaitEvent(NVTEVT_STRG_ATTACH, ¶mNum, paramArray); #if defined(_MODEL_565_CARDV_HY5137_) System_SetState(SYS_STATE_CARD, CARD_REMOVED); #endif Ux_PostEvent(NVTEVT_STRG_ATTACH, 2, stg_id, 0xFF); #endif } DX_HANDLE pStrgDev = Dx_GetObject(DX_CLASS_STORAGE_EXT | m_FsDxTypeMap[stg_id]); if (GxStrg_CloseDevice(stg_id) != TRUE) { char *pDxName = "unknown"; Dx_GetInfo(pStrgDev, DX_INFO_NAME, &pDxName); DBG_ERR("Storage mount %s fail\r\n", pDxName); return NVTEVT_CONSUME; } return NVTEVT_CONSUME; } INT32 System_OnStrgAttach(VControl *pCtrl, UINT32 paramNum, UINT32 *paramArray) { SHMINFO *p_shm; unsigned char *p_fdt = (unsigned char *)fdt_get_base(); int len; int nodeoffset; const void *nodep; /* property node pointer */ unsigned int *p_data; UINT32 result = paramArray[1]; if (p_fdt== NULL) { DBG_ERR("p_fdt is NULL.\n"); return NVTEVT_CONSUME; } // read SHMEM_PATH nodeoffset = fdt_path_offset(p_fdt, SHMEM_PATH); if (nodeoffset < 0) { DBG_ERR("failed to offset for %s = %d \n", SHMEM_PATH, nodeoffset); } else { DBG_DUMP("offset for %s = %d \n", SHMEM_PATH, nodeoffset); } nodep = fdt_getprop(p_fdt, nodeoffset, "reg", &len); if (len == 0 || nodep == NULL) { DBG_ERR("failed to access reg.\n"); return NVTEVT_CONSUME; } else { p_data = (unsigned int *)nodep; p_shm = (SHMINFO *)be32_to_cpu(p_data[0]); DBG_DUMP("p_shm = 0x%08X\n", (int)p_shm); } ////////////////////////////////////////////////// if (m_GxStrgType == FST_FS_TYPE_LINUX) { //Do Nothing } else { //m_GxStrgType == FST_FS_TYPE_UITRON //if spi use RamDisk as inner Memory,need to format RamDisk #if defined(_EMBMEM_SPI_NOR_) FS_HANDLE pStrgDevCur = (FS_HANDLE)GxStrg_GetDevice(0); FS_HANDLE pStrgDevRAM = (FS_HANDLE)Dx_GetObject(DX_CLASS_STORAGE_EXT | USER_DX_TYPE_EMBMEM_FAT); if ((pStrgDevCur == pStrgDevRAM) && (result != FST_STA_OK)) { result = FileSys_FormatDisk(pStrgDevCur, TRUE); } #endif #if ( !defined(_EMBMEM_SPI_NOR_) && (FS_MULTI_STRG_FUNC == ENABLE)) UINT32 stg_id = paramArray[0]; if (stg_id != 0) { // stg_id=1 is interal storage FAT return NVTEVT_CONSUME; } #endif } switch (result) { case FST_STA_OK: #if (USE_DCF == ENABLE) if (!UI_GetData(FL_IsCopyToCarding)) { DCF_ScanObj(); } #endif System_SetState(SYS_STATE_FS, FS_INIT_OK); if (p_shm && p_shm->boot.LdCtrl2 & LDCF_UPDATE_FW) { FST_FILE hFile = FileSys_OpenFile(FW_DEL_INDIACTION_PATH, FST_OPEN_READ | FST_OPEN_EXISTING); if (hFile != NULL) { DBG_DUMP("Detected %s, delete %s \r\n", FW_DEL_INDIACTION_PATH, LOADER_UPD_FW_PATH); FileSys_CloseFile(hFile); // Delete FW bin from A: if (FileSys_DeleteFile(LOADER_UPD_FW_PATH) != FST_STA_OK) { DBG_ERR("delete "_BIN_NAME_".BIN failed .\r\n"); } if (FileSys_DeleteFile(FW_DEL_INDIACTION_PATH) != FST_STA_OK) { DBG_ERR("delete %s failed .\r\n", FW_DEL_INDIACTION_PATH); } } } #if (LOGFILE_FUNC==ENABLE) #if HUNTING_CAMERA_MCU == ENABLE UIMenuStoreInfo *puiPara = sf_ui_para_get(); if ((puiPara->DebugMode) && SxTimer_GetFuncActive(SX_TIMER_DET_SYSTEM_ERROR_ID) == 0) #else if (SxTimer_GetFuncActive(SX_TIMER_DET_SYSTEM_ERROR_ID) == 0) #endif { LOGFILE_OPEN logOpenParm = {0}; UINT32 maxFileNum = 32; UINT32 maxFileSize = 0x100000; // 1MB CHAR rootDir[LOGFILE_ROOT_DIR_MAX_LEN + 1] = "A:\\LOG\\"; #if defined(_CPU2_LINUX_) CHAR rootDir2[LOGFILE_ROOT_DIR_MAX_LEN + 1] = "A:\\Novatek\\LOG2\\"; #endif CHAR sysErrRootDir[LOGFILE_ROOT_DIR_MAX_LEN + 1] = "A:\\SYS\\"; logOpenParm.maxFileNum = maxFileNum; logOpenParm.maxFileSize = maxFileSize; logOpenParm.isPreAllocAllFiles = TRUE; logOpenParm.isSaveLastTimeSysErrLog = wdt_getResetNum()>0 ? TRUE : FALSE; logOpenParm.lastTimeSysErrLogBuffAddr = mempool_logfile; logOpenParm.lastTimeSysErrLogBuffSize = POOL_SIZE_LOGFILE; logOpenParm.isZeroFile = TRUE; strncpy(logOpenParm.rootDir, rootDir, LOGFILE_ROOT_DIR_MAX_LEN); #if defined(_CPU2_LINUX_) strncpy(logOpenParm.rootDir2, rootDir2, LOGFILE_ROOT_DIR_MAX_LEN); #endif strncpy(logOpenParm.sysErrRootDir, sysErrRootDir, LOGFILE_ROOT_DIR_MAX_LEN); LogFile_Open(&logOpenParm); //start scan SxTimer_SetFuncActive(SX_TIMER_DET_SYSTEM_ERROR_ID, TRUE); } #endif #if (USERLOG_FUNC == ENABLE) { userlog_open(); } #endif break; case FST_STA_DISK_UNFORMAT: System_SetState(SYS_STATE_FS, FS_UNFORMATTED); break; case FST_STA_DISK_UNKNOWN_FORMAT: System_SetState(SYS_STATE_FS, FS_UNKNOWN_FORMAT); break; case FST_STA_CARD_ERR: System_SetState(SYS_STATE_FS, FS_DISK_ERROR); break; default: System_SetState(SYS_STATE_FS, FS_DISK_ERROR); break; } Ux_PostEvent(NVTEVT_STORAGE_INIT, 0, 0); #if (PWR_FUNC == ENABLE) GxPower_SetControl(GXPWR_CTRL_AUTOSLEEP_EN, 0xff); //reset #endif return NVTEVT_CONSUME; } INT32 System_OnStrgDetach(VControl *pCtrl, UINT32 paramNum, UINT32 *paramArray) { if (m_GxStrgType == FST_FS_TYPE_LINUX) { UINT32 stg_id = paramArray[0]; if (stg_id != 0) { //not sd-1 return NVTEVT_CONSUME; } } switch (paramArray[1]) { case FST_STA_OK: DBG_IND("FS: unmount OK\r\n"); break; default: DBG_ERR("^RFS: unmount FAIL\r\n"); break; } return NVTEVT_CONSUME; } BOOL gChkCardPwrOn = FALSE; BOOL gChkCardChange = FALSE; void Storage_PowerOn_Start(void) { gChkCardPwrOn = GxStrg_GetDeviceCtrl(0, CARD_INSERT); DBG_IND("^BStg Power On = %d\r\n", gChkCardPwrOn); } void Storage_UpdateSource(void) { DBG_IND("^Y-------------CARD det\r\n"); if (gChkCardPwrOn) { if (FALSE == GxStrg_GetDeviceCtrl(0, CARD_INSERT)) { //CARD�w�ް� gChkCardChange = TRUE; } } else { if (TRUE == GxStrg_GetDeviceCtrl(0, CARD_INSERT)) { //CARD�w���J gChkCardChange = TRUE; } } } void Storage_PowerOn_End(void) { Storage_UpdateSource(); gChkCardPwrOn = GxStrg_GetDeviceCtrl(0, CARD_INSERT); if (TRUE == gChkCardChange) { //CARD���g���� System_PowerOff(SYS_POWEROFF_NORMAL); //���� return; } } #endif /////////////////////////////////////////////////////////////////////////////// // // PSTORE // /////////////////////////////////////////////////////////////////////////////// #if (PST_FUNC == ENABLE) void System_PS_Format(void) { PSFMT gFmtStruct = {MAX_BLK_PER_SEC, MAX_SEC_NUM}; PStore_Format(&gFmtStruct); } void System_OnStrgInit_PS(void) { //PHASE-2 : Init & Open Lib or LibExt TM_BOOT_BEGIN("nand", "init_ps"); #if (PST_FUNC == ENABLE) // Open PStore PSFMT gFmtStruct = {MAX_BLK_PER_SEC, MAX_SEC_NUM}; PSTORE_INIT_PARAM gPStoreParam; UINT32 result = 0; UINT8 *pBuf; #if defined(_CPU2_LINUX_) && defined(_EMBMEM_EMMC_) PStore_Init(PS_TYPE_FILESYS, PST_FS_DRIVE[0]); UINT32 paramNum; UINT32 paramArray[MAX_MESSAGE_PARAM_NUM]; do { UserWaitEvent(NVTEVT_STRG_ATTACH, ¶mNum, paramArray); } while(paramArray[0] != PST_DEV_ID); //PStore will mount first before dev[0],dev[1] #else PStore_Init(PS_TYPE_EMBEDED, 0); #endif pBuf = (UINT8 *)mempool_pstore; if(!pBuf){ DBG_ERR("fail to allocate pstore buffer of %d bytes\n", POOL_SIZE_PS_BUFFER); return; } gPStoreParam.pBuf = pBuf; gPStoreParam.uiBufSize = POOL_SIZE_PS_BUFFER; DBG_DUMP("PStore uiBufSize=%d\r\n", gPStoreParam.uiBufSize); result = PStore_Open(EMB_GETSTRGOBJ(STRG_OBJ_PSTORE1), &gPStoreParam); if (result != E_PS_OK) { DBG_ERR("PStore Open fail %d format \r\n", result); PStore_Format(&gFmtStruct); } #if defined(_CPU2_LINUX_) { PSTOREIPC_OPEN PsopenObj = {0}; // open pstore ipc PstoreIpc_Open(&PsopenObj); } #endif #endif TM_BOOT_END("nand", "init_ps"); } void System_OnStrgExit_PS(void) { #if (PST_FUNC == ENABLE) #if defined(_CPU2_LINUX_) PstoreIpc_Close(); #endif PStore_Close(); #endif } #endif /////////////////////////////////////////////////////////////////////////////// // // FWSTORE // /////////////////////////////////////////////////////////////////////////////// #include "FileSysTsk.h" #if (FWS_FUNC == ENABLE) #include "FwSrvApi.h" #endif #include "MemCheck.h" #include "sys_fwload.h" UINT32 UserSection_Load[10] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0}; UINT32 UserSection_Order_full[] = { CODE_SECTION_02, CODE_SECTION_03, CODE_SECTION_04, CODE_SECTION_05, CODE_SECTION_06, CODE_SECTION_07, CODE_SECTION_08, CODE_SECTION_09, CODE_SECTION_10, FWSRV_PL_BURST_END_TAG }; int order = 1; void UserSection_LoadCb(const UINT32 Idx) { DBG_DUMP("Section-%.2ld: (LOAD)\r\n", Idx + 1); UserSection_Load[Idx] = 1; //mark loaded order++; if (Idx == 9) { //Section-10 if (mp_fwsrv_work_buf) { free(mp_fwsrv_work_buf); mp_fwsrv_work_buf = NULL; } } \ } void System_OnStrgInit_FWS(void) { SHMINFO *p_shm; FWSRV_INIT Init = {0}; unsigned char *p_fdt = (unsigned char *)fdt_get_base(); if (p_fdt == NULL) { DBG_ERR("p_fdt is NULL.\n"); return; } int len; int nodeoffset; const void *nodep; /* property node pointer */ // read SHMEM_PATH nodeoffset = fdt_path_offset(p_fdt, SHMEM_PATH); if (nodeoffset < 0) { DBG_ERR("failed to offset for %s = %d \n", SHMEM_PATH, nodeoffset); } else { DBG_DUMP("offset for %s = %d \n", SHMEM_PATH, nodeoffset); } nodep = fdt_getprop(p_fdt, nodeoffset, "reg", &len); if (len == 0 || nodep == NULL) { DBG_ERR("failed to access reg.\n"); return; } else { unsigned int *p_data = (unsigned int *)nodep; p_shm = (SHMINFO *)be32_to_cpu(p_data[0]); DBG_DUMP("p_shm = 0x%08X\n", (int)p_shm); if (p_shm->boot.LdCtrl2 & LDCF_BOOT_CARD) { DBG_DUMP(DBG_COLOR_HI_YELLOW"\r\nNotice: Boot from T.bin. app.dtb will load from flash!!!\r\n\r\n"DBG_COLOR_END); } } // init fwsrv Init.uiApiVer = FWSRV_API_VERSION; Init.StrgMap.pStrgFdt = EMB_GETSTRGOBJ(STRG_OBJ_FW_FDT); Init.StrgMap.pStrgApp = EMB_GETSTRGOBJ(STRG_OBJ_FW_APP); Init.StrgMap.pStrgUboot = EMB_GETSTRGOBJ(STRG_OBJ_FW_UBOOT); Init.StrgMap.pStrgRtos = EMB_GETSTRGOBJ(STRG_OBJ_FW_RTOS); Init.PlInit.uiApiVer = PARTLOAD_API_VERSION; Init.PlInit.pStrg = EMB_GETSTRGOBJ(STRG_OBJ_FW_RTOS); #if defined(_FW_TYPE_PARTIAL_COMPRESS_) mp_fwsrv_work_buf = (void *)malloc(FW_PARTIAL_COMPRESS_WORK_BUF_SIZE); Init.PlInit.DataType = PARTLOAD_DATA_TYPE_COMPRESS_GZ; Init.PlInit.uiWorkingAddr = (UINT32)mp_fwsrv_work_buf; Init.PlInit.uiWorkingSize = FW_PARTIAL_COMPRESS_WORK_BUF_SIZE ; #elif defined(_FW_TYPE_PARTIAL_) mp_fwsrv_work_buf = (void *)malloc(_EMBMEM_BLK_SIZE_); Init.PlInit.DataType = PARTLOAD_DATA_TYPE_UNCOMPRESS; Init.PlInit.uiWorkingAddr = (UINT32)mp_fwsrv_work_buf; Init.PlInit.uiWorkingSize = _EMBMEM_BLK_SIZE_ ; #endif Init.PlInit.uiAddrBegin = _BOARD_RTOS_ADDR_ + p_shm->boot.LdLoadSize; FwSrv_Init(&Init); FwSrv_Open(); } void System_OnStrgExit_FWS(void) { #if (FWS_FUNC == ENABLE) ER er; er = FwSrv_Close(); if (er != FWSRV_ER_OK) { DBG_ERR("Close failed!\r\n"); } #endif } void System_CPU2_Start(void) { } void System_CPU2_Stop(void) { } void System_CPU2_WaitReady(void) { } void System_DSP_Start(void) { } void System_DSP_WaitReady(void) { } void System_OnStrg_DownloadFW(void) { #if defined(_FW_TYPE_PARTIAL_) || defined(_FW_TYPE_PARTIAL_COMPRESS_) SHMINFO *p_shm; unsigned char *p_fdt = (unsigned char *)fdt_get_base(); if (p_fdt == NULL) { DBG_ERR("p_fdt is NULL.\n"); return; } int len; int nodeoffset; const void *nodep; /* property node pointer */ // read SHMEM_PATH nodeoffset = fdt_path_offset(p_fdt, SHMEM_PATH); if (nodeoffset < 0) { DBG_ERR("failed to offset for %s = %d \n", SHMEM_PATH, nodeoffset); } else { DBG_DUMP("offset for %s = %d \n", SHMEM_PATH, nodeoffset); } nodep = fdt_getprop(p_fdt, nodeoffset, "reg", &len); if (len == 0 || nodep == NULL) { DBG_ERR("failed to access reg.\n"); return; } else { unsigned int *p_data = (unsigned int *)nodep; p_shm = (SHMINFO *)be32_to_cpu(p_data[0]); DBG_DUMP("p_shm = 0x%08X\n", (int)p_shm); } if ((p_shm->boot.LdCtrl2 & LDCF_BOOT_CARD) == 0) { FWSRV_CMD Cmd = {0}; FWSRV_PL_LOAD_BURST_IN pl_in = {0}; // start partial load void (*LoadCallback)(const UINT32 Idx) = UserSection_LoadCb; UINT32 *SecOrderTable = UserSection_Order_full; LoadCallback(CODE_SECTION_01); // 1st part has loaded by loader ER er; pl_in.puiIdxSequence = SecOrderTable; pl_in.fpLoadedCb = LoadCallback; Cmd.Idx = FWSRV_CMD_IDX_PL_LOAD_BURST; //continue load Cmd.In.pData = &pl_in; Cmd.In.uiNumByte = sizeof(pl_in); Cmd.Prop.bExitCmdFinish = TRUE; er = FwSrv_Cmd(&Cmd); if (er != FWSRV_ER_OK) { DBG_ERR("Process failed!\r\n"); return; } } #endif return; } #if (IPCAM_FUNC != ENABLE) static void CheckSumOKCb(void) { //Create a zero file to indicate deleting FW after loader update FST_FILE hFile = FileSys_OpenFile(FW_DEL_INDIACTION_PATH,FST_OPEN_WRITE|FST_OPEN_ALWAYS); if(hFile != NULL) { FileSys_CloseFile(hFile); } else { DBG_ERR("create indication %s failed.\r\n",FW_DEL_INDIACTION_PATH); return; } #if (MD5_CHECK_ENABLE) DBG_DUMP("CheckSumOKCb: uiUpdateFWName %s\r\n", uiUpdateFWName); hFile = FileSys_OpenFile(uiUpdateFWName, FST_OPEN_WRITE|FST_OPEN_ALWAYS); if(hFile != NULL) { FileSys_TruncFile(hFile, g_FWBufSize); FileSys_CloseFile(hFile); } else { DBG_ERR("create backup file %s failed.\r\n", "A:\\"_BIN_NAME_".BIN"); return; } #endif DBG_DUMP("CheckSumOKCb: rename %s\r\n", _BIN_NAME_".BIN"); //Rename to be safe, that loader can update by name for next updating if FW updating FW failed. if(FileSys_RenameFile(_BIN_NAME_".BIN",uiUpdateFWName, TRUE)==FST_STA_OK) { m_bUpdRename = TRUE; } else { DBG_ERR("cannot rename bin file.\r\n"); } } #if (USER_PACK_UPDATE == ENABLE) static BOOL UpdateFw_CheckFlashDSAVer(char *ver, int length) { char FlashVer[128] = {0}; int i, FlashVerLen = 0; BOOL CheckStatus = TRUE; FlashVerLen = length; strncpy(FlashVer, ver, FlashVerLen); //DBG_DUMP(" ===FlashVer:%s===FlashVerLen:%d===\r\n", FlashVer, FlashVerLen); for (i = 0; i < FlashVerLen; i++) { if (FlashVer[i]>'9' || FlashVer[i]<'0') { CheckStatus = FALSE; break; } else { CheckStatus = TRUE; break; } } return CheckStatus; } #endif UINT32 System_OnStrg_UploadFW(UINT32 DevID) { INT32 fst_er; ER fws_er; unsigned char *p_Mem = NULL; FST_FILE hFile = NULL; UINT32 uiFwSize = 0; #if (USER_PACK_UPDATE == ENABLE) UINT32 uiFwAddr; #endif #if (MD5_CHECK_ENABLE) unsigned char MD5Digest[16] = {0}; UINT32 i; INT32 MD5Status; UINT8 *cPtr = NULL; UINT32 AppendLen = 0; #endif #if (FW_VERSION_CHECK_ENABLE) char *VerInfo = NULL; #endif m_bUpdRename = FALSE; #if (defined(_NVT_ETHREARCAM_TX_)) if(sEthCamFwUd.FwAddr==0 && sEthCamFwUd.FwSize==0) { #endif uiFwSize = FileSys_GetFileLen(FW_UPDATE_NAME); hFile = FileSys_OpenFile(FW_UPDATE_NAME, FST_OPEN_READ); if (hFile == 0) { DBG_ERR("cannot find %s\r\n", FW_UPDATE_NAME); return UPDNAND_STS_FW_READ2_ERR; } p_Mem = (unsigned char *)SxCmd_GetTempMem(uiFwSize); if(NULL == p_Mem){ DBG_ERR("Alloc Temp Mem is NULL(uiFwSize=%d)\r\n",uiFwSize); return UPDNAND_STS_FW_READ2_ERR; } #if (USER_PACK_UPDATE == ENABLE) uiFwAddr = (UINT32)p_Mem; #endif fst_er = FileSys_ReadFile(hFile, (UINT8 *)p_Mem, &uiFwSize, 0, NULL); FileSys_CloseFile(hFile); if (fst_er != FST_STA_OK) { DBG_ERR("FW bin read fail\r\n"); return UPDNAND_STS_FW_READ2_ERR; } #if (defined(_NVT_ETHREARCAM_TX_)) }else{ uiFwSize = sEthCamFwUd.FwSize; p_Mem =(unsigned char *) sEthCamFwUd.FwAddr; } #endif #if (MD5_CHECK_ENABLE) MD5Status = TRUE; // Get append length information cPtr = (UINT8*)(p_Mem + uiFwSize); AppendLen = (*(cPtr-2))+(*(cPtr-1))*256; if (AppendLen >= uiFwSize) { DBG_ERR("FW Size Fail\r\n"); MD5Status = FALSE; goto MD5_Err; } // Check whether "ecbf" is presented at file tail. uiFwSize -= AppendLen; cPtr = (UINT8*)(p_Mem + uiFwSize); if ((*cPtr != 'e') || (*(cPtr+1) != 'c') || (*(cPtr+2) != 'b') || (*(cPtr+3) != 'f')) { DBG_ERR("Cannot find MD5 info\r\n"); MD5Status = FALSE; goto MD5_Err; } // If you want compare version, do something here.... #if (FW_VERSION_CHECK_ENABLE) VerInfo = (char *)(uiFwAddr+uiFwSize+4+16+2); DBG_DUMP("========>New VerInfo = %s\r\n", VerInfo); DBG_DUMP("========>Cur VerInfo = %s\r\n", CurVerInfo); INT32 VerInfoStatus = FALSE; char szMode[8]; int major = 0, middle = 0, min = 0; int ret = 0; int major2 = 0, middle2 = 0, min2 = 0; ret = sscanf(VerInfo, "\"%[0-9a-zA-Z]\"\"%d.%d.%d\"", szMode, &major, &middle, &min); DBG_DUMP("New VerInfo = %s, %d, %d, %d, ret = %d \r\n", szMode, major, middle, min, ret); ret = sscanf(CurVerInfo, "%d.%d.%d", &major2, &middle2, &min2); DBG_DUMP("Cur VerInfo = %s, %d, %d, %d , ret = %d \r\n", CurVerInfoType, major2, middle2, min2, ret); if (strcmp(szMode, CurVerInfoType) == 0) { if (major == major2) { if (middle == middle2) { if (min == min2) { VerInfoStatus = TRUE; } else if(min > min2) { VerInfoStatus = TRUE; } } else if (middle > middle2) { VerInfoStatus = TRUE; } } else if(major > major2) { VerInfoStatus = TRUE; } } if ((g_FwUpdateType == FW_UPDATE_TYPE_FW) && (VerInfoStatus == FALSE)) { DBG_DUMP("FW not support low version upgrade!!!\r\n"); return UPDNAND_STS_FW_READ2_VERSION_ERR; } #endif //g_FwUpdating = TRUE; // Calculate MD5 value md5_calc(MD5Digest, (UINT8*)uiFwAddr, uiFwSize); // Compare MD5 value for (i = 0; i < 16; i++) { if (MD5Digest[i] != *(cPtr+4+i)) { MD5Status = FALSE; } } MD5_Err: if (MD5Status == TRUE) { //FWBufAddr = uiFwAddr; g_FWBufSize = uiFwSize; DBG_DUMP(" MD5 value TRUE \r\n"); //g_uiUpdateFWSetpTotail = ((FWBufSize/1024)/60); #if 0 // remove MD5 data from FW bin file DBG_DUMP("uiUpdateFWName: %s\r\n", uiUpdateFWName); //hFile = FileSys_OpenFile(FW_UPDATE_NAME, FST_OPEN_WRITE|FST_OPEN_ALWAYS); hFile = FileSys_OpenFile(uiUpdateFWName, FST_OPEN_WRITE|FST_OPEN_ALWAYS); if (hFile != NULL) { fst_er = FileSys_TruncFile(hFile, g_FWBufSize); FileSys_CloseFile(hFile); if (fst_er != FST_STA_OK) { DBG_ERR("truncate %s fail\r\n", FW_UPDATE_NAME); return UPDNAND_STS_FW_READ2_ERR; } if (g_FwUpdateType == FW_UPDATE_TYPE_FW) { //GxStrg_CloseDevice(0); // don't need to close storage device for 575! since it's only one cpu! //DrvCARD_EnableCardPower(TRUE); // temporarily } } else { DBG_ERR("cannot open %s for write\r\n", FW_UPDATE_NAME); return UPDNAND_STS_FW_READ2_ERR; } // TEST!!! //Rename to be safe, that loader can update by name for next updating if FW updating FW failed. DBG_DUMP("Rename bin: %s\r\n", _BIN_NAME_".BIN"); if (FileSys_RenameFile(_BIN_NAME_".BIN", uiUpdateFWName, TRUE) == FST_STA_OK) { m_bUpdRename = TRUE; } else { DBG_ERR("cannot rename bin file.\r\n"); return UPDNAND_STS_FW_READ2_ERR; } #elif 0 CheckSumOKCb(); // TEST!!! #endif } else { DBG_DUMP(" MD5 value fail \r\n"); return UPDNAND_STS_FW_READ2_ERR; } #endif #if (USER_PACK_UPDATE == ENABLE) NVTPACK_GET_PARTITION_INPUT input_partition; NVTPACK_MEM output_partition; NVTPACK_ER pack_ret = NVTPACK_ER_FAILED; DSAPackInfo stNandPackInfo; char NewVerInfo[128] = {0}, szStr[32]; char CurrentVerInfoVer[128] = {0}; static BOOL CurrentVerInfoVerCheck = TRUE; int rval = 0; UINT32 uiPartition_len; UINT8 *uiPartition_addr; // 1. update DSA, if necessary if (g_FwUpdateType == FW_UPDATE_TYPE_DSA) { // update DSA only uiPartition_addr = (unsigned char *)uiFwAddr; uiPartition_len = uiFwSize; pack_ret = NVTPACK_ER_SUCCESS; } else if (g_FwUpdateType == FW_UPDATE_TYPE_FW) { // update whole FW, including DSA input_partition.id = PACK_ITEM_EDOG; input_partition.mem.len = uiFwSize; input_partition.mem.p_data = (unsigned char *)uiFwAddr; // check if DSA partition exist, then get address and size pack_ret = nvtpack_get_partition(&input_partition, &output_partition); if (pack_ret == NVTPACK_ER_SUCCESS) { uiPartition_addr = (unsigned char *)output_partition.p_data; uiPartition_len = output_partition.len; } else { DBG_ERR("get partition PACK_ITEM_EDOG failed!\r\n"); } } else { // not support, go to FW update goto FW_Update; } if (pack_ret == NVTPACK_ER_SUCCESS) { // DSA partition exist, update it // DSA version and data are packed, we need to depack to get version firstly input_partition.id = 0; // id 0 means DSA version input_partition.mem.len = uiPartition_len; input_partition.mem.p_data = (unsigned char *)uiPartition_addr; NVTPACK_MEM output_partition_DSA; nvtpack_get_partition(&input_partition, &output_partition_DSA); memset(&stNewPackInfo, '\0', sizeof(DSAPackInfo)); g_bUpdNeedDSAData = FALSE; strcpy(NewVerInfo, (const char *)(output_partition_DSA.p_data)); //J635-20170831-9846984-a61e99aa54557c5c9da517741366e097 DBG_DUMP("DSA New VerInfo = %s\r\n", NewVerInfo); rval = sscanf(NewVerInfo, "%*[0-9a-zA-Z]-%[0-9a-zA-Z]-%[0-9a-zA-Z]-%[0-9a-zA-Z]", stNewPackInfo.szVer, szStr, stNewPackInfo.szMd5Sum); stNewPackInfo.DsaLen = atoi(szStr); DBG_DUMP("New VerInfo = %s, %u, %s, rval = %d\r\n", stNewPackInfo.szVer, stNewPackInfo.DsaLen, stNewPackInfo.szMd5Sum, rval); memset(&stNandPackInfo, '\0', sizeof(DSAPackInfo)); UserPartition_Read((INT8 *)&stNandPackInfo, 0, sizeof(stNandPackInfo), USR_PARTI_DSA_VER); DBG_DUMP("Flash VerInfo = %s, %u, %s, rval = %d\r\n", stNandPackInfo.szVer, stNandPackInfo.DsaLen, stNandPackInfo.szMd5Sum, rval); strncpy(CurrentVerInfoVer, (const char *)(stNandPackInfo.szVer), 8); CurrentVerInfoVerCheck = UpdateFw_CheckFlashDSAVer(CurrentVerInfoVer, 8); DBG_DUMP("Flash CurrentVerInfoVer = %s, CurrentVerInfoVerCheck = %d\r\n", CurrentVerInfoVer, CurrentVerInfoVerCheck); if (CurrentVerInfoVerCheck == FALSE) { //check flash ver failed, the first time to update!!! stNewPackInfo.DsaUpdate = DSA_PACK_UPDATE_OVER; stNewPackInfo.DsaMagic = DSA_PACK_INFO_MAGIC; g_bUpdNeedDSAData = TRUE; } else { //!begin update checking //if((strncasecmp(stNewPackInfo.szVer, stNandPackInfo.szVer, 8) >= 0) || (stNandPackInfo.DsaUpdate == DSA_PACK_IS_UPDATING)) if((strncmp(stNewPackInfo.szVer, stNandPackInfo.szVer, 8) >= 0) || (stNandPackInfo.DsaUpdate == DSA_PACK_IS_UPDATING)) { stNewPackInfo.DsaUpdate = DSA_PACK_UPDATE_OVER; stNewPackInfo.DsaMagic = DSA_PACK_INFO_MAGIC; g_bUpdNeedDSAData = TRUE; } else { DBG_DUMP("DSA not support low version upgrade!!!\r\n"); } } DBG_DUMP("g_bUpdNeedDSAData = %d\r\n", g_bUpdNeedDSAData); if (g_bUpdNeedDSAData == TRUE) { //Ux_OpenWindow(&UIFlowWndUpdateFWCtrl,1,UIFlow_UpdateFW_Update); stNandPackInfo.DsaUpdate = DSA_PACK_IS_UPDATING; UserPartition_Write((INT8 *)&stNandPackInfo, 0, sizeof(stNandPackInfo), USR_PARTI_DSA_VER); input_partition.id = 1; input_partition.mem.len = uiPartition_len; input_partition.mem.p_data = (unsigned char *)uiPartition_addr; nvtpack_get_partition(&input_partition, &output_partition_DSA); UserPartition_Write(output_partition_DSA.p_data, 0, output_partition_DSA.len, USR_PARTI_DSA_DATA); UserPartition_Write((INT8 *)&stNewPackInfo, 0, sizeof(stNewPackInfo), USR_PARTI_DSA_VER); } } if (g_FwUpdateType == FW_UPDATE_TYPE_FW) { // update whole FW, including WAV and TSR if (g_bUpdNeedDSAData == FALSE) { //g_uiUpdateFWSetpTotail = ( FWBufSize/(1024*100)); //Ux_OpenWindow(&UIFlowWndUpdateFWCtrl,1,UIFlow_UpdateFW_Update); } // 2. Update WAV data if necessary input_partition.id = PACK_ITEM_WAV; input_partition.mem.len = uiFwSize; input_partition.mem.p_data = (unsigned char *)uiFwAddr; pack_ret = nvtpack_get_partition(&input_partition, &output_partition); if (pack_ret == NVTPACK_ER_SUCCESS) { DBG_DUMP("get partition PACK_ITEM_WAV success, update WAV data, addr 0x%X, size %d\r\n", output_partition.p_data, output_partition.len); UserPartition_Write(output_partition.p_data, 0, output_partition.len, USR_PARTI_WAV_DATA); } // 3. update TSR model if necessary input_partition.id = PACK_ITEM_TSR_MODEL; input_partition.mem.len = uiFwSize; input_partition.mem.p_data = (unsigned char *)uiFwAddr; pack_ret = nvtpack_get_partition(&input_partition, &output_partition); if (pack_ret == NVTPACK_ER_SUCCESS) { UINT32 ocr_size_buf = output_partition.len; DBG_DUMP("Updata TSR OCR buf size = %x\r\n", ocr_size_buf); UserPartition_Write((INT8 *)(&ocr_size_buf), 0, sizeof(UINT32), USR_PARTI_TSR_MODEL); UserPartition_Write(output_partition.p_data, 0+sizeof(UINT32), output_partition.len, USR_PARTI_TSR_MODEL); } else { DBG_ERR("get partition PACK_ITEM_TSR_MODEL failed!\r\n"); } } FW_Update: // DSA update finish if (g_FwUpdateType == FW_UPDATE_TYPE_DSA) { DBG_DUMP("DSA update finish\r\n"); FileSys_DeleteFile(DSA_UPDATE_NAME); //GxStrg_CloseDevice(0); // don't need to close storage device for 575! since it's only one cpu! //DrvCARD_EnableCardPower(TRUE); // temporarily return UPDNAND_STS_FW_OK; } #endif FWSRV_BIN_UPDATE_ALL_IN_ONE Desc = {0}; Desc.uiSrcBufAddr = (UINT32)p_Mem; Desc.uiSrcBufSize = (UINT32)uiFwSize; Desc.fpCheckSumCb = CheckSumOKCb; //we rename bin after check sum OK FWSRV_CMD Cmd = {0}; Cmd.Idx = FWSRV_CMD_IDX_BIN_UPDATE_ALL_IN_ONE; //continue load Cmd.In.pData = &Desc; Cmd.In.uiNumByte = sizeof(Desc); Cmd.Prop.bExitCmdFinish = TRUE; fws_er = FwSrv_Cmd(&Cmd); #if (defined(_NVT_ETHREARCAM_TX_)) if(sEthCamFwUd.FwAddr==0 && sEthCamFwUd.FwSize==0) { #endif SxCmd_RelTempMem((UINT32)p_Mem); #if (defined(_NVT_ETHREARCAM_TX_)) }else{ EthCam_TxFwUpdate_RelTempBuffer(g_uiEthCam_TxFwUpdate_FwAddr); } #endif if(fws_er == FWSRV_ER_INVALID_UPDATED_DATA || fws_er == FWSRV_ER_WRITE_BLOCK) { DBG_ERR("update failed, start to use loader update mechanism.\r\n"); //GxSystem_EnableHWReset(0); //GxSystem_PowerOff(); return UPDNAND_STS_FW_WRITE_CHK_ERR; } else if(fws_er != FWSRV_ER_OK) { DBG_ERR("FW bin check failed %d\r\n",fws_er); if(m_bUpdRename) { if(FileSys_RenameFile(&uiUpdateFWName[3], LOADER_UPD_FW_PATH, TRUE)==FST_STA_OK) //[3]: remove "A:\\" { FileSys_DeleteFile(FW_DEL_INDIACTION_PATH); } } return UPDNAND_STS_FW_READ_CHK_ERR; } //if success, we rename back to original name and delete indication file if(m_bUpdRename) { if(FileSys_RenameFile(&uiUpdateFWName[3], LOADER_UPD_FW_PATH, TRUE)==FST_STA_OK) //[3]: remove "A:\\" { FileSys_DeleteFile(FW_DEL_INDIACTION_PATH); } } DBG_DUMP("\r\nupdate finished!\r\n"); return UPDNAND_STS_FW_OK; } #endif #if (LOGFILE_FUNC==ENABLE) void System_DetErr(void) { #if 0 //LOGFILE_FUNC TODO extern void LogFile_DumpMemAndSwReset(void); #if (LOGFILE_FUNC==ENABLE) if (LogFile_ChkSysErr() != E_OK) { LogFile_DumpMemAndSwReset(); } #endif #endif //LOGFILE_FUNC TODO } #endif /////////////////////////////////////////////////////////////////////////////// // // User Partition // /////////////////////////////////////////////////////////////////////////////// #if (USER_PACK_UPDATE == ENABLE) ER UserPartition_Read(INT8 *pReadBuf, UINT32 ulStartAddress, UINT32 ulDataLength, USR_PARTI_SECTION USR_PARTI_S) { ER err = E_OK; UINT32 i, uiBlkSize; DX_HANDLE pStrgDev; //UINT32 pBuf; //UINT32 uiPoolSize; //pBuf = mempool_userparti_rw; //uiPoolSize = POOL_SIZE_USERPARTI_RW; switch (USR_PARTI_S) { case USR_PARTI_WAV_DATA: // refer to EMBTYPE_USER0 in System_OnStrgInit_EMBMEM() //pStrgDev = Dx_GetObject(DX_CLASS_STORAGE_EXT | USER_DX_TYPE_EMBMEM_UITRON); pStrgDev = Dx_GetObject(DX_CLASS_STORAGE_EXT | DX_TYPE_EMBMEM4); // for STRG_OBJ_FW_USER0 (STRG_OBJ_FW_RSV5) break; case USR_PARTI_DSA_VER: case USR_PARTI_DSA_DATA: // refer to EMBTYPE_USER1 in System_OnStrgInit_EMBMEM() pStrgDev = Dx_GetObject(DX_CLASS_STORAGE_EXT | USER_DX_TYPE_EMBMEM_UITRON); break; default: DBG_ERR("partition not support!\r\n"); return E_SYS; } STORAGE_OBJ *pStrg = (STORAGE_OBJ *)Dx_Getcaps(pStrgDev, STORAGE_CAPS_HANDLE, 0); UINT32 uiStartSec = 0, uiEndSec = 0; UINT32 uiBeginOff = 0, uiEndLen = 0, offset = 0; UINT8 *tmpBuf = (UINT8 *)mempool_userparti_rw;//OS_GetMempoolAddr(POOL_ID_USER_PARTITION_RW_BUFFER); if (pStrg != NULL) { pStrg->Open(); // get sector size => �ݹL SPI FW �ϬO�� block �����Ū�g, 1 block = 4KB, �H�U function �o�쪺�|�O 4K pStrg->Lock(); pStrg->GetParam(STRG_GET_SECTOR_SIZE, (UINT32)&uiBlkSize, 0); pStrg->Unlock(); switch (USR_PARTI_S) { case USR_PARTI_DSA_VER: uiStartSec = 0; uiEndSec = (ulStartAddress + ulDataLength) / uiBlkSize; break; case USR_PARTI_DSA_DATA: uiStartSec = ulStartAddress / uiBlkSize + 1; uiEndSec = (ulStartAddress + ulDataLength) / uiBlkSize + 1; break; case USR_PARTI_WAV_DATA: default: uiStartSec = ulStartAddress / uiBlkSize; uiEndSec = (ulStartAddress + ulDataLength) / uiBlkSize; break; } uiBeginOff = ulStartAddress % uiBlkSize; uiEndLen = (ulStartAddress + ulDataLength) % uiBlkSize; pStrg->Lock(); i = uiStartSec; while (i <= uiEndSec) { err = pStrg->RdSectors((INT8 *)tmpBuf, i, 1); if (err != E_OK) { DBG_ERR("read err = %d\r\n", err); break; } if (uiStartSec == uiEndSec) { memcpy((UINT8 *)pReadBuf+offset, tmpBuf+uiBeginOff, uiEndLen-uiBeginOff); break; } if ((uiStartSec == i) && (uiBeginOff > 0)) { memcpy((UINT8 *)pReadBuf+offset, tmpBuf+uiBeginOff, uiBlkSize-uiBeginOff); offset += uiBlkSize-uiBeginOff; } else if ((uiEndSec == i) && (uiEndLen > 0)) { memcpy((UINT8 *)pReadBuf+offset, tmpBuf, uiEndLen); offset += uiEndLen; } else if (offset < ulDataLength) { memcpy((UINT8 *)pReadBuf+offset, tmpBuf, uiBlkSize); offset += uiBlkSize; } i++; } pStrg->Unlock(); pStrg->Close(); } else { DBG_ERR("pStrg = NULL\r\n"); err = E_SYS; } return err; } ER UserPartition_Write(INT8 *pWriteBuf, UINT32 ulStartAddress, UINT32 ulDataLength, USR_PARTI_SECTION USR_PARTI_S) { ER err = E_OK; UINT32 uiBlkSize, uiSecCnt = 0; DX_HANDLE pStrgDev; switch (USR_PARTI_S) { case USR_PARTI_WAV_DATA: // refer to EMBTYPE_USER0 in System_OnStrgInit_EMBMEM() //pStrgDev = Dx_GetObject(DX_CLASS_STORAGE_EXT | USER_DX_TYPE_EMBMEM_UITRON); pStrgDev = Dx_GetObject(DX_CLASS_STORAGE_EXT | DX_TYPE_EMBMEM4); // for STRG_OBJ_FW_USER0 (STRG_OBJ_FW_RSV5) break; case USR_PARTI_DSA_VER: case USR_PARTI_DSA_DATA: // refer to EMBTYPE_USER1 in System_OnStrgInit_EMBMEM() pStrgDev = Dx_GetObject(DX_CLASS_STORAGE_EXT | USER_DX_TYPE_EMBMEM_UITRON); break; default: DBG_ERR("partition not support!\r\n"); return E_SYS; } STORAGE_OBJ *pStrg = (STORAGE_OBJ *)Dx_Getcaps(pStrgDev, STORAGE_CAPS_HANDLE, 0); UINT32 uiStartSec = 0, uiEndSec = 0; UINT32 uiBeginOff = 0, uiEndLen = 0, offset = 0; UINT8 *tmpBuf = (UINT8 *)mempool_userparti_rw;//OS_GetMempoolAddr(POOL_ID_USER_PARTITION_RW_BUFFER); if (pStrg != NULL) { pStrg->Open(); // get sector size => �ݹL SPI FW �ϬO�� block �����Ū�g, 1 block = 64KB, �H�U function �o�쪺�|�O 64K pStrg->Lock(); pStrg->GetParam(STRG_GET_SECTOR_SIZE, (UINT32)&uiBlkSize, 0); pStrg->Unlock(); switch (USR_PARTI_S) { case USR_PARTI_DSA_VER: uiStartSec = 0; uiEndSec = (ulStartAddress + ulDataLength) / uiBlkSize; break; case USR_PARTI_DSA_DATA: uiStartSec = ulStartAddress / uiBlkSize + 1; uiEndSec = (ulStartAddress + ulDataLength) / uiBlkSize + 1; break; case USR_PARTI_WAV_DATA: default: uiStartSec = ulStartAddress / uiBlkSize; uiEndSec = (ulStartAddress + ulDataLength) / uiBlkSize; break; } uiBeginOff = ulStartAddress % uiBlkSize; uiEndLen = (ulStartAddress + ulDataLength) % uiBlkSize; uiSecCnt = uiEndSec - uiStartSec + 1; pStrg->Lock(); if (uiStartSec == uiEndSec) { err = pStrg->RdSectors((INT8 *)tmpBuf, uiStartSec, 1); if (err != E_OK) { DBG_ERR("RdSectors err=%d\r\n", err); } else { memcpy(tmpBuf+uiBeginOff, pWriteBuf, uiEndLen-uiBeginOff); err = pStrg->WrSectors((INT8 *)tmpBuf, uiStartSec, 1); if (err != E_OK) { DBG_ERR("WrSectors err=%d\r\n", err); } } } else { if (uiBeginOff > 0) { offset = uiBlkSize-uiBeginOff; memcpy((UINT8 *)tmpBuf+uiBeginOff, pWriteBuf, uiBlkSize-uiBeginOff); err = pStrg->WrSectors((INT8 *)tmpBuf, uiStartSec, 1); if (err != E_OK) { DBG_ERR("WrSectors err=%d\r\n", err); } uiStartSec++; uiSecCnt--; } #if 0 if (uiEndLen > 0) { memcpy((UINT8 *)tmpBuf, pWriteBuf+(ulDataLength-uiEndLen), uiEndLen); err = pStrg->WrSectors((INT8 *)tmpBuf, uiEndSec, 1); if (err != E_OK) { DBG_ERR("WrSectors err=%d\r\n", err); } uiSecCnt--; } else if (uiEndLen == 0) { uiSecCnt--; } if (uiSecCnt > 0) { err = pStrg->WrSectors((INT8 *)pWriteBuf+offset, uiStartSec, uiSecCnt); if (err != E_OK) { DBG_ERR("WrSectors err=%d\r\n", err); } } #else if (uiSecCnt > 0) { err = pStrg->WrSectors((INT8 *)pWriteBuf+offset, uiStartSec, uiSecCnt); if (err != E_OK) { DBG_ERR("WrSectors err=%d\r\n", err); } } #endif } pStrg->Unlock(); pStrg->Close(); } else { DBG_ERR("pStrg = NULL\r\n"); err = E_SYS; } return err; } #endif