GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lx_nor_flash_simulator.c Lines: 31 39 79.5 %
Date: 2026-03-06 18:45:40 Branches: 10 12 83.3 %

Line Branch Exec Source
1
/***************************************************************************
2
 * Copyright (c) 2024 Microsoft Corporation
3
 * Copyright (c) 2026-present Eclipse ThreadX contributors
4
 *
5
 * This program and the accompanying materials are made available under the
6
 * terms of the MIT License which is available at
7
 * https://opensource.org/licenses/MIT.
8
 *
9
 * SPDX-License-Identifier: MIT
10
 **************************************************************************/
11
12
13
/**************************************************************************/
14
/**************************************************************************/
15
/**                                                                       */
16
/** LevelX Component                                                      */
17
/**                                                                       */
18
/**   NOR Flash Simulator                                                 */
19
/**                                                                       */
20
/**************************************************************************/
21
/**************************************************************************/
22
23
24
/* Include necessary files.  */
25
26
#include "lx_api.h"
27
28
/* Define constants for the NOR flash simulation. */
29
30
/* This configuration is for one physical sector of overhead.  */
31
32
33
#define TOTAL_BLOCKS                        8
34
#define PHYSICAL_SECTORS_PER_BLOCK          16          /* Min value of 2, max value of 120 for 1 sector of overhead.  */
35
#define WORDS_PER_PHYSICAL_SECTOR           128
36
#define FREE_BIT_MAP_WORDS                  ((PHYSICAL_SECTORS_PER_BLOCK-1)/32)+1
37
#define USABLE_SECTORS_PER_BLOCK            (PHYSICAL_SECTORS_PER_BLOCK-1)
38
#define UNUSED_METADATA_WORDS_PER_BLOCK     (WORDS_PER_PHYSICAL_SECTOR-(3+FREE_BIT_MAP_WORDS+USABLE_SECTORS_PER_BLOCK))
39
40
41
typedef struct PHYSICAL_SECTOR_STRUCT
42
{
43
    unsigned long memory[WORDS_PER_PHYSICAL_SECTOR];
44
} PHYSICAL_SECTOR;
45
46
47
typedef struct FLASH_BLOCK_STRUCT
48
{
49
    unsigned long       erase_count;
50
    unsigned long       min_log_sector;
51
    unsigned long       max_log_sector;
52
    unsigned long       free_bit_map[FREE_BIT_MAP_WORDS];
53
    unsigned long       sector_metadata[USABLE_SECTORS_PER_BLOCK];
54
    unsigned long       unused_words[UNUSED_METADATA_WORDS_PER_BLOCK];
55
    PHYSICAL_SECTOR     physical_sectors[USABLE_SECTORS_PER_BLOCK];
56
} FLASH_BLOCK;
57
58
FLASH_BLOCK   nor_memory_area[TOTAL_BLOCKS];
59
60
ULONG         nor_sector_memory[WORDS_PER_PHYSICAL_SECTOR];
61
62
UINT  _lx_nor_flash_simulator_initialize(LX_NOR_FLASH *nor_flash);
63
UINT  _lx_nor_flash_simulator_erase_all(VOID);
64
#ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
65
UINT  _lx_nor_flash_simulator_read(LX_NOR_FLASH *nor_flash, ULONG *flash_address, ULONG *destination, ULONG words);
66
UINT  _lx_nor_flash_simulator_write(LX_NOR_FLASH *nor_flash, ULONG *flash_address, ULONG *source, ULONG words);
67
UINT  _lx_nor_flash_simulator_block_erase(LX_NOR_FLASH *nor_flash, ULONG block, ULONG erase_count);
68
UINT  _lx_nor_flash_simulator_block_erased_verify(LX_NOR_FLASH *nor_flash, ULONG block);
69
UINT  _lx_nor_flash_simulator_system_error(LX_NOR_FLASH *nor_flash, UINT error_code, ULONG block, ULONG sector);
70
#else
71
UINT  _lx_nor_flash_simulator_read(ULONG *flash_address, ULONG *destination, ULONG words);
72
UINT  _lx_nor_flash_simulator_write(ULONG *flash_address, ULONG *source, ULONG words);
73
UINT  _lx_nor_flash_simulator_block_erase(ULONG block, ULONG erase_count);
74
UINT  _lx_nor_flash_simulator_block_erased_verify(ULONG block);
75
UINT  _lx_nor_flash_simulator_system_error(UINT error_code, ULONG block, ULONG sector);
76
#endif
77
78
79
26
UINT  _lx_nor_flash_simulator_initialize(LX_NOR_FLASH *nor_flash)
80
{
81
82
    /* Setup the base address of the flash memory.  */
83
26
    nor_flash -> lx_nor_flash_base_address =                (ULONG *) &nor_memory_area[0];
84
85
    /* Setup geometry of the flash.  */
86
26
    nor_flash -> lx_nor_flash_total_blocks =                TOTAL_BLOCKS;
87
26
    nor_flash -> lx_nor_flash_words_per_block =             sizeof(FLASH_BLOCK)/sizeof(ULONG);
88
89
    /* Setup function pointers for the NOR flash services.  */
90
26
    nor_flash -> lx_nor_flash_driver_read =                 _lx_nor_flash_simulator_read;
91
26
    nor_flash -> lx_nor_flash_driver_write =                _lx_nor_flash_simulator_write;
92
26
    nor_flash -> lx_nor_flash_driver_block_erase =          _lx_nor_flash_simulator_block_erase;
93
26
    nor_flash -> lx_nor_flash_driver_block_erased_verify =  _lx_nor_flash_simulator_block_erased_verify;
94
95
    /* Setup local buffer for NOR flash operation. This buffer must be the sector size of the NOR flash memory.  */
96
26
    nor_flash -> lx_nor_flash_sector_buffer =  &nor_sector_memory[0];
97
98
    /* Return success.  */
99
26
    return(LX_SUCCESS);
100
}
101
102
#ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
103
UINT  _lx_nor_flash_simulator_read(LX_NOR_FLASH *nor_flash, ULONG *flash_address, ULONG *destination, ULONG words)
104
#else
105
205061
UINT  _lx_nor_flash_simulator_read(ULONG *flash_address, ULONG *destination, ULONG words)
106
#endif
107
{
108
109
#ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
110
    LX_PARAMETER_NOT_USED(nor_flash);
111
#endif
112
113
    /* Loop to read flash.  */
114
4738028
    while (words--)
115
    {
116
        /* Copy word.  */
117
4532967
        *destination++ =  *flash_address++;
118
    }
119
120
205061
    return(LX_SUCCESS);
121
}
122
123
124
#ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
125
UINT  _lx_nor_flash_simulator_write(LX_NOR_FLASH *nor_flash, ULONG *flash_address, ULONG *source, ULONG words)
126
#else
127
113510
UINT  _lx_nor_flash_simulator_write(ULONG *flash_address, ULONG *source, ULONG words)
128
#endif
129
{
130
131
#ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
132
    LX_PARAMETER_NOT_USED(nor_flash);
133
#endif
134
135
    /* Loop to write flash.  */
136
2497018
    while (words--)
137
    {
138
139
        /* Copy word.  */
140
2383508
        *flash_address++ =  *source++;
141
    }
142
143
113510
    return(LX_SUCCESS);
144
}
145
146
#ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
147
UINT  _lx_nor_flash_simulator_block_erase(LX_NOR_FLASH *nor_flash, ULONG block, ULONG erase_count)
148
#else
149
1218
UINT  _lx_nor_flash_simulator_block_erase(ULONG block, ULONG erase_count)
150
#endif
151
{
152
153
ULONG   *pointer;
154
ULONG   words;
155
156
#ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
157
    LX_PARAMETER_NOT_USED(nor_flash);
158
#endif
159
    LX_PARAMETER_NOT_USED(erase_count);
160
161
    /* Setup pointer.  */
162
1218
    pointer =  (ULONG *) &nor_memory_area[block];
163
164
    /* Loop to erase block.  */
165
1218
    words =  sizeof(FLASH_BLOCK)/sizeof(ULONG);
166
2495682
    while (words--)
167
    {
168
169
        /* Erase word of block.  */
170
2494464
        *pointer++ =  (ULONG) 0xFFFFFFFF;
171
    }
172
173
1218
    return(LX_SUCCESS);
174
}
175
176
177
UINT  _lx_nor_flash_simulator_erase_all(VOID)
178
{
179
180
ULONG   *pointer;
181
ULONG   words;
182
183
184
    /* Setup pointer.  */
185
    pointer =  (ULONG *) &nor_memory_area[0];
186
187
    /* Loop to erase block.  */
188
    words =  sizeof(nor_memory_area)/(sizeof(ULONG));
189
    while (words--)
190
    {
191
192
        /* Erase word of block.  */
193
        *pointer++ =  (ULONG) 0xFFFFFFFF;
194
    }
195
196
    return(LX_SUCCESS);
197
}
198
199
200
#ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
201
UINT  _lx_nor_flash_simulator_block_erased_verify(LX_NOR_FLASH *nor_flash, ULONG block)
202
#else
203
116
UINT  _lx_nor_flash_simulator_block_erased_verify(ULONG block)
204
#endif
205
{
206
207
ULONG   *word_ptr;
208
ULONG   words;
209
210
#ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
211
    LX_PARAMETER_NOT_USED(nor_flash);
212
#endif
213
214
    /* Determine if the block is completely erased.  */
215
216
    /* Pickup the pointer to the first word of the block.  */
217
116
    word_ptr =  (ULONG *) &nor_memory_area[block].erase_count;
218
219
    /* Calculate the number of words in a block.  */
220
116
    words =  sizeof(FLASH_BLOCK)/sizeof(ULONG);
221
222
    /* Loop to check if the block is erased.  */
223
118906
    while (words--)
224
    {
225
226
        /* Is this word erased?  */
227
118848
        if (*word_ptr++ != 0xFFFFFFFF)
228
58
            return(LX_ERROR);
229
    }
230
231
    /* Return success.  */
232
58
    return(LX_SUCCESS);
233
}
234
235
#ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
236
UINT  _lx_nor_flash_simulator_system_error(LX_NOR_FLASH *nor_flash, UINT error_code, ULONG block, ULONG sector)
237
#else
238
UINT  _lx_nor_flash_simulator_system_error(UINT error_code, ULONG block, ULONG sector)
239
#endif
240
{
241
242
#ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
243
    LX_PARAMETER_NOT_USED(nor_flash);
244
#endif
245
    LX_PARAMETER_NOT_USED(error_code);
246
    LX_PARAMETER_NOT_USED(block);
247
    LX_PARAMETER_NOT_USED(sector);
248
249
    /* Custom processing goes here...  all errors are fatal.  */
250
    return(LX_ERROR);
251
}
252