GCC Code Coverage Report


Directory: common/src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 94.9% 37 / 0 / 39
Functions: 100.0% 1 / 0 / 1
Branches: 90.0% 18 / 0 / 20

lx_nor_flash_driver_read.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 // Portions of this file were generated with AI assistance.
13
14
15 /**************************************************************************/
16 /**************************************************************************/
17 /** */
18 /** LevelX Component */
19 /** */
20 /** NOR Flash */
21 /** */
22 /**************************************************************************/
23 /**************************************************************************/
24
25 #define LX_SOURCE_CODE
26
27
28 /* Disable ThreadX error checking. */
29
30 #ifndef LX_DISABLE_ERROR_CHECKING
31 #define LX_DISABLE_ERROR_CHECKING
32 #endif
33
34
35 /* Include necessary system files. */
36
37 #include "lx_api.h"
38
39
40 /**************************************************************************/
41 /* */
42 /* FUNCTION RELEASE */
43 /* */
44 /* _lx_nor_flash_extended_cache_read PORTABLE C */
45 /* 6.2.1 */
46 /* AUTHOR */
47 /* */
48 /* William E. Lamie, Microsoft Corporation */
49 /* */
50 /* DESCRIPTION */
51 /* */
52 /* This function performs a read of the NOR flash memory. */
53 /* */
54 /* INPUT */
55 /* */
56 /* nor_flash NOR flash instance */
57 /* flash_address Address of NOR flash to read */
58 /* destination Destination for the read */
59 /* words Number of words to read */
60 /* */
61 /* OUTPUT */
62 /* */
63 /* return status */
64 /* */
65 /* CALLS */
66 /* */
67 /* (lx_nor_flash_driver_read) Actual driver read */
68 /* */
69 /* CALLED BY */
70 /* */
71 /* Application Code */
72 /* */
73 /**************************************************************************/
74 3081418 UINT _lx_nor_flash_driver_read(LX_NOR_FLASH *nor_flash, ULONG *flash_address, ULONG *destination, ULONG words)
75 {
76 #ifndef LX_NOR_DISABLE_EXTENDED_CACHE
77
78 UINT status;
79 UINT i;
80 ULONG *cache_entry_start;
81 ULONG cache_entry_start_value;
82 ULONG cache_entry_end_value;
83 ULONG cache_offset;
84 ULONG flash_address_value;
85 ULONG base_address_value;
86 UINT least_used_cache_entry;
87
88
89 /* Is the request a whole sector or a partial sector. */
90
4/4
✓ Branch 2 → 3 taken 2932354 times.
✓ Branch 2 → 21 taken 143440 times.
✓ Branch 3 → 4 taken 1243546 times.
✓ Branch 3 → 21 taken 1688808 times.
3075794 if ((words == 1) && (nor_flash -> lx_nor_flash_extended_cache_entries))
91 {
92
93 /* One word request, which implies that it is a NOR flash metadata read. */
94
95
96 /* Initialize the least used cache entry. */
97 1243546 least_used_cache_entry = 0;
98
99 /* MISRA C:2012 Rule 11.4 deviation: NOR driver addresses may be logical
100 address tokens, including zero, so compare address values without
101 dereferencing them. */
102 1243546 flash_address_value = (ULONG)flash_address;
103
104 do
105 {
106
107 /* Loop through the cache entries to see if there is a sector in cache. */
108
2/2
✓ Branch 14 → 6 taken 3647664 times.
✓ Branch 14 → 15 taken 128066 times.
3775730 for (i = 0; i < nor_flash -> lx_nor_flash_extended_cache_entries; i++)
109 {
110
111 /* Search through the cache to find the entry. */
112
113 /* Determine the cache entry addresses. */
114 3647664 cache_entry_start = nor_flash -> lx_nor_flash_extended_cache[i].lx_nor_flash_extended_cache_entry_sector_address;
115
116 /* Determine if the flash address is in the cache entry. */
117
2/2
✓ Branch 6 → 7 taken 3632970 times.
✓ Branch 6 → 10 taken 14694 times.
3647664 if (nor_flash -> lx_nor_flash_extended_cache[i].lx_nor_flash_extended_cache_entry_valid)
118 {
119 3632970 cache_entry_start_value = (ULONG)cache_entry_start;
120 3632970 cache_entry_end_value = cache_entry_start_value + (LX_NOR_SECTOR_SIZE * sizeof(ULONG));
121
122
4/4
✓ Branch 7 → 8 taken 2601858 times.
✓ Branch 7 → 10 taken 1031112 times.
✓ Branch 8 → 9 taken 1243546 times.
✓ Branch 8 → 10 taken 1358312 times.
3632970 if ((flash_address_value >= cache_entry_start_value) && (flash_address_value < cache_entry_end_value))
123 {
124
125 /* Yes, we found the entry. */
126
127 /* Increment the accessed count. */
128 1243546 nor_flash -> lx_nor_flash_extended_cache[i].lx_nor_flash_extended_cache_entry_access_count++;
129
130 /* Calculate the offset into the cache entry. */
131 1243546 cache_offset = (flash_address_value - cache_entry_start_value) / sizeof(ULONG);
132
133 /* Copy the word from the cache. */
134 1243546 *destination = *(nor_flash -> lx_nor_flash_extended_cache[i].lx_nor_flash_extended_cache_entry_sector_memory + cache_offset);
135
136 /* Increment the number of cache hits. */
137 1243546 nor_flash -> lx_nor_flash_extended_cache_hits++;
138
139 /* Return success. */
140 1243546 return(LX_SUCCESS);
141 }
142 }
143
144 /* Determine if we have a new least used sector. */
145
2/2
✓ Branch 10 → 11 taken 1437304 times.
✓ Branch 10 → 13 taken 966814 times.
2404118 if (i != least_used_cache_entry)
146 {
147
148 /* Determine if this entry has a smaller accessed count. */
149 1437304 if (nor_flash -> lx_nor_flash_extended_cache[i].lx_nor_flash_extended_cache_entry_access_count <
150
2/2
✓ Branch 11 → 12 taken 494426 times.
✓ Branch 11 → 13 taken 942878 times.
1437304 nor_flash -> lx_nor_flash_extended_cache[least_used_cache_entry].lx_nor_flash_extended_cache_entry_access_count)
151 {
152
153 /* New least used entry. */
154 494426 least_used_cache_entry = i;
155 }
156 }
157 }
158
159 /* Now read in the sector into the cache. */
160 128066 base_address_value = (ULONG)(nor_flash -> lx_nor_flash_base_address);
161 128066 cache_offset = (flash_address_value - base_address_value) / sizeof(ULONG);
162 128066 cache_offset = cache_offset & ~((ULONG) (LX_NOR_SECTOR_SIZE-1));
163 128066 cache_entry_start = (ULONG *)(base_address_value + (cache_offset * sizeof(ULONG)));
164
165 /* Call the actual driver read function. */
166 #ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
167 16152 status = (nor_flash -> lx_nor_flash_driver_read)(nor_flash, cache_entry_start,
168 nor_flash -> lx_nor_flash_extended_cache[least_used_cache_entry].lx_nor_flash_extended_cache_entry_sector_memory,
169 LX_NOR_SECTOR_SIZE);
170 #else
171 111914 status = (nor_flash -> lx_nor_flash_driver_read)(cache_entry_start,
172 nor_flash -> lx_nor_flash_extended_cache[least_used_cache_entry].lx_nor_flash_extended_cache_entry_sector_memory,
173 LX_NOR_SECTOR_SIZE);
174 #endif
175
176 /* Determine if there was an error. */
177
1/2
✗ Branch 16 → 17 not taken.
✓ Branch 16 → 18 taken 128066 times.
128066 if (status != LX_SUCCESS)
178 {
179
180 /* Return the error to the caller. */
181 ✗ return(status);
182 }
183
184 /* Setup the cache entry. */
185 128066 nor_flash -> lx_nor_flash_extended_cache[least_used_cache_entry].lx_nor_flash_extended_cache_entry_sector_address = cache_entry_start;
186 128066 nor_flash -> lx_nor_flash_extended_cache[least_used_cache_entry].lx_nor_flash_extended_cache_entry_access_count = 0;
187 128066 nor_flash -> lx_nor_flash_extended_cache[least_used_cache_entry].lx_nor_flash_extended_cache_entry_valid = LX_TRUE;
188
189 /* Increment the number of cache misses. */
190 128066 nor_flash -> lx_nor_flash_extended_cache_misses++;
191
192 /* Decrement the number of cache hits, so that the increment that will happen next will be cancelled out. */
193 128066 nor_flash -> lx_nor_flash_extended_cache_hits--;
194
195
1/2
✓ Branch 18 → 19 taken 128066 times.
✗ Branch 18 → 20 not taken.
128066 } while (status == LX_SUCCESS);
196
197 /* Return success. */
198 ✗ return(LX_SUCCESS);
199 }
200 else
201 {
202
203 /* Call the actual driver read function. */
204 #ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
205 188913 status = (nor_flash -> lx_nor_flash_driver_read)(nor_flash, flash_address, destination, words);
206 #else
207 1643335 status = (nor_flash -> lx_nor_flash_driver_read)(flash_address, destination, words);
208 #endif
209
210 /* Return completion status. */
211 1832248 return(status);
212 }
213 #else
214 UINT status;
215
216
217 /* Call the actual driver read function. */
218 #ifdef LX_NOR_ENABLE_CONTROL_BLOCK_FOR_DRIVER_INTERFACE
219 status = (nor_flash -> lx_nor_flash_driver_read)(nor_flash, flash_address, destination, words);
220 #else
221 5624 status = (nor_flash -> lx_nor_flash_driver_read)(flash_address, destination, words);
222 #endif
223
224 /* Return completion status. */
225 5624 return(status);
226 #endif
227 }
228