Skip to content

Commit 8700158

Browse files
0xc0170c1728p9
authored andcommitted
flash: add FlashIAP class
Flash IAP that provides erase/read/program to an internal API. It invokes flash HAL functions. FlashIAP checks for alignments for erase and program. HAL functions do not, to avoid duplication per target implementation.
1 parent bae0f97 commit 8700158

File tree

3 files changed

+306
-0
lines changed

3 files changed

+306
-0
lines changed

drivers/FlashIAP.cpp

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2017 ARM Limited
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
* SOFTWARE.
21+
*/
22+
23+
#include <string.h>
24+
#include "FlashIAP.h"
25+
#include "mbed_assert.h"
26+
27+
28+
#ifdef DEVICE_FLASH
29+
30+
namespace mbed {
31+
32+
SingletonPtr<PlatformMutex> FlashIAP::_mutex;
33+
34+
static inline bool is_aligned(uint32_t number, uint32_t alignment)
35+
{
36+
if ((number % alignment) != 0) {
37+
return false;
38+
} else {
39+
return true;
40+
}
41+
}
42+
43+
FlashIAP::FlashIAP()
44+
{
45+
46+
}
47+
48+
FlashIAP::~FlashIAP()
49+
{
50+
51+
}
52+
53+
int FlashIAP::init()
54+
{
55+
int ret = 0;
56+
_mutex->lock();
57+
if (flash_init(&_flash)) {
58+
ret = -1;
59+
}
60+
_mutex->unlock();
61+
return ret;
62+
}
63+
64+
int FlashIAP::deinit()
65+
{
66+
int ret = 0;
67+
_mutex->lock();
68+
if (flash_free(&_flash)) {
69+
ret = -1;
70+
}
71+
_mutex->unlock();
72+
return ret;
73+
}
74+
75+
76+
int FlashIAP::read(void *buffer, uint32_t addr, uint32_t size)
77+
{
78+
_mutex->lock();
79+
memcpy(buffer, (const void *)addr, size);
80+
_mutex->unlock();
81+
return 0;
82+
}
83+
84+
int FlashIAP::program(const void *buffer, uint32_t addr, uint32_t size)
85+
{
86+
uint32_t page_size = get_page_size();
87+
uint32_t current_sector_size = flash_get_sector_size(&_flash, addr);
88+
// addr and size should be aligned to page size, and multiple of page size
89+
// page program should not cross sector boundaries
90+
if (!is_aligned(addr, page_size) ||
91+
!is_aligned(size, page_size) ||
92+
(size < page_size) ||
93+
(((addr % current_sector_size) + size) > current_sector_size)) {
94+
return -1;
95+
}
96+
97+
int ret = 0;
98+
_mutex->lock();
99+
if (flash_program_page(&_flash, addr, (const uint8_t *)buffer, size)) {
100+
ret = -1;
101+
}
102+
_mutex->unlock();
103+
return ret;
104+
}
105+
106+
bool FlashIAP::is_aligned_to_sector(uint32_t addr, uint32_t size)
107+
{
108+
uint32_t current_sector_size = flash_get_sector_size(&_flash, addr);
109+
if (!is_aligned(size, current_sector_size) ||
110+
!is_aligned(addr, current_sector_size)) {
111+
return false;
112+
} else {
113+
return true;
114+
}
115+
}
116+
117+
int FlashIAP::erase(uint32_t addr, uint32_t size)
118+
{
119+
uint32_t current_sector_size = 0UL;
120+
121+
if (!is_aligned_to_sector(addr, size)) {
122+
return -1;
123+
}
124+
125+
int32_t ret = 0;
126+
_mutex->lock();
127+
while (size) {
128+
ret = flash_erase_sector(&_flash, addr);
129+
if (ret != 0) {
130+
ret = -1;
131+
break;
132+
}
133+
current_sector_size = flash_get_sector_size(&_flash, addr);
134+
if (!is_aligned_to_sector(addr, size)) {
135+
ret = -1;
136+
break;
137+
}
138+
size -= current_sector_size;
139+
addr += current_sector_size;
140+
}
141+
_mutex->unlock();
142+
return ret;
143+
}
144+
145+
uint32_t FlashIAP::get_page_size() const
146+
{
147+
return flash_get_page_size(&_flash);
148+
}
149+
150+
uint32_t FlashIAP::get_sector_size(uint32_t addr) const
151+
{
152+
return flash_get_sector_size(&_flash, addr);
153+
}
154+
155+
uint32_t FlashIAP::get_flash_start() const
156+
{
157+
return flash_get_start_address(&_flash);
158+
}
159+
160+
uint32_t FlashIAP::get_flash_size() const
161+
{
162+
return flash_get_size(&_flash);
163+
}
164+
165+
}
166+
167+
#endif

