diff --git a/examples/stm32/f3/stm32f3-discovery/flash/Makefile b/examples/stm32/f3/stm32f3-discovery/flash/Makefile new file mode 100644 index 00000000..9b61fb18 --- /dev/null +++ b/examples/stm32/f3/stm32f3-discovery/flash/Makefile @@ -0,0 +1,26 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2019 Roel Gerrits +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +BINARY = flash + +# Note: in this example we use a custom linker script! +LDSCRIPT = stm32f3-discovery.ld + +include ../../Makefile.include + diff --git a/examples/stm32/f3/stm32f3-discovery/flash/README.md b/examples/stm32/f3/stm32f3-discovery/flash/README.md new file mode 100644 index 00000000..0f194c1f --- /dev/null +++ b/examples/stm32/f3/stm32f3-discovery/flash/README.md @@ -0,0 +1,20 @@ +# README + +Example code that demonstrates the reading and writing of flash +at runtime. + +For this we add a custom section in the linker file that defines +which section of flash we will use to write to. + +The linker file will provide the C code with a variable that is used +to get the address of our flash section. + +The example will read the variable from flash, write it to the LED's, +then it will increase the counter and write it back to flash. + +This will cause the LED pattern to change at every reset or power cycle. + +NOTE: The flash memory in stm32 chips has a limited durability of +about 10.000 erase/write cycles, after which it may become unreliable. +Keep this in mind when designing your application. + diff --git a/examples/stm32/f3/stm32f3-discovery/flash/flash.c b/examples/stm32/f3/stm32f3-discovery/flash/flash.c new file mode 100644 index 00000000..e4ca27a0 --- /dev/null +++ b/examples/stm32/f3/stm32f3-discovery/flash/flash.c @@ -0,0 +1,77 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2019 Roel Gerrits + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#include +#include +#include + +static void gpio_setup(void) +{ + /* Enable GPIOE clock. */ + rcc_periph_clock_enable(RCC_GPIOE); + + /* Set GPIO12 (in GPIO port E) to 'output push-pull'. */ + gpio_mode_setup(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, + GPIO8 | GPIO9 | GPIO10 | GPIO11 | + GPIO12 | GPIO13 | GPIO14 | GPIO15); +} + + +/* + * This variable is made available by the linker script + * it's address is the address where the my_flash section starts + */ +extern uint8_t _my_flash_start; + + +int main(void) +{ + uint16_t counter; + + gpio_setup(); + + /* Read value from flash, for reading we can just read from + * the address as with any other variable. Writing requires a + * little more effort as we will see later on. + */ + counter = _my_flash_start; + + /* Write the counter's binary value to the LED's on port E */ + gpio_set(GPIOE, (counter & 0xff) << 8); + + /* In order to write to flash we have to unlock it first */ + flash_unlock(); + + /* Flash memory can only be written if it's been erased first + * so let's do that now */ + uint32_t my_flash_addr = (uint32_t) &_my_flash_start; + flash_erase_page(my_flash_addr); + + /* Increment counter and write it to flash */ + counter++; + flash_program_half_word(my_flash_addr, counter); + + + while (1) { + /* do absolutely nothing */ + } + + return 0; +} + diff --git a/examples/stm32/f3/stm32f3-discovery/flash/stm32f3-discovery.ld b/examples/stm32/f3/stm32f3-discovery/flash/stm32f3-discovery.ld new file mode 100644 index 00000000..ec9692e9 --- /dev/null +++ b/examples/stm32/f3/stm32f3-discovery/flash/stm32f3-discovery.ld @@ -0,0 +1,57 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2019 Roel Gerrits + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for ST STM32F3DISCOVERY (STM32F303VC, 256K flash, + * 48K RAM (Of which 8kB are CCM RAM and 40KB are SRAM). */ + +/* Define memory regions. */ +MEMORY +{ + /* NOTE: we decrease the length of the rom section with 2K + * as to make space for our custom flash section! */ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 254K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 40K + + /* reserve the last page of memory for permanent storage functionality */ + my_flash (rw) : ORIGIN = 0x08000000 + 254K, LENGTH = 2K +} + + + +/* + * Define a custom flash section. + * This is done for the single purpose of obtaining a + * variable (_my_flash_start) that is located at the start of + * the my_flash section. This variable can then be used in code + * to learn the the start address of that flash section, + * + * &_my_flash_start will be equal to 0x803f800 in this case. +*/ +SECTIONS +{ + .my_flash : + { + _my_flash_start = .; + } > my_flash +} + + +/* Include the common ld script. */ +INCLUDE cortex-m-generic.ld +