From 1acbd6e560300a1227ce7582d48e44e75cc3ebf8 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Fri, 5 Feb 2021 18:23:10 +0100 Subject: [PATCH] cpu/native: add periph/flashpage implementation Add a simple RAM-backed flashpage implementation for native, to allow for easier testing of flashpage based applications / features. --- cpu/native/Kconfig | 2 ++ cpu/native/Makefile.features | 2 ++ cpu/native/include/cpu.h | 1 + cpu/native/include/cpu_conf.h | 26 +++++++++++++++ cpu/native/periph/flashpage.c | 62 +++++++++++++++++++++++++++++++++++ 5 files changed, 93 insertions(+) create mode 100644 cpu/native/periph/flashpage.c diff --git a/cpu/native/Kconfig b/cpu/native/Kconfig index 423a7b4c00..66d22218fc 100644 --- a/cpu/native/Kconfig +++ b/cpu/native/Kconfig @@ -14,6 +14,8 @@ config CPU_ARCH_NATIVE select HAS_LIBSTDCPP select HAS_PERIPH_CPUID select HAS_PERIPH_EEPROM + select HAS_PERIPH_FLASHPAGE + select HAS_PERIPH_FLASHPAGE_PAGEWISE select HAS_PERIPH_HWRNG select HAS_PERIPH_PM select HAS_PERIPH_PWM diff --git a/cpu/native/Makefile.features b/cpu/native/Makefile.features index a2e82ccce3..5761916aca 100644 --- a/cpu/native/Makefile.features +++ b/cpu/native/Makefile.features @@ -12,6 +12,8 @@ ifneq ($(DISABLE_LIBSTDCPP),1) endif FEATURES_PROVIDED += periph_cpuid FEATURES_PROVIDED += periph_eeprom +FEATURES_PROVIDED += periph_flashpage +FEATURES_PROVIDED += periph_flashpage_pagewise FEATURES_PROVIDED += periph_hwrng FEATURES_PROVIDED += periph_pm FEATURES_PROVIDED += periph_pwm diff --git a/cpu/native/include/cpu.h b/cpu/native/include/cpu.h index ff38639fd5..48740ff0c7 100644 --- a/cpu/native/include/cpu.h +++ b/cpu/native/include/cpu.h @@ -21,6 +21,7 @@ #define CPU_H #include +#include "cpu_conf.h" #ifdef __cplusplus extern "C" { diff --git a/cpu/native/include/cpu_conf.h b/cpu/native/include/cpu_conf.h index 4fa31791fb..c94cd898c9 100644 --- a/cpu/native/include/cpu_conf.h +++ b/cpu/native/include/cpu_conf.h @@ -60,6 +60,32 @@ extern "C" { # define CONFIG_GNRC_PKTBUF_SIZE (2048) #endif +/** + * @brief Native Flash emulation + * Use unusual parameters to trigger edge cases + * @{ + */ +#ifndef FLASHPAGE_SIZE +#define FLASHPAGE_SIZE (512) +#endif +#ifndef FLASHPAGE_NUMOF +#define FLASHPAGE_NUMOF (32) +#endif +#ifndef FLASHPAGE_WRITE_BLOCK_ALIGNMENT +#define FLASHPAGE_WRITE_BLOCK_ALIGNMENT (8) +#endif +#ifndef FLASHPAGE_WRITE_BLOCK_SIZE +#define FLASHPAGE_WRITE_BLOCK_SIZE (16) +#endif +#ifndef FLASHPAGE_ERASE_STATE +#define FLASHPAGE_ERASE_STATE (0x0) +#endif + +extern char _native_flash[FLASHPAGE_SIZE * FLASHPAGE_NUMOF]; + +#define CPU_FLASH_BASE ((uintptr_t)_native_flash) +/** @} */ + #ifdef __cplusplus } #endif diff --git a/cpu/native/periph/flashpage.c b/cpu/native/periph/flashpage.c new file mode 100644 index 0000000000..20f0492685 --- /dev/null +++ b/cpu/native/periph/flashpage.c @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2021 ML!PA Consulting GmbH + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup cpu_native + * @ingroup drivers_periph_flashpage + * @{ + * + * @file + * @brief Low-level flashpage driver emulation + * + * @author Benjamin Valentin + * @} + */ + +#include +#include + +#include "cpu.h" +#include "periph/flashpage.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + +char _native_flash[FLASHPAGE_SIZE * FLASHPAGE_NUMOF]; + +void flashpage_erase(unsigned page) +{ + assert(page < FLASHPAGE_NUMOF); + + DEBUG("%p: erase %u bytes\n", flashpage_addr(page), FLASHPAGE_SIZE); + + memset(flashpage_addr(page), FLASHPAGE_ERASE_STATE, FLASHPAGE_SIZE); +} + +static void _flash_write(uint8_t *dst, const char *src, size_t len) +{ + while (len--) { +#if FLASHPAGE_ERASE_STATE == 0x0 + *dst++ |= *src++; +#else + *dst++ &= *src++; +#endif + } +} + +void flashpage_write(void *target_addr, const void *data, size_t len) +{ + assert((uintptr_t)target_addr >= (uintptr_t)_native_flash); + assert((uintptr_t)target_addr + len <= (uintptr_t)_native_flash + sizeof(_native_flash)); + assert(!(len % FLASHPAGE_WRITE_BLOCK_SIZE)); + assert(!((unsigned)target_addr % FLASHPAGE_WRITE_BLOCK_ALIGNMENT)); + + DEBUG("%p: write %u bytes\n", target_addr, len); + + _flash_write(target_addr, data, len); +}