drivers/FlashIAP.h

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2017 ARM Limited
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
* SOFTWARE.
21+
*/
22+
#ifndef MBED_FLASHIAP_H
23+
#define MBED_FLASHIAP_H
24+
25+
#ifdef DEVICE_FLASH
26+
27+
#include "flash_api.h"
28+
#include "platform/SingletonPtr.h"
29+
#include "platform/PlatformMutex.h"
30+
31+
namespace mbed {
32+
33+
/** \addtogroup drivers */
34+
/** @{*/
35+
36+
/** Flash IAP driver. It invokes flash HAL functions.
37+
*
38+
* Note Synchronization level: Thread safe
39+
*/
40+
class FlashIAP {
41+
public:
42+
FlashIAP();
43+
~FlashIAP();
44+
45+
/** Initialize a flash IAP device
46+
*
47+
* Should be called once per lifetime of the object.
48+
* @return 0 on success or a negative error code on failure
49+
*/
50+
int init();
51+
52+
/** Deinitialize a flash IAP device
53+
*
54+
* @return 0 on success or a negative error code on failure
55+
*/
56+
int deinit();
57+
58+
/** Read data from a flash device.
59+
*
60+
* This method invokes memcpy - reads number of bytes from the address
61+
*
62+
* @param buffer Buffer to write to
63+
* @param addr Flash address to begin reading from
64+
* @param size Size to read in bytes
65+
* @return 0 on success, negative error code on failure
66+
*/
67+
int read(void *buffer, uint32_t addr, uint32_t size);
68+
69+
/** Program data to pages
70+
*
71+
* The sectors must have been erased prior to being programmed
72+
*
73+
* @param buffer Buffer of data to be written
74+
* @param addr Address of a page to begin writing to, must be a multiple of program and sector sizes
75+
* @param size Size to write in bytes, must be a multiple of program and sector sizes
76+
* @return 0 on success, negative error code on failure
77+
*/
78+
int program(const void *buffer, uint32_t addr, uint32_t size);
79+
80+
/** Erase sectors
81+
*
82+
* The state of an erased sector is undefined until it has been programmed
83+
*
84+
* @param addr Address of a sector to begin erasing, must be a multiple of the sector size
85+
* @param size Size to erase in bytes, must be a multiple of the sector size
86+
* @return 0 on success, negative error code on failure
87+
*/
88+
int erase(uint32_t addr, uint32_t size);
89+
90+
/** Get the sector size at the defined address
91+
*
92+
* Sector size might differ at address ranges.
93+
* An example <0-0x1000, sector size=1024; 0x10000-0x20000, size=2048>
94+
*
95+
* @param addr Address of or inside the sector to query
96+
* @return Size of a sector in bytes or MBED_FLASH_INVALID_SIZE if not mapped
97+
*/
98+
uint32_t get_sector_size(uint32_t addr) const;
99+
100+
/** Get the flash start address
101+
*
102+
* @return Flash start address
103+
*/
104+
uint32_t get_flash_start() const;
105+
106+
/** Get the flash size
107+
*
108+
* @return Flash size
109+
*/
110+
uint32_t get_flash_size() const;
111+
112+
/** Get the program page size
113+
*
114+
* @return Size of a program page in bytes
115+
*/
116+
uint32_t get_page_size() const;
117+
118+
private:
119+
120+
/** Check if address and size are aligned to a sector
121+
*
122+
* @param addr Address of block to check for alignment
123+
* @param size Size of block to check for alignment
124+
* @return true if the block is sector aligned, false otherwise
125+
*/
126+
bool is_aligned_to_sector(uint32_t addr, uint32_t size);
127+
128+
flash_t _flash;
129+
static SingletonPtr<PlatformMutex> _mutex;
130+
};
131+
132+
} /* namespace mbed */
133+
134+
#endif /* DEVICE_FLASH */
135+
136+
#endif /* MBED_FLASHIAP_H */
137+
138+
/** @}*/

mbed.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
#include "drivers/Ethernet.h"
8282
#include "drivers/CAN.h"
8383
#include "drivers/RawSerial.h"
84+
#include "drivers/FlashIAP.h"
8485

8586
// mbed Internal components
8687
#include "drivers/Timer.h"

0 commit comments

Comments
 (0)