mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #6864 from davidsaada/david_flashiap_unaligned_src
FlashIAP: Fix problem of programming source buffer not aligned to 4pull/6480/head
commit
15ff9a8bf7
|
@ -22,6 +22,7 @@
|
|||
#include "utest/utest.h"
|
||||
#include "unity/unity.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
#include <algorithm>
|
||||
|
||||
#include "mbed.h"
|
||||
|
||||
|
@ -48,10 +49,10 @@ void flashiap_program_test()
|
|||
TEST_ASSERT_NOT_EQUAL(0, sector_size);
|
||||
TEST_ASSERT_NOT_EQUAL(0, page_size);
|
||||
TEST_ASSERT_TRUE(sector_size % page_size == 0);
|
||||
const uint8_t test_value = 0xCE;
|
||||
uint8_t *data = new uint8_t[page_size];
|
||||
for (uint32_t i = 0; i < page_size; i++) {
|
||||
data[i] = test_value;
|
||||
uint32_t prog_size = std::max(page_size, (uint32_t)8);
|
||||
uint8_t *data = new uint8_t[prog_size + 2];
|
||||
for (uint32_t i = 0; i < prog_size + 2; i++) {
|
||||
data[i] = i;
|
||||
}
|
||||
|
||||
// the one before the last sector in the system
|
||||
|
@ -61,19 +62,29 @@ void flashiap_program_test()
|
|||
TEST_ASSERT_EQUAL_INT32(0, ret);
|
||||
|
||||
|
||||
for (uint32_t i = 0; i < sector_size / page_size; i++) {
|
||||
uint32_t page_addr = address + i * page_size;
|
||||
ret = flash_device.program(data, page_addr, page_size);
|
||||
for (uint32_t i = 0; i < sector_size / prog_size; i++) {
|
||||
uint32_t prog_addr = address + i * prog_size;
|
||||
ret = flash_device.program(data, prog_addr, prog_size);
|
||||
TEST_ASSERT_EQUAL_INT32(0, ret);
|
||||
}
|
||||
|
||||
uint8_t *data_flashed = new uint8_t[page_size];
|
||||
for (uint32_t i = 0; i < sector_size / page_size; i++) {
|
||||
uint32_t page_addr = address + i * page_size;
|
||||
ret = flash_device.read(data_flashed, page_addr, page_size);
|
||||
uint8_t *data_flashed = new uint8_t[prog_size];
|
||||
for (uint32_t i = 0; i < sector_size / prog_size; i++) {
|
||||
uint32_t page_addr = address + i * prog_size;
|
||||
ret = flash_device.read(data_flashed, page_addr, prog_size);
|
||||
TEST_ASSERT_EQUAL_INT32(0, ret);
|
||||
TEST_ASSERT_EQUAL_UINT8_ARRAY(data, data_flashed, page_size);
|
||||
TEST_ASSERT_EQUAL_UINT8_ARRAY(data, data_flashed, prog_size);
|
||||
}
|
||||
|
||||
// check programming of unaligned buffer and size
|
||||
ret = flash_device.erase(address, sector_size);
|
||||
TEST_ASSERT_EQUAL_INT32(0, ret);
|
||||
ret = flash_device.program(data + 2, address, prog_size);
|
||||
TEST_ASSERT_EQUAL_INT32(0, ret);
|
||||
ret = flash_device.read(data_flashed, address, prog_size - 1);
|
||||
TEST_ASSERT_EQUAL_INT32(0, ret);
|
||||
TEST_ASSERT_EQUAL_UINT8_ARRAY(data + 2, data_flashed, prog_size - 1);
|
||||
|
||||
delete[] data;
|
||||
delete[] data_flashed;
|
||||
|
||||
|
|
|
@ -107,10 +107,18 @@ int FlashIAP::program(const void *buffer, uint32_t addr, uint32_t size)
|
|||
_mutex->lock();
|
||||
while (size) {
|
||||
uint32_t current_sector_size = flash_get_sector_size(&_flash, addr);
|
||||
bool unaligned_src = (((size_t) buf / sizeof(uint32_t) * sizeof(uint32_t)) != (size_t) buf);
|
||||
chunk = std::min(current_sector_size - (addr % current_sector_size), size);
|
||||
if (chunk < page_size) {
|
||||
// Need to use the internal page buffer in any of these two cases:
|
||||
// 1. Size is not page aligned
|
||||
// 2. Source buffer is not aligned to uint32_t. This is not supported by many targets (although
|
||||
// the pointer they accept is of uint8_t).
|
||||
if (unaligned_src || (chunk < page_size)) {
|
||||
chunk = std::min(chunk, page_size);
|
||||
memcpy(_page_buf, buf, chunk);
|
||||
memset(_page_buf + chunk, 0xFF, page_size - chunk);
|
||||
if (chunk < page_size) {
|
||||
memset(_page_buf + chunk, 0xFF, page_size - chunk);
|
||||
}
|
||||
prog_buf = _page_buf;
|
||||
prog_size = page_size;
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue