Skip to content

Commit

Permalink
samples: olimex_stm32_e407: CCM usage example
Browse files Browse the repository at this point in the history
Add an example program showing the use of the STM32 CCM.

Signed-off-by: Erwin Rol <[email protected]>
  • Loading branch information
lowlander authored and galak committed Feb 13, 2018
1 parent 3f3466a commit 6c0e69e
Show file tree
Hide file tree
Showing 6 changed files with 333 additions and 0 deletions.
4 changes: 4 additions & 0 deletions samples/boards/olimex_stm32_e407/ccm/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
project(NONE)

target_sources(app PRIVATE src/main.c)
146 changes: 146 additions & 0 deletions samples/boards/olimex_stm32_e407/ccm/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
.. _olimex_stm32_e407_ccm:

Olimex STM32-E407 CCM example
#############################

Overview
********

Show usage of the Core Coupled Memory (CCM) that is available
on several STM32 devices. The very important difference with
normal RAM is that CCM can not be used for DMA.

By prefixing a variable with __ccm_data_section, __ccm_bss_section,
or __ccm_noinit_section those variables are placed in the CCM.

The __ccm_data_section prefix should be used for variables that
are initialized. Like the normal data section the initial
values take up space in the FLASH image.

The __ccm_bss_section prefix should be used for variables that
should be initialized to 0. Like the normal bss section they
do not take up FLASH space.

The __ccm_noinit_section prefix should be used for variables
that don't need to have a defined initial value (for example
buffers that will receive data). Compared to bss or data the
kernel does not need to initialize the noinit section making
the startup slightly faster.

To add CCM support to a board, add the following line to the
board's DTS file ``chosen`` section:

.. code-block:: console
zephyr,ccm = &ccm0;
For example the olimex STM32 E407 DTS file looks like this:

.. literalinclude:: ../../../../boards/arm/olimex_stm32_e407/olimex_stm32_e407.dts
:linenos:

Building
********

.. code-block:: console
$ cd samples/boards/olimex_stm32_e407/ccm
$ mkdir build
$ cmake ../ -DBOARD=olimex_stm32_e407
$ make
Running
*******

The first time the example is run after power on, the output will
look like this:

.. code-block:: console
***** BOOTING ZEPHYR OS v1.10.99 - BUILD: Jan 14 2018 09:32:46 *****
CCM (Core Coupled Memory) usage example
The total used CCM area : [0x10000000, 0x10000021)
Zero initialized BSS area : [0x10000000, 0x10000007)
Unitialized NOINIT area : [0x10000008, 0x10000013)
Initialised DATA area : [0x10000014, 0x10000021)
Start of DATA in FLASH : 0x08003940
Checking initial variable values: ... PASSED
Initial variable values:
ccm_data_var_8 addr: 0x10000014 value: 0x12
ccm_data_var_16 addr: 0x10000016 value: 0x3456
ccm_data_var_32 addr: 0x10000018 value: 0x789abcde
ccm_data_array addr: 0x1000001c size: 5 value:
0x11 0x22 0x33 0x44 0x55
ccm_bss_array addr: 0x10000000 size: 7 value:
0x00 0x00 0x00 0x00 0x00 0x00 0x00
ccm_noinit_array addr: 0x10000008 size: 11 value:
0xa9 0x99 0xba 0x90 0xe1 0x2a 0xba 0x93 0x4c 0xfe 0x4b
Variable values after writing:
ccm_data_var_8 addr: 0x10000014 value: 0xed
ccm_data_var_16 addr: 0x10000016 value: 0xcba9
ccm_data_var_32 addr: 0x10000018 value: 0x87654321
ccm_data_array addr: 0x1000001c size: 5 value:
0xaa 0xaa 0xaa 0xaa 0xaa
ccm_bss_array addr: 0x10000000 size: 7 value:
0xbb 0xbb 0xbb 0xbb 0xbb 0xbb 0xbb
ccm_noinit_array addr: 0x10000008 size: 11 value:
0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc
Example end
First, each CCM section is listed with its address and size. Next, some usage
examples are shown. Note that the ``noinit`` section holds variables with
uninitialized data. After writing to the variables, they all should hold the
values shown above.

When the board is reset (without power-cycling), the output looks like this:

