Rtos API example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers FlashIAP.cpp Source File

FlashIAP.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2017 ARM Limited
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a copy
00005  * of this software and associated documentation files (the "Software"), to deal
00006  * in the Software without restriction, including without limitation the rights
00007  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00008  * copies of the Software, and to permit persons to whom the Software is
00009  * furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included in
00012  * all copies or substantial portions of the Software.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00019  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
00020  * SOFTWARE.
00021  */
00022 
00023 #include <string.h>
00024 #include "FlashIAP.h"
00025 #include "mbed_assert.h"
00026 
00027 
00028 #ifdef DEVICE_FLASH
00029 
00030 namespace mbed {
00031 
00032 SingletonPtr<PlatformMutex>  FlashIAP::_mutex;
00033 
00034 static inline bool is_aligned(uint32_t number, uint32_t alignment)
00035 {
00036     if ((number % alignment) != 0) {
00037         return false;
00038     } else {
00039         return true;
00040     }
00041 }
00042 
00043 FlashIAP::FlashIAP()
00044 {
00045 
00046 }
00047 
00048 FlashIAP::~FlashIAP()
00049 {
00050 
00051 }
00052 
00053 int FlashIAP::init()
00054 {
00055     int ret = 0;
00056     _mutex->lock();
00057     if (flash_init(&_flash)) {
00058         ret = -1;
00059     }
00060     _mutex->unlock();
00061     return ret;
00062 }
00063 
00064 int FlashIAP::deinit()
00065 {
00066     int ret = 0;
00067     _mutex->lock();
00068     if (flash_free(&_flash)) {
00069         ret = -1;
00070     }
00071     _mutex->unlock();
00072     return ret;
00073 }
00074 
00075 
00076 int FlashIAP::read(void *buffer, uint32_t addr, uint32_t size)
00077 {
00078     int32_t ret = -1;
00079     _mutex->lock();
00080     ret = flash_read(&_flash, addr, (uint8_t *) buffer, size);
00081     _mutex->unlock();
00082     return ret;
00083 }
00084 
00085 int FlashIAP::program(const void *buffer, uint32_t addr, uint32_t size)
00086 {
00087     uint32_t page_size = get_page_size();
00088     uint32_t current_sector_size = flash_get_sector_size(&_flash, addr);
00089     // addr and size should be aligned to page size, and multiple of page size
00090     // page program should not cross sector boundaries
00091     if (!is_aligned(addr, page_size) ||
00092         !is_aligned(size, page_size) ||
00093         (size < page_size) ||
00094         (((addr % current_sector_size) + size) > current_sector_size)) {
00095         return -1;
00096     }
00097 
00098     int ret = 0;
00099     _mutex->lock();
00100     if (flash_program_page(&_flash, addr, (const uint8_t *)buffer, size)) {
00101         ret = -1;
00102     }
00103     _mutex->unlock();
00104     return ret;
00105 }
00106 
00107 bool FlashIAP::is_aligned_to_sector(uint32_t addr, uint32_t size)
00108 {
00109     uint32_t current_sector_size = flash_get_sector_size(&_flash, addr);
00110     if (!is_aligned(size, current_sector_size) ||
00111         !is_aligned(addr, current_sector_size)) {
00112         return false;
00113     } else {
00114         return true;
00115     }
00116 }
00117 
00118 int FlashIAP::erase(uint32_t addr, uint32_t size)
00119 {
00120     uint32_t current_sector_size = 0UL;
00121 
00122     if (!is_aligned_to_sector(addr, size)) {
00123         return -1;
00124     }
00125 
00126     int32_t ret = 0;
00127     _mutex->lock();
00128     while (size) {
00129         ret = flash_erase_sector(&_flash, addr);
00130         if (ret != 0) {
00131             ret = -1;
00132             break;
00133         }
00134         current_sector_size = flash_get_sector_size(&_flash, addr);
00135         if (!is_aligned_to_sector(addr, size)) {
00136             ret = -1;
00137             break;
00138         }
00139         size -= current_sector_size;
00140         addr += current_sector_size;
00141     }
00142     _mutex->unlock();
00143     return ret;
00144 }
00145 
00146 uint32_t FlashIAP::get_page_size() const
00147 {
00148     return flash_get_page_size(&_flash);
00149 }
00150 
00151 uint32_t FlashIAP::get_sector_size(uint32_t addr) const
00152 {
00153     return flash_get_sector_size(&_flash, addr);
00154 }
00155 
00156 uint32_t FlashIAP::get_flash_start() const
00157 {
00158     return flash_get_start_address(&_flash);
00159 }
00160 
00161 uint32_t FlashIAP::get_flash_size() const
00162 {
00163     return flash_get_size(&_flash);
00164 }
00165 
00166 }
00167 
00168 #endif