void test_memory_is_copied_1(void) { ihex_recordset_t *rs = ihex_rs_from_file("res/big-a.hex"); uint8_t *dst = (uint8_t*) malloc(8192); if (rs == NULL) { CU_FAIL("File \"res/big-a.hex\" does not exist."); return; } ihex_mem_copy(rs, dst, 8192, IHEX_WIDTH_8BIT, IHEX_ORDER_BIGENDIAN); // :100400000B 0B 0B 98 B0 2D 0B 0B 0B 88 80 04 00 00 00 00 29 CU_ASSERT_EQUAL(dst[0x400], 0x0B); CU_ASSERT_EQUAL(dst[0x401], 0x0B); CU_ASSERT_EQUAL(dst[0x402], 0x0B); CU_ASSERT_EQUAL(dst[0x403], 0x98); CU_ASSERT_EQUAL(dst[0x404], 0xB0); CU_ASSERT_EQUAL(dst[0x405], 0x2D); CU_ASSERT_EQUAL(dst[0x406], 0x0B); CU_ASSERT_EQUAL(dst[0x407], 0x0B); CU_ASSERT_EQUAL(dst[0x408], 0x0B); CU_ASSERT_EQUAL(dst[0x409], 0x88); CU_ASSERT_EQUAL(dst[0x40A], 0x80); CU_ASSERT_EQUAL(dst[0x40B], 0x04); CU_ASSERT_EQUAL(dst[0x40C], 0x00); CU_ASSERT_EQUAL(dst[0x40D], 0x00); CU_ASSERT_EQUAL(dst[0x40E], 0x00); CU_ASSERT_EQUAL(dst[0x40F], 0x00); }
void test_can_read_ihex_rs_from_file_1(void) { ihex_recordset_t* r = ihex_rs_from_file("res/hex1.dat"); CU_ASSERT_PTR_NOT_NULL_FATAL(r); CU_ASSERT_EQUAL_FATAL(r->ihrs_count, 6); IHEX_ASSERT_REC_EQUAL(&(r->ihrs_records[1]), 0x10, 0x0100, IHEX_DATA, 0x21); }
void test_can_read_ihex_rs_from_file_2(void) { ihex_recordset_t* r = ihex_rs_from_file("res/big-a.hex"); CU_ASSERT_PTR_NOT_NULL_FATAL(r); CU_ASSERT_EQUAL_FATAL(r->ihrs_count, 214); IHEX_ASSERT_REC_EQUAL(&(r->ihrs_records[2]), 0x10, 0x0400, IHEX_DATA, 0x0B); }
void test_memory_is_copied_1(void) { uint32_t addr_min; uint32_t addr_max; ihex_recordset_t *rs; int rv; uint8_t *dst; ulong_t size; ulong_t ofst; ulong_t n; rs = ihex_rs_from_file("C:/ble_nrf51/tandd/nrf51/examples/ble_peripheral/ble_app_K1/pca10028/s110/arm4/_build/nrf51422_xxac_s110.hex"); size = ihex_rs_get_size(rs); printf("ihex_rs_get_size: size = %d\n", size); rv = ihex_rs_get_address_range(rs, &addr_min, &addr_max); printf("ihex_rs_get_address_range: rv = %d, addr_min = 0x%08x, addr_max = 0x%08x\n", rv, addr_min, addr_max); dst = (uint8_t*) malloc(0x30000);//8192); if (rs == NULL) { //CU_FAIL("File \"res/big-a.hex\" does not exist."); return; } //rv = ihex_mem_copy(rs, dst, 0x30000/*8192*/, IHEX_WIDTH_8BIT, IHEX_ORDER_BIGENDIAN); ofst = 0; n = 0x20; rv = ihex_mem_copy_from_offset(rs, dst, ofst, n, IHEX_WIDTH_8BIT, IHEX_ORDER_BIGENDIAN); printf("rv = %d\n", rv); ofst = 0x08; n = 0x10; rv = ihex_mem_copy_from_offset(rs, dst, ofst, n, IHEX_WIDTH_8BIT, IHEX_ORDER_BIGENDIAN); printf("rv = %d\n", rv); ofst = 0x2744; n = 0x100; rv = ihex_mem_copy_from_offset(rs, dst, ofst, n, IHEX_WIDTH_8BIT, IHEX_ORDER_BIGENDIAN); printf("rv = %d\n", rv); free(dst); }
int main(int argc,char **argv) { if ((argc<3|| argc>4) ||(argc==4&&strcasecmp(argv[3],"force"))) { fprintf(stderr,"usage: flash900 <firmware> <serial port> [force]\n"); exit(-1); } int fd=open(argv[2],O_RDWR); if (fd==-1) { fprintf(stderr,"Could not open serial port '%s'\n",argv[2]); exit(-1); } if (set_nonblock(fd)) { fprintf(stderr,"Could not set serial port '%s' non-blocking\n",argv[2]); exit(-1); } int speeds[8]={230400,115200,57600,38400,19200,9600,2400,1200}; int speed_count=8; printf("Trying to get command mode...\n"); int i; for(i=0;i<speed_count;i++) { // set port speed and non-blocking, and disable CTSRTS if (setup_serial_port(fd,speeds[i])) { fprintf(stderr,"Could not setup serial port '%s'\n",argv[2]); exit(-1); } int last_char = 0; // Make sure we have left command mode and bootloader mode // 0 = $30 = bootloader reboot command unsigned char cmd[260]; bzero(&cmd[0],260); printf("Checking if stuck in bootloader\n"); // Make sure there is no command in progress with the boot loader write(fd,cmd,260); // Try to sync with bootloader if it is already running cmd[0]=GET_DEVICE; cmd[1]=EOC; write(fd,cmd,2); unsigned char bootloaderdetect[4]={0x43,0x91,0x12,0x10}; int state=0; long long timeout=gettime_ms()+1250; while(gettime_ms()<timeout) { unsigned char buffer[2]; int r=read(fd,buffer,1); if (r==1) { // printf(" read %02X\n",buffer[0]); if (buffer[0]==bootloaderdetect[state]) state++; else state=0; if (state==4) { printf("Looks like we are in the bootloader already\n"); break; } } } if (state==4) printf("Detected RFD900 is already in bootloader\n"); else { printf("Trying to switch to AT command mode\n"); write(fd,"\b\b\b\b\b\b\b\b\b\b\b\b\r",14); // give it time to process the above, so that the first character of ATO // doesn't get eaten. usleep(10000); write(fd,"ATO\r",4); // sleep(2); // allow 2 sec to reboot if it was in bootloader mode already // now try to get to AT command mode sleep(1); write(fd,"+++",3); // now wait for upto 1.2 seconds for "OK" timeout=gettime_ms()+1200; state=0; while(gettime_ms()<timeout) { char buffer[1]; int r=read(fd,buffer,1); if (r==1) { // printf(" read %02X\n",buffer[0]); if ((buffer[0]=='K') && (last_char == 'O')) state=2; else state=0; last_char = buffer[0]; if (state==2) break; } else usleep(10000); } if (state==2) { // try AT&UPDATE or ATS1=115\rAT&W\rATZ if the modem isn't already on 115200bps printf("Switching to boot loader...\n"); char *cmd="AT&UPDATE\r\n"; if (speeds[i]==115200) { write(fd,cmd,strlen(cmd)); } else { char *cmd="ATS1=115\r\n"; write(fd,cmd,strlen(cmd)); sleep(1); cmd="AT&W\r\n"; write(fd,cmd,strlen(cmd)); sleep(1); cmd="ATZ\r\n"; write(fd,cmd,strlen(cmd)); sleep(1); // Go back to looking for modem at 115200 printf("Changing modem from %d to 115200bps\n", speeds[i]); i=-1; continue; } // then switch to 115200 regardless of the speed we were at, // since the bootloader always talks 115200 setup_serial_port(fd,115200); // give time to switch to boot loader // and consume any characters that arrive in the meantime timeout=gettime_ms()+1500; while(gettime_ms()<timeout) { unsigned char buffer[2]; int r=read(fd,(char *)buffer,1); // fprintf(stderr,"Read %02X from bootloader.\n",buffer[0]); if (r!=1) usleep(100000); else { // printf(" read %02X\n",buffer[0]); } } state=4; } } if (state==4) { // got command mode (probably) printf("Got OK at %d\n",speeds[i]); // ask for board ID unsigned char cmd[1024]; cmd[0]=GET_DEVICE; cmd[1]=EOC; write(fd,cmd,2); int id = next_char(fd); int freq = next_char(fd); expect_insync(fd); expect_ok(fd); char filename[1024]; snprintf(filename,1024,"%s-%02X-%02X.ihx",argv[1],id,freq); printf("Board id = $%02x, freq = $%02x : Will load firmware from '%s'\n", id,freq,filename); ihex_recordset_t *ihex=ihex_rs_from_file(filename); if (!ihex) { fprintf(stderr,"Could not read intelhex from file '%s'\n",filename); // Reboot radio write(fd,"0",1); exit(-2); } printf("Read %d IHEX records from firmware file\n",ihex->ihrs_count); // Sort IHEX records into ascending address order so that when we flash // them we don't mess things up by writing the flash data in the wrong order qsort(ihex->ihrs_records,ihex->ihrs_count,sizeof(ihex_record_t), compare_ihex_record); int i; if (0) for(i=0;i<ihex->ihrs_count;i++) printf("$%04x - $%04x\n", ihex->ihrs_records[i].ihr_address, ihex->ihrs_records[i].ihr_address+ ihex->ihrs_records[i].ihr_length-1); // Reset parameters cmd[0]=PARAM_ERASE; cmd[1]=EOC; write(fd,cmd,2); expect_insync(fd); expect_ok(fd); printf("Erased parameters.\n"); // Program all parts of the firmware and verify that that got written printf("Checking if the radio already has this version of firmware...\n"); int fail=0; if (argc==3) { // read flash and compare with ihex records unsigned char buffer[65536]; printf("Bulk reading from flash...\n"); read_64kb_flash(fd,buffer); printf("Read all 64KB flash. Now verifying...\n"); int i; for(i=0;i<ihex->ihrs_count;i++) if (ihex->ihrs_records[i].ihr_type==0x00) { if (fail) break; if (memcmp(&buffer[ihex->ihrs_records[i].ihr_address], ihex->ihrs_records[i].ihr_data, ihex->ihrs_records[i].ihr_length)) fail=1; } } if ((argc==4)||fail) { printf("\nFirmware differs: erasing and flashing...\n"); // Erase ROM printf("Erasing flash.\n"); cmd[0]=CHIP_ERASE; cmd[1]=EOC; write(fd,cmd,2); expect_insync(fd); expect_ok(fd); // Write ROM printf("Flash erased, now writing new firmware.\n"); write_or_verify_flash(fd,ihex,1); } // Reboot radio write(fd,"0",1); break; } else { printf("Modem doesn't seem to be at %dbps\n",speeds[i]); } } return 0; }
int image_ihex_merge_file(const char *filename, const nvm_symbol *list, int list_size, size_t blob_size) { ihex_recordset_t *rs; uint32_t start, end; char *blob; int symbols = 0; if (! filename || ! blob_size) return -1; //invalid parameters rs = ihex_rs_from_file(filename); if (! rs) { switch (ihex_errno()) { case IHEX_ERR_INCORRECT_CHECKSUM: case IHEX_ERR_NO_EOF: case IHEX_ERR_PARSE_ERROR: case IHEX_ERR_WRONG_RECORD_LENGTH: case IHEX_ERR_UNKNOWN_RECORD_TYPE: // Parse error, not a well-formed Intel Hex file return 0; case IHEX_ERR_NO_INPUT: case IHEX_ERR_MMAP_FAILED: case IHEX_ERR_READ_FAILED: // File not accessible symbols = -2; break; case IHEX_ERR_MALLOC_FAILED: default: // System error symbols = -3; break; } fprintf(stderr, _("Cannot open image \"%s\" (%s)\n"), filename, ihex_error()); return symbols; } if (0 != ihex_rs_get_address_range(rs, &start, &end)) { fprintf(stderr, _("Could not determine data range in Intel Hex file \"%s\" (%s)\n"), filename, ihex_error()); symbols = -4; } else if (rs->ihrs_count == 0 || start >= end) { fprintf(stderr, _("Image file \"%s\" is empty\n"), filename); } else { if (DEBUG) printf(_("%s: %s contains range 0x%04" PRIx32 " to 0x%04" PRIx32 "\n"), __func__, filename, start, end > 0 ? end - 1 : 0); if (blob_size > end) { fprintf(stderr, _("Image file \"%s\" is too small, %zu of %zu bytes missing\n"), filename, blob_size - end, blob_size); blob_size = end; } // Allocate and initialize memory for needed ihex content blob = calloc(1, blob_size); if (! blob) { fprintf(stderr, _("Could not copy data from Intel Hex file \"%s\" (%s)\n"), filename, strerror(errno)); symbols = -3; } else { if (0 != ihex_byte_copy(rs, (void*) blob, blob_size, 0)) { fprintf(stderr, _("Could not copy data from Intel Hex file \"%s\" (%s)\n"), filename, ihex_error()); symbols = -4; } else { symbols = image_raw_merge_mem(blob, list, list_size, blob_size); } free(blob); } } ihex_rs_free(rs); return symbols; }