Skip to content

Commit 63ed12c

Browse files
authored
Merge pull request #60 from rahmanih/add_new_level_apis_pr
New APIs: - lx_nor_flash_format(): setup the NOR Flash for a new and fresh filesystem. - lx_nor_flash_open_extended(): adds a user data pointer that could be passed to the underlying low-level NOR driver. - lx_nand_flash_open_extended(): adds a user data pointer that could be passed to the underlying low-level NAND driver. Updated APIs: - lx_nor_flash_open(): call the lx_nor_flash_open_extended() with a NULL as user data pointer. - lx_nand_flash_open(): call the lx_nand_flash_open_extended() with a NULL as user data pointer.
2 parents a176186 + 47b2a17 commit 63ed12c

11 files changed

+2059
-1542
lines changed

common/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ target_sources(${PROJECT_NAME} PRIVATE
2020
${CMAKE_CURRENT_LIST_DIR}/src/lx_nand_flash_erase_count_set.c
2121
${CMAKE_CURRENT_LIST_DIR}/src/lx_nand_flash_extended_cache_enable.c
2222
${CMAKE_CURRENT_LIST_DIR}/src/lx_nand_flash_format.c
23+
${CMAKE_CURRENT_LIST_DIR}/src/lx_nand_flash_format_extended.c
2324
${CMAKE_CURRENT_LIST_DIR}/src/lx_nand_flash_free_block_list_add.c
2425
${CMAKE_CURRENT_LIST_DIR}/src/lx_nand_flash_initialize.c
2526
${CMAKE_CURRENT_LIST_DIR}/src/lx_nand_flash_mapped_block_list_add.c
@@ -30,6 +31,7 @@ target_sources(${PROJECT_NAME} PRIVATE
3031
${CMAKE_CURRENT_LIST_DIR}/src/lx_nand_flash_metadata_build.c
3132
${CMAKE_CURRENT_LIST_DIR}/src/lx_nand_flash_metadata_write.c
3233
${CMAKE_CURRENT_LIST_DIR}/src/lx_nand_flash_open.c
34+
${CMAKE_CURRENT_LIST_DIR}/src/lx_nand_flash_open_extended.c
3335
${CMAKE_CURRENT_LIST_DIR}/src/lx_nand_flash_page_ecc_check.c
3436
${CMAKE_CURRENT_LIST_DIR}/src/lx_nand_flash_page_ecc_compute.c
3537
${CMAKE_CURRENT_LIST_DIR}/src/lx_nand_flash_partial_defragment.c
@@ -52,6 +54,8 @@ target_sources(${PROJECT_NAME} PRIVATE
5254
${CMAKE_CURRENT_LIST_DIR}/src/lx_nor_flash_logical_sector_find.c
5355
${CMAKE_CURRENT_LIST_DIR}/src/lx_nor_flash_next_block_to_erase_find.c
5456
${CMAKE_CURRENT_LIST_DIR}/src/lx_nor_flash_open.c
57+
${CMAKE_CURRENT_LIST_DIR}/src/lx_nor_flash_open_extended.c
58+
${CMAKE_CURRENT_LIST_DIR}/src/lx_nor_flash_format.c
5559
${CMAKE_CURRENT_LIST_DIR}/src/lx_nor_flash_partial_defragment.c
5660
${CMAKE_CURRENT_LIST_DIR}/src/lx_nor_flash_physical_sector_allocate.c
5761
${CMAKE_CURRENT_LIST_DIR}/src/lx_nor_flash_sector_mapping_cache_invalidate.c

common/inc/lx_api.h

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/***************************************************************************
2-
* Copyright (c) 2024 Microsoft Corporation
3-
*
2+
* Copyright (c) 2024 Microsoft Corporation
3+
* Portion Copyright (c) 2025 STMicroelectronics
4+
*
45
* This program and the accompanying materials are made available under the
56
* terms of the MIT License which is available at
67
* https://opensource.org/licenses/MIT.
@@ -528,7 +529,6 @@ typedef struct LX_NAND_FLASH_STRUCT
528529
#endif
529530
UCHAR *lx_nand_flash_page_buffer;
530531
UINT lx_nand_flash_page_buffer_size;
531-
532532
#ifdef LX_THREAD_SAFE_ENABLE
533533

534534
/* When this conditional is used, the LevelX code utilizes a ThreadX mutex for thread
@@ -537,6 +537,8 @@ typedef struct LX_NAND_FLASH_STRUCT
537537
TX_MUTEX lx_nand_flash_mutex;
538538
#endif
539539

540+
/* user data pointer optionally passed by the application to the driver via the lx_nand_flash_open_extended */
541+
VOID *lx_nand_flash_driver_info_ptr;
540542
/* Define the NAND flash control block open next/previous pointers. */
541543
struct LX_NAND_FLASH_STRUCT *lx_nand_flash_open_next,
542544
*lx_nand_flash_open_previous;
@@ -666,7 +668,8 @@ typedef struct LX_NOR_FLASH_STRUCT
666668
a higher layer. */
667669
TX_MUTEX lx_nor_flash_mutex;
668670
#endif
669-
671+
/* user data pointer optionally passed by the application to the driver via the lx_nor_flash_open_extended */
672+
VOID *lx_nor_flash_driver_info_ptr;
670673
/* Define the NOR flash control block open next/previous pointers. */
671674
struct LX_NOR_FLASH_STRUCT *lx_nor_flash_open_next,
672675
*lx_nor_flash_open_previous;
@@ -725,8 +728,10 @@ extern ULONG _lx_nor_flash_opened_cou
725728
#define lx_nand_flash_partial_defragment _lx_nand_flash_partial_defragment
726729
#define lx_nand_flash_extended_cache_enable _lx_nand_flash_extended_cache_enable
727730
#define lx_nand_flash_format _lx_nand_flash_format
731+
#define lx_nand_flash_format_extended _lx_nand_flash_format_extended
728732
#define lx_nand_flash_initialize _lx_nand_flash_initialize
729733
#define lx_nand_flash_open _lx_nand_flash_open
734+
#define lx_nand_flash_open_extended _lx_nand_flash_open_extended
730735
#define lx_nand_flash_page_ecc_check _lx_nand_flash_page_ecc_check
731736
#define lx_nand_flash_page_ecc_compute _lx_nand_flash_page_ecc_compute
732737
#define lx_nand_flash_sector_read _lx_nand_flash_sector_read
@@ -743,7 +748,9 @@ extern ULONG _lx_nor_flash_opened_cou
743748
#define lx_nor_flash_partial_defragment _lx_nor_flash_partial_defragment
744749
#define lx_nor_flash_extended_cache_enable _lx_nor_flash_extended_cache_enable
745750
#define lx_nor_flash_initialize _lx_nor_flash_initialize
751+
#define lx_nor_flash_format _lx_nor_flash_format
746752
#define lx_nor_flash_open _lx_nor_flash_open
753+
#define lx_nor_flash_open_extended _lx_nor_flash_open_extended
747754
#define lx_nor_flash_sector_read _lx_nor_flash_sector_read
748755
#define lx_nor_flash_sector_release _lx_nor_flash_sector_release
749756
#define lx_nor_flash_sector_write _lx_nor_flash_sector_write
@@ -759,7 +766,13 @@ UINT _lx_nand_flash_extended_cache_enable(LX_NAND_FLASH *nand_flash, VOID *m
759766
UINT _lx_nand_flash_format(LX_NAND_FLASH* nand_flash, CHAR* name,
760767
UINT(*nand_driver_initialize)(LX_NAND_FLASH*),
761768
ULONG* memory_ptr, UINT memory_size);
769+
UINT _lx_nand_flash_format_extended(LX_NAND_FLASH* nand_flash, CHAR* name,
770+
UINT(*nand_driver_initialize)(LX_NAND_FLASH*), VOID *nand_driver_info_ptr,
771+
ULONG* memory_ptr, UINT memory_size);
762772
UINT _lx_nand_flash_open(LX_NAND_FLASH *nand_flash, CHAR *name, UINT (*nand_driver_initialize)(LX_NAND_FLASH *), ULONG* memory_ptr, UINT memory_size);
773+
UINT _lx_nand_flash_open_extended(LX_NAND_FLASH *nand_flash, CHAR *name,
774+
UINT (*nand_driver_initialize)(LX_NAND_FLASH *), VOID *nand_driver_info_ptr,
775+
ULONG* memory_ptr, UINT memory_size);
763776
UINT _lx_nand_flash_page_ecc_check(LX_NAND_FLASH *nand_flash, UCHAR *page_buffer, UCHAR *ecc_buffer);
764777
UINT _lx_nand_flash_page_ecc_compute(LX_NAND_FLASH *nand_flash, UCHAR *page_buffer, UCHAR *ecc_buffer);
765778
UINT _lx_nand_flash_partial_defragment(LX_NAND_FLASH *nand_flash, UINT max_blocks);
@@ -774,7 +787,9 @@ UINT _lx_nor_flash_close(LX_NOR_FLASH *nor_flash);
774787
UINT _lx_nor_flash_defragment(LX_NOR_FLASH *nor_flash);
775788
UINT _lx_nor_flash_extended_cache_enable(LX_NOR_FLASH *nor_flash, VOID *memory, ULONG size);
776789
UINT _lx_nor_flash_initialize(void);
790+
UINT _lx_nor_flash_format(LX_NOR_FLASH *nor_flash, CHAR *name, UINT (*nor_driver_initialize)(LX_NOR_FLASH *), VOID *nor_driver_info_ptr);
777791
UINT _lx_nor_flash_open(LX_NOR_FLASH *nor_flash, CHAR *name, UINT (*nor_driver_initialize)(LX_NOR_FLASH *));
792+
UINT _lx_nor_flash_open_extended(LX_NOR_FLASH *nor_flash, CHAR *name, UINT (*nor_driver_initialize)(LX_NOR_FLASH *), VOID *nor_driver_info_ptr);
778793
UINT _lx_nor_flash_partial_defragment(LX_NOR_FLASH *nor_flash, UINT max_blocks);
779794
UINT _lx_nor_flash_sector_read(LX_NOR_FLASH *nor_flash, ULONG logical_sector, VOID *buffer);
780795
UINT _lx_nor_flash_sector_release(LX_NOR_FLASH *nor_flash, ULONG logical_sector);

common/src/lx_nand_flash_format.c

Lines changed: 7 additions & 209 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/***************************************************************************
22
* Copyright (c) 2024 Microsoft Corporation
3+
* Copyright (c) 2025 STMicroelectronics
34
*
45
* This program and the accompanying materials are made available under the
56
* terms of the MIT License which is available at
@@ -39,7 +40,7 @@
3940
/* FUNCTION RELEASE */
4041
/* */
4142
/* _lx_nand_flash_format PORTABLE C */
42-
/* 6.3.0 */
43+
/* */
4344
/* AUTHOR */
4445
/* */
4546
/* Xiuwen Cai, Microsoft Corporation */
@@ -64,224 +65,21 @@
6465
/* return status */
6566
/* */
6667
/* CALLS */
67-
/* */
68-
/* (nand_driver_initialize) Driver initialize */
69-
/* LX_MEMSET Initialize memory */
70-
/* _lx_nand_flash_memory_initialize Initialize buffer */
71-
/* _lx_nand_flash_driver_block_status_get */
72-
/* Driver block status get */
73-
/* _lx_nand_flash_driver_block_status_set */
74-
/* Driver block status set */
75-
/* _lx_nand_flash_metadata_build Build metadata */
76-
/* _lx_nand_flash_metadata_write Write metadata */
77-
/* _lx_nand_flash_driver_block_erase Driver block erase */
78-
/* _lx_nand_flash_system_error System error handler */
79-
/* tx_mutex_create Create thread-safe mutex */
80-
/* */
68+
/* _lx_nand_flash_format_extended */
69+
/* */
8170
/* CALLED BY */
8271
/* */
8372
/* Application Code */
8473
/* */
85-
/* RELEASE HISTORY */
86-
/* */
87-
/* DATE NAME DESCRIPTION */
88-
/* */
89-
/* 03-08-2023 Xiuwen Cai Initial Version 6.2.1 */
90-
/* 10-31-2023 Xiuwen Cai Modified comment(s), */
91-
/* avoided clearing user */
92-
/* extension in flash control */
93-
/* block, */
94-
/* resulting in version 6.3.0 */
95-
/* */
9674
/**************************************************************************/
9775
UINT _lx_nand_flash_format(LX_NAND_FLASH* nand_flash, CHAR* name,
9876
UINT(*nand_driver_initialize)(LX_NAND_FLASH*),
9977
ULONG* memory_ptr, UINT memory_size)
10078
{
10179

102-
ULONG block;
103-
UCHAR block_status;
104-
UINT status;
105-
UCHAR *page_buffer_ptr;
106-
107-
LX_PARAMETER_NOT_USED(name);
108-
109-
/* Clear the NAND flash control block. User extension is not cleared. */
110-
LX_MEMSET(nand_flash, 0, (ULONG)((UCHAR*)&(nand_flash -> lx_nand_flash_open_previous) - (UCHAR*)nand_flash) + sizeof(nand_flash -> lx_nand_flash_open_previous));
111-
112-
/* Call the flash driver's initialization function. */
113-
(nand_driver_initialize)(nand_flash);
114-
115-
/* Determine if we can support this NAND flash size. */
116-
if (nand_flash -> lx_nand_flash_pages_per_block > LX_NAND_MAX_PAGE_PER_BLOCK || nand_flash -> lx_nand_flash_total_blocks > LX_NAND_MAX_BLOCK_COUNT)
117-
{
118-
return(LX_ERROR);
119-
}
120-
121-
/* Check if it is new LevelX NAND driver. */
122-
if (nand_flash -> lx_nand_flash_driver_pages_read == LX_NULL || nand_flash -> lx_nand_flash_driver_pages_write == LX_NULL || nand_flash -> lx_nand_flash_driver_pages_copy == LX_NULL)
123-
{
124-
return(LX_ERROR);
125-
}
126-
127-
/* Check the spare data length. */
128-
if (nand_flash -> lx_nand_flash_spare_data1_length < sizeof(ULONG))
129-
{
130-
return(LX_ERROR);
131-
}
132-
133-
/* Calculate the number of words per block and per page. */
134-
nand_flash -> lx_nand_flash_words_per_page = (nand_flash -> lx_nand_flash_bytes_per_page / sizeof(ULONG));
135-
nand_flash -> lx_nand_flash_words_per_block = (nand_flash -> lx_nand_flash_words_per_page * nand_flash -> lx_nand_flash_pages_per_block);
136-
137-
/* Calculate the total pages. */
138-
nand_flash -> lx_nand_flash_total_pages = nand_flash -> lx_nand_flash_total_blocks * nand_flash -> lx_nand_flash_pages_per_block;
139-
140-
/* Initialize memory buffer. */
141-
status = _lx_nand_flash_memory_initialize(nand_flash, memory_ptr, memory_size);
142-
if (status != LX_SUCCESS)
143-
{
144-
return(status);
145-
}
146-
147-
/* Initialize block numbers. */
148-
nand_flash -> lx_nand_flash_metadata_block_number = LX_NAND_BLOCK_UNMAPPED;
149-
nand_flash -> lx_nand_flash_metadata_block_number_next = LX_NAND_BLOCK_UNMAPPED;
150-
nand_flash -> lx_nand_flash_backup_metadata_block_number = LX_NAND_BLOCK_UNMAPPED;
151-
nand_flash -> lx_nand_flash_backup_metadata_block_number_next = LX_NAND_BLOCK_UNMAPPED;
152-
153-
/* Initialize the block status buffer. */
154-
LX_MEMSET(nand_flash -> lx_nand_flash_block_status_table, 0xFF, nand_flash -> lx_nand_flash_block_status_table_size);
155-
156-
/* Loop through the blocks to check for bad blocks and determine the minimum and maximum erase count for each good block. */
157-
for (block = 0; block < nand_flash -> lx_nand_flash_total_blocks; block++)
158-
{
159-
160-
/* First, check to make sure this block is good. */
161-
status = _lx_nand_flash_driver_block_status_get(nand_flash, block, &block_status);
162-
163-
/* Check for an error from flash driver. */
164-
if (status)
165-
{
166-
167-
/* Call system error handler. */
168-
_lx_nand_flash_system_error(nand_flash, status, block, 0);
169-
170-
/* Return an error. */
171-
return(LX_ERROR);
172-
}
80+
UINT status;
17381

174-
/* Is this block bad? */
175-
if (block_status != LX_NAND_GOOD_BLOCK)
176-
{
82+
status = _lx_nand_flash_format_extended(nand_flash, name, nand_driver_initialize, NULL, memory_ptr, memory_size);
17783

178-
/* Yes, this block is bad. */
179-
180-
/* Increment the number of bad blocks. */
181-
nand_flash -> lx_nand_flash_bad_blocks++;
182-
183-
/* Save the block status. */
184-
nand_flash -> lx_nand_flash_block_status_table[block] = LX_NAND_BLOCK_STATUS_BAD;
185-
186-
/* Continue to the next block. */
187-
continue;
188-
}
189-
190-
/* Erase the block. */
191-
status = _lx_nand_flash_driver_block_erase(nand_flash, block, 0);
192-
193-
/* Check for an error from flash driver. */
194-
if (status)
195-
{
196-
197-
/* Call system error handler. */
198-
_lx_nand_flash_system_error(nand_flash, status, block, 0);
199-
200-
/* Attempt to mark this block as bad. */
201-
status = _lx_nand_flash_driver_block_status_set(nand_flash, block, LX_NAND_BAD_BLOCK);
202-
203-
/* Check for error in setting the block status. */
204-
if (status)
205-
{
206-
207-
/* Call system error handler. */
208-
_lx_nand_flash_system_error(nand_flash, status, block, 0);
209-
}
210-
211-
/* Increment the bad block count. */
212-
nand_flash -> lx_nand_flash_bad_blocks++;
213-
214-
/* Save the block status. */
215-
nand_flash -> lx_nand_flash_block_status_table[block] = LX_NAND_BLOCK_STATUS_BAD;
216-
}
217-
else
218-
{
219-
220-
/* Allocate blocks for metadata. */
221-
if (nand_flash -> lx_nand_flash_metadata_block_number == LX_NAND_BLOCK_UNMAPPED)
222-
{
223-
nand_flash -> lx_nand_flash_metadata_block_number = block;
224-
nand_flash -> lx_nand_flash_metadata_block_number_current = block;
225-
}
226-
else if (nand_flash -> lx_nand_flash_backup_metadata_block_number == LX_NAND_BLOCK_UNMAPPED)
227-
{
228-
nand_flash -> lx_nand_flash_backup_metadata_block_number = block;
229-
nand_flash -> lx_nand_flash_backup_metadata_block_number_current = block;
230-
}
231-
else if (nand_flash -> lx_nand_flash_metadata_block_number_next == LX_NAND_BLOCK_UNMAPPED)
232-
{
233-
nand_flash -> lx_nand_flash_metadata_block_number_next = block;
234-
}
235-
else if (nand_flash -> lx_nand_flash_backup_metadata_block_number_next == LX_NAND_BLOCK_UNMAPPED)
236-
{
237-
nand_flash -> lx_nand_flash_backup_metadata_block_number_next = block;
238-
}
239-
}
240-
}
241-
242-
/* There should be enough blocks for metadata. */
243-
if (nand_flash -> lx_nand_flash_backup_metadata_block_number_next == LX_NAND_BLOCK_UNMAPPED)
244-
{
245-
return (LX_NO_BLOCKS);
246-
}
247-
248-
/* Save the block status for metadata. */
249-
nand_flash -> lx_nand_flash_block_status_table[nand_flash -> lx_nand_flash_backup_metadata_block_number_next] = LX_NAND_BLOCK_STATUS_ALLOCATED;
250-
nand_flash -> lx_nand_flash_block_status_table[nand_flash -> lx_nand_flash_metadata_block_number_next] = LX_NAND_BLOCK_STATUS_ALLOCATED;
251-
nand_flash -> lx_nand_flash_block_status_table[nand_flash -> lx_nand_flash_backup_metadata_block_number] = (USHORT)nand_flash -> lx_nand_flash_backup_metadata_block_number_next;
252-
nand_flash -> lx_nand_flash_block_status_table[nand_flash -> lx_nand_flash_metadata_block_number] = (USHORT)nand_flash -> lx_nand_flash_metadata_block_number_next;
253-
254-
/* Initialize the mapping table. */
255-
LX_MEMSET(nand_flash -> lx_nand_flash_block_mapping_table, 0xFF, nand_flash -> lx_nand_flash_block_mapping_table_size);
256-
257-
/* Build initial metadata. */
258-
status = _lx_nand_flash_metadata_build(nand_flash);
259-
if (status != LX_SUCCESS)
260-
{
261-
/* Return error status. */
262-
return(status);
263-
}
264-
265-
/* Get buffer for page data. */
266-
page_buffer_ptr = nand_flash -> lx_nand_flash_page_buffer;
267-
268-
/* Initialize the page buffer. */
269-
LX_MEMSET(page_buffer_ptr, 0xFF, nand_flash -> lx_nand_flash_bytes_per_page);
270-
271-
/* Set the next block numbers. */
272-
LX_UTILITY_LONG_SET(&page_buffer_ptr[LX_NAND_BLOCK_LINK_MAIN_METADATA_OFFSET], nand_flash -> lx_nand_flash_metadata_block_number_next);
273-
LX_UTILITY_LONG_SET(&page_buffer_ptr[LX_NAND_BLOCK_LINK_BACKUP_METADATA_OFFSET], nand_flash -> lx_nand_flash_backup_metadata_block_number_next);
274-
275-
/* Save the next block numbers to metadata block. */
276-
status = _lx_nand_flash_metadata_write(nand_flash, page_buffer_ptr, LX_NAND_PAGE_TYPE_BLOCK_LINK);
277-
278-
if (status != LX_SUCCESS)
279-
{
280-
/* Return error status. */
281-
return(status);
282-
}
283-
284-
/* Return a successful completion. */
285-
return(LX_SUCCESS);
84+
return status;
28685
}
287-

0 commit comments

Comments
 (0)