.. code-block:: console
***** BOOTING ZEPHYR OS v1.10.99 - BUILD: Jan 14 2018 09:32:46 *****
CCM (Core Coupled Memory) usage example
The total used CCM area : [0x10000000, 0x10000021)
Zero initialized BSS area : [0x10000000, 0x10000007)
Unitialized NOINIT area : [0x10000008, 0x10000013)
Initialised DATA area : [0x10000014, 0x10000021)
Start of DATA in FLASH : 0x08003940
Checking initial variable values: ... PASSED
Initial variable values:
ccm_data_var_8 addr: 0x10000014 value: 0x12
ccm_data_var_16 addr: 0x10000016 value: 0x3456
ccm_data_var_32 addr: 0x10000018 value: 0x789abcde
ccm_data_array addr: 0x1000001c size: 5 value:
0x11 0x22 0x33 0x44 0x55
ccm_bss_array addr: 0x10000000 size: 7 value:
0x00 0x00 0x00 0x00 0x00 0x00 0x00
ccm_noinit_array addr: 0x10000008 size: 11 value:
0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc
Variable values after writing:
ccm_data_var_8 addr: 0x10000014 value: 0xed
ccm_data_var_16 addr: 0x10000016 value: 0xcba9
ccm_data_var_32 addr: 0x10000018 value: 0x87654321
ccm_data_array addr: 0x1000001c size: 5 value:
0xaa 0xaa 0xaa 0xaa 0xaa
ccm_bss_array addr: 0x10000000 size: 7 value:
0xbb 0xbb 0xbb 0xbb 0xbb 0xbb 0xbb
ccm_noinit_array addr: 0x10000008 size: 11 value:
0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc 0xcc
Example end
The difference with the first run is that the ccm_noinit section still has the
values from the last write. It is important to notice that this is not guaranteed,
it still should be considered uninitialized leftover data.

17 changes: 17 additions & 0 deletions samples/boards/olimex_stm32_e407/ccm/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
CONFIG_BOOT_BANNER=y
CONFIG_CONSOLE=y
CONFIG_CONSOLE_INPUT_MAX_LINE_LEN=128
CONFIG_CONSOLE_HAS_DRIVER=y
CONFIG_CONSOLE_HANDLER=y
CONFIG_UART_CONSOLE=y
CONFIG_SERIAL=y
CONFIG_UART_STM32=y
CONFIG_UART_STM32_PORT_1=y
CONFIG_PRINTK=y
CONFIG_STDOUT_CONSOLE=y
CONFIG_EARLY_CONSOLE=y
CONFIG_SYS_LOG=y
CONFIG_SYS_LOG_SHOW_TAGS=y
CONFIG_SYS_LOG_SHOW_COLOR=y
CONFIG_SYS_LOG_DEFAULT_LEVEL=0
CONFIG_SYS_LOG_OVERRIDE_LEVEL=0
8 changes: 8 additions & 0 deletions samples/boards/olimex_stm32_e407/ccm/sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
sample:
name: CCM usages example on Olimex STM32-E407
tests:
test:
build_only: true
platform_whitelist: olimex_stm32_e407
tags: samples

