#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 48 of file firm_upgrade.c.
| #define MAX_DATA_LINE 16 |
| #define UPGRADE_SIZE_MAX 50 |
Definition at line 73 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 220 of file firm_upgrade.c.
References UPGRADE_SIZE_MAX.
Referenced by firm_upgrade_run().
00221 { 00222 char ram_msg_upgrade[UPGRADE_SIZE_MAX+1]; 00223 00224 // Move data from FLASH to RAM, because printf don't support flash 00225 for( U8 u8_i=0; u8_i<UPGRADE_SIZE_MAX; u8_i++ ) 00226 { 00227 ram_msg_upgrade[u8_i] = msg_to_upgrade[u8_i]; 00228 } 00229 ram_msg_upgrade[UPGRADE_SIZE_MAX]=0; // Add terminator in case of 00230 printf( "\"" ); 00231 printf( ram_msg_upgrade ); 00232 printf( "\"\r\n" ); 00233 }
| 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 330 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().
00331 { 00332 char file_status_name[] = "status.txt"; 00333 00334 printf( status ); 00335 printf( "\n\r" ); 00336 00337 // Create a status file if possible 00338 if( !nav_file_create((FS_STRING)file_status_name) ) 00339 { 00340 if( fs_g_status != FS_ERR_FILE_EXIST ) 00341 return; // Error during creation file 00342 // File exist then continue 00343 } 00344 if( file_open(FOPEN_MODE_W) ) 00345 { 00346 // Write status in file 00347 file_write_buf( (unsigned char*) status, strlen(status) ); 00348 file_close(); 00349 } 00350 }
| static Bool firm_upgrade_searchfile | ( | const char * | filename | ) | [static] |
Searchs a HEX file in the U-Disks.
| file | name to search |
Definition at line 242 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().
00243 { 00244 U8 u8_drive_lun; 00245 00246 //** Search "Hello.txt" file in all USB-Disk 00247 u8_drive_lun = 1; // 1 is USB lun in this demo (0 = DataFlash, 1 = USB Host) 00248 while( 1 ) 00249 { 00250 if( u8_drive_lun >= nav_drive_nb() ) 00251 return FALSE; 00252 // Mount USB disk 00253 nav_drive_set( u8_drive_lun ); 00254 if( nav_partition_mount() ) 00255 { 00256 // Mount OK then seacrh file 00257 if( nav_setcwd((FS_STRING)filename,TRUE,FALSE) ) 00258 break; // File Found 00259 } 00260 u8_drive_lun++; // Go to next USB disk 00261 } 00262 return TRUE; 00263 }
| 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 274 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().
00275 { 00276 U8 u8_i, u8_nb_data, u8_crc=0; 00277 U8 *ptr_data; 00278 00279 // Check header line 00280 if( ':' != file_getc()) 00281 return FALSE; 00282 00283 // Get data size 00284 u8_nb_data = firm_upgrade_readbyte(); 00285 u8_crc += u8_nb_data; 00286 if( u8_nb_data > line->u8_nb_data ) 00287 return FALSE; 00288 line->u8_nb_data = u8_nb_data; 00289 00290 // Get data address 00291 line->u16_add = (((U16)firm_upgrade_readbyte())<<8) | firm_upgrade_readbyte(); 00292 u8_crc += LSB(line->u16_add); 00293 u8_crc += MSB(line->u16_add); 00294 00295 // Read record type 00296 // - 00, data record, contains data and 16-bit address. The format described above. 00297 // - 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. 00298 // - 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. 00299 // - 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. 00300 // - 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. 00301 // - 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. 00302 line->u8_type = firm_upgrade_readbyte(); 00303 u8_crc += line->u8_type; 00304 00305 // Get data 00306 ptr_data = line->datas; 00307 for( u8_i=0; u8_i<u8_nb_data; u8_i++ ) 00308 { 00309 *ptr_data = firm_upgrade_readbyte(); 00310 u8_crc += *ptr_data; 00311 ptr_data++; 00312 } 00313 00314 // Check CRC 00315 // 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) 00316 // together will always result in a value wherein the least significant byte is zero (0x00). 00317 u8_crc += firm_upgrade_readbyte(); 00318 00319 // Read end of line = '\r' and '\n' 00320 file_getc();file_getc(); 00321 00322 return( 0 == u8_crc ); 00323 }
This function is used to convert a ascii character into 4 bit number '5' => 5 'A' => 10.
| ASCII | characters to convert |
Definition at line 360 of file firm_upgrade.c.
Referenced by firm_upgrade_readbyte().
00361 { 00362 U8 byte=0; 00363 if( ('0'<=ascii) && (ascii<='9') ) 00364 byte = ascii-'0'; 00365 if( ('a'<=ascii) && (ascii<='f') ) 00366 byte = (ascii-'a'+10); 00367 if( ('A'<=ascii) && (ascii<='F') ) 00368 byte = (ascii-'A'+10); 00369 return byte; 00370 }
| 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 377 of file firm_upgrade.c.
References file_getc(), and firm_upgrade_ascii2bin().
Referenced by firm_upgrade_readhexline().
00378 { 00379 U8 ascii_msb ,ascii_lsb; 00380 ascii_msb = file_getc(); 00381 ascii_lsb = file_getc(); 00382 return (firm_upgrade_ascii2bin(ascii_msb)<<4) | firm_upgrade_ascii2bin(ascii_lsb); 00383 }
| 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 108 of file firm_upgrade.c.
Referenced by host_ms_task().
00109 { 00110 Fs_index sav_index; 00111 U8 u8_i, save_int; 00112 St_hex_line hex_line; 00113 U8 datas[MAX_DATA_LINE]; 00114 char filename[30]; 00115 00116 hex_line.datas = datas; // Init data buffer used 00117 hex_line.u8_type = 0; // Autotrize only type 0 00118 00119 // Save current position to resolve it before exit routine 00120 sav_index = nav_getindex(); 00121 00122 printf("\n\rDislpay upgrade zone BEFORE upgrade:\n\r"); 00123 firm_upgrade_displayzone(); 00124 00125 printf("Search upgrade file\n\r...\r"); 00126 if( !firm_upgrade_searchfile( "upgrade*" ) ) 00127 { 00128 firm_upgrade_status("No upgrade file"); 00129 nav_gotoindex(&sav_index); 00130 return; 00131 } 00132 00133 nav_file_getname( filename, 50 ); 00134 printf("Open upgrade file \"%s\"\n\r...\r", filename ); 00135 if( !file_open(FOPEN_MODE_R) ) 00136 { 00137 firm_upgrade_status("!! Error to open upgrade file"); 00138 nav_gotoindex(&sav_index); // Restore previous position 00139 return; 00140 } 00141 00142 printf("Check upgrade file\n\r...\r"); 00143 while (!file_eof()) 00144 { 00145 // For each text line, check upgrade zone 00146 hex_line.u8_nb_data = MAX_DATA_LINE; 00147 if( !firm_upgrade_readhexline( &hex_line ) ) 00148 { 00149 file_close(); 00150 firm_upgrade_status("!! Error in HEX file format"); 00151 nav_gotoindex(&sav_index); 00152 return; 00153 } 00154 00155 if( (hex_line.u16_add < UPGRADE_ADDR) 00156 || (hex_line.u16_add+hex_line.u8_nb_data) > (UPGRADE_ADDR+UPGRADE_SIZE_MAX) ) 00157 { 00158 file_close(); 00159 firm_upgrade_status("!! Upgrade zone not autorized"); 00160 nav_gotoindex(&sav_index); 00161 return; 00162 } 00163 } 00164 00165 printf("Program FLASH\n\r...\r"); 00166 // Check bootloader 00167 if( !flash_lib_check() ) 00168 { 00169 file_close(); 00170 firm_upgrade_status("!! The bootloder if not loaded"); 00171 nav_gotoindex(&sav_index); 00172 return; 00173 } 00174 00175 file_seek(0,FS_SEEK_SET); // Restart at beginning of file 00176 while (!file_eof()) 00177 { 00178 // For each text line, check upgrade zone 00179 hex_line.u8_nb_data = MAX_DATA_LINE; 00180 if( !firm_upgrade_readhexline( &hex_line ) ) 00181 { 00182 file_close(); 00183 firm_upgrade_status("!! Error in HEX file format"); 00184 nav_gotoindex(&sav_index); 00185 return; 00186 } 00187 00188 // Disabling the interrupt 00189 save_int=Get_interrupt_state(); 00190 Disable_interrupt(); 00191 // Writing the flash with a check of highest flash address 00192 flash_wr_block( hex_line.datas, hex_line.u16_add, hex_line.u8_nb_data ); 00193 // Read data in flash and check programmation with buffer 00194 for( u8_i=0; u8_i<hex_line.u8_nb_data; u8_i++ ) 00195 { 00196 if( hex_line.datas[u8_i] != flash_rd_byte((U8 farcode*)hex_line.u16_add) ) 00197 { 00198 file_close(); 00199 firm_upgrade_status("!! Programmation in flash BAD\n\r!!! Check if the bootloader is loaded in chip."); 00200 nav_gotoindex(&sav_index); 00201 return; 00202 } 00203 hex_line.u16_add++; 00204 } 00205 // Restore interrupt state 00206 if(save_int) { Enable_interrupt(); } 00207 } 00208 00209 file_close(); 00210 firm_upgrade_status("Upgrade successfull"); 00211 nav_gotoindex(&sav_index); 00212 00213 printf("Dislpay upgrade zone AFTER upgrade:\n\r"); 00214 firm_upgrade_displayzone(); 00215 }
1.5.3