void BmpReader::init(FILE* f, size_t& w, size_t& h) { my_file = f; my_pixel_offset = read_file_header(f); size_t bpp, table_num; read_image_header(f, w, h, bpp, table_num); if(bpp == 8) read_color_table(f, my_color_table, table_num); else if(bpp != 24) throw InvalidFormat("unexpected bits per pixel in BMP image header"); }
void boot_application(void) { nvms_t update_part; nvms_t exec_part; nvms_t header_part; int32_t *int_vector_table = (int32_t *) 0; int32_t *image_address; suota_1_1_image_header_t new_header = { {0} }; suota_1_1_image_header_t current_header = { {0} }; TRACE("\r\nBootloader started\r\n"); if (force_suota) { return; } update_part = ad_nvms_open(NVMS_FW_UPDATE_PART); exec_part = ad_nvms_open(NVMS_FW_EXEC_PART); header_part = ad_nvms_open(NVMS_IMAGE_HEADER_PART); TRACE("Checking for update image.\r\n"); read_image_header(update_part, SUOTA_IMAGE_HEADER_OFFSET, &new_header); if (image_ready(&new_header)) { /* Check if there is valid image for update, check CRC */ if (valid_image(&new_header, update_part, new_header.exec_location, true)) { TRACE("Updating image.\r\n"); update_image(&new_header, update_part, exec_part, header_part); } else { TRACE("New image invalid, erasing.\r\n"); /* Update image not good, just erase it and start whatever is there */ new_header.signature[0] = 0; new_header.signature[1] = 0; ad_nvms_write(update_part, SUOTA_IMAGE_HEADER_OFFSET, (uint8_t *) &new_header, sizeof(new_header)); } } /* * Check if current image is valid, CRC can be forced by image header but it is not * forced here. */ read_image_header(header_part, 0, ¤t_header); TRACE("Validating current image.\r\n"); if (!valid_image(¤t_header, exec_part, 0, false)) { TRACE("Current image invalid, starting SUOTA.\r\n"); return; } /* * The following code assumes that code will be executed in QSPI cached mode. * * The binary image that is stored in the QSPI flash must be compiled for a specific * address, other than address 0x0 (or 0x8000000) since this is where the boot loader is * stored. * The binary images that are stored in the QSPI Flash, except for the boot loader image, * must not be modified in any way before flashed. No image header must be preceded. The * images start with the initial stack pointer and the reset handler and the rest of the * vector table and image code and data follow. * The complete vector table of the application image is copied from the image location * to the RAM. */ if (256 != ad_nvms_get_pointer(exec_part, 0, 256, (const void **) &image_address)) { return; } /* Check sanity of image */ if (!image_sanity_check(image_address)) { TRACE("Current executable insane, starting SUOTA.\r\n"); return; } TRACE("Starting image at 0x%X, reset vector 0x%X.\r\n", (unsigned int) image_address, (unsigned int) image_address[1]); /* * In OS environment some interrupt could already be enabled, disable all before * interrupt vectors are changed. */ __disable_irq(); /* Copy interrupt vector table from image */ memcpy(int_vector_table, image_address, 0x100); /* * If bootloader changed any configuration (GPIO, clocks) it should be uninitialized here */ periph_deinit(); /* * Reset platform */ reboot(); for (;;) { } }