GCC Code Coverage Report


Directory: common/src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 69.2% 146 / 0 / 211
Functions: 100.0% 1 / 0 / 1
Branches: 70.8% 293 / 0 / 414

lx_nor_flash_open_extended.c
Line Branch Exec Source
1 /***************************************************************************
2 * Copyright (c) 2025 Microsoft Corporation
3 * Portion Copyright (c) 2025 STMicroelectronics
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 */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23 #define LX_SOURCE_CODE
24
25
26 /* Disable ThreadX error checking. */
27
28 #ifndef LX_DISABLE_ERROR_CHECKING
29 #define LX_DISABLE_ERROR_CHECKING
30 #endif
31
32
33 /* Include necessary system files. */
34
35 #include "lx_api.h"
36
37 /**************************************************************************/
38 /* */
39 /* FUNCTION RELEASE */
40 /* */
41 /* _lx_nor_flash_open_extended PORTABLE C */
42 /* 6.3.0 */
43 /* AUTHOR */
44 /* */
45 /* William E. Lamie, Microsoft Corporation */
46 /* */
47 /* DESCRIPTION */
48 /* */
49 /* This function opens a NOR flash instance and ensures the NOR flash */
50 /* is in a coherent state. */
51 /* */
52 /* INPUT */
53 /* */
54 /* nor_flash NOR flash instance */
55 /* name Name of NOR flash instance */
56 /* nor_driver_initialize Driver initialize */
57 /* nor_driver_info_ptr Driver user data pointer */
58 /* */
59 /* OUTPUT */
60 /* */
61 /* return status */
62 /* */
63 /* CALLS */
64 /* */
65 /* (nor_driver_initialize) Driver initialize */
66 /* _lx_nor_flash_driver_read Driver read */
67 /* _lx_nor_flash_driver_write Driver write */
68 /* (lx_nor_flash_driver_block_erased_verify) */
69 /* NOR flash verify block erased */
70 /* _lx_nor_flash_driver_block_erase Driver block erase */
71 /* _lx_nor_flash_logical_sector_find Find logical sector */
72 /* _lx_nor_flash_system_error System error handler */
73 /* tx_mutex_create Create thread-safe mutex */
74 /* */
75 /* CALLED BY */
76 /* */
77 /* Application Code */
78 /* */
79 /**************************************************************************/
80
81 190 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)
82 {
83 ULONG sectors_per_block;
84 ULONG sector_map_words;
85 ULONG bit_map_words;
86 ULONG bit_map_mask;
87 ULONG total_header_words;
88 ULONG header_sectors;
89 ULONG *block_word_ptr;
90 ULONG block_word;
91 ULONG temp;
92 ULONG free_sectors;
93 ULONG used_sectors;
94 ULONG *new_map_entry;
95 ULONG *new_sector_address;
96 ULONG erased_count, min_erased_count, max_erased_count, temp_erased_count, min_erased_blocks;
97 ULONG j, k, l;
98 UINT status;
99 #ifdef LX_FREE_SECTOR_DATA_VERIFY
100 ULONG *sector_word_ptr;
101 ULONG sector_word;
102 #endif
103 LX_NOR_FLASH *tail_ptr;
104 LX_INTERRUPT_SAVE_AREA
105
106 LX_PARAMETER_NOT_USED(name);
107
108 /* Clear the NOR flash control block. User extension is not cleared. */
109
2/2
✓ Branch 4 → 3 taken 68096 times.
✓ Branch 4 → 5 taken 133 times.
68286 LX_MEMSET(nor_flash, 0, (ULONG)((UCHAR*)&(nor_flash -> lx_nor_flash_open_previous) - (UCHAR*)nor_flash) + sizeof(nor_flash -> lx_nor_flash_open_previous));
110
111 /* Pass the driver info ptr */
112 190 nor_flash -> lx_nor_flash_driver_info_ptr = nor_driver_info_ptr;
113
114 /* Call the flash driver's initialization function. */
115 190 (nor_driver_initialize)(nor_flash);
116
117 #ifndef LX_DIRECT_READ
118
119 /* Determine if the driver supplied a RAM buffer for reading the NOR sector if direct read is not
120 supported. */
121
2/4
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 38 times.
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 114 times.
152 if (nor_flash -> lx_nor_flash_sector_buffer == LX_NULL)
122 {
123
124 /* Return an error. */
125 ✗ return(LX_NO_MEMORY);
126 }
127 #endif
128
129 /* Setup the offset to the free bit map. */
130 190 nor_flash -> lx_nor_flash_block_free_bit_map_offset = sizeof(LX_NOR_FLASH_BLOCK_HEADER)/sizeof(ULONG);
131
132 /* Calculate the number of bits we need in the free physical sector bit map. Subtract 1 to account for the
133 flash block header itself. The case where multiple physical sectors are needed for certain sized flash
134 devices is handled below. */
135 190 sectors_per_block = (nor_flash -> lx_nor_flash_words_per_block / LX_NOR_SECTOR_SIZE) - 1;
136
137 /* Calculate the number of words required for the sector map array. */
138 190 sector_map_words = sectors_per_block;
139
140 /* Calculate the number of words we need for the free physical sector bit map. */
141 190 bit_map_words = (sectors_per_block + 31)/ 32;
142
143 /* Save the number of bit map words. */
144 190 nor_flash -> lx_nor_flash_block_bit_map_words = bit_map_words;
145
146 /* Setup the offset (in words) to the array of physical sector mapping. */
147 190 nor_flash -> lx_nor_flash_block_physical_sector_mapping_offset = nor_flash -> lx_nor_flash_block_free_bit_map_offset + bit_map_words;
148
149 /* Calculate the total number of words required for the flash block header. */
150 190 total_header_words = sizeof(LX_NOR_FLASH_BLOCK_HEADER)/sizeof(ULONG) + bit_map_words + sector_map_words;
151
152 /* Determine if more physical sectors are needed, which can happen on large devices. */
153
4/8
✓ Branch 3 → 4 taken 19 times.
✗ Branch 3 → 5 not taken.
✓ Branch 5 → 6 taken 38 times.
✗ Branch 5 → 7 not taken.
✓ Branch 6 → 7 taken 19 times.
✗ Branch 6 → 8 not taken.
✓ Branch 8 → 9 taken 114 times.
✗ Branch 8 → 10 not taken.
190 if (total_header_words <= LX_NOR_SECTOR_SIZE)
154 {
155
156 /* Round up to the size of 1 physical sector. */
157 190 total_header_words = LX_NOR_SECTOR_SIZE;
158 }
159 else
160 {
161
162 /* Otherwise calculate how many header sectors are necessary. */
163 ✗ header_sectors = (total_header_words-1)/LX_NOR_SECTOR_SIZE;
164
165 /* Round up to the next sector. */
166 ✗ header_sectors++;
167
168 /* Compute the total header words, rounding to the next sector. */
169 ✗ total_header_words = header_sectors * LX_NOR_SECTOR_SIZE;
170
171 /* Adjust the number of sectors per block. */
172 ✗ sectors_per_block = sectors_per_block - (header_sectors - 1);
173 }
174
175 /* Save the offset to the sector area. */
176 190 nor_flash -> lx_nor_flash_block_physical_sector_offset = total_header_words;
177
178 /* Save the physical sectors per block and total physical sectors. */
179 190 nor_flash -> lx_nor_flash_physical_sectors_per_block = sectors_per_block;
180 190 nor_flash -> lx_nor_flash_total_physical_sectors = nor_flash -> lx_nor_flash_total_blocks * sectors_per_block;
181
182 /* Build the free bit map mask, for the portion of the bit map that is less than 32 bits. */
183
4/8
✓ Branch 6 → 7 taken 19 times.
✗ Branch 6 → 8 not taken.
✓ Branch 8 → 9 taken 38 times.
✗ Branch 8 → 10 not taken.
✓ Branch 9 → 10 taken 19 times.
✗ Branch 9 → 11 not taken.
✓ Branch 11 → 12 taken 114 times.
✗ Branch 11 → 13 not taken.
190 if ((sectors_per_block % 32) != 0)
184 {
185 190 bit_map_mask = (ULONG)(1 << (sectors_per_block % 32));
186 190 bit_map_mask = bit_map_mask - 1;
187 }
188 else
189 {
190
191 /* Exactly 32 sectors for the bit map mask. */
192 ✗ bit_map_mask = LX_ALL_ONES;
193 }
194
195 /* Save the free bit map mask in the control block. */
196 190 nor_flash -> lx_nor_flash_block_bit_map_mask = bit_map_mask;
197
198 /* Setup default values for the max/min erased counts. */
199 190 min_erased_count = LX_ALL_ONES;
200 190 min_erased_blocks = 0;
201 190 max_erased_count = 0;
202
203 /* Setup the block word pointer to the first word of the first block, which is effectively the
204 flash base address. */
205 190 block_word_ptr = nor_flash -> lx_nor_flash_base_address;
206
207 /* Loop through the blocks to determine the minimum and maximum erase count. */
208
8/8
✓ Branch 19 → 10 taken 152 times.
✓ Branch 19 → 20 taken 19 times.
✓ Branch 22 → 13 taken 152 times.
✓ Branch 22 → 23 taken 19 times.
✓ Branch 25 → 12 taken 304 times.
✓ Branch 25 → 26 taken 38 times.
✓ Branch 28 → 15 taken 912 times.
✓ Branch 28 → 29 taken 114 times.
1710 for (l = 0; l < nor_flash -> lx_nor_flash_total_blocks; l++)
209 {
210
211 /* Pickup the first word of the block. If the flash manager has executed before, this word contains the
212 erase count for the block. Otherwise, if the word is 0xFFFFFFFF, this flash block was either erased
213 or this is the first time it was used. */
214 #ifdef LX_DIRECT_READ
215
216 /* Read the word directly. */
217 304 block_word = *block_word_ptr;
218 #else
219
220 1216 status = _lx_nor_flash_driver_read(nor_flash, block_word_ptr, &block_word, 1);
221
222 /* Check for an error from flash driver. Drivers should never return an error.. */
223
2/4
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 16 taken 304 times.
✗ Branch 16 → 17 not taken.
✓ Branch 16 → 19 taken 912 times.
1216 if (status)
224 {
225
226 /* Call system error handler. */
227 ✗ _lx_nor_flash_system_error(nor_flash, status);
228
229 /* Return an error. */
230 ✗ return(LX_ERROR);
231 }
232 #endif
233
234 /* Is the block erased? */
235
12/16
✓ Branch 10 → 11 taken 92 times.
✓ Branch 10 → 18 taken 60 times.
✓ Branch 11 → 12 taken 92 times.
✗ Branch 11 → 18 not taken.
✓ Branch 13 → 14 taken 92 times.
✓ Branch 13 → 21 taken 60 times.
✓ Branch 14 → 15 taken 92 times.
✗ Branch 14 → 21 not taken.
✓ Branch 16 → 17 taken 184 times.
✓ Branch 16 → 24 taken 120 times.
✓ Branch 17 → 18 taken 184 times.
✗ Branch 17 → 24 not taken.
✓ Branch 19 → 20 taken 552 times.
✓ Branch 19 → 27 taken 360 times.
✓ Branch 20 → 21 taken 552 times.
✗ Branch 20 → 27 not taken.
1520 if (((block_word & LX_BLOCK_ERASED) != LX_BLOCK_ERASED) && (block_word != LX_BLOCK_ERASE_STARTED))
236 {
237
238 /* No, valid block. Isolate the erased count. */
239 920 erased_count = (block_word & LX_BLOCK_ERASE_COUNT_MASK);
240
241 /* Is the erased count the minimum? */
242
8/8
✓ Branch 12 → 13 taken 80 times.
✓ Branch 12 → 14 taken 12 times.
✓ Branch 15 → 16 taken 80 times.
✓ Branch 15 → 17 taken 12 times.
✓ Branch 18 → 19 taken 160 times.
✓ Branch 18 → 20 taken 24 times.
✓ Branch 21 → 22 taken 480 times.
✓ Branch 21 → 23 taken 72 times.
920 if (erased_count == min_erased_count)
243 {
244
245 /* Yes, increment the minimum erased block count. */
246 800 min_erased_blocks++;
247 }
248
249 /* Is this the new minimum? */
250
8/8
✓ Branch 14 → 15 taken 12 times.
✓ Branch 14 → 16 taken 80 times.
✓ Branch 17 → 18 taken 12 times.
✓ Branch 17 → 19 taken 80 times.
✓ Branch 20 → 21 taken 24 times.
✓ Branch 20 → 22 taken 160 times.
✓ Branch 23 → 24 taken 72 times.
✓ Branch 23 → 25 taken 480 times.
920 if (erased_count < min_erased_count)
251 {
252
253 /* Yes, remember the new minimum. */
254 120 min_erased_count = erased_count;
255
256 /* Reset the minimum erased block count. */
257 120 min_erased_blocks = 1;
258 }
259
260 /* Is this the new maximum? */
261
8/8
✓ Branch 16 → 17 taken 12 times.
✓ Branch 16 → 18 taken 80 times.
✓ Branch 19 → 20 taken 12 times.
✓ Branch 19 → 21 taken 80 times.
✓ Branch 22 → 23 taken 24 times.
✓ Branch 22 → 24 taken 160 times.
✓ Branch 25 → 26 taken 72 times.
✓ Branch 25 → 27 taken 480 times.
920 if (erased_count > max_erased_count)
262 {
263
264 /* Yes, remember the new maximum. */
265 120 max_erased_count = erased_count;
266 }
267 }
268
269 /* Move to the next flash block. */
270 1520 block_word_ptr = block_word_ptr + (nor_flash -> lx_nor_flash_words_per_block);
271 }
272
273 /* If we haven't found any erased counts, we can assume the flash is completely erased and needs to
274 be setup for the first time. */
275
8/8
✓ Branch 20 → 21 taken 7 times.
✓ Branch 20 → 32 taken 12 times.
✓ Branch 23 → 24 taken 7 times.
✓ Branch 23 → 35 taken 12 times.
✓ Branch 26 → 27 taken 14 times.
✓ Branch 26 → 38 taken 24 times.
✓ Branch 29 → 30 taken 42 times.
✓ Branch 29 → 41 taken 72 times.
190 if (min_erased_count == LX_ALL_ONES)
276 {
277
278 /* Indicate that this is the initial format. */
279 70 nor_flash -> lx_nor_flash_diagnostic_initial_format = LX_TRUE;
280
281 /* Setup the block word pointer to the first word of the first block, which is effectively the
282 flash base address. */
283 70 block_word_ptr = nor_flash -> lx_nor_flash_base_address;
284
285 /* Loop through the blocks to setup the flash the fist time. */
286
10/10
✓ Branch 31 → 22 taken 56 times.
✓ Branch 31 → 120 taken 7 times.
✓ Branch 34 → 25 taken 56 times.
✓ Branch 34 → 123 taken 7 times.
✓ Branch 37 → 28 taken 112 times.
✓ Branch 37 → 132 taken 7 times.
✓ Branch 37 → 142 taken 7 times.
✓ Branch 40 → 31 taken 336 times.
✓ Branch 40 → 135 taken 35 times.
✓ Branch 40 → 145 taken 7 times.
630 for (l = 0; l < nor_flash -> lx_nor_flash_total_blocks; l++)
287 {
288
289 /* Setup the free bit map that corresponds to the free physical sectors in this
290 block. Note that we only need to setup the portion of the free bit map that doesn't
291 have sectors associated with it. */
292 560 status = _lx_nor_flash_driver_write(nor_flash, block_word_ptr+(nor_flash -> lx_nor_flash_block_free_bit_map_offset + (bit_map_words-1)) , &bit_map_mask, 1);
293
294 /* Check for an error from flash driver. Drivers should never return an error.. */
295
4/8
✗ Branch 23 → 24 not taken.
✓ Branch 23 → 26 taken 56 times.
✗ Branch 26 → 27 not taken.
✓ Branch 26 → 29 taken 56 times.
✗ Branch 29 → 30 not taken.
✓ Branch 29 → 32 taken 112 times.
✗ Branch 32 → 33 not taken.
✓ Branch 32 → 35 taken 336 times.
560 if (status)
296 {
297
298 /* Call system error handler. */
299 ✗ _lx_nor_flash_system_error(nor_flash, status);
300
301 /* Return an error. */
302 ✗ return(LX_ERROR);
303 }
304
305 /* Setup the initial erase count to 1. */
306 560 block_word = ((ULONG) 1);
307
308 /* Write the initial erase count for the block. */
309 560 status = _lx_nor_flash_driver_write(nor_flash, block_word_ptr, &block_word, 1);
310
311 /* Check for an error from flash driver. Drivers should never return an error.. */
312
4/8
✗ Branch 27 → 28 not taken.
✓ Branch 27 → 30 taken 56 times.
✗ Branch 30 → 31 not taken.
✓ Branch 30 → 33 taken 56 times.
✗ Branch 33 → 34 not taken.
✓ Branch 33 → 36 taken 112 times.
✗ Branch 36 → 37 not taken.
✓ Branch 36 → 39 taken 336 times.
560 if (status)
313 {
314
315 /* Call system error handler. */
316 ✗ _lx_nor_flash_system_error(nor_flash, status);
317
318 /* Return an error. */
319 ✗ return(LX_ERROR);
320 }
321
322 /* Update the overall minimum and maximum erase count. */
323 560 nor_flash -> lx_nor_flash_minimum_erase_count = 1;
324 560 nor_flash -> lx_nor_flash_minimum_erased_blocks = nor_flash -> lx_nor_flash_total_blocks;
325 560 nor_flash -> lx_nor_flash_maximum_erase_count = 1;
326
327 /* Update the number of free physical sectors. */
328 560 nor_flash -> lx_nor_flash_free_physical_sectors = nor_flash -> lx_nor_flash_free_physical_sectors + sectors_per_block;
329
330 /* Move to the next flash block. */
331 560 block_word_ptr = block_word_ptr + (nor_flash -> lx_nor_flash_words_per_block);
332 }
333 }
334 else
335 {
336
337 /* At this point, we have a previously managed flash structure. This needs to be traversed to prepare for the
338 current flash operation. */
339
340 /* Default the flash free sector search to an invalid value. */
341 120 nor_flash -> lx_nor_flash_free_block_search = nor_flash -> lx_nor_flash_total_blocks;
342
343 /* Setup the block word pointer to the first word of the first block, which is effectively the
344 flash base address. */
345 120 block_word_ptr = nor_flash -> lx_nor_flash_base_address;
346
347 /* Loop through the blocks. */
348
12/12
✓ Branch 117 → 33 taken 96 times.
✓ Branch 117 → 118 taken 12 times.
✓ Branch 120 → 36 taken 96 times.
✓ Branch 120 → 121 taken 12 times.
✓ Branch 129 → 39 taken 96 times.
✓ Branch 129 → 130 taken 12 times.
✓ Branch 132 → 42 taken 480 times.
✓ Branch 132 → 133 taken 60 times.
✓ Branch 139 → 39 taken 96 times.
✓ Branch 139 → 140 taken 12 times.
✓ Branch 142 → 42 taken 96 times.
✓ Branch 142 → 143 taken 12 times.
1080 for (l = 0; l < nor_flash -> lx_nor_flash_total_blocks; l++)
349 {
350
351 /* First, determine if this block has a valid erase count. */
352 #ifdef LX_DIRECT_READ
353
354 /* Read the word directly. */
355 192 block_word = *block_word_ptr;
356 #else
357 768 status = _lx_nor_flash_driver_read(nor_flash, block_word_ptr, &block_word, 1);
358
359 /* Check for an error from flash driver. Drivers should never return an error.. */
360
2/4
✗ Branch 40 → 41 not taken.
✓ Branch 40 → 43 taken 192 times.
✗ Branch 43 → 44 not taken.
✓ Branch 43 → 46 taken 576 times.
768 if (status)
361 {
362
363 /* Call system error handler. */
364 ✗ _lx_nor_flash_system_error(nor_flash, status);
365
366 /* Return an error. */
367 ✗ return(LX_ERROR);
368 }
369 #endif
370
371 /* Is the block erased? */
372
12/16
✓ Branch 33 → 34 taken 92 times.
✓ Branch 33 → 35 taken 4 times.
✗ Branch 34 → 35 not taken.
✓ Branch 34 → 60 taken 92 times.
✓ Branch 36 → 37 taken 92 times.
✓ Branch 36 → 38 taken 4 times.
✗ Branch 37 → 38 not taken.
✓ Branch 37 → 63 taken 92 times.
✓ Branch 43 → 44 taken 184 times.
✓ Branch 43 → 45 taken 8 times.
✗ Branch 44 → 45 not taken.
✓ Branch 44 → 70 taken 184 times.
✓ Branch 46 → 47 taken 552 times.
✓ Branch 46 → 48 taken 24 times.
✗ Branch 47 → 48 not taken.
✓ Branch 47 → 73 taken 552 times.
960 if (((block_word & LX_BLOCK_ERASED) == LX_BLOCK_ERASED) || (block_word == LX_BLOCK_ERASE_STARTED))
373 {
374
375 /* This can happen if we were previously in the process of erasing the flash block and a
376 power interruption occurs. It should only occur once though. */
377
378 /* Is this the first time? */
379
4/8
✗ Branch 35 → 36 not taken.
✓ Branch 35 → 38 taken 4 times.
✗ Branch 38 → 39 not taken.
✓ Branch 38 → 41 taken 4 times.
✗ Branch 45 → 46 not taken.
✓ Branch 45 → 48 taken 8 times.
✗ Branch 48 → 49 not taken.
✓ Branch 48 → 51 taken 24 times.
40 if (nor_flash -> lx_nor_flash_diagnostic_erased_block)
380 {
381
382 /* No, this is a potential format error, since this should only happen once in a given
383 NOR flash format. */
384 ✗ _lx_nor_flash_system_error(nor_flash, LX_SYSTEM_INVALID_BLOCK);
385
386 /* Return an error. */
387 ✗ return(LX_ERROR);
388 }
389
390 /* Increment the erased block diagnostic. */
391 40 nor_flash -> lx_nor_flash_diagnostic_erased_block++;
392
393 /* Check to see if the block is erased. */
394 #ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
395 4 status = (nor_flash -> lx_nor_flash_driver_block_erased_verify)(nor_flash, l);
396 #else
397 36 status = (nor_flash -> lx_nor_flash_driver_block_erased_verify)(l);
398 #endif
399
400 /* Is the block completely erased? */
401
8/8
✓ Branch 39 → 40 taken 2 times.
✓ Branch 39 → 47 taken 2 times.
✓ Branch 42 → 43 taken 2 times.
✓ Branch 42 → 50 taken 2 times.
✓ Branch 49 → 50 taken 4 times.
✓ Branch 49 → 57 taken 4 times.
✓ Branch 52 → 53 taken 12 times.
✓ Branch 52 → 60 taken 12 times.
40 if (status != LX_SUCCESS)
402 {
403
404 /* Is this the first time? */
405
4/8
✗ Branch 40 → 41 not taken.
✓ Branch 40 → 43 taken 2 times.
✗ Branch 43 → 44 not taken.
✓ Branch 43 → 46 taken 2 times.
✗ Branch 50 → 51 not taken.
✓ Branch 50 → 53 taken 4 times.
✗ Branch 53 → 54 not taken.
✓ Branch 53 → 56 taken 12 times.
20 if (nor_flash -> lx_nor_flash_diagnostic_re_erase_block)
406 {
407
408 /* No, this is a potential format error, since this should only happen once in a given
409 NOR flash format. */
410 ✗ _lx_nor_flash_system_error(nor_flash, LX_SYSTEM_INVALID_BLOCK);
411
412 /* Return an error. */
413 ✗ return(LX_ERROR);
414 }
415
416 /* Increment the erased block diagnostic. */
417 20 nor_flash -> lx_nor_flash_diagnostic_re_erase_block++;
418
419 /* No, the block is not fully erased, erase it again. */
420 20 status = _lx_nor_flash_driver_block_erase(nor_flash, l, max_erased_count);
421
422 /* Check for an error from flash driver. Drivers should never return an error.. */
423
4/8
✗ Branch 44 → 45 not taken.
✓ Branch 44 → 47 taken 2 times.
✗ Branch 47 → 48 not taken.
✓ Branch 47 → 50 taken 2 times.
✗ Branch 54 → 55 not taken.
✓ Branch 54 → 57 taken 4 times.
✗ Branch 57 → 58 not taken.
✓ Branch 57 → 60 taken 12 times.
20 if (status)
424 {
425
426 /* Call system error handler. */
427 ✗ _lx_nor_flash_system_error(nor_flash, status);
428
429 /* Return an error. */
430 ✗ return(LX_ERROR);
431 }
432 }
433
434 /* Setup the free bit map that corresponds to the free physical sectors in this
435 block. Note that we only need to setup the portion of the free bit map that doesn't
436 have sectors associated with it. */
437 40 status = _lx_nor_flash_driver_write(nor_flash, block_word_ptr+(nor_flash -> lx_nor_flash_block_free_bit_map_offset + (bit_map_words-1)) , &bit_map_mask, 1);
438
439 /* Check for an error from flash driver. Drivers should never return an error.. */
440
4/8
✗ Branch 48 → 49 not taken.
✓ Branch 48 → 51 taken 4 times.
✗ Branch 51 → 52 not taken.
✓ Branch 51 → 54 taken 4 times.
✗ Branch 58 → 59 not taken.
✓ Branch 58 → 61 taken 8 times.
✗ Branch 61 → 62 not taken.
✓ Branch 61 → 64 taken 24 times.
40 if (status)
441 {
442
443 /* Call system error handler. */
444 ✗ _lx_nor_flash_system_error(nor_flash, status);
445
446 /* Return an error. */
447 ✗ return(LX_ERROR);
448 }
449
450 /* Write the initial erase count for the block with upper bit set. */
451 40 temp_erased_count = (max_erased_count | LX_BLOCK_ERASED);
452 40 status = _lx_nor_flash_driver_write(nor_flash, block_word_ptr, &temp_erased_count, 1);
453
454 /* Check for an error from flash driver. Drivers should never return an error.. */
455
4/8
✗ Branch 52 → 53 not taken.
✓ Branch 52 → 55 taken 4 times.
✗ Branch 55 → 56 not taken.
✓ Branch 55 → 58 taken 4 times.
✗ Branch 62 → 63 not taken.
✓ Branch 62 → 65 taken 8 times.
✗ Branch 65 → 66 not taken.
✓ Branch 65 → 68 taken 24 times.
40 if (status)
456 {
457
458 /* Call system error handler. */
459 ✗ _lx_nor_flash_system_error(nor_flash, status);
460
461 /* Return an error. */
462 ✗ return(LX_ERROR);
463 }
464
465 /* Write the final initial erase count for the block. */
466 40 status = _lx_nor_flash_driver_write(nor_flash, block_word_ptr, &max_erased_count, 1);
467
468 /* Check for an error from flash driver. Drivers should never return an error.. */
469
4/8
✗ Branch 56 → 57 not taken.
✓ Branch 56 → 59 taken 4 times.
✗ Branch 59 → 60 not taken.
✓ Branch 59 → 62 taken 4 times.
✗ Branch 66 → 67 not taken.
✓ Branch 66 → 69 taken 8 times.
✗ Branch 69 → 70 not taken.
✓ Branch 69 → 72 taken 24 times.
40 if (status)
470 {
471
472 /* Call system error handler. */
473 ✗ _lx_nor_flash_system_error(nor_flash, status);
474
475 /* Return an error. */
476 ✗ return(LX_ERROR);
477 }
478
479 /* Update the number of free physical sectors. */
480 40 nor_flash -> lx_nor_flash_free_physical_sectors = nor_flash -> lx_nor_flash_free_physical_sectors + sectors_per_block;
481 }
482 else
483 {
484
485 /* Calculate the number of free sectors from the free sector bit map. */
486 920 free_sectors = 0;
487
8/8
✓ Branch 68 → 61 taken 92 times.
✓ Branch 68 → 69 taken 92 times.
✓ Branch 71 → 64 taken 92 times.
✓ Branch 71 → 72 taken 92 times.
✓ Branch 82 → 71 taken 184 times.
✓ Branch 82 → 83 taken 184 times.
✓ Branch 85 → 74 taken 552 times.
✓ Branch 85 → 86 taken 552 times.
1840 for (j = 0; j < bit_map_words; j++)
488 {
489
490 /* Read this word of the free sector bit map. */
491 #ifdef LX_DIRECT_READ
492
493 /* Read the word directly. */
494 184 block_word = *(block_word_ptr + nor_flash -> lx_nor_flash_block_free_bit_map_offset + j);
495 #else
496 736 status = _lx_nor_flash_driver_read(nor_flash, (block_word_ptr + nor_flash -> lx_nor_flash_block_free_bit_map_offset + j), &block_word, 1);
497
498 /* Check for an error from flash driver. Drivers should never return an error.. */
499
2/4
✗ Branch 72 → 73 not taken.
✓ Branch 72 → 75 taken 184 times.
✗ Branch 75 → 76 not taken.
✓ Branch 75 → 78 taken 552 times.
736 if (status)
500 {
501
502 /* Call system error handler. */
503 ✗ _lx_nor_flash_system_error(nor_flash, status);
504
505 /* Return an error. */
506 ✗ return(LX_ERROR);
507 }
508 #endif
509
510 /* Count the number of set bits (free sectors). */
511
8/8
✓ Branch 66 → 62 taken 2944 times.
✓ Branch 66 → 67 taken 92 times.
✓ Branch 69 → 65 taken 2944 times.
✓ Branch 69 → 70 taken 92 times.
✓ Branch 80 → 76 taken 5888 times.
✓ Branch 80 → 81 taken 184 times.
✓ Branch 83 → 79 taken 17664 times.
✓ Branch 83 → 84 taken 552 times.
30360 for (k = 0; k < 32; k++)
512 {
513
514 /* Is this sector free? */
515
8/8
✓ Branch 62 → 63 taken 1252 times.
✓ Branch 62 → 65 taken 1692 times.
✓ Branch 65 → 66 taken 1252 times.
✓ Branch 65 → 68 taken 1692 times.
✓ Branch 76 → 77 taken 2504 times.
✓ Branch 76 → 79 taken 3384 times.
✓ Branch 79 → 80 taken 7512 times.
✓ Branch 79 → 82 taken 10152 times.
29440 if (block_word & 1)
516 {
517 /* Yes, this sector is free, increment the free sectors count. */
518 12520 free_sectors++;
519
520 /* Determine if we need to update the search pointer. */
521
8/8
✓ Branch 63 → 64 taken 12 times.
✓ Branch 63 → 65 taken 1240 times.
✓ Branch 66 → 67 taken 12 times.
✓ Branch 66 → 68 taken 1240 times.
✓ Branch 77 → 78 taken 24 times.
✓ Branch 77 → 79 taken 2480 times.
✓ Branch 80 → 81 taken 72 times.
✓ Branch 80 → 82 taken 7440 times.
12520 if (nor_flash -> lx_nor_flash_free_block_search == nor_flash -> lx_nor_flash_total_blocks)
522 {
523
524 /* Remember the block with free sectors. */
525 120 nor_flash -> lx_nor_flash_free_block_search = l;
526 }
527 }
528
529 /* Shift down the free sector. */
530 29440 block_word = block_word >> 1;
531 }
532 }
533
534 /* Update the number of free physical sectors. */
535 920 nor_flash -> lx_nor_flash_free_physical_sectors = nor_flash -> lx_nor_flash_free_physical_sectors + free_sectors;
536
537 /* We need to now examine the mapping list. */
538
539 /* Calculate how many non-free sectors there are - this includes valid and obsolete sectors. */
540 920 used_sectors = sectors_per_block - free_sectors;
541
542 /* Now walk the list of logical-physical sector mapping. */
543
12/12
✓ Branch 115 → 70 taken 1380 times.
✓ Branch 115 → 116 taken 92 times.
✓ Branch 118 → 73 taken 1380 times.
✓ Branch 118 → 119 taken 92 times.
✓ Branch 127 → 84 taken 1380 times.
✓ Branch 127 → 128 taken 92 times.
✓ Branch 130 → 87 taken 6900 times.
✓ Branch 130 → 131 taken 460 times.
✓ Branch 137 → 84 taken 1380 times.
✓ Branch 137 → 138 taken 92 times.
✓ Branch 140 → 87 taken 1380 times.
✓ Branch 140 → 141 taken 92 times.
14720 for (j = 0; j < sectors_per_block; j++)
544 {
545
546 /* Read this word of the sector mapping list. */
547 #ifdef LX_DIRECT_READ
548
549 /* Read the word directly. */
550 2760 block_word = *(block_word_ptr + nor_flash -> lx_nor_flash_block_physical_sector_mapping_offset + j);
551 #else
552 11040 status = _lx_nor_flash_driver_read(nor_flash, (block_word_ptr + nor_flash -> lx_nor_flash_block_physical_sector_mapping_offset + j), &block_word, 1);
553
554 /* Check for an error from flash driver. Drivers should never return an error.. */
555
2/4
✗ Branch 85 → 86 not taken.
✓ Branch 85 → 88 taken 2760 times.
✗ Branch 88 → 89 not taken.
✓ Branch 88 → 91 taken 8280 times.
11040 if (status)
556 {
557
558 /* Call system error handler. */
559 ✗ _lx_nor_flash_system_error(nor_flash, status);
560
561 /* Return an error. */
562 ✗ return(LX_ERROR);
563 }
564 #endif
565
566 /* Determine if we are expecting to find a used sector. */
567
8/8
✓ Branch 70 → 71 taken 128 times.
✓ Branch 70 → 102 taken 1252 times.
✓ Branch 73 → 74 taken 128 times.
✓ Branch 73 → 105 taken 1252 times.
✓ Branch 88 → 89 taken 256 times.
✓ Branch 88 → 120 taken 2504 times.
✓ Branch 91 → 92 taken 768 times.
✓ Branch 91 → 123 taken 7512 times.
13800 if (used_sectors)
568 {
569
570 /* Yes, we expect this entry to be used. */
571
572 /* Is this sector in-use? */
573
8/8
✓ Branch 71 → 72 taken 122 times.
✓ Branch 71 → 84 taken 6 times.
✓ Branch 74 → 75 taken 122 times.
✓ Branch 74 → 87 taken 6 times.
✓ Branch 89 → 90 taken 244 times.
✓ Branch 89 → 102 taken 12 times.
✓ Branch 92 → 93 taken 732 times.
✓ Branch 92 → 105 taken 36 times.
1280 if ((block_word & LX_NOR_LOGICAL_SECTOR_MASK) != LX_NOR_LOGICAL_SECTOR_MASK)
574 {
575
576 /* Determine if the valid bit is set and the superceded bit is clear. This indicates the block was
577 about to become obsolete. */
578
16/16
✓ Branch 72 → 73 taken 110 times.
✓ Branch 72 → 93 taken 12 times.
✓ Branch 73 → 74 taken 4 times.
✓ Branch 73 → 93 taken 106 times.
✓ Branch 75 → 76 taken 110 times.
✓ Branch 75 → 96 taken 12 times.
✓ Branch 76 → 77 taken 4 times.
✓ Branch 76 → 96 taken 106 times.
✓ Branch 90 → 91 taken 220 times.
✓ Branch 90 → 111 taken 24 times.
✓ Branch 91 → 92 taken 8 times.
✓ Branch 91 → 111 taken 212 times.
✓ Branch 93 → 94 taken 660 times.
✓ Branch 93 → 114 taken 72 times.
✓ Branch 94 → 95 taken 24 times.
✓ Branch 94 → 114 taken 636 times.
1220 if ((block_word & LX_NOR_PHYSICAL_SECTOR_VALID) && ((block_word & LX_NOR_PHYSICAL_SECTOR_SUPERCEDED) == 0))
579 {
580
581
582 /* Increment the being obsoleted count. */
583 40 nor_flash -> lx_nor_flash_diagnostic_sector_being_obsoleted++;
584
585 /* Save the currently mapped physical sectors. */
586 40 temp = nor_flash -> lx_nor_flash_mapped_physical_sectors;
587
588 /* Indicate all the physical sectors are mapped for the purpose of this search. */
589 40 nor_flash -> lx_nor_flash_mapped_physical_sectors = nor_flash -> lx_nor_flash_total_physical_sectors;
590
591 /* Yes, this block was about to become obsolete. Perform a search for a logical sector entry that
592 has both of these bits set. */
593 40 _lx_nor_flash_logical_sector_find(nor_flash, (block_word & LX_NOR_LOGICAL_SECTOR_MASK), LX_TRUE, &new_map_entry, &new_sector_address);
594
595 /* Restore the number of mapped physical sectors. */
596 40 nor_flash -> lx_nor_flash_mapped_physical_sectors = temp;
597
598 /* Determine if the new logical sector entry is present. */
599
8/8
✓ Branch 75 → 76 taken 2 times.
✓ Branch 75 → 93 taken 2 times.
✓ Branch 78 → 79 taken 2 times.
✓ Branch 78 → 96 taken 2 times.
✓ Branch 93 → 94 taken 4 times.
✓ Branch 93 → 111 taken 4 times.
✓ Branch 96 → 97 taken 12 times.
✓ Branch 96 → 114 taken 12 times.
40 if (new_map_entry)
600 {
601
602 /* Yes, make the current entry obsolete in favor of the new entry. */
603 20 block_word = block_word & ~((ULONG) LX_NOR_PHYSICAL_SECTOR_VALID);
604 20 status = _lx_nor_flash_driver_write(nor_flash, (block_word_ptr + nor_flash -> lx_nor_flash_block_physical_sector_mapping_offset + j), &block_word, 1);
605
606 /* Check for an error from flash driver. Drivers should never return an error.. */
607
4/8
✗ Branch 77 → 78 not taken.
✓ Branch 77 → 80 taken 2 times.
✗ Branch 80 → 81 not taken.
✓ Branch 80 → 83 taken 2 times.
✗ Branch 95 → 96 not taken.
✓ Branch 95 → 98 taken 4 times.
✗ Branch 98 → 99 not taken.
✓ Branch 98 → 101 taken 12 times.
20 if (status)
608 {
609
610 /* Call system error handler. */
611 ✗ _lx_nor_flash_system_error(nor_flash, status);
612
613 /* Return an error. */
614 ✗ return(LX_ERROR);
615 }
616
617 /* Is this the first time? */
618
4/8
✗ Branch 80 → 81 not taken.
✓ Branch 80 → 83 taken 2 times.
✗ Branch 83 → 84 not taken.
✓ Branch 83 → 86 taken 2 times.
✗ Branch 98 → 99 not taken.
✓ Branch 98 → 101 taken 4 times.
✗ Branch 101 → 102 not taken.
✓ Branch 101 → 104 taken 12 times.
20 if (nor_flash -> lx_nor_flash_diagnostic_sector_obsoleted)
619 {
620
621 /* No, this is a potential format error, since this should only happen once in a given
622 NOR flash format. */
623 ✗ _lx_nor_flash_system_error(nor_flash, LX_SYSTEM_INVALID_FORMAT);
624
625 /* Return an error. */
626 ✗ return(LX_ERROR);
627 }
628
629 /* Increment the obsoleted count. */
630 20 nor_flash -> lx_nor_flash_diagnostic_sector_obsoleted++;
631 }
632 }
633 }
634
635 /* Determine if the sector is free. */
636
4/8
✓ Branch 84 → 85 taken 6 times.
✗ Branch 84 → 93 not taken.
✓ Branch 87 → 88 taken 6 times.
✗ Branch 87 → 96 not taken.
✓ Branch 102 → 103 taken 12 times.
✗ Branch 102 → 111 not taken.
✓ Branch 105 → 106 taken 36 times.
✗ Branch 105 → 114 not taken.
60 else if (block_word == LX_NOR_PHYSICAL_SECTOR_FREE)
637 {
638
639 /* A free entry when there are still used sectors implies that the sector was allocated and a power interruption
640 took place prior to writing the new logical sector number into the list. */
641
642 /* Is this the first time? */
643
4/8
✗ Branch 85 → 86 not taken.
✓ Branch 85 → 88 taken 6 times.
✗ Branch 88 → 89 not taken.
✓ Branch 88 → 91 taken 6 times.
✗ Branch 103 → 104 not taken.
✓ Branch 103 → 106 taken 12 times.
✗ Branch 106 → 107 not taken.
✓ Branch 106 → 109 taken 36 times.
60 if (nor_flash -> lx_nor_flash_diagnostic_mapping_invalidated)
644 {
645
646 /* No, this is a potential format error, since this should only happen once in a given
647 NOR flash format. */
648 ✗ _lx_nor_flash_system_error(nor_flash, LX_SYSTEM_INVALID_FORMAT);
649
650 /* Return an error. */
651 ✗ return(LX_ERROR);
652 }
653
654 /* Write 0s out to this entry to invalidate the sector entry. */
655 60 block_word = 0;
656 60 status = _lx_nor_flash_driver_write(nor_flash, (block_word_ptr + nor_flash -> lx_nor_flash_block_physical_sector_mapping_offset + j), &block_word, 1);
657
658 /* Check for an error from flash driver. Drivers should never return an error.. */
659
4/8
✗ Branch 89 → 90 not taken.
✓ Branch 89 → 92 taken 6 times.
✗ Branch 92 → 93 not taken.
✓ Branch 92 → 95 taken 6 times.
✗ Branch 107 → 108 not taken.
✓ Branch 107 → 110 taken 12 times.
✗ Branch 110 → 111 not taken.
✓ Branch 110 → 113 taken 36 times.
60 if (status)
660 {
661
662 /* Call system error handler. */
663 ✗ _lx_nor_flash_system_error(nor_flash, status);
664
665 /* Return an error. */
666 ✗ return(LX_ERROR);
667 }
668
669 /* Increment the number of mapping invalidates. */
670 60 nor_flash -> lx_nor_flash_diagnostic_mapping_invalidated++;
671 }
672
673 /* Yes, now determine if the sector is obsolete. */
674
8/8
✓ Branch 93 → 94 taken 20 times.
✓ Branch 93 → 95 taken 108 times.
✓ Branch 96 → 97 taken 20 times.
✓ Branch 96 → 98 taken 108 times.
✓ Branch 111 → 112 taken 40 times.
✓ Branch 111 → 113 taken 216 times.
✓ Branch 114 → 115 taken 120 times.
✓ Branch 114 → 116 taken 648 times.
1280 if ((block_word & LX_NOR_PHYSICAL_SECTOR_VALID) == 0)
675 {
676
677 /* Increment the number of obsolete sectors. */
678 200 nor_flash -> lx_nor_flash_obsolete_physical_sectors++;
679 }
680
681 /* Determine if the mapping for this sector isn't yet valid. */
682
4/8
✗ Branch 95 → 96 not taken.
✓ Branch 95 → 100 taken 108 times.
✗ Branch 98 → 99 not taken.
✓ Branch 98 → 103 taken 108 times.
✗ Branch 113 → 114 not taken.
✓ Branch 113 → 118 taken 216 times.
✗ Branch 116 → 117 not taken.
✓ Branch 116 → 121 taken 648 times.
1080 else if (block_word & LX_NOR_PHYSICAL_SECTOR_MAPPING_NOT_VALID)
683 {
684
685 /* Yes, a power interruption or reset occurred while the sector mapping entry was being written. */
686
687 /* Increment the number of obsolete sectors. */
688 ✗ nor_flash -> lx_nor_flash_obsolete_physical_sectors++;
689
690 /* Increment the interrupted mapping counter. */
691 ✗ nor_flash -> lx_nor_flash_diagnostic_mapping_write_interrupted++;
692
693 /* Invalidate this entry - clearing valid bit, superceded bit and logical sector. */
694 ✗ block_word = 0;
695 ✗ status = _lx_nor_flash_driver_write(nor_flash, (block_word_ptr + nor_flash -> lx_nor_flash_block_physical_sector_mapping_offset + j), &block_word, 1);
696
697 /* Check for an error from flash driver. Drivers should never return an error.. */
698 ✗ if (status)
699 {
700
701 /* Call system error handler. */
702 ✗ _lx_nor_flash_system_error(nor_flash, status);
703
704 /* Return an error. */
705 ✗ return(LX_ERROR);
706 }
707 }
708 else
709 {
710 /* Increment the number of mapped physical sectors. */
711 1080 nor_flash -> lx_nor_flash_mapped_physical_sectors++;
712 }
713
714 /* Decrease the number of used sectors. */
715 1280 used_sectors--;
716 }
717 else
718 {
719
720 /* No more used sectors in this flash block. */
721
722 /* In this case the entry must be free or there is a serious NOR flash format error present. */
723
4/8
✗ Branch 102 → 103 not taken.
✓ Branch 102 → 108 taken 1252 times.
✗ Branch 105 → 106 not taken.
✓ Branch 105 → 111 taken 1252 times.
✗ Branch 120 → 121 not taken.
✓ Branch 120 → 126 taken 2504 times.
✗ Branch 123 → 124 not taken.
✓ Branch 123 → 129 taken 7512 times.
12520 if (block_word != LX_NOR_PHYSICAL_SECTOR_FREE)
724 {
725
726 /* Increment the sector not free diagnostic. */
727 ✗ nor_flash -> lx_nor_flash_diagnostic_sector_not_free++;
728
729 /* NOR flash format. */
730 ✗ _lx_nor_flash_system_error(nor_flash, LX_SYSTEM_INVALID_FORMAT);
731
732 /* Write 0s out to this entry to invalidate the sector entry. */
733 ✗ block_word = 0;
734 ✗ status = _lx_nor_flash_driver_write(nor_flash, (block_word_ptr + nor_flash -> lx_nor_flash_block_physical_sector_mapping_offset + j), &block_word, 1);
735
736 /* Check for an error from flash driver. Drivers should never return an error.. */
737 ✗ if (status)
738 {
739
740 /* Call system error handler. */
741 ✗ _lx_nor_flash_system_error(nor_flash, status);
742
743 /* Return an error. */
744 ✗ return(LX_ERROR);
745 }
746 }
747
748 #ifdef LX_FREE_SECTOR_DATA_VERIFY
749
750 /* Pickup address of the free sector data area. */
751 5008 sector_word_ptr = block_word_ptr + (nor_flash -> lx_nor_flash_block_physical_sector_offset) + (j * LX_NOR_SECTOR_SIZE);
752
753 /* Determine if the data for this sector is free. */
754
8/8
✓ Branch 113 → 109 taken 160256 times.
✓ Branch 113 → 114 taken 1252 times.
✓ Branch 116 → 112 taken 160256 times.
✓ Branch 116 → 117 taken 1252 times.
✓ Branch 135 → 127 taken 160256 times.
✓ Branch 135 → 136 taken 1252 times.
✓ Branch 138 → 130 taken 160256 times.
✓ Branch 138 → 139 taken 1252 times.
646032 for (k = 0; k < LX_NOR_SECTOR_SIZE; k++)
755 {
756
757 #ifdef LX_DIRECT_READ
758
759 /* Read the word directly. */
760 320512 sector_word = *(sector_word_ptr);
761 #else
762 320512 status = _lx_nor_flash_driver_read(nor_flash, (sector_word_ptr), &sector_word, 1);
763
764 /* Check for an error from flash driver. Drivers should never return an error.. */
765
2/4
✗ Branch 128 → 129 not taken.
✓ Branch 128 → 131 taken 160256 times.
✗ Branch 131 → 132 not taken.
✓ Branch 131 → 134 taken 160256 times.
320512 if (status)
766 {
767
768 /* Call system error handler. */
769 ✗ _lx_nor_flash_system_error(nor_flash, status);
770
771 /* Return an error. */
772 ✗ return(LX_ERROR);
773 }
774 #endif
775
776 /* Determine if this word is not available. */
777
4/8
✗ Branch 109 → 110 not taken.
✓ Branch 109 → 112 taken 160256 times.
✗ Branch 112 → 113 not taken.
✓ Branch 112 → 115 taken 160256 times.
✗ Branch 131 → 132 not taken.
✓ Branch 131 → 134 taken 160256 times.
✗ Branch 134 → 135 not taken.
✓ Branch 134 → 137 taken 160256 times.
641024 if (sector_word != LX_NOR_PHYSICAL_SECTOR_FREE)
778 {
779
780 /* Increment the sector data not free diagnostic. */
781 ✗ nor_flash -> lx_nor_flash_diagnostic_sector_data_not_free++;
782
783 /* This is a format error. */
784 ✗ _lx_nor_flash_system_error(nor_flash, LX_SYSTEM_INVALID_BLOCK);
785
786 /* Return an error. */
787 ✗ return(LX_ERROR);
788 }
789
790 /* Move to the next word in the sector. */
791 641024 sector_word_ptr++;
792 }
793 #endif
794 }
795 }
796 }
797
798 /* Move to the next flash block. */
799 960 block_word_ptr = block_word_ptr + (nor_flash -> lx_nor_flash_words_per_block);
800 }
801
802 /* Update the overall minimum and maximum erase count. */
803 120 nor_flash -> lx_nor_flash_minimum_erase_count = min_erased_count;
804 120 nor_flash -> lx_nor_flash_minimum_erased_blocks = min_erased_blocks;
805 120 nor_flash -> lx_nor_flash_maximum_erase_count = max_erased_count;
806
807 /* Determine if we need to update the free sector search pointer. */
808
6/12
✗ Branch 118 → 119 not taken.
✓ Branch 118 → 120 taken 12 times.
✗ Branch 121 → 122 not taken.
✓ Branch 121 → 123 taken 12 times.
✗ Branch 130 → 131 not taken.
✓ Branch 130 → 132 taken 12 times.
✗ Branch 133 → 134 not taken.
✓ Branch 133 → 135 taken 60 times.
✗ Branch 140 → 141 not taken.
✓ Branch 140 → 142 taken 12 times.
✗ Branch 143 → 144 not taken.
✓ Branch 143 → 145 taken 12 times.
120 if (nor_flash -> lx_nor_flash_free_block_search == nor_flash -> lx_nor_flash_total_blocks)
809 {
810
811 /* Just start at the beginning. */
812 ✗ nor_flash -> lx_nor_flash_free_block_search = 0;
813 }
814 }
815
816 #ifdef LX_THREAD_SAFE_ENABLE
817
818 /* If the thread safe option is enabled, create a ThreadX mutex that will be used in all external APIs
819 in order to provide thread-safe operation. */
820 19 status = tx_mutex_create(&nor_flash -> lx_nor_flash_mutex, "NOR Flash Mutex", TX_NO_INHERIT);
821
822 /* Determine if the mutex creation encountered an error. */
823
1/2
✗ Branch 124 → 125 not taken.
✓ Branch 124 → 127 taken 19 times.
19 if (status != LX_SUCCESS)
824 {
825
826 /* Call system error handler, since this should not happen. */
827 ✗ _lx_nor_flash_system_error(nor_flash, LX_SYSTEM_MUTEX_CREATE_FAILED);
828
829 /* Return error to caller. */
830 ✗ return(LX_ERROR);
831 }
832 #endif
833
834 /* Enable the sector mapping cache. */
835 190 nor_flash -> lx_nor_flash_sector_mapping_cache_enabled = LX_TRUE;
836
837 /* Initialize the last found block and sector markers. */
838 190 nor_flash -> lx_nor_flash_found_block_search = 0;
839 190 nor_flash -> lx_nor_flash_found_sector_search = 0;
840
841 /* Lockout interrupts. */
842 133 LX_DISABLE
843
844 /* At this point, the NOR flash has been opened successfully. Place the
845 NOR flash control block on the linked list of currently opened NOR flashes. */
846
847 /* Set the NOR flash state to open. */
848 190 nor_flash -> lx_nor_flash_state = LX_NOR_FLASH_OPENED;
849
850 /* Place the NOR flash control block on the list of opened NOR flashes. First,
851 check for an empty list. */
852
6/12
✗ Branch 120 → 121 not taken.
✓ Branch 120 → 122 taken 19 times.
✗ Branch 128 → 129 not taken.
✓ Branch 128 → 130 taken 19 times.
✗ Branch 132 → 133 not taken.
✓ Branch 132 → 134 taken 19 times.
✗ Branch 136 → 137 not taken.
✓ Branch 136 → 138 taken 95 times.
✗ Branch 142 → 143 not taken.
✓ Branch 142 → 144 taken 19 times.
✗ Branch 146 → 147 not taken.
✓ Branch 146 → 148 taken 19 times.
190 if (_lx_nor_flash_opened_count)
853 {
854
855 /* List is not empty - other NOR flashes are open. */
856
857 /* Pickup tail pointer. */
858 ✗ tail_ptr = _lx_nor_flash_opened_ptr -> lx_nor_flash_open_previous;
859
860 /* Place the new NOR flash control block in the list. */
861 ✗ _lx_nor_flash_opened_ptr -> lx_nor_flash_open_previous = nor_flash;
862 ✗ tail_ptr -> lx_nor_flash_open_next = nor_flash;
863
864 /* Setup this NOR flash's opened links. */
865 ✗ nor_flash -> lx_nor_flash_open_previous = tail_ptr;
866 ✗ nor_flash -> lx_nor_flash_open_next = _lx_nor_flash_opened_ptr;
867 }
868 else
869 {
870
871 /* The opened NOR flash list is empty. Add the NOR flash to empty list. */
872 190 _lx_nor_flash_opened_ptr = nor_flash;
873 190 nor_flash -> lx_nor_flash_open_next = nor_flash;
874 190 nor_flash -> lx_nor_flash_open_previous = nor_flash;
875 }
876
877 /* Increment the opened NOR flash counter. */
878 190 _lx_nor_flash_opened_count++;
879
880 /* Restore interrupts. */
881 133 LX_RESTORE
882
883 /* Return a successful completion. */
884 190 return(LX_SUCCESS);
885 }
886
887