45 #include <px4_platform_common/defines.h> 46 #include <px4_platform_common/posix.h> 55 #include <nuttx/compiler.h> 56 #include <nuttx/progmem.h> 58 #if defined(CONFIG_ARCH_HAVE_PROGMEM) 68 typedef uint32_t h_magic_t;
69 typedef uint16_t h_size_t;
70 typedef uint16_t h_flag_t;
71 typedef uint16_t data_size_t;
73 typedef enum flash_config_t {
74 LargestBlock = 2 * 1024,
75 MagicSig = 0xaa553cc3,
79 typedef enum flash_flags_t {
81 MaskEntry = ~SizeMask,
82 BlankEntry = (h_flag_t)BlankSig,
83 ValidEntry = (0xa5ac & ~SizeMask),
94 #pragma GCC diagnostic push 95 #pragma GCC diagnostic ignored "-Wattributes" 96 typedef begin_packed_struct
struct flash_entry_header_t {
104 } end_packed_struct flash_entry_header_t;
105 #pragma GCC diagnostic pop 114 static uint8_t *working_buffer;
115 static uint16_t working_buffer_size;
116 static bool working_buffer_static;
118 static int last_erased;
125 .
n = {
'p',
'a',
'r',
'm'},
143 if (!working_buffer_static && working_buffer != NULL) {
144 free(working_buffer);
145 working_buffer = NULL;
146 working_buffer_size = 0;
166 static inline int blank_flash(uint32_t *pf)
168 return *pf == BlankSig;
186 static bool blank_check(flash_entry_header_t *pf,
190 uint32_t *pm = (uint32_t *) pf;
191 new_size /=
sizeof(uint32_t);
193 while (new_size-- && rv) {
194 if (!blank_flash(pm++)) {
218 static inline int valid_magic(h_magic_t *pm)
220 return *pm == MagicSig;
239 static inline int blank_magic(h_magic_t *pm)
241 return *pm == BlankSig;
258 static inline int erased_entry(flash_entry_header_t *fi)
260 return (fi->flag & MaskEntry) == ErasedEntry;
278 static inline int blank_entry(flash_entry_header_t *fi)
280 return fi->magic == BlankSig && fi->flag == BlankEntry;
298 static inline int valid_entry(flash_entry_header_t *fi)
300 return (fi->flag & MaskEntry) == ValidEntry;
318 static inline int entry_size_adjust(flash_entry_header_t *fi)
320 return fi->flag & SizeMask;
339 static inline flash_entry_header_t *next_entry(flash_entry_header_t *fi)
341 uint8_t *pb = (uint8_t *)fi;
342 return (flash_entry_header_t *) &pb[fi->size];
360 static inline uint8_t *entry_data(flash_entry_header_t *fi)
362 return ((uint8_t *)fi) +
sizeof(flash_entry_header_t);
380 static inline data_size_t entry_data_length(flash_entry_header_t *fi)
382 return fi->size - (
sizeof(flash_entry_header_t) + entry_size_adjust(fi));
401 static inline const uint8_t *entry_crc_start(flash_entry_header_t *fi)
403 return (
const uint8_t *)&fi->size;
422 static inline data_size_t entry_crc_length(flash_entry_header_t *fi)
424 return fi->size - offsetof(flash_entry_header_t, size);
444 for (
int s = 0; sector_map[s].
address; s++) {
446 h_magic_t *pmagic = (h_magic_t *) sector_map[s].address;
447 h_magic_t *pe = pmagic + (sector_map[s].
size /
sizeof(h_magic_t)) - 1;
452 while (pmagic != pe && !valid_magic(pmagic)) {
459 if (pmagic == pe) {
continue; }
463 flash_entry_header_t *pf = (flash_entry_header_t *) pmagic;
467 if (pf->crc == crc32(entry_crc_start(pf), entry_crc_length(pf))) {
471 if (valid_entry(pf) && pf->file_token.t == token.
t) {
480 pmagic = (h_magic_t *) pf;
484 if (blank_entry(pf)) {
517 static flash_entry_header_t *find_free(data_size_t required)
519 for (
int s = 0; sector_map[s].
address; s++) {
521 h_magic_t *pmagic = (h_magic_t *) sector_map[s].address;
522 h_magic_t *pe = pmagic + (sector_map[s].
size /
sizeof(h_magic_t)) - 1;
528 if (valid_magic(pmagic)) {
530 flash_entry_header_t *pf = (flash_entry_header_t *) pmagic;
534 if (pf->crc == crc32(entry_crc_start(pf), entry_crc_length(pf))) {
538 pmagic = ((uint32_t *) next_entry(pf));
546 if (blank_magic(pmagic)) {
548 flash_entry_header_t *pf = (flash_entry_header_t *) pmagic;
550 if (blank_entry(pf) && blank_check(pf, required)) {
555 }
while (++pmagic != pe);
581 for (
int s = 0; sector_map[s].
address; s++) {
582 if (current == §or_map[s]) {
583 if (sector_map[s + 1].address) {
590 return §or_map[s];
616 for (
int s = 0; sector_map[s].
address != 0; s++) {
617 uint8_t *pb = (uint8_t *) sector_map[s].address;
618 uint8_t *pe = pb + sector_map[s].
size - 1;
619 uint8_t *pc = (uint8_t *) current;
621 if (pc >= pb && pc <= pe) {
622 return §or_map[s];
650 ssize_t
block = up_progmem_getpage((
size_t)pf);
652 if (block > 0 && block == sm->
page) {
653 last_erased = sm->
page;
654 ssize_t size = up_progmem_eraseblock(block);
656 if (size < 0 || size != (ssize_t)sm->
size) {
680 static int erase_entry(flash_entry_header_t *pf)
682 h_flag_t
data = ErasedEntry;
683 size_t size =
sizeof(h_flag_t);
684 int rv = up_progmem_write((
size_t) &pf->flag, &data, size);
705 *pf,
size_t new_size)
708 uint8_t *psector_first = (uint8_t *) sm->
address;
709 uint8_t *psector_last = psector_first + sm->
size - 1;
710 uint8_t *pnext_end = (uint8_t *)(valid_magic((h_magic_t *)pf) ? next_entry(pf) : pf) + new_size;
712 if (pnext_end >= psector_first && pnext_end <= psector_last) {
750 flash_entry_header_t *pf = find_entry(token);
753 (*buffer) = entry_data(pf);
754 rv = entry_data_length(pf);
792 size_t total_size = buf_size +
sizeof(flash_entry_header_t);
793 size_t alignment =
sizeof(h_magic_t) - 1;
794 size_t size_adjust = ((total_size + alignment) & ~alignment) - total_size;
795 total_size += size_adjust;
799 flash_entry_header_t *pf = find_entry(token);
805 pf = find_free(total_size);
821 if (current_sector == 0) {
829 rv = erase_entry(pf);
845 current_sector = get_next_sector_descriptor(current_sector);
849 if (current_sector->
size < total_size) {
859 rv = erase_entry(pf);
865 pf = (flash_entry_header_t *) current_sector->
address;
868 if (!blank_check(pf, total_size)) {
869 rv = erase_sector(current_sector, pf);
873 flash_entry_header_t *pn = (flash_entry_header_t *)(buffer -
sizeof(flash_entry_header_t));
874 pn->magic = MagicSig;
875 pn->file_token.t = token.
t;
876 pn->flag = ValidEntry + size_adjust;
877 pn->size = total_size;
879 for (
size_t a = 0; a < size_adjust; a++) {
880 buffer[buf_size + a] = (uint8_t)BlankSig;
883 pn->crc = crc32(entry_crc_start(pn), entry_crc_length(pn));
884 rv = up_progmem_write((
size_t) pf, pn, pn->size);
885 int system_bytes = (
sizeof(flash_entry_header_t) + size_adjust);
887 if (rv >= system_bytes) {
925 if (!working_buffer_static) {
927 working_buffer_size = *buf_size +
sizeof(flash_entry_header_t);
928 working_buffer = malloc(working_buffer_size);
934 if (working_buffer == NULL) {
936 working_buffer_size = 0;
941 *buffer = &working_buffer[
sizeof(flash_entry_header_t)];
942 *buf_size = working_buffer_size -
sizeof(flash_entry_header_t);
943 memset(working_buffer, 0xff, working_buffer_size);
973 for (
int s = 0; sector_map[s].
address; s++) {
974 int sz = erase_sector(§or_map[s], (flash_entry_header_t *)sector_map[s].address);
980 rv += sector_map[s].
size;
1018 sector_map = fconfig;
1019 working_buffer_static = buffer != NULL;
1021 if (!working_buffer_static) {
1025 working_buffer = buffer;
1026 working_buffer_size = size;
1031 flash_entry_header_t *pf = find_entry(parameters_token);
1036 size_t total_size = size +
sizeof(flash_entry_header_t);
1037 size_t alignment =
sizeof(h_magic_t) - 1;
1038 size_t size_adjust = ((total_size + alignment) & ~alignment) - total_size;
1039 total_size += size_adjust;
1043 if (find_free(total_size) == NULL) {
1054 #if defined(FLASH_UNIT_TEST) 1057 {1, 16 * 1024, 0x08004000},
1058 {2, 16 * 1024, 0x08008000},
1064 uint8_t test_buf[32 * 1024];
1068 uint16_t largest_block = (32 * 1024) + 32;
1069 uint8_t *buffer = malloc(largest_block);
1073 for (
int t = 0; t <
sizeof(test_buf); t++) {
1074 test_buf[t] = (uint8_t) t;
1084 for (
int a = 0; a <= 4; a++) {
1086 memcpy(fbuffer, test_buf, a);
1092 if (read != written) {
1093 static volatile int j;
1100 for (
int a = 0; a <= 8; a++) {
1102 memcpy(fbuffer, test_buf, block);
1108 if (read != written) {
1109 static volatile int j;
__EXPORT const flash_file_token_t parameters_token
__EXPORT void parameter_flashfs_free(void)
static void read(bootloader_app_shared_t *pshared)
__EXPORT int parameter_flashfs_alloc(flash_file_token_t ft, uint8_t **buffer, size_t *buf_size)
__EXPORT int parameter_flashfs_init(sector_descriptor_t *fconfig, uint8_t *buffer, uint16_t size)
void test(enum LPS25H_BUS busid)
Perform some basic functional tests on the driver; make sure we can collect data from the sensor in p...
__EXPORT int parameter_flashfs_read(flash_file_token_t ft, uint8_t **buffer, size_t *buf_size)
__EXPORT int parameter_flashfs_write(flash_file_token_t ft, uint8_t *buffer, size_t buf_size)
uint8_t n[sizeof(flash_file_tokens_t)]
__EXPORT int parameter_flashfs_erase(void)