2018-12-11 02:46 PM
I have some functions to read-and write to memory to STM32F103 internal memory. This functions work on the gcc and standard linker script. When I want to use the internal flash with stm32 and freertos. FreeRtos does not allow to me access when I want to write a data into internal flash. Here is the standard freertos linker script file.
Default linker script file for freertos for stm32.
/*************************************************
* linker script for ST32F103 & MPU REV 1.02
************************************************/
GROUP(libgcc.a libc.a)
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
SRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 96K
}
/* Higher address of the user mode stack */
_estack = ORIGIN(SRAM)+LENGTH(SRAM);
/*
*There will be a link error if there is not this amount of RAM free at the end.
*/
_Minimum_Stack_Size = 1K;
_Minimum_Heap_Size = 1K;
/* Variables used by FreeRTOS-MPU. */
_Privileged_Functions_Region_Size = 16K;
_Privileged_Data_Region_Size = 512;
__FLASH_segment_start__ = ORIGIN( FLASH );
__FLASH_segment_end__ = __FLASH_segment_start__ + LENGTH( FLASH );
__privileged_functions_start__ = ORIGIN( FLASH );
__privileged_functions_end__ = __privileged_functions_start__ + _Privileged_Functions_Region_Size;
__SRAM_segment_start__ = ORIGIN( SRAM );
__SRAM_segment_end__ = __SRAM_segment_start__ + LENGTH( SRAM );
__privileged_data_start__ = ORIGIN( SRAM );
__privileged_data_end__ = ORIGIN( SRAM ) + _Privileged_Data_Region_Size;
ENTRY(Reset_Handler)
SECTIONS
{
/*
Privileged section at the start of the flash.
Vectors must be first whatever.
*/
.isr_vectors :
{
. = ALIGN(4);
_isr_vectors_offs = . - __FLASH_segment_start__;
KEEP(*(.isr_vectors)) /* Startup code */
} >FLASH
privileged_functions :
{
. = ALIGN(4);
*(privileged_functions)
} > FLASH
/* Non privileged code starts here. */
.text_offset :
{
. = ALIGN(4);
. = . + _Privileged_Functions_Region_Size;
} > FLASH
.text :
{
. = ALIGN(4);
*(.text) /* remaining code */
*(.text.*) /* remaining code */
*(.rodata) /* read-only data (constants) */
*(.rodata*)
*(.glue_7)
*(.glue_7t)
} > FLASH
/*
.ARM.exidx is sorted, so has to go in its own output section.
*/
. = ALIGN(4);
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} >FLASH
__exidx_end = .;
/* -- */
.data.align :
{
. = ALIGN(4);
_etext = .;
_sipdata = _etext; /* Used by the startup in order to initialize privileged variables */
} >FLASH
/* -- */
.pdata.align :
{
. = ALIGN(4);
. = . + _Privileged_Data_Region_Size;
_sidata = .; /* Used by the startup in order to initialize variables */
} >FLASH
/*
* This is the Privileged data section. It is stored in RAM but the initial values
* are held in flash and copied to RAM by the startup code
*/
privileged_data : AT ( _sipdata ) /* AT makes the LMA follow on in the binary image */
{
. = ALIGN(4);
_bss = .;
_spdata = . ;
*(privileged_data)
_epdata = . ;
} > SRAM
/*
* This is the initialized data section. It is stored in RAM but the initial values
* are held in flash and copied to RAM by the startup code
*/
.data_offset :
{
. = ALIGN(4);
. = . + _Privileged_Data_Region_Size;
} > SRAM
.data : AT ( _sidata ) /* AT makes the LMA follow on in the binary image */
{
_sdata = . ; /* Used by the startup in order to initialize the .data section */
KEEP(*(vtable))
KEEP( *(.data) )
KEEP( *(.data.*) )
. = ALIGN(4);
_edata = . ; /* Used by the startup in order to initialize the .data section */
} >SRAM
/*
* This is the uninitialized data section. Date here is stored in RAM and will be
* set to zero by the startup code.
*/
.bss :
{
. = ALIGN(4);
_sbss = .; /* Used by the startup in order to initialize the .bss section */
*(.bss)
*(.bss.*)
*(COMMON)
. = ALIGN(4);
_ebss = . ; /* Used by the startup in order to initialize the .bss section */
} >SRAM
/*
* This is the heap section
* This is just to check that there is enough RAM left for the heap
* It should generate an error if it's full.
*/
._sheap :
{
. = ALIGN(4);
_heap_begin = . ;
. = . + _Minimum_Heap_Size ;
. = ALIGN(4);
_heap_end = . ;
} >SRAM
/*
* This is the user stack section
* This is just to check that there is enough RAM left for the User mode stack
* It should generate an error if it's full.
*/
._usrstack :
{
. = ALIGN(4);
_susrstack = . ;
. = . + _Minimum_Stack_Size ;
. = ALIGN(4);
_eusrstack = . ;
} >SRAM
PROVIDE ( end = _ebss );
PROVIDE ( _end = _ebss );
PROVIDE( _heap = _heap_begin );
PROVIDE ( _eheap = _heap_end );
}
and here is the my new linker script file here to access the last page of the stm32f103 which is page 255. When I want to modify the page255. It does not allow me. Do you have suggestion that how can use the internal flash of the stm32 with freertos? I just need to use one page in the flash when freertos in the usage. Everything works if I do not use freertos
2018-12-11 02:49 PM
and here is the edited linker script file. The different between two linker script file. Thank you from now
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1022K
FLASH_STORAGE (rwx) : ORIGIN = 0x08000000+1022K, LENGTH = 2K
/*************************************************
* linker script for ST32F103 & MPU REV 1.02
************************************************/
GROUP(libgcc.a libc.a)
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1022K
FLASH_STORAGE (rwx) : ORIGIN = 0x08000000+1022K, LENGTH = 2K
SRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 96K
}
/* Higher address of the user mode stack */
_estack = ORIGIN(SRAM)+LENGTH(SRAM);
/*
*There will be a link error if there is not this amount of RAM free at the end.
*/
_Minimum_Stack_Size = 1K;
_Minimum_Heap_Size = 1K;
/* Variables used by FreeRTOS-MPU. */
_Privileged_Functions_Region_Size = 16K;
_Privileged_Data_Region_Size = 512;
__FLASH_segment_start__ = ORIGIN( FLASH );
__FLASH_segment_end__ = __FLASH_segment_start__ + LENGTH( FLASH );
__privileged_functions_start__ = ORIGIN( FLASH );
__privileged_functions_end__ = __privileged_functions_start__ + _Privileged_Functions_Region_Size;
__SRAM_segment_start__ = ORIGIN( SRAM );
__SRAM_segment_end__ = __SRAM_segment_start__ + LENGTH( SRAM );
__privileged_data_start__ = ORIGIN( SRAM );
__privileged_data_end__ = ORIGIN( SRAM ) + _Privileged_Data_Region_Size;
ENTRY(Reset_Handler)
SECTIONS
{
/*
Privileged section at the start of the flash.
Vectors must be first whatever.
*/
.isr_vectors :
{
. = ALIGN(4);
_isr_vectors_offs = . - __FLASH_segment_start__;
KEEP(*(.isr_vectors)) /* Startup code */
} >FLASH
privileged_functions :
{
. = ALIGN(4);
*(privileged_functions)
} > FLASH
/* Non privileged code starts here. */
.text_offset :
{
. = ALIGN(4);
. = . + _Privileged_Functions_Region_Size;
} > FLASH
.text :
{
. = ALIGN(4);
*(.text) /* remaining code */
*(.text.*) /* remaining code */
*(.rodata) /* read-only data (constants) */
*(.rodata*)
*(.glue_7)
*(.glue_7t)
} > FLASH
/*
.ARM.exidx is sorted, so has to go in its own output section.
*/
. = ALIGN(4);
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} >FLASH
__exidx_end = .;
/* -- */
.data.align :
{
. = ALIGN(4);
_etext = .;
_sipdata = _etext; /* Used by the startup in order to initialize privileged variables */
} >FLASH
/* -- */
.pdata.align :
{
. = ALIGN(4);
. = . + _Privileged_Data_Region_Size;
_sidata = .; /* Used by the startup in order to initialize variables */
} >FLASH
/*
* This is the Privileged data section. It is stored in RAM but the initial values
* are held in flash and copied to RAM by the startup code
*/
privileged_data : AT ( _sipdata ) /* AT makes the LMA follow on in the binary image */
{
. = ALIGN(4);
_bss = .;
_spdata = . ;
*(privileged_data)
_epdata = . ;
} > SRAM
/*
* This is the initialized data section. It is stored in RAM but the initial values
* are held in flash and copied to RAM by the startup code
*/
.data_offset :
{
. = ALIGN(4);
. = . + _Privileged_Data_Region_Size;
} > SRAM
.data : AT ( _sidata ) /* AT makes the LMA follow on in the binary image */
{
_sdata = . ; /* Used by the startup in order to initialize the .data section */
KEEP(*(vtable))
KEEP( *(.data) )
KEEP( *(.data.*) )
. = ALIGN(4);
_edata = . ; /* Used by the startup in order to initialize the .data section */
} >SRAM
/*
* This is the uninitialized data section. Date here is stored in RAM and will be
* set to zero by the startup code.
*/
.bss :
{
. = ALIGN(4);
_sbss = .; /* Used by the startup in order to initialize the .bss section */
*(.bss)
*(.bss.*)
*(COMMON)
. = ALIGN(4);
_ebss = . ; /* Used by the startup in order to initialize the .bss section */
} >SRAM
/*
* This is the heap section
* This is just to check that there is enough RAM left for the heap
* It should generate an error if it's full.
*/
._sheap :
{
. = ALIGN(4);
_heap_begin = . ;
. = . + _Minimum_Heap_Size ;
. = ALIGN(4);
_heap_end = . ;
} >SRAM
/*
* This is the user stack section
* This is just to check that there is enough RAM left for the User mode stack
* It should generate an error if it's full.
*/
._usrstack :
{
. = ALIGN(4);
_susrstack = . ;
. = . + _Minimum_Stack_Size ;
. = ALIGN(4);
_eusrstack = . ;
} >SRAM
PROVIDE ( end = _ebss );
PROVIDE ( _end = _ebss );
PROVIDE( _heap = _heap_begin );
PROVIDE ( _eheap = _heap_end );
}
2018-12-11 02:49 PM
Check the MPU settings to understand what/why areas are protected from access
2018-12-11 03:05 PM
I will look that. You mean I will touch the linker script right?
2018-12-11 03:33 PM
No, something in your code is enabling and configuring the MPU with ranges of valid/usable addresses, review *that* code, once you understand what that is doing, and the expectation that creates pivot to how that gets described/controlled in the script.
Seem to recall the MPU wants regions which are a power of two. Check the TRM for the core.