The 2nd loader to boot from uSD memory.
Toolkit:STM Development System
Location:/bipom/devtools/STM32/examples/Wipom/usd_loader
#include "usd_storage.h" UBYTE IAP_Buf[IAP_BUF_SIZE]; //******************************************************************************** void Puts(char* str) { #ifdef uSD_LOADER_ENABLE_MESSAGES for (;*str;) putChar(*str++); #endif } //******************************************************************************** static void cmd_run (ULONG run_addr) { PFV fp; // fp = (PFV)(*(__IO uint32_t*) (run_addr+4)); #ifdef uSD_LOADER_ENABLE_DEBUG_MESSAGES tprintf("\n\rRun applicaiton at 0x%x...", run_addr); #endif Puts ("\n\r"); delayMs(50); /* Initialize user application's Stack Pointer */ __set_MSP(*(__IO uint32_t*) run_addr); // remap Vector table //SCB->VTOR = run_addr | ((uint32_t)&_isr_vectors_offs & (uint32_t)0x1FFFFF80);; // Jump to application; (*fp)(); } //******************************************************************************** static void cmd_reset (void) { PFV fp; fp = (PFV)(RESET_ADDR+4); __set_MSP(*(__IO uint32_t*) RESET_ADDR); (*fp)(); } //******************************************************************************** static ERRCODE Remove_Update(void) { ERRCODE ec=SUCCESS; APP_INFO *pINFO = (APP_INFO *)IAP_Buf; // Read the whole sector if (ReadMemory_uSD_LOADER(IAP_Buf,0,DATASTORAGEAPI_SECTOR_SIZE)) { ec = ERROR; goto func_end; } // Reset the update flag in the buffer pINFO->update = 0; // Re-calculate the checks pINFO->crc16 = Crc16_uSD_LOADER((ULONG)pINFO,sizeof(APP_INFO)-sizeof(USHORT),uC_MEMORY); // Copy the RAM buffer back ec = WriteMemory_uSD_LOADER(IAP_Buf,0); // func_end: return ec; } //******************************************************************************** static ULONG APP_Update(ULONG start_addr, ULONG app_size_byte) { ULONG current_addr; ULONG sector_index; ULONG iap_prog_cnt; ULONG new_sector; ULONG sector_size, sector_size_sum; ULONG update_addr; ULONG retCode; ULONG block_size; ULONG data_cnt; // FLASH_Unlock(); // iap_prog_cnt = (app_size_byte+IAP_BUF_SIZE-1) IAP_BUF_SIZE; #ifdef uSD_LOADER_ENABLE_DEBUG_MESSAGES tprintf("\n\rApp size: %d bytes, iap program number: %d (%d bytes once).\n", app_size_byte, iap_prog_cnt, IAP_BUF_SIZE); #endif // new_sector = 1; update_addr = PROG_ADDR; current_addr = start_addr; sector_index = update_addr>>IAP_SHIFT_BITS; data_cnt = 0; while (iap_prog_cnt != 0) { block_size = app_size_byte - data_cnt; if(block_size > IAP_BUF_SIZE) block_size = IAP_BUF_SIZE; // Copy the next data to IAP_Buf if(ReadMemory_uSD_LOADER(IAP_Buf,current_addr,block_size)) { app_size_byte =0; break; } // Check if we start a new sector if (new_sector) { #ifdef uSD_LOADER_ENABLE_DEBUG_MESSAGES tprintf("\n\rPrepare and erase sector %d.\n", sector_index); #endif if ((retCode =IAP_PrepareErase(sector_index)) != 0) { #ifdef uSD_LOADER_ENABLE_DEBUG_MESSAGES tprintf("\n\rFailed to erase sector %d, ec=%lu\n", sector_index,retCode); #endif Puts ("\n\rERROR: can't erase Flash sector"); return 0; } sector_size = IAP_BUF_SIZE; sector_size_sum = 0; new_sector = 0; } // #ifdef uSD_LOADER_ENABLE_DEBUG_MESSAGES tprintf("\n\rProgram at addr 0x%x.\n", update_addr); #endif if (IAP_Program(sector_index, update_addr) != 0) { #ifdef uSD_LOADER_ENABLE_DEBUG_MESSAGES tprintf("\n\rFailed to program secotr %d.\n", sector_index); #endif Puts ("\n\rERROR: can't write Flash data"); app_size_byte =0; break; } // update_addr += IAP_BUF_SIZE; sector_size_sum += IAP_BUF_SIZE; current_addr += IAP_BUF_SIZE; iap_prog_cnt--; data_cnt += block_size; if (sector_size_sum == sector_size) { sector_index++; new_sector = 1; } } // FLASH_Lock(); return app_size_byte; } //******************************************************************************** // prepare and erase sector with specified index, // if OK, return 0, otherwise return the error code */ //******************************************************************************** ERRCODE IAP_PrepareErase(ULONG sector_index) { ERRCODE ec = SUCCESS; if(FLASH_COMPLETE != FLASH_ErasePage(sector_index<<IAP_SHIFT_BITS)) ec = ERROR; return ec; } //******************************************************************************** // program content in IAP_Buf to internal flash with address of // app_addr, and sector index of sector_index. // if ok, return 0, otherwise return the error code. */ //******************************************************************************** ERRCODE IAP_Program(ULONG sector_index, ULONG app_addr) { ERRCODE ec = SUCCESS; ULONG address = (sector_index<<IAP_SHIFT_BITS); ULONG* ramData = (ULONG*)IAP_Buf; ULONG ndx; for ( ndx =0 ; ndx < (IAP_BUF_SIZE>>2) ; ndx++) { if(FLASH_COMPLETE != FLASH_ProgramWord(address,ramData[ndx])) { ec = ERROR; break; } if( (*((ULONG*)address)) != ramData[ndx] ) { ec = ERROR; break; } address += 4; } // return ec; } //******************************************************************************** int main (void) { APP_INFO info; ULONG address; ULONG size; ERRCODE ec = SUCCESS; // Init_uSD_LOADER(); // Puts ("\n\ruSD Boot Loader "); Puts (uSD_LOADER_REVISION); Puts ("\n\rDate: "); Puts (__DATE__); Puts (" Time: "); Puts (__TIME__); // Test uSD and Virtual memory #ifdef LOCAL_uSD_TEST Local_uSD_Test(); #endif // Read uSD to get the APP INFO structure if (ReadMemory_uSD_LOADER((UBYTE *)&info,0,sizeof(APP_INFO))) info.update =0; // address = sizeof(APP_INFO); size = info.size; // //Check if we need to update the application code if(UPDATE_FLAG == info.update) { // Check the application size if(MAX_APP_SIZE > info.size) { // Check if Crc16 of header is OK if(info.crc16 == Crc16_uSD_LOADER((ULONG)&info,sizeof(APP_INFO)-sizeof(USHORT),uC_MEMORY)) { // if(info.checkSum == Crc16_uSD_LOADER(address,size,uSD_MEMORY)) { ec = ERROR; // if(APP_Update(address,size)==size) { Puts ("\n\rSUCCEES: new image is copied"); if(info.checkSum == Crc16_uSD_LOADER(PROG_ADDR,size,uC_MEMORY)) { ec = SUCCESS; Puts("\n\rSUCCEES: new application is updated"); if(Remove_Update()) { Puts("\n\rWARNING: can't remove update status"); } } else Puts("\n\rERROR: invalid data check sum"); }else Puts("\n\rERROR: can't update the image"); } else Puts("\n\rERROR: invalid image check sum"); } else Puts("\n\rERROR: invalid header check sum"); } else Puts("\n\rERROR: too big image size"); } Puts ("\n\rRun the application at 0x08010000 address"); Puts ("\n\r"); // Run the application if(ec) cmd_reset(); else cmd_run(RUN_ADDR); // We should never reach that code Puts ("\n\rERROR: can't run the application"); for (;;) cmd_reset(); return 0; }