#include "config.h"#include "conf_usb.h"#include "modules/file_system/fat.h"#include "modules/file_system/fs_com.h"#include "modules/file_system/navigation.h"#include "modules/file_system/file.h"#include "modules/file_system/nav_utils.h"#include "lib_mcu/flash/flash_lib.h"#include "stdio.h"#include "string.h"
Go to the source code of this file.
Data Structures | |
| struct | St_hex_line |
Defines | |
| #define | HOST_UPGRADE_MODE DISABLE |
| #define | MAX_DATA_LINE 16 |
| #define | UPGRADE_SIZE_MAX 50 |
| #define | UPGRADE_ADDR 0x333 |
Functions | |
| code char msg_to_upgrade[50] | At (0x333) |
| static void | firm_upgrade_displayzone (void) |
| Displays on UART the space used to upgrade firmware. | |
| static void | firm_upgrade_status (char *status) |
| This function creates a file on disk with the status of upgrade. | |
| static Bool | firm_upgrade_searchfile (const char *filename) |
| Searchs a HEX file in the U-Disks. | |
| static Bool | firm_upgrade_readhexline (St_hex_line *line) |
| Reads and decodes a text line with HEX format. | |
| static U8 | firm_upgrade_ascii2bin (U8 ascii) |
| This function is used to convert a ascii character into 4 bit number '5' => 5 'A' => 10. | |
| static U8 | firm_upgrade_readbyte (void) |
| This function reads and converts two ascii characters into byte number '51' => 0x51 'A1' => 0xA1. | |
| void | firm_upgrade_run (void) |
| This function runs the upgrade process. | |
Definition in file firm_upgrade.c.
| #define HOST_UPGRADE_MODE DISABLE |
Definition at line 51 of file firm_upgrade.c.
| #define MAX_DATA_LINE 16 |
| #define UPGRADE_SIZE_MAX 50 |
Definition at line 76 of file firm_upgrade.c.
Referenced by firm_upgrade_displayzone(), and firm_upgrade_run().
| #define UPGRADE_ADDR 0x333 |
| code char msg_to_upgrade [ 50 ] At | ( | 0x333 | ) |
| static void firm_upgrade_displayzone | ( | void | ) | [static] |
Displays on UART the space used to upgrade firmware.
Definition at line 223 of file firm_upgrade.c.
References UPGRADE_SIZE_MAX.
Referenced by firm_upgrade_run().
00224 { 00225 char ram_msg_upgrade[UPGRADE_SIZE_MAX+1]; 00226 00227 // Move data from FLASH to RAM, because printf don't support flash 00228 for( U8 u8_i=0; u8_i<UPGRADE_SIZE_MAX; u8_i++ ) 00229 { 00230 ram_msg_upgrade[u8_i] = msg_to_upgrade[u8_i]; 00231 } 00232 ram_msg_upgrade[UPGRADE_SIZE_MAX]=0; // Add terminator in case of 00233 printf( "\"" ); 00234 printf( ram_msg_upgrade ); 00235 printf( "\"\r\n" ); 00236 }
| static void firm_upgrade_status | ( | char * | status | ) | [static] |
This function creates a file on disk with the status of upgrade.
| status | to write |
Definition at line 333 of file firm_upgrade.c.
References file_close(), file_open(), file_write_buf(), FOPEN_MODE_W, FS_ERR_FILE_EXIST, fs_g_status, and nav_file_create().
Referenced by firm_upgrade_run().
00334 { 00335 char file_status_name[] = "status.txt"; 00336 00337 printf( status ); 00338 printf( "\n\r" ); 00339 00340 // Create a status file if possible 00341 if( !nav_file_create((FS_STRING)file_status_name) ) 00342 { 00343 if( fs_g_status != FS_ERR_FILE_EXIST ) 00344 return; // Error during creation file 00345 // File exist then continue 00346 } 00347 if( file_open(FOPEN_MODE_W) ) 00348 { 00349 // Write status in file 00350 file_write_buf( (unsigned char*) status, strlen(status) ); 00351 file_close(); 00352 } 00353 }
| static Bool firm_upgrade_searchfile | ( | const char * | filename | ) | [static] |
Searchs a HEX file in the U-Disks.
| file | name to search |
Definition at line 245 of file firm_upgrade.c.
References FALSE, nav_drive_nb(), nav_drive_set(), nav_partition_mount(), nav_setcwd(), and TRUE.
Referenced by firm_upgrade_run().
00246 { 00247 U8 u8_drive_lun; 00248 00249 //** Search "Hello.txt" file in all USB-Disk 00250 u8_drive_lun = 1; // 1 is USB lun in this demo (0 = DataFlash, 1 = USB Host) 00251 while( 1 ) 00252 { 00253 if( u8_drive_lun >= nav_drive_nb() ) 00254 return FALSE; 00255 // Mount USB disk 00256 nav_drive_set( u8_drive_lun ); 00257 if( nav_partition_mount() ) 00258 { 00259 // Mount OK then seacrh file 00260 if( nav_setcwd((FS_STRING)filename,TRUE,FALSE) ) 00261 break; // File Found 00262 } 00263 u8_drive_lun++; // Go to next USB disk 00264 } 00265 return TRUE; 00266 }
| static Bool firm_upgrade_readhexline | ( | St_hex_line * | line | ) | [static] |
Reads and decodes a text line with HEX format.
| line | Specify in struct:
|
Definition at line 277 of file firm_upgrade.c.
References St_hex_line::datas, FALSE, file_getc(), firm_upgrade_readbyte(), LSB, MSB, St_hex_line::u16_add, St_hex_line::u8_nb_data, and St_hex_line::u8_type.
Referenced by firm_upgrade_run().
00278 { 00279 U8 u8_i, u8_nb_data, u8_crc=0; 00280 U8 *ptr_data; 00281 00282 // Check header line 00283 if( ':' != file_getc()) 00284 return FALSE; 00285 00286 // Get data size 00287 u8_nb_data = firm_upgrade_readbyte(); 00288 u8_crc += u8_nb_data; 00289 if( u8_nb_data > line->u8_nb_data ) 00290 return FALSE; 00291 line->u8_nb_data = u8_nb_data; 00292 00293 // Get data address 00294 line->u16_add = (((U16)firm_upgrade_readbyte())<<8) | firm_upgrade_readbyte(); 00295 u8_crc += LSB(line->u16_add); 00296 u8_crc += MSB(line->u16_add); 00297 00298 // Read record type 00299 // - 00, data record, contains data and 16-bit address. The format described above. 00300 // - 01, End Of File record, a file termination record. No data. Has to be the last line of the file, only one per file permitted. Usually ':00000001FF'. Originally the End Of File record could contain a start address for the program being loaded, e.g. :00AB2F0125 would make a jump to address AB2F. This was convenient when programs were loaded from punched paper tape. 00301 // - 02, Extended Segment Address Record, segment-base address. Used when 16 bits are not enough, identical to 80x86 real mode addressing. The address specified by the 02 record is multiplied by 16 (shifted 4 bits left) and added to the subsequent 00 record addresses. This allows addressing of up to a megabyte of address space. The address field of this record has to be 0000, the byte count is 02 (the segment is 16-bit). The least significant hex digit of the segment address is always 0. 00302 // - 03, Start Segment Address Record. For 80x86 processors, it specifies the initial content of the CS:IP registers. The address field is 0000, the byte count is 04, the first two bytes are the CS value, the latter two are the IP value. 00303 // - 04, Extended Linear Address Record, allowing for fully 32 bit addressing. The address field is 0000, the byte count is 02. The two data bytes represent the upper 16 bits of the 32 bit address, when combined with the address of the 00 type record. 00304 // - 05, Start Linear Address Record. The address field is 0000, the byte count is 04. The 4 data bytes represent the 32-bit value loaded into the EIP register of the 80386 and higher CPU. 00305 line->u8_type = firm_upgrade_readbyte(); 00306 u8_crc += line->u8_type; 00307 00308 // Get data 00309 ptr_data = line->datas; 00310 for( u8_i=0; u8_i<u8_nb_data; u8_i++ ) 00311 { 00312 *ptr_data = firm_upgrade_readbyte(); 00313 u8_crc += *ptr_data; 00314 ptr_data++; 00315 } 00316 00317 // Check CRC 00318 // If the checksum is correct, adding all the bytes (the Byte count, both bytes in Address, the Record type, each Data byte and the Checksum) 00319 // together will always result in a value wherein the least significant byte is zero (0x00). 00320 u8_crc += firm_upgrade_readbyte(); 00321 00322 // Read end of line = '\r' and '\n' 00323 file_getc();file_getc(); 00324 00325 return( 0 == u8_crc ); 00326 }
This function is used to convert a ascii character into 4 bit number '5' => 5 'A' => 10.
| ASCII | characters to convert |
Definition at line 363 of file firm_upgrade.c.
Referenced by firm_upgrade_readbyte().
00364 { 00365 U8 byte=0; 00366 if( ('0'<=ascii) && (ascii<='9') ) 00367 byte = ascii-'0'; 00368 if( ('a'<=ascii) && (ascii<='f') ) 00369 byte = (ascii-'a'+10); 00370 if( ('A'<=ascii) && (ascii<='F') ) 00371 byte = (ascii-'A'+10); 00372 return byte; 00373 }
| static U8 firm_upgrade_readbyte | ( | void | ) | [static] |
This function reads and converts two ascii characters into byte number '51' => 0x51 'A1' => 0xA1.
Definition at line 380 of file firm_upgrade.c.
References file_getc(), and firm_upgrade_ascii2bin().
Referenced by firm_upgrade_readhexline().
00381 { 00382 U8 ascii_msb ,ascii_lsb; 00383 ascii_msb = file_getc(); 00384 ascii_lsb = file_getc(); 00385 return (firm_upgrade_ascii2bin(ascii_msb)<<4) | firm_upgrade_ascii2bin(ascii_lsb); 00386 }
| void firm_upgrade_run | ( | void | ) |
This function runs the upgrade process.
//! The status of process is display on UART and writed in a status file on U-Disk. //!
Definition at line 111 of file firm_upgrade.c.
Referenced by host_ms_task().
00112 { 00113 Fs_index sav_index; 00114 U8 u8_i, save_int; 00115 St_hex_line hex_line; 00116 U8 datas[MAX_DATA_LINE]; 00117 char filename[30]; 00118 00119 hex_line.datas = datas; // Init data buffer used 00120 hex_line.u8_type = 0; // Autotrize only type 0 00121 00122 // Save current position to resolve it before exit routine 00123 sav_index = nav_getindex(); 00124 00125 printf("\n\rDislpay upgrade zone BEFORE upgrade:\n\r"); 00126 firm_upgrade_displayzone(); 00127 00128 printf("Search upgrade file\n\r...\r"); 00129 if( !firm_upgrade_searchfile( "upgrade*" ) ) 00130 { 00131 firm_upgrade_status("No upgrade file"); 00132 nav_gotoindex(&sav_index); 00133 return; 00134 } 00135 00136 nav_file_getname( filename, 50 ); 00137 printf("Open upgrade file \"%s\"\n\r...\r", filename ); 00138 if( !file_open(FOPEN_MODE_R) ) 00139 { 00140 firm_upgrade_status("!! Error to open upgrade file"); 00141 nav_gotoindex(&sav_index); // Restore previous position 00142 return; 00143 } 00144 00145 printf("Check upgrade file\n\r...\r"); 00146 while (!file_eof()) 00147 { 00148 // For each text line, check upgrade zone 00149 hex_line.u8_nb_data = MAX_DATA_LINE; 00150 if( !firm_upgrade_readhexline( &hex_line ) ) 00151 { 00152 file_close(); 00153 firm_upgrade_status("!! Error in HEX file format"); 00154 nav_gotoindex(&sav_index); 00155 return; 00156 } 00157 00158 if( (hex_line.u16_add < UPGRADE_ADDR) 00159 || (hex_line.u16_add+hex_line.u8_nb_data) > (UPGRADE_ADDR+UPGRADE_SIZE_MAX) ) 00160 { 00161 file_close(); 00162 firm_upgrade_status("!! Upgrade zone not autorized"); 00163 nav_gotoindex(&sav_index); 00164 return; 00165 } 00166 } 00167 00168 printf("Program FLASH\n\r...\r"); 00169 // Check bootloader 00170 if( !flash_lib_check() ) 00171 { 00172 file_close(); 00173 firm_upgrade_status("!! The bootloder if not loaded"); 00174 nav_gotoindex(&sav_index); 00175 return; 00176 } 00177 00178 file_seek(0,FS_SEEK_SET); // Restart at beginning of file 00179 while (!file_eof()) 00180 { 00181 // For each text line, check upgrade zone 00182 hex_line.u8_nb_data = MAX_DATA_LINE; 00183 if( !firm_upgrade_readhexline( &hex_line ) ) 00184 { 00185 file_close(); 00186 firm_upgrade_status("!! Error in HEX file format"); 00187 nav_gotoindex(&sav_index); 00188 return; 00189 } 00190 00191 // Disabling the interrupt 00192 save_int=Get_interrupt_state(); 00193 Disable_interrupt(); 00194 // Writing the flash with a check of highest flash address 00195 flash_wr_block( hex_line.datas, hex_line.u16_add, hex_line.u8_nb_data ); 00196 // Read data in flash and check programmation with buffer 00197 for( u8_i=0; u8_i<hex_line.u8_nb_data; u8_i++ ) 00198 { 00199 if( hex_line.datas[u8_i] != flash_rd_byte((U8 farcode*)hex_line.u16_add) ) 00200 { 00201 file_close(); 00202 firm_upgrade_status("!! Programmation in flash BAD\n\r!!! Check if the bootloader is loaded in chip."); 00203 nav_gotoindex(&sav_index); 00204 return; 00205 } 00206 hex_line.u16_add++; 00207 } 00208 // Restore interrupt state 00209 if(save_int) { Enable_interrupt(); } 00210 } 00211 00212 file_close(); 00213 firm_upgrade_status("Upgrade successfull"); 00214 nav_gotoindex(&sav_index); 00215 00216 printf("Dislpay upgrade zone AFTER upgrade:\n\r"); 00217 firm_upgrade_displayzone(); 00218 }
1.5.3