Add non-volatile memory support to STM

This commit is contained in:
jgillick 2020-03-22 02:22:59 -07:00
parent fa95c1d09f
commit d76b76cb1d
8 changed files with 286 additions and 6 deletions

View File

@ -0,0 +1,118 @@
/*
GNU linker script for STM32F411 via Micropython
*/
/* Specify the memory areas */
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K /* entire flash */
FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 16K /* sector 0 */
FLASH_FS (rx) : ORIGIN = 0x08004000, LENGTH = 32K /* sectors 1,2 are 16K */
FLASH_NVM (rwx) : ORIGIN = 0x0800C000, LENGTH = 16K /* sector 3 is 16K */
FLASH_TEXT (rx) : ORIGIN = 0x08010000, LENGTH = 448K /* sector 4 is 64K, sectors 5,6,7 are 128K */
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
}
/* produce a link error if there is not this amount of RAM for these sections */
_minimum_stack_size = 2K;
_minimum_heap_size = 16K;
/* Define the top end of the stack. The stack is full descending so begins just
above last byte of RAM. Note that EABI requires the stack to be 8-byte
aligned for a call. */
_estack = ORIGIN(RAM) + LENGTH(RAM);
/* RAM extents for the garbage collector */
_ram_start = ORIGIN(RAM);
_ram_end = ORIGIN(RAM) + LENGTH(RAM);
_heap_start = _ebss; /* heap starts just after statically allocated memory */
_heap_end = 0x2001c000; /* tunable */
ENTRY(Reset_Handler)
/* define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
/* This first flash block is 16K annd the isr vectors only take up
about 400 bytes. Micropython pads this with files, but this didn't
work with the size of Circuitpython's ff object. */
. = ALIGN(4);
} >FLASH_ISR
/* Non-volitile memory */
.nvm_data :
{
. = ALIGN(4);
KEEP(*(.nvm_data))
. = ALIGN(4);
} >FLASH_NVM
/* The program code and other data goes into FLASH */
.text :
{
. = ALIGN(4);
*(.text*) /* .text* sections (code) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
/* *(.glue_7) */ /* glue arm to thumb code */
/* *(.glue_7t) */ /* glue thumb to arm code */
. = ALIGN(4);
_etext = .; /* define a global symbol at end of code */
} >FLASH_TEXT
/* used by the startup to initialize data */
_sidata = LOADADDR(.data);
/* This is the initialized data section
The program executes knowing that the data is in the RAM
but the loader puts the initial values in the FLASH (inidata).
It is one task of the startup to copy the initial values from FLASH to RAM. */
.data :
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */
*(.data*) /* .data* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */
} >RAM AT> FLASH_TEXT
/* Uninitialized data section */
.bss :
{
. = ALIGN(4);
_sbss = .; /* define a global symbol at bss start; used by startup code */
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end; used by startup code and GC */
} >RAM
/* this is to define the start of the heap, and make sure we have a minimum size */
.heap :
{
. = ALIGN(4);
. = . + _minimum_heap_size;
. = ALIGN(4);
} >RAM
/* this just checks there is enough RAM for the stack */
.stack :
{
. = ALIGN(4);
. = . + _minimum_stack_size;
. = ALIGN(4);
} >RAM
.ARM.attributes 0 : { *(.ARM.attributes) }
}

View File

@ -26,17 +26,18 @@
#define MICROPY_HW_BOARD_NAME "THUNDERPACK"
#define MICROPY_HW_MCU_NAME "STM32F411CE"
#define FLASH_SIZE (0x80000)
#define FLASH_PAGE_SIZE (0x4000)
#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x2000 - 0xC000)
#define FLASH_SIZE (0x80000)
#define FLASH_PAGE_SIZE (0x4000)
#define CIRCUITPY_INTERNAL_NVM_SIZE (0x4000)
#define CIRCUITPY_INTERNAL_NVM_START_ADDR (0x0800C000)
#define CIRCUITPY_INTERNAL_NVM_SECTOR FLASH_SECTOR_3
#define BOARD_FLASH_SIZE (FLASH_SIZE - CIRCUITPY_INTERNAL_NVM_SIZE- 0x2000 - 0xC000)
#define BOARD_OSC_DIV (24)
#define BOARD_OVERWRITE_SWD (1)
#define BOARD_NO_VBUS_SENSE (1)
// Status LEDs
#define MICROPY_HW_LED_TX (&pin_PA00)
#define MICROPY_HW_LED_RX (&pin_PB01)
#define MICROPY_HW_LED_STATUS (&pin_PA02)
#define DEFAULT_I2C_BUS_SCL (&pin_PB06)

