Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added example demonstrating reading and writing from and to flash memory #196

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions examples/stm32/f3/stm32f3-discovery/flash/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
##
## This file is part of the libopencm3 project.
##
## Copyright (C) 2019 Roel Gerrits <[email protected]>
##
## 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 <http://www.gnu.org/licenses/>.
##

BINARY = flash

# Note: in this example we use a custom linker script!
LDSCRIPT = stm32f3-discovery.ld

include ../../Makefile.include

20 changes: 20 additions & 0 deletions examples/stm32/f3/stm32f3-discovery/flash/README.md
Original file line number Diff line number Diff line change
@@ -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.

77 changes: 77 additions & 0 deletions examples/stm32/f3/stm32f3-discovery/flash/flash.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2019 Roel Gerrits <[email protected]>
*
* 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 <http://www.gnu.org/licenses/>.
*/

#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/flash.h>

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;
}

57 changes: 57 additions & 0 deletions examples/stm32/f3/stm32f3-discovery/flash/stm32f3-discovery.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2019 Roel Gerrits <[email protected]>
*
* 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 <http://www.gnu.org/licenses/>.
*/

/* 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