GCC Code Coverage Report


Directory: common/src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 73.5% 25 / 0 / 34
Functions: 100.0% 1 / 0 / 1
Branches: 53.7% 22 / 0 / 41

lx_nor_flash_sector_release.c
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 */
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 /* */
40 /* FUNCTION RELEASE */
41 /* */
42 /* _lx_nor_flash_sector_release PORTABLE C */
43 /* 6.3.0 */
44 /* AUTHOR */
45 /* */
46 /* William E. Lamie, Microsoft Corporation */
47 /* */
48 /* DESCRIPTION */
49 /* */
50 /* This function releases a logical sector from being managed in the */
51 /* NOR flash. */
52 /* */
53 /* INPUT */
54 /* */
55 /* nor_flash NOR flash instance */
56 /* logical_sector Logical sector number */
57 /* */
58 /* OUTPUT */
59 /* */
60 /* return status */
61 /* */
62 /* CALLS */
63 /* */
64 /* _lx_nor_flash_driver_write Driver flash sector write */
65 /* _lx_nor_flash_driver_read Driver flash sector read */
66 /* _lx_nor_flash_block_reclaim Reclaim one flash block */
67 /* _lx_nor_flash_sector_mapping_cache_invalidate */
68 /* Invalidate cache entry */
69 /* _lx_nor_flash_logical_sector_find Find logical sector */
70 /* _lx_nor_flash_system_error Internal system error handler */
71 /* tx_mutex_get Get thread protection */
72 /* tx_mutex_put Release thread protection */
73 /* */
74 /* CALLED BY */
75 /* */
76 /* Application Code */
77 /* */
78 /**************************************************************************/
79 1042 UINT _lx_nor_flash_sector_release(LX_NOR_FLASH *nor_flash, ULONG logical_sector)
80 {
81
82 UINT status;
83 ULONG *mapping_address;
84 ULONG mapping_entry;
85 ULONG *sector_address;
86 ULONG i;
87 #ifdef LX_NOR_ENABLE_OBSOLETE_COUNT_CACHE
88 ULONG block;
89 #endif
90
91
92 #ifdef LX_THREAD_SAFE_ENABLE
93
94 /* Obtain the thread safe mutex. */
95 104 tx_mutex_get(&nor_flash -> lx_nor_flash_mutex, TX_WAIT_FOREVER);
96 #endif
97
98 /* Increment the number of read requests. */
99 1042 nor_flash -> lx_nor_flash_read_requests++;
100
101 /* See if we can find the sector in the current mapping. */
102 1042 _lx_nor_flash_logical_sector_find(nor_flash, logical_sector, LX_FALSE, &mapping_address, &sector_address);
103
104 /* Determine if the logical sector was found. */
105
7/7
✓ Branch 3 → 4 taken 920 times.
✓ Branch 3 → 16 taken 2 times.
✓ Branch 3 → 20 taken 10 times.
✓ Branch 3 → 22 taken 4 times.
✓ Branch 3 → 24 taken 2 times.
✓ Branch 4 → 5 taken 102 times.
✓ Branch 4 → 18 taken 2 times.
1042 if (mapping_address)
106 {
107
108 /* Yes, we were able to find the logical sector. */
109
110 /* Read in the old sector mapping. */
111 #ifdef LX_DIRECT_READ
112
113 /* Read the word directly. */
114 204 mapping_entry = *(mapping_address);
115 #else
116 818 status = _lx_nor_flash_driver_read(nor_flash, mapping_address, &mapping_entry, 1);
117
118 /* Check for an error from flash driver. Drivers should never return an error.. */
119
1/2
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 8 taken 818 times.
818 if (status)
120 {
121
122 /* Call system error handler. */
123 ✗ _lx_nor_flash_system_error(nor_flash, status);
124
125 #ifdef LX_THREAD_SAFE_ENABLE
126
127 /* Release the thread safe mutex. */
128 tx_mutex_put(&nor_flash -> lx_nor_flash_mutex);
129 #endif
130
131 /* Return status. */
132 ✗ return(LX_ERROR);
133 }
134 #endif
135
136 /* Mark this sector as invalid. */
137 /* Now clear bits 31 and 30, which indicates this sector is now obsoleted. */
138 1022 mapping_entry = mapping_entry & ~(((ULONG) LX_NOR_PHYSICAL_SECTOR_VALID) | ((ULONG) LX_NOR_PHYSICAL_SECTOR_SUPERCEDED));
139
140 /* Write the value back to the flash to clear bits 31 & 30. */
141 1022 status = _lx_nor_flash_driver_write(nor_flash, mapping_address, &mapping_entry, 1);
142
143 /* Check for an error from flash driver. Drivers should never return an error.. */
144
3/6
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 8 taken 102 times.
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 10 taken 102 times.
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 12 taken 818 times.
1022 if (status)
145 {
146
147 /* Call system error handler. */
148 ✗ _lx_nor_flash_system_error(nor_flash, status);
149
150 #ifdef LX_THREAD_SAFE_ENABLE
151
152 /* Release the thread safe mutex. */
153 ✗ tx_mutex_put(&nor_flash -> lx_nor_flash_mutex);
154 #endif
155
156 /* Return status. */
157 ✗ return(LX_ERROR);
158 }
159
160 #ifndef LX_NOR_DISABLE_EXTENDED_CACHE
161 #ifdef LX_NOR_ENABLE_MAPPING_BITMAP
162
163 /* Determine if the logical sector is within the mapping bitmap. */
164
2/2
✓ Branch 12 → 13 taken 203 times.
✓ Branch 12 → 14 taken 2 times.
205 if (logical_sector < nor_flash -> lx_nor_flash_extended_cache_mapping_bitmap_max_logical_sector)
165 {
166
167 /* Set the bit in the mapping bitmap. */
168 203 nor_flash -> lx_nor_flash_extended_cache_mapping_bitmap[logical_sector >> 5] &= (ULONG)~(1 << (logical_sector & 31));
169 }
170 #endif
171 #endif
172
173 /* Increment the number of obsolete physical sectors. */
174 1022 nor_flash -> lx_nor_flash_obsolete_physical_sectors++;
175
176 #ifdef LX_NOR_ENABLE_OBSOLETE_COUNT_CACHE
177
178 /* Get the block number from mapping address. */
179 206 block = (ULONG)(mapping_address - nor_flash -> lx_nor_flash_base_address) / nor_flash -> lx_nor_flash_words_per_block;
180
181 /* Determine if this block is within the range of the obsolete count cache. */
182
4/4
✓ Branch 12 → 13 taken 102 times.
✓ Branch 12 → 14 taken 1 time.
✓ Branch 14 → 15 taken 102 times.
✓ Branch 14 → 16 taken 1 time.
206 if (block < nor_flash -> lx_nor_flash_extended_cache_obsolete_count_max_block)
183 {
184
185 /* Increment the obsolete count for this block. */
186 204 nor_flash -> lx_nor_flash_extended_cache_obsolete_count[block] ++;
187 }
188 #endif
189
190 /* Decrement the number of mapped physical sectors. */
191 1022 nor_flash -> lx_nor_flash_mapped_physical_sectors--;
192
193 /* Ensure the sector mapping cache no longer has this sector. */
194 1022 _lx_nor_flash_sector_mapping_cache_invalidate(nor_flash, logical_sector);
195
196 /* Determine if there are less than two block's worth of free sectors. */
197 1022 i = 0;
198
5/10
✗ Branch 14 → 10 not taken.
✓ Branch 14 → 15 taken 102 times.
✗ Branch 16 → 12 not taken.
✓ Branch 16 → 17 taken 102 times.
✗ Branch 18 → 14 not taken.
✓ Branch 18 → 19 taken 510 times.
✗ Branch 20 → 16 not taken.
✓ Branch 20 → 21 taken 205 times.
✗ Branch 22 → 18 not taken.
✓ Branch 22 → 23 taken 103 times.
1022 while (nor_flash -> lx_nor_flash_free_physical_sectors <= nor_flash -> lx_nor_flash_physical_sectors_per_block)
199 {
200
201 /* Attempt to reclaim one physical block. */
202 ✗ _lx_nor_flash_block_reclaim(nor_flash);
203
204 /* Increment the block count. */
205 ✗ i++;
206
207 /* Have we exceeded the number of blocks in the system? */
208 ✗ if (i >= nor_flash -> lx_nor_flash_total_blocks)
209 {
210
211 /* Yes, break out of the loop. */
212 ✗ break;
213 }
214 }
215
216 /* Set the status to success. */
217 1022 status = LX_SUCCESS;
218 }
219 else
220 {
221
222 /* Could not find the logical sector. */
223 20 status = LX_SECTOR_NOT_FOUND;
224 }
225
226 #ifdef LX_THREAD_SAFE_ENABLE
227
228 /* Release the thread safe mutex. */
229 104 tx_mutex_put(&nor_flash -> lx_nor_flash_mutex);
230 #endif
231
232 /* Return status. */
233 1042 return(status);
234 }
235
236