int main(void) { struct nffs_area_desc descs[NFFS_AREA_MAX]; /** Contains indices of the areas which can contain image data. */ uint8_t img_areas[NFFS_AREA_MAX]; /** Areas representing the beginning of image slots. */ uint8_t img_starts[2]; int cnt; int total; struct boot_rsp rsp; int rc; struct boot_req req = { .br_area_descs = descs, .br_image_areas = img_areas, .br_slot_areas = img_starts, }; os_init(); cnt = (NFFS_AREA_MAX / 2) - 3; rc = flash_area_to_nffs_desc(FLASH_AREA_IMAGE_0, &cnt, descs); img_starts[0] = 0; total = cnt; cnt = (NFFS_AREA_MAX / 2) - 3; rc = flash_area_to_nffs_desc(FLASH_AREA_IMAGE_1, &cnt, &descs[total]); assert(rc == 0); img_starts[1] = total; total += cnt; cnt = 1; rc = flash_area_to_nffs_desc(FLASH_AREA_IMAGE_SCRATCH, &cnt, &descs[total]); assert(rc == 0); req.br_scratch_area_idx = total; total += 1; req.br_num_image_areas = total; for (cnt = 0; cnt < total; cnt++) { img_areas[cnt] = cnt; } cnt = 6; rc = flash_area_to_nffs_desc(FLASH_AREA_NFFS, &cnt, &descs[total]); assert(rc == 0); total += cnt; nffs_config.nc_num_inodes = 50; nffs_config.nc_num_blocks = 50; nffs_config.nc_num_cache_blocks = 32; rc = boot_go(&req, &rsp); assert(rc == 0); system_start((void *)(rsp.br_image_addr + rsp.br_hdr->ih_hdr_size)); return 0; }
void boot_test_util_mark_revert(void) { struct boot_swap_state state_slot0 = { .magic = BOOT_MAGIC_GOOD, .copy_done = 0x01, .image_ok = 0xff, }; boot_test_util_write_swap_state(FLASH_AREA_IMAGE_0, &state_slot0); } void boot_test_util_verify_area(const struct flash_area *area_desc, const struct image_header *hdr, uint32_t image_addr, int img_msb) { struct image_header temp_hdr; uint32_t area_end; uint32_t img_size; uint32_t img_off; uint32_t img_end; uint32_t addr; uint8_t buf[256]; int rem_area; int past_image; int chunk_sz; int rem_img; int rc; int i; addr = area_desc->fa_off; if (hdr != NULL) { img_size = hdr->ih_img_size; if (addr == image_addr) { rc = hal_flash_read(area_desc->fa_device_id, image_addr, &temp_hdr, sizeof temp_hdr); TEST_ASSERT(rc == 0); TEST_ASSERT(memcmp(&temp_hdr, hdr, sizeof *hdr) == 0); addr += hdr->ih_hdr_size; } } else { img_size = 0; } area_end = area_desc->fa_off + area_desc->fa_size; img_end = image_addr + img_size; past_image = addr >= img_end; while (addr < area_end) { rem_area = area_end - addr; rem_img = img_end - addr; if (hdr != NULL) { img_off = addr - image_addr - hdr->ih_hdr_size; } else { img_off = 0; } if (rem_area > sizeof buf) { chunk_sz = sizeof buf; } else { chunk_sz = rem_area; } rc = hal_flash_read(area_desc->fa_device_id, addr, buf, chunk_sz); TEST_ASSERT(rc == 0); for (i = 0; i < chunk_sz; i++) { if (rem_img > 0) { TEST_ASSERT(buf[i] == boot_test_util_byte_at(img_msb, img_off + i)); } else if (past_image) { #if 0 TEST_ASSERT(buf[i] == 0xff); #endif } } addr += chunk_sz; } } void boot_test_util_verify_status_clear(void) { struct boot_swap_state state_slot0; int rc; rc = boot_read_swap_state_img(0, &state_slot0); assert(rc == 0); TEST_ASSERT(state_slot0.magic != BOOT_MAGIC_UNSET || state_slot0.copy_done != 0); } void boot_test_util_verify_flash(const struct image_header *hdr0, int orig_slot_0, const struct image_header *hdr1, int orig_slot_1) { const struct flash_area *area_desc; int area_idx; area_idx = 0; while (1) { area_desc = boot_test_area_descs + area_idx; if (area_desc->fa_off == boot_test_img_addrs[1].address && area_desc->fa_device_id == boot_test_img_addrs[1].flash_id) { break; } boot_test_util_verify_area(area_desc, hdr0, boot_test_img_addrs[0].address, orig_slot_0); area_idx++; } while (1) { if (area_idx == BOOT_TEST_AREA_IDX_SCRATCH) { break; } area_desc = boot_test_area_descs + area_idx; boot_test_util_verify_area(area_desc, hdr1, boot_test_img_addrs[1].address, orig_slot_1); area_idx++; } } void boot_test_util_verify_all(int expected_swap_type, const struct image_header *hdr0, const struct image_header *hdr1) { const struct image_header *slot0hdr; const struct image_header *slot1hdr; struct boot_rsp rsp; int orig_slot_0; int orig_slot_1; int num_swaps; int rc; int i; TEST_ASSERT_FATAL(hdr0 != NULL || hdr1 != NULL); num_swaps = 0; for (i = 0; i < 3; i++) { rc = boot_go(&rsp); TEST_ASSERT_FATAL(rc == 0); if (expected_swap_type != BOOT_SWAP_TYPE_NONE) { num_swaps++; } if (num_swaps % 2 == 0) { if (hdr0 != NULL) { slot0hdr = hdr0; slot1hdr = hdr1; } else { slot0hdr = hdr1; slot1hdr = hdr0; } orig_slot_0 = 0; orig_slot_1 = 1; } else { if (hdr1 != NULL) { slot0hdr = hdr1; slot1hdr = hdr0; } else { slot0hdr = hdr0; slot1hdr = hdr1; } orig_slot_0 = 1; orig_slot_1 = 0; } TEST_ASSERT(memcmp(rsp.br_hdr, slot0hdr, sizeof *slot0hdr) == 0); TEST_ASSERT(rsp.br_flash_id == boot_test_img_addrs[0].flash_id); TEST_ASSERT(rsp.br_image_addr == boot_test_img_addrs[0].address); boot_test_util_verify_flash(slot0hdr, orig_slot_0, slot1hdr, orig_slot_1); boot_test_util_verify_status_clear(); if (expected_swap_type != BOOT_SWAP_TYPE_NONE) { switch (expected_swap_type) { case BOOT_SWAP_TYPE_TEST: expected_swap_type = BOOT_SWAP_TYPE_REVERT; break; case BOOT_SWAP_TYPE_REVERT: expected_swap_type = BOOT_SWAP_TYPE_NONE; break; default: TEST_ASSERT_FATAL(0); break; } } } }