View File

@ -7,12 +7,14 @@ USB_DEVICES = "CDC,MSC"
INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = NONE
CIRCUITPY_NVM = 1
MCU_SERIES = m4
MCU_VARIANT = stm32f4
MCU_SUB_VARIANT = stm32f411xe
MCU_PACKAGE = 48
CMSIS_MCU = STM32F411xE
LD_FILE = boards/STM32F411VETx_FLASH.ld
LD_FILE = boards/STM32F411VETx_nvm_FLASH.ld
STARTUP_FILE = startup_stm32f411xe.s

View File

@ -32,6 +32,7 @@
#include "common-hal/microcontroller/Pin.h"
#include "common-hal/microcontroller/Processor.h"
#include "shared-bindings/nvm/ByteArray.h"
#include "shared-bindings/microcontroller/__init__.h"
#include "shared-bindings/microcontroller/Pin.h"
#include "shared-bindings/microcontroller/Processor.h"
@ -109,6 +110,17 @@ const mcu_processor_obj_t common_hal_mcu_processor_obj = {
},
};
#if CIRCUITPY_INTERNAL_NVM_SIZE > 0
// The singleton nvm.ByteArray object.
const nvm_bytearray_obj_t common_hal_mcu_nvm_obj = {
.base = {
.type = &nvm_bytearray_type,
},
.len = NVM_BYTEARRAY_BUFFER,
.start_address = (uint8_t*) (CIRCUITPY_INTERNAL_NVM_START_ADDR)
};
#endif
STATIC const mp_rom_map_elem_t mcu_pin_globals_table[] = {
#if MCU_PACKAGE >= 100
{ MP_ROM_QSTR(MP_QSTR_PE02), MP_ROM_PTR(&pin_PE02) },

View File

@ -0,0 +1,73 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "common-hal/nvm/ByteArray.h"
#include "stm32f4xx_hal.h"
#include "supervisor/shared/stack.h"
#include <stdint.h>
#include <string.h>
uint32_t common_hal_nvm_bytearray_get_length(nvm_bytearray_obj_t *self) {
return self->len;
}
bool common_hal_nvm_bytearray_set_bytes(nvm_bytearray_obj_t *self,
uint32_t start_index, uint8_t* values, uint32_t len) {
// Copy flash to buffer
uint8_t buffer[self->len];
memcpy(buffer, self->start_address, self->len);
// Set bytes in buffer
memmove(buffer + start_index, values, len);
// Erase flash sector
HAL_FLASH_Unlock();
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGSERR );
FLASH_Erase_Sector(CIRCUITPY_INTERNAL_NVM_SECTOR, VOLTAGE_RANGE_3);
// Write bytes to flash
uint32_t i;
uint32_t flash_addr = (uint32_t)self->start_address;
for (i = 0; i < self->len; i++, flash_addr++) {
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, flash_addr, buffer[i]) != HAL_OK) {
HAL_FLASH_Lock();
return false;
}
}
// Finish up
HAL_FLASH_Lock();
return true;
}
// NVM memory is memory mapped so reading it is easy.
void common_hal_nvm_bytearray_get_bytes(nvm_bytearray_obj_t *self,
uint32_t start_index, uint32_t len, uint8_t* values) {
memcpy(values, self->start_address + start_index, len);
}

View File

@ -0,0 +1,43 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MICROPY_INCLUDED_STM32_COMMON_HAL_NVM_BYTEARRAY_H
#define MICROPY_INCLUDED_STM32_COMMON_HAL_NVM_BYTEARRAY_H
#include "py/obj.h"
// STM flash is saved in sectors (not pages), at a minimum size of 16k.
// To limit the RAM usage during writing, we want to set a smaller
// maximum value.
#define NVM_BYTEARRAY_BUFFER 512
typedef struct {
mp_obj_base_t base;
uint8_t* start_address;
uint32_t len;
} nvm_bytearray_obj_t;
#endif // MICROPY_INCLUDED_STM32_COMMON_HAL_NVM_BYTEARRAY_H

View File

@ -0,0 +1,27 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// No nvm module functions.

View File

@ -39,8 +39,12 @@
#ifdef STM32F411xE
#define STM32_FLASH_SIZE 0x80000 //512KiB
#ifdef CIRCUITPY_NVM
#define INTERNAL_FLASH_FILESYSTEM_SIZE 0x8000 //32KiB
#else
#define INTERNAL_FLASH_FILESYSTEM_SIZE 0xC000 //48KiB
#endif
#endif
#ifdef STM32F412Zx
#define STM32_FLASH_SIZE 0x100000 //1MB