GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lx_nor_flash_sector_release.c Lines: 17 25 68.0 %
Date: 2026-03-06 18:45:40 Branches: 5 10 50.0 %

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
104
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
    tx_mutex_get(&nor_flash -> lx_nor_flash_mutex, TX_WAIT_FOREVER);
96
#endif
97
98
    /* Increment the number of read requests.  */
99
104
    nor_flash -> lx_nor_flash_read_requests++;
100
101
    /* See if we can find the sector in the current mapping.  */
102
104
    _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
104
    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
        mapping_entry =  *(mapping_address);
115
#else
116
102
        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
102
        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
102
        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
102
        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
102
        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
        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
            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
102
        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
        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
        if (block < nor_flash -> lx_nor_flash_extended_cache_obsolete_count_max_block)
183
        {
184
185
            /* Increment the obsolete count for this block.  */
186
            nor_flash -> lx_nor_flash_extended_cache_obsolete_count[block] ++;
187
        }
188
#endif
189
190
        /* Decrement the number of mapped physical sectors.  */
191
102
        nor_flash -> lx_nor_flash_mapped_physical_sectors--;
192
193
        /* Ensure the sector mapping cache no longer has this sector.  */
194
102
        _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
102
        i =  0;
198
102
        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
102
        status =  LX_SUCCESS;
218
    }
219
    else
220
    {
221
222
        /* Could not find the logical sector.  */
223
2
        status =  LX_SECTOR_NOT_FOUND;
224
    }
225
226
#ifdef LX_THREAD_SAFE_ENABLE
227
228
    /* Release the thread safe mutex.  */
229
    tx_mutex_put(&nor_flash -> lx_nor_flash_mutex);
230
#endif
231
232
    /* Return status.  */
233
104
    return(status);
234
}
235