static void boot_test_util_copy_area(int from_area_idx, int to_area_idx) { const struct nffs_area_desc *from_area_desc; const struct nffs_area_desc *to_area_desc; void *buf; int rc; from_area_desc = boot_test_area_descs + from_area_idx; to_area_desc = boot_test_area_descs + to_area_idx; TEST_ASSERT(from_area_desc->nad_length == to_area_desc->nad_length); buf = malloc(from_area_desc->nad_length); TEST_ASSERT(buf != NULL); rc = hal_flash_read(from_area_desc->nad_flash_id, from_area_desc->nad_offset, buf, from_area_desc->nad_length); TEST_ASSERT(rc == 0); rc = hal_flash_erase(to_area_desc->nad_flash_id, to_area_desc->nad_offset, to_area_desc->nad_length); TEST_ASSERT(rc == 0); rc = hal_flash_write(to_area_desc->nad_flash_id, to_area_desc->nad_offset, buf, to_area_desc->nad_length); TEST_ASSERT(rc == 0); free(buf); }
/** * Writes the supplied boot status to the flash file system. The boot status * contains the current state of an in-progress image copy operation. * * @param bs The boot status to write. * * @return 0 on success; nonzero on failure. */ int boot_write_status(struct boot_status *bs) { uint32_t off; uint8_t flash_id; uint8_t val; if (bs->idx == 0) { /* * Write to scratch */ boot_scratch_loc(&flash_id, &off); } else { /* * Write to slot 0; */ boot_magic_loc(0, &flash_id, &off); } off -= ((3 * bs->elem_sz) * bs->idx + bs->elem_sz * (bs->state + 1)); val = bs->state; hal_flash_write(flash_id, off, &val, sizeof(val)); return 0; }
/** * Writes a chunk of data to flash. * * @param area_idx The index of the area to write to. * @param area_offset The offset within the area to write to. * @param data The data to write to flash. * @param len The number of bytes to write. * * @return 0 on success; * FS_ERANGE on an attempt to write to an * invalid address range, or on an attempt to * perform a non-strictly-sequential write; * FS_EFLASH_ERROR on flash error. */ int nffs_flash_write(uint8_t area_idx, uint32_t area_offset, const void *data, uint32_t len) { struct nffs_area *area; int rc; assert(area_idx < nffs_num_areas); area = nffs_areas + area_idx; if (area_offset + len > area->na_length) { return FS_ERANGE; } if (area_offset < area->na_cur) { return FS_ERANGE; } rc = hal_flash_write(area->na_flash_id, area->na_offset + area_offset, data, len); if (rc != 0) { return FS_HW_ERROR; } area->na_cur = area_offset + len; return 0; }
static void boot_test_util_swap_areas(int area_idx1, int area_idx2) { const struct nffs_area_desc *area_desc1; const struct nffs_area_desc *area_desc2; void *buf1; void *buf2; int rc; area_desc1 = boot_test_area_descs + area_idx1; area_desc2 = boot_test_area_descs + area_idx2; TEST_ASSERT(area_desc1->nad_length == area_desc2->nad_length); buf1 = malloc(area_desc1->nad_length); TEST_ASSERT(buf1 != NULL); buf2 = malloc(area_desc2->nad_length); TEST_ASSERT(buf2 != NULL); rc = hal_flash_read(area_desc1->nad_flash_id, area_desc1->nad_offset, buf1, area_desc1->nad_length); TEST_ASSERT(rc == 0); rc = hal_flash_read(area_desc2->nad_flash_id, area_desc2->nad_offset, buf2, area_desc2->nad_length); TEST_ASSERT(rc == 0); rc = hal_flash_erase(area_desc1->nad_flash_id, area_desc1->nad_offset, area_desc1->nad_length); TEST_ASSERT(rc == 0); rc = hal_flash_erase(area_desc2->nad_flash_id, area_desc2->nad_offset, area_desc2->nad_length); TEST_ASSERT(rc == 0); rc = hal_flash_write(area_desc1->nad_flash_id, area_desc1->nad_offset, buf2, area_desc1->nad_length); TEST_ASSERT(rc == 0); rc = hal_flash_write(area_desc2->nad_flash_id, area_desc2->nad_offset, buf1, area_desc2->nad_length); TEST_ASSERT(rc == 0); free(buf1); free(buf2); }
static void boot_test_util_write_hash(const struct image_header *hdr, int slot) { uint8_t tmpdata[1024]; uint8_t hash[32]; int rc; uint32_t off; uint32_t blk_sz; uint32_t sz; mbedtls_sha256_context ctx; uint8_t flash_id; uint32_t addr; struct image_tlv tlv; mbedtls_sha256_init(&ctx); mbedtls_sha256_starts(&ctx, 0); flash_id = boot_test_img_addrs[slot].flash_id; addr = boot_test_img_addrs[slot].address; sz = hdr->ih_hdr_size + hdr->ih_img_size; for (off = 0; off < sz; off += blk_sz) { blk_sz = sz - off; if (blk_sz > sizeof(tmpdata)) { blk_sz = sizeof(tmpdata); } rc = hal_flash_read(flash_id, addr + off, tmpdata, blk_sz); TEST_ASSERT(rc == 0); mbedtls_sha256_update(&ctx, tmpdata, blk_sz); } mbedtls_sha256_finish(&ctx, hash); tlv.it_type = IMAGE_TLV_SHA256; tlv._pad = 0; tlv.it_len = sizeof(hash); rc = hal_flash_write(flash_id, addr + off, &tlv, sizeof(tlv)); TEST_ASSERT(rc == 0); off += sizeof(tlv); rc = hal_flash_write(flash_id, addr + off, hash, sizeof(hash)); TEST_ASSERT(rc == 0); }
static void boot_test_util_write_image(const struct image_header *hdr, int slot) { uint32_t image_off; uint32_t off; uint8_t flash_id; uint8_t buf[256]; int chunk_sz; int rc; int i; TEST_ASSERT(slot == 0 || slot == 1); flash_id = boot_test_img_addrs[slot].flash_id; off = boot_test_img_addrs[slot].address; rc = hal_flash_write(flash_id, off, hdr, sizeof *hdr); TEST_ASSERT(rc == 0); off += hdr->ih_hdr_size; image_off = 0; while (image_off < hdr->ih_img_size) { if (hdr->ih_img_size - image_off > sizeof buf) { chunk_sz = sizeof buf; } else { chunk_sz = hdr->ih_img_size - image_off; } for (i = 0; i < chunk_sz; i++) { buf[i] = boot_test_util_byte_at(slot, image_off + i); } rc = hal_flash_write(flash_id, off + image_off, buf, chunk_sz); TEST_ASSERT(rc == 0); image_off += chunk_sz; } }
/** * Finalizes the copy-in-progress status on the flash. The boot status * contains the current state of an in-progress image copy operation. By * clearing this, it is implied that there is no copy operation in * progress. */ void boot_clear_status(void) { uint32_t off; uint8_t val = 0; uint8_t flash_id; /* * Write to slot 0; boot_img_trailer is the 8 bytes within image slot. * Here we say that copy operation was finished. */ boot_magic_loc(0, &flash_id, &off); off += sizeof(uint32_t); hal_flash_write(flash_id, off, &val, sizeof(val)); }
/** * Copies the contents of one area to another. The destination area must * be erased prior to this function being called. * * @param from_area_idx The index of the source area. * @param to_area_idx The index of the destination area. * * @return 0 on success; nonzero on failure. */ static int boot_copy_area(int from_area_idx, int to_area_idx) { const struct nffs_area_desc *from_area_desc; const struct nffs_area_desc *to_area_desc; uint32_t from_addr; uint32_t to_addr; uint32_t off; int chunk_sz; int rc; static uint8_t buf[1024]; from_area_desc = boot_req->br_area_descs + from_area_idx; to_area_desc = boot_req->br_area_descs + to_area_idx; assert(to_area_desc->nad_length >= from_area_desc->nad_length); off = 0; while (off < from_area_desc->nad_length) { if (from_area_desc->nad_length - off > sizeof buf) { chunk_sz = sizeof buf; } else { chunk_sz = from_area_desc->nad_length - off; } from_addr = from_area_desc->nad_offset + off; rc = hal_flash_read(from_area_desc->nad_flash_id, from_addr, buf, chunk_sz); if (rc != 0) { return rc; } to_addr = to_area_desc->nad_offset + off; rc = hal_flash_write(to_area_desc->nad_flash_id, to_addr, buf, chunk_sz); if (rc != 0) { return rc; } off += chunk_sz; } return 0; }
static hal_result_t s_hal_eeprom_writeflash(uint32_t addr, uint32_t size, void * data) { //#warning --> acemor: todo: add a function which writes manages write data in flash: read page, change, erase, write. // need a buffer of 2k ... shall we pass it with the cfg? uint32_t pageaddr = hal_flash_get_pageaddr(addr); uint32_t pagesize = hal_flash_get_pagesize(addr); uint32_t offset = addr - pageaddr; if(hal_false == hal_flash_address_isvalid(addr)) { // cannot write at the address the first bytes return(hal_res_NOK_generic); } if(hal_false == hal_flash_address_isvalid(addr+size-1)) { // cannot write at the address the last bytes return(hal_res_NOK_generic); } if(NULL == s_hal_eeprom_emulated_flash_cfg.flashpagebuffer) { // dont have a pagebuffer return(hal_res_NOK_generic); } #warning: eeprom in flash so far i can write only .... fix it if((offset+size) > pagesize) { return(hal_res_NOK_generic); } memset(s_hal_eeprom_emulated_flash_cfg.flashpagebuffer, 0, s_hal_eeprom_emulated_flash_cfg.flashpagesize); hal_flash_read(pageaddr, pagesize, s_hal_eeprom_emulated_flash_cfg.flashpagebuffer); memcpy(&((uint8_t*)s_hal_eeprom_emulated_flash_cfg.flashpagebuffer)[offset], data, size); hal_flash_write(pageaddr, pagesize, s_hal_eeprom_emulated_flash_cfg.flashpagebuffer); return(hal_res_OK); }
static int stm32l475_ota_write(hal_ota_module_t *m, volatile uint32_t* off_set, uint8_t* in_buf ,uint32_t in_buf_len) { hal_partition_t pno = HAL_PARTITION_OTA_TEMP; int ret; if (ota_info.ota_len == 0) { _off_set = 0; CRC16_Init( &contex ); memset(&ota_info, 0 , sizeof ota_info); } CRC16_Update( &contex, in_buf, in_buf_len); if (!FLASH_bank1_enabled()) { pno = HAL_PARTITION_APPLICATION; } ret = hal_flash_write(pno, &_off_set, in_buf, in_buf_len); ota_info.ota_len += in_buf_len; return ret; }
static hal_result_t s_hal_eeprom_writeflash(uint32_t addr, uint32_t size, void * data) { uint32_t pageaddr = hal_flash_get_pageaddr(addr); uint32_t pagesize = hal_flash_get_pagesize(addr); uint32_t offset = addr - pageaddr; uint32_t count = 0; uint32_t numbytes = 0; uint8_t* data2write = data; if(hal_false == hal_flash_address_isvalid(addr)) { // cannot write at the address the first bytes return(hal_res_NOK_generic); } if(hal_false == hal_flash_address_isvalid(addr+size-1)) { // cannot write at the address the last bytes return(hal_res_NOK_generic); } if(NULL == s_hal_eeprom_emulated_flash_cfg.flashpagebuffer) { // dont have a pagebuffer return(hal_res_NOK_generic); } for(;;) { pageaddr = hal_flash_get_pageaddr(addr); pagesize = hal_flash_get_pagesize(addr); offset = addr - pageaddr; numbytes = (size<(pagesize-offset)) ? (size) : (pagesize-offset); data2write = (uint8_t*)data + count;; if(s_hal_eeprom_emulated_flash_cfg.flashpagesize < pagesize) { // cannot write in a page with size bigger than the buffer capacity return(hal_res_NOK_generic); } // read a page and place content in buffer hal_flash_read(pageaddr, pagesize, s_hal_eeprom_emulated_flash_cfg.flashpagebuffer); // change the buffer memcpy(&((uint8_t*)s_hal_eeprom_emulated_flash_cfg.flashpagebuffer)[offset], data2write, numbytes); // erase the page hal_flash_erase(pageaddr, pagesize); // write the buffer hal_flash_write(pageaddr, pagesize, s_hal_eeprom_emulated_flash_cfg.flashpagebuffer); count += numbytes; size -= numbytes; addr = pageaddr+pagesize; if(0 == size) { return(hal_res_OK); } } }
static hal_result_t s_hal_eeprom_eraseflash(uint32_t addr, uint32_t size) { uint32_t pageaddr = hal_flash_get_pageaddr(addr); uint32_t pagesize = hal_flash_get_pagesize(addr); uint32_t offset = addr - pageaddr; uint32_t numbytes = 0; if(hal_false == hal_flash_address_isvalid(addr)) { // cannot erase at the address of the first bytes return(hal_res_NOK_generic); } if(hal_false == hal_flash_address_isvalid(addr+size-1)) { // cannot erase at the address of the last bytes return(hal_res_NOK_generic); } if(NULL == s_hal_eeprom_emulated_flash_cfg.flashpagebuffer) { // dont have a pagebuffer return(hal_res_NOK_generic); } for(;;) { pageaddr = hal_flash_get_pageaddr(addr); pagesize = hal_flash_get_pagesize(addr); offset = addr - pageaddr; numbytes = (size<(pagesize-offset)) ? (size) : (pagesize-offset); if(s_hal_eeprom_emulated_flash_cfg.flashpagesize < pagesize) { // cannot erase a page with size bigger than the buffer capacity return(hal_res_NOK_generic); } if(numbytes == pagesize) { // just erase hal_flash_erase(pageaddr, pagesize); } else { // need to save some data in the page... // read a page and place content in buffer hal_flash_read(pageaddr, pagesize, s_hal_eeprom_emulated_flash_cfg.flashpagebuffer); // set to 0xff a part of the buffer memset(&((uint8_t*)s_hal_eeprom_emulated_flash_cfg.flashpagebuffer)[offset], 0xFF, numbytes); // erase the full page hal_flash_erase(pageaddr, pagesize); // write the buffer hal_flash_write(pageaddr, pagesize, s_hal_eeprom_emulated_flash_cfg.flashpagebuffer); } size -= numbytes; addr = pageaddr+pagesize; if(0 == size) { return(hal_res_OK); } } }
int record_to_flash(void) { int ret = 0; int pos_buff = 0; uint32_t pos_flash = 0; uint32_t part_len = DATA_BUFF_LEN / 2; uint32_t part_bytes = part_len * SAI_DATA_BYTES; uint32_t total_size = get_audio_part_len(); if (!aos_mutex_is_valid(&sai_mutex)) { KIDS_A10_PRT("aos_mutex_is_valid return false.\n"); return -1; } ret = aos_mutex_lock(&sai_mutex, SAI_WAIT_TIMEOUT); if (ret != 0) { KIDS_A10_PRT("SAI is very busy now.\n"); return -1; } if (!aos_sem_is_valid(&audio_sem)) { KIDS_A10_PRT("aos_sem_is_valid return false.\n"); ret = -1; goto REC_EXIT; } ret = reinit_sai_and_dma(SAI_dir_rx_p2m); if (ret != 0) { ret = -1; goto REC_EXIT; } printf("Record time is %f seconds!\n", get_run_time()); ret = HAL_SAI_Receive_DMA(&hsai_BlockA1, (uint8_t *)data_buff, DATA_BUFF_LEN); if (ret != 0) { KIDS_A10_PRT("HAL_SAI_Receive_DMA return failed.\n"); ret = -1; goto REC_EXIT; } #ifdef FLASH_MONO_DATA while (1) { /* Wait a callback event */ while (UpdatePointer == -1) { ret = aos_sem_wait(&audio_sem, DMA_WAIT_TIMEOUT); if (ret != 0) KIDS_A10_PRT("DMA timeout.\n"); } pos_buff = UpdatePointer; UpdatePointer = -1; /* Upate the first or the second part of the buffer */ ready_to_save(&data_buff[pos_buff], part_len); ret = hal_flash_write(PART_FOR_AUDIO, &pos_flash, &data_buff[pos_buff], part_bytes / 2); if (ret != 0) { ret = -1; break; } /* check the end of the file */ if ((pos_flash + part_bytes / 2) > total_size) { ret = HAL_SAI_DMAStop(&hsai_BlockA1); if (ret != 0) { KIDS_A10_PRT("HAL_SAI_DMAStop return failed.\n"); ret = -1; } break; } if (UpdatePointer != -1) { /* Buffer update time is too long compare to the data transfer time */ KIDS_A10_PRT("UpdatePointer error.\n"); ret = -1; break; } } #else while (1) { /* Wait a callback event */ while (UpdatePointer == -1) { aos_sem_wait(&audio_sem, DMA_WAIT_TIMEOUT); if (ret != 0) KIDS_A10_PRT("DMA timeout.\n"); } pos_buff = UpdatePointer; UpdatePointer = -1; /* Upate the first or the second part of the buffer */ ret = hal_flash_write(PART_FOR_AUDIO, &pos_flash, &data_buff[pos_buff], part_bytes); if (ret != 0) { ret = -1; break; } /* check the end of the file */ if ((pos_flash + part_bytes) > total_size) { ret = HAL_SAI_DMAStop(&hsai_BlockA1); if (ret != 0) { KIDS_A10_PRT("HAL_SAI_DMAStop return failed.\n"); ret = -1; } break; } if (UpdatePointer != -1) { /* Buffer update time is too long compare to the data transfer time */ KIDS_A10_PRT("UpdatePointer error.\n"); ret = -1; break; } } #endif REC_EXIT: ret = aos_mutex_unlock(&sai_mutex); if (ret != 0) { KIDS_A10_PRT("SAI release failed.\n"); } return ret; }