mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-04-14 10:07:39 +08:00
- move systick.c under chip specific sources - move do_jump into chip specific main.c as arch_do_jump - wrap flash writes to "arch_flash_write" and implement in chip specific main.c - add bootloader TOC check - sync image_toc.h with the version currently in use with old bootloader Signed-off-by: Jukka Laitinen <jukkax@ssrc.tii.ae>
161 lines
3.9 KiB
C
161 lines
3.9 KiB
C
/****************************************************************************
|
|
*
|
|
* Copyright (c) 2019 PX4 Development Team. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in
|
|
* the documentation and/or other materials provided with the
|
|
* distribution.
|
|
* 3. Neither the name PX4 nor the names of its contributors may be
|
|
* used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#include <string.h>
|
|
#include "flash_cache.h"
|
|
|
|
#include "hw_config.h"
|
|
|
|
#include <nuttx/progmem.h>
|
|
|
|
extern ssize_t arch_flash_write(size_t address, const void *buffer, size_t buflen);
|
|
|
|
flash_cache_line_t flash_cache[FC_NUMBER_LINES];
|
|
|
|
|
|
static inline void fcl_reset(flash_cache_line_t *fcl)
|
|
{
|
|
memset(fcl, 0xff, sizeof(flash_cache_line_t));
|
|
}
|
|
|
|
inline void fc_reset(void)
|
|
{
|
|
for (unsigned w = 0; w < FC_NUMBER_LINES; w++) {
|
|
fcl_reset(&flash_cache[w]);
|
|
}
|
|
|
|
flash_cache[0].start_address = APP_LOAD_ADDRESS;
|
|
}
|
|
|
|
static inline flash_cache_line_t *fc_line_select(uint32_t address)
|
|
{
|
|
for (unsigned w = 0; w < FC_NUMBER_LINES; w++) {
|
|
if (flash_cache[w].start_address == (address & FC_ADDRESS_MASK)) {
|
|
return &flash_cache[w];
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
inline int fc_is_dirty(flash_cache_line_t *fl)
|
|
{
|
|
return fl->index != FC_CLEAN;
|
|
}
|
|
|
|
|
|
int fc_flush(flash_cache_line_t *fl)
|
|
{
|
|
size_t bytes = (fl->index + 1) * sizeof(fl->words[0]);
|
|
size_t rv = arch_flash_write(fl->start_address, fl->words, bytes);
|
|
|
|
if (rv == bytes) {
|
|
rv = 0;
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
int fc_write(uint32_t address, uint32_t word)
|
|
{
|
|
flash_cache_line_t *fc = fc_line_select(address);
|
|
flash_cache_line_t *fc1 = &flash_cache[1];
|
|
uint32_t index = FC_ADDR2INDX(address);
|
|
int rv = 0;
|
|
|
|
if (fc == NULL && index == 0) {
|
|
fc = fc1;
|
|
fc->start_address = address;
|
|
}
|
|
|
|
if (fc) {
|
|
|
|
fc->words[index] = word;
|
|
|
|
// Are we back writing the first word?
|
|
|
|
if (fc == &flash_cache[0] && index == 0 && fc->index == 7) {
|
|
|
|
if (fc_is_dirty(fc1)) {
|
|
|
|
// write out last fragment of data
|
|
|
|
rv = fc_flush(fc1);
|
|
|
|
if (rv != 0) {
|
|
fcl_reset(fc1);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
rv = fc_flush(fc);
|
|
fcl_reset(fc);
|
|
return rv;
|
|
}
|
|
|
|
fc->index = index;
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
uint32_t fc_read(uint32_t address)
|
|
{
|
|
// Assume a cache miss read from FLASH memory
|
|
|
|
uint32_t rv = *(uint32_t *) address;
|
|
|
|
flash_cache_line_t *fc = fc_line_select(address);
|
|
|
|
if (fc) {
|
|
|
|
// Cache hit retrieve word from cache
|
|
|
|
uint32_t index = FC_ADDR2INDX(address);
|
|
rv = fc->words[index];
|
|
|
|
// Reading the last word in cache (not first words)
|
|
|
|
if (fc != &flash_cache[0] && index == FC_LAST_WORD) {
|
|
if (fc_flush(fc)) {
|
|
rv ^= 0xffffffff;
|
|
|
|
} else {
|
|
fcl_reset(fc);
|
|
}
|
|
}
|
|
}
|
|
|
|
return rv;
|
|
}
|