Skip to content

Commit 6cd97df

Browse files
committed
fix(spi_nand_flash): Fix review comments
1 parent 1d88d9d commit 6cd97df

21 files changed

Lines changed: 587 additions & 531 deletions

spi_nand_flash/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ endif()
1515

1616
if(${target} STREQUAL "linux")
1717
list(APPEND srcs "src/nand_impl_linux.c"
18-
"src/nand_linux_mmap_emul.c")
18+
"src/nand_linux_mmap_emul.c"
19+
"src/spi_nand_flash_test_helpers.c")
1920
else()
2021
list(APPEND srcs "src/devices/nand_winbond.c"
2122
"src/devices/nand_gigadevice.c"
@@ -25,6 +26,7 @@ else()
2526
"src/devices/nand_xtx.c"
2627
"src/nand_impl.c"
2728
"src/nand_diag_api.c"
29+
"src/spi_nand_flash_test_helpers.c"
2830
"src/spi_nand_oper.c")
2931

3032
set(priv_reqs esp_mm)

spi_nand_flash/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ graph TD
4646
```
4747

4848
**Key Benefits:**
49-
- **Backward Compatible**: Existing code works unchanged
49+
- **Backward Compatible**: Existing code works unchanged; sector-named APIs are retained as aliases of the page API
50+
- **Page terminology**: Public API uses *page* (read_page, write_page, get_page_count, get_page_size) to align with NAND flash; sector names remain for compatibility
5051
- **Modular Design**: Clear separation between wear-leveling and flash management
5152
- **Enhanced Features**: Direct access to flash and wear-leveling layers
5253

spi_nand_flash/host_test/README.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,13 @@ spi_nand_flash_config_t nand_flash_config = {&cfg, 0, SPI_NAND_IO_MODE_SIO, 0};
4848
spi_nand_flash_device_t *handle;
4949
spi_nand_flash_init_device(&nand_flash_config, &handle);
5050

51-
// Use direct NAND operations
52-
spi_nand_flash_read_sector(handle, buffer, sector_id);
53-
spi_nand_flash_write_sector(handle, buffer, sector_id);
51+
// Use direct NAND operations (page API preferred; sector API is also supported)
52+
uint32_t page_size;
53+
spi_nand_flash_get_page_size(handle, &page_size);
54+
uint8_t *buffer = malloc(page_size);
55+
uint32_t page_id = 0;
56+
spi_nand_flash_read_page(handle, buffer, page_id);
57+
spi_nand_flash_write_page(handle, buffer, page_id);
5458

5559
// Cleanup
5660
spi_nand_flash_deinit_device(handle);
@@ -69,7 +73,8 @@ esp_blockdev_handle_t nand_bdl;
6973
nand_flash_get_blockdev(&nand_flash_config, &device_handle, &nand_bdl);
7074
7175
// Use block device operations
72-
nand_bdl->ops->read(nand_bdl, buffer, sector_size, offset, size);
76+
uint32_t page_size = nand_bdl->geometry.read_size; // BDL geometry uses page size
77+
nand_bdl->ops->read(nand_bdl, buffer, page_size, offset, size);
7378
nand_bdl->ops->write(nand_bdl, buffer, offset, size);
7479
7580
// Cleanup

spi_nand_flash/host_test/main/test_nand_flash.cpp

Lines changed: 35 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -8,57 +8,34 @@
88
#include <string.h>
99

1010
#include "spi_nand_flash.h"
11+
#include "spi_nand_flash_test_helpers.h"
1112
#include "nand_linux_mmap_emul.h"
1213
#include "nand_private/nand_impl_wrap.h"
1314

1415
#include <catch2/catch_test_macros.hpp>
1516

16-
#define PATTERN_SEED 0x12345678
17-
18-
static void fill_buffer(uint32_t seed, uint8_t *dst, size_t count)
19-
{
20-
srand(seed);
21-
for (size_t i = 0; i < count; ++i) {
22-
uint32_t val = rand();
23-
memcpy(dst + i * sizeof(uint32_t), &val, sizeof(val));
24-
}
25-
}
26-
27-
static void check_buffer(uint32_t seed, const uint8_t *src, size_t count)
28-
{
29-
srand(seed);
30-
for (size_t i = 0; i < count; ++i) {
31-
uint32_t val;
32-
memcpy(&val, src + i * sizeof(uint32_t), sizeof(val));
33-
if (!(rand() == val)) {
34-
printf("Val not equal\n");
35-
}
36-
}
37-
}
38-
3917
TEST_CASE("verify mark_bad_block works", "[spi_nand_flash]")
4018
{
4119
nand_file_mmap_emul_config_t conf = {"", 50 * 1024 * 1024, true};
4220
spi_nand_flash_config_t nand_flash_config = {&conf, 0, SPI_NAND_IO_MODE_SIO, 0};
4321
spi_nand_flash_device_t *device_handle;
4422
REQUIRE(spi_nand_flash_init_device(&nand_flash_config, &device_handle) == ESP_OK);
4523

46-
uint32_t sector_num, sector_size;
47-
REQUIRE(spi_nand_flash_get_capacity(device_handle, &sector_num) == 0);
48-
REQUIRE(spi_nand_flash_get_sector_size(device_handle, &sector_size) == 0);
24+
uint32_t block_num;
25+
REQUIRE(spi_nand_flash_get_block_num(device_handle, &block_num) == 0);
4926

5027
uint32_t test_block = 15;
51-
if (test_block < sector_num) {
52-
bool is_bad_status = false;
53-
// Verify if test_block is not bad block
54-
REQUIRE(nand_wrap_is_bad(device_handle, test_block, &is_bad_status) == 0);
55-
REQUIRE(is_bad_status == false);
56-
// mark test_block as a bad block
57-
REQUIRE(nand_wrap_mark_bad(device_handle, test_block) == 0);
58-
// Verify if test_block is marked as bad block
59-
REQUIRE(nand_wrap_is_bad(device_handle, test_block, &is_bad_status) == 0);
60-
REQUIRE(is_bad_status == true);
61-
}
28+
REQUIRE((test_block < block_num) == true);
29+
30+
bool is_bad_status = false;
31+
// Verify if test_block is not bad block
32+
REQUIRE(nand_wrap_is_bad(device_handle, test_block, &is_bad_status) == 0);
33+
REQUIRE(is_bad_status == false);
34+
// mark test_block as a bad block
35+
REQUIRE(nand_wrap_mark_bad(device_handle, test_block) == 0);
36+
// Verify if test_block is marked as bad block
37+
REQUIRE(nand_wrap_is_bad(device_handle, test_block, &is_bad_status) == 0);
38+
REQUIRE(is_bad_status == true);
6239

6340
spi_nand_flash_deinit_device(device_handle);
6441
}
@@ -80,30 +57,32 @@ TEST_CASE("verify nand_prog, nand_read, nand_copy, nand_is_free works", "[spi_na
8057
uint8_t *temp_buf = (uint8_t *)malloc(sector_size);
8158
REQUIRE(temp_buf != NULL);
8259

83-
fill_buffer(PATTERN_SEED, pattern_buf, sector_size / sizeof(uint32_t));
60+
spi_nand_flash_fill_buffer(pattern_buf, sector_size / sizeof(uint32_t));
8461

8562
bool is_page_free = true;
8663
uint32_t test_block = 20;
8764
uint32_t test_page = test_block * (block_size / sector_size); //(block_num * pages_per_block)
8865
uint32_t dst_page = test_page + 1;
89-
if (test_page < sector_num) {
90-
// Verify if test_page is free
91-
REQUIRE(nand_wrap_is_free(device_handle, test_page, &is_page_free) == 0);
92-
REQUIRE(is_page_free == true);
93-
// Write/program test_page
94-
REQUIRE(nand_wrap_prog(device_handle, test_page, pattern_buf) == 0);
95-
// Verify if test_page is used/programmed
96-
REQUIRE(nand_wrap_is_free(device_handle, test_page, &is_page_free) == 0);
97-
REQUIRE(is_page_free == false);
98-
99-
REQUIRE(nand_wrap_read(device_handle, test_page, 0, sector_size, temp_buf) == 0);
100-
check_buffer(PATTERN_SEED, temp_buf, sector_size / sizeof(uint32_t));
101-
102-
REQUIRE(nand_wrap_copy(device_handle, test_page, dst_page) == 0);
103-
104-
REQUIRE(nand_wrap_read(device_handle, dst_page, 0, sector_size, temp_buf) == 0);
105-
check_buffer(PATTERN_SEED, temp_buf, sector_size / sizeof(uint32_t));
106-
}
66+
67+
REQUIRE((test_page < sector_num) == true);
68+
69+
// Verify if test_page is free
70+
REQUIRE(nand_wrap_is_free(device_handle, test_page, &is_page_free) == 0);
71+
REQUIRE(is_page_free == true);
72+
// Write/program test_page
73+
REQUIRE(nand_wrap_prog(device_handle, test_page, pattern_buf) == 0);
74+
// Verify if test_page is used/programmed
75+
REQUIRE(nand_wrap_is_free(device_handle, test_page, &is_page_free) == 0);
76+
REQUIRE(is_page_free == false);
77+
78+
REQUIRE(nand_wrap_read(device_handle, test_page, 0, sector_size, temp_buf) == 0);
79+
REQUIRE(spi_nand_flash_check_buffer(temp_buf, sector_size / sizeof(uint32_t)) == 0);
80+
81+
REQUIRE(nand_wrap_copy(device_handle, test_page, dst_page) == 0);
82+
83+
REQUIRE(nand_wrap_read(device_handle, dst_page, 0, sector_size, temp_buf) == 0);
84+
REQUIRE(spi_nand_flash_check_buffer(temp_buf, sector_size / sizeof(uint32_t)) == 0);
85+
10786
free(pattern_buf);
10887
free(temp_buf);
10988
spi_nand_flash_deinit_device(device_handle);

spi_nand_flash/host_test/main/test_nand_flash_bdl.cpp

Lines changed: 29 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -8,35 +8,13 @@
88
#include <string.h>
99

1010
#include "spi_nand_flash.h"
11+
#include "spi_nand_flash_test_helpers.h"
1112
#include "nand_linux_mmap_emul.h"
1213
#include "esp_blockdev.h"
1314
#include "esp_nand_blockdev.h"
1415

1516
#include <catch2/catch_test_macros.hpp>
1617

17-
#define PATTERN_SEED 0x12345678
18-
19-
static void fill_buffer(uint32_t seed, uint8_t *dst, size_t count)
20-
{
21-
srand(seed);
22-
for (size_t i = 0; i < count; ++i) {
23-
uint32_t val = rand();
24-
memcpy(dst + i * sizeof(uint32_t), &val, sizeof(val));
25-
}
26-
}
27-
28-
static void check_buffer(uint32_t seed, const uint8_t *src, size_t count)
29-
{
30-
srand(seed);
31-
for (size_t i = 0; i < count; ++i) {
32-
uint32_t val;
33-
memcpy(&val, src + i * sizeof(uint32_t), sizeof(val));
34-
if (!(rand() == val)) {
35-
printf("Val not equal\n");
36-
}
37-
}
38-
}
39-
4018
TEST_CASE("verify mark_bad_block works with bdl interface", "[spi_nand_flash][bdl]")
4119
{
4220
nand_file_mmap_emul_config_t conf = {"", 50 * 1024 * 1024, true};
@@ -48,19 +26,18 @@ TEST_CASE("verify mark_bad_block works with bdl interface", "[spi_nand_flash][bd
4826
uint32_t block_num = nand_bdl->geometry.disk_size / block_size;
4927

5028
uint32_t test_block = 15;
51-
if (test_block < block_num) {
52-
REQUIRE(nand_bdl->ops->erase(nand_bdl, test_block * block_size, block_size) == 0);
53-
// Verify if test_block is not bad block
54-
esp_blockdev_cmd_arg_is_bad_block_t bad_block_status = {test_block, false};
55-
REQUIRE(nand_bdl->ops->ioctl(nand_bdl, ESP_BLOCKDEV_CMD_IS_BAD_BLOCK, &bad_block_status) == 0);
56-
REQUIRE(bad_block_status.status == false);
57-
// mark test_block as a bad block
58-
uint32_t block = test_block;
59-
REQUIRE(nand_bdl->ops->ioctl(nand_bdl, ESP_BLOCKDEV_CMD_MARK_BAD_BLOCK, &block) == 0);
60-
// Verify if test_block is marked as bad block
61-
REQUIRE(nand_bdl->ops->ioctl(nand_bdl, ESP_BLOCKDEV_CMD_IS_BAD_BLOCK, &bad_block_status) == 0);
62-
REQUIRE(bad_block_status.status == true);
63-
}
29+
REQUIRE((test_block < block_num) == true);
30+
REQUIRE(nand_bdl->ops->erase(nand_bdl, test_block * block_size, block_size) == 0);
31+
// Verify if test_block is not bad block
32+
esp_blockdev_cmd_arg_is_bad_block_t bad_block_status = {test_block, false};
33+
REQUIRE(nand_bdl->ops->ioctl(nand_bdl, ESP_BLOCKDEV_CMD_IS_BAD_BLOCK, &bad_block_status) == 0);
34+
REQUIRE(bad_block_status.status == false);
35+
// mark test_block as a bad block
36+
uint32_t block = test_block;
37+
REQUIRE(nand_bdl->ops->ioctl(nand_bdl, ESP_BLOCKDEV_CMD_MARK_BAD_BLOCK, &block) == 0);
38+
// Verify if test_block is marked as bad block
39+
REQUIRE(nand_bdl->ops->ioctl(nand_bdl, ESP_BLOCKDEV_CMD_IS_BAD_BLOCK, &bad_block_status) == 0);
40+
REQUIRE(bad_block_status.status == true);
6441

6542
nand_bdl->ops->release(nand_bdl);
6643
}
@@ -81,24 +58,25 @@ TEST_CASE("verify nand_prog, nand_read, nand_copy, nand_is_free works with bdl i
8158
uint8_t *temp_buf = (uint8_t *)malloc(sector_size);
8259
REQUIRE(temp_buf != NULL);
8360

84-
fill_buffer(PATTERN_SEED, pattern_buf, sector_size / sizeof(uint32_t));
61+
spi_nand_flash_fill_buffer(pattern_buf, sector_size / sizeof(uint32_t));
8562

8663
uint32_t test_block = 20;
8764
uint32_t test_page = test_block * (block_size / sector_size); //(block_num * pages_per_block)
88-
if (test_page < sector_num) {
89-
// Verify if test_page is free
90-
esp_blockdev_cmd_arg_is_free_page_t page_free_status = {test_page, true};
91-
REQUIRE(nand_bdl->ops->ioctl(nand_bdl, ESP_BLOCKDEV_CMD_IS_FREE_PAGE, &page_free_status) == 0);
92-
REQUIRE(page_free_status.status == true);
93-
// Write/program test_page
94-
REQUIRE(nand_bdl->ops->write(nand_bdl, pattern_buf, test_page * sector_size, sector_size) == 0);
95-
// Verify if test_page is used/programmed
96-
REQUIRE(nand_bdl->ops->ioctl(nand_bdl, ESP_BLOCKDEV_CMD_IS_FREE_PAGE, &page_free_status) == 0);
97-
REQUIRE(page_free_status.status == false);
98-
99-
REQUIRE(nand_bdl->ops->read(nand_bdl, temp_buf, sector_size, test_page * sector_size, sector_size) == 0);
100-
check_buffer(PATTERN_SEED, temp_buf, sector_size / sizeof(uint32_t));
101-
}
65+
66+
REQUIRE((test_page < sector_num) == true);
67+
// Verify if test_page is free
68+
esp_blockdev_cmd_arg_is_free_page_t page_free_status = {test_page, true};
69+
REQUIRE(nand_bdl->ops->ioctl(nand_bdl, ESP_BLOCKDEV_CMD_IS_FREE_PAGE, &page_free_status) == 0);
70+
REQUIRE(page_free_status.status == true);
71+
// Write/program test_page
72+
REQUIRE(nand_bdl->ops->write(nand_bdl, pattern_buf, test_page * sector_size, sector_size) == 0);
73+
// Verify if test_page is used/programmed
74+
REQUIRE(nand_bdl->ops->ioctl(nand_bdl, ESP_BLOCKDEV_CMD_IS_FREE_PAGE, &page_free_status) == 0);
75+
REQUIRE(page_free_status.status == false);
76+
77+
REQUIRE(nand_bdl->ops->read(nand_bdl, temp_buf, sector_size, test_page * sector_size, sector_size) == 0);
78+
REQUIRE(spi_nand_flash_check_buffer(temp_buf, sector_size / sizeof(uint32_t)) == 0);
79+
10280
free(pattern_buf);
10381
free(temp_buf);
10482
nand_bdl->ops->release(nand_bdl);

spi_nand_flash/include/esp_nand_blockdev.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,8 @@ extern "C" {
173173
*/
174174
typedef struct {
175175
uint32_t num; /*!< IN: Block number or page number */
176-
bool status; /*!< OUT: Bad block status or page free status (true/false) */
176+
bool status; /*!< OUT: Bad block status (True: bad block or False: good block)
177+
or Page free status (True: free page or False: occupied page)*/
177178
} esp_blockdev_cmd_arg_status_t;
178179

179180
typedef esp_blockdev_cmd_arg_status_t esp_blockdev_cmd_arg_is_bad_block_t;

0 commit comments

Comments
 (0)