148 changes: 148 additions & 0 deletions samples/boards/olimex_stm32_e407/ccm/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/*
* Copyright (c) 2017 Erwin Rol <[email protected]>
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr.h>
#include <device.h>
#include <stdio.h>
#include <string.h>

#include <linker/linker-defs.h>

#define CCM_DATA_VAR_8_VAL 0x12
#define CCM_DATA_VAR_16_VAL 0x3456
#define CCM_DATA_VAR_32_VAL 0x789ABCDE

#define CCM_DATA_ARRAY_SIZE 5
#define CCM_BSS_ARRAY_SIZE 7
#define CCM_NOINIT_ARRAY_SIZE 11

#define CCM_DATA_ARRAY_VAL(i) (((i)+1)*0x11)

u8_t __ccm_data_section ccm_data_var_8 = CCM_DATA_VAR_8_VAL;
u16_t __ccm_data_section ccm_data_var_16 = CCM_DATA_VAR_16_VAL;
u32_t __ccm_data_section ccm_data_var_32 = CCM_DATA_VAR_32_VAL;

u8_t __ccm_data_section ccm_data_array[CCM_DATA_ARRAY_SIZE] = {
CCM_DATA_ARRAY_VAL(0),
CCM_DATA_ARRAY_VAL(1),
CCM_DATA_ARRAY_VAL(2),
CCM_DATA_ARRAY_VAL(3),
CCM_DATA_ARRAY_VAL(4),
};
u8_t __ccm_bss_section ccm_bss_array[CCM_BSS_ARRAY_SIZE];
u8_t __ccm_noinit_section ccm_noinit_array[CCM_NOINIT_ARRAY_SIZE];

void print_array(const void *array, u32_t size)
{
int i;

for (i = 0; i < size; i++) {
printf("0x%02x ", ((const char *)array)[i]);
}
}

void check_initial_var_values(void)
{
int i;
int check_failed = 0;

printf("\nChecking initial variable values: ... ");

if (ccm_data_var_8 != CCM_DATA_VAR_8_VAL) {
check_failed = 1;
printf("\nccm_data_var_8 incorrect: 0x%02x should be 0x%02x",
ccm_data_var_8, CCM_DATA_VAR_8_VAL);
}

if (ccm_data_var_16 != CCM_DATA_VAR_16_VAL) {
check_failed = 1;
printf("\nccm_data_var_16 incorrect: 0x%04x should be 0x%04x",
ccm_data_var_16, CCM_DATA_VAR_16_VAL);
}

if (ccm_data_var_32 != CCM_DATA_VAR_32_VAL) {
check_failed = 1;
printf("\nccm_data_var_32 incorrect: 0x%08x should be 0x%08x",
ccm_data_var_32, CCM_DATA_VAR_32_VAL);
}

for (i = 0; i < CCM_DATA_ARRAY_SIZE; i++) {
if (ccm_data_array[i] != CCM_DATA_ARRAY_VAL(i)) {
check_failed = 1;
printf("\nccm_data_array[%d] incorrect: "
"0x%02x should be 0x%02x",
i, ccm_data_array[i], CCM_DATA_ARRAY_VAL(i));
}
}

for (i = 0; i < CCM_BSS_ARRAY_SIZE; i++) {
if (ccm_bss_array[i] != 0x00) {
check_failed = 1;
printf("\nccm_bss_array[%d] incorrect: "
"0x%02x should be 0x00",
i, ccm_bss_array[i]);
}
}

if (!check_failed) {
printf("PASSED\n");
}
}

void print_var_values(void)
{
printf("ccm_data_var_8 addr: %p value: 0x%02x\n",
&ccm_data_var_8, ccm_data_var_8);
printf("ccm_data_var_16 addr: %p value: 0x%04x\n",
&ccm_data_var_16, ccm_data_var_16);
printf("ccm_data_var_32 addr: %p value: 0x%08x\n",
&ccm_data_var_32, ccm_data_var_32);
printf("ccm_data_array addr: %p size: %d value:\n\t",
ccm_data_array, sizeof(ccm_data_array));
print_array(ccm_data_array, sizeof(ccm_data_array));
printf("\nccm_bss_array addr: %p size: %d value:\n\t",
ccm_bss_array, sizeof(ccm_bss_array));
print_array(ccm_bss_array, sizeof(ccm_bss_array));
printf("\nccm_noinit_array addr: %p size: %d value:\n\t",
ccm_noinit_array, sizeof(ccm_noinit_array));
print_array(ccm_noinit_array, sizeof(ccm_noinit_array));
printf("\n");
}

void main(void)
{
printf("\nCCM (Core Coupled Memory) usage example\n\n");

printf("The total used CCM area : [%p, %p)\n",
&__ccm_start, &__ccm_end);
printf("Zero initialized BSS area : [%p, %p)\n",
&__ccm_bss_start, &__ccm_bss_end);
printf("Unitialized NOINIT area : [%p, %p)\n",
&__ccm_noinit_start, &__ccm_noinit_end);
printf("Initialised DATA area : [%p, %p)\n",
&__ccm_data_start, &__ccm_data_end);
printf("Start of DATA in FLASH : %p\n",
&__ccm_data_rom_start);

check_initial_var_values();

printf("\nInitial variable values:\n");
print_var_values();

ccm_data_var_8 = ~CCM_DATA_VAR_8_VAL;
ccm_data_var_16 = ~CCM_DATA_VAR_16_VAL;
ccm_data_var_32 = ~CCM_DATA_VAR_32_VAL;

memset(ccm_data_array, 0xAA, sizeof(ccm_data_array));
memset(ccm_bss_array, 0xBB, sizeof(ccm_bss_array));
memset(ccm_noinit_array, 0xCC, sizeof(ccm_noinit_array));

printf("\nVariable values after writing:\n");
print_var_values();

printf("\nExample end\n");
}

10 changes: 10 additions & 0 deletions samples/boards/olimex_stm32_e407/olimex_stm32_e407.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.. _olimex_stm32_e407-samples:

Olimex STM32-E407 Samples
#########################

.. toctree::
:maxdepth: 1
:glob:

**/*

0 comments on commit 6c0e69e

Please sign in to comment.