arm: Placing the functions which holds __ramfunc into '.ramfunc'

Using __ramfunc to places a function in RAM instead of Flash.
Code that for example reprograms flash at runtime can't execute
from flash, in that case must placing code into RAM.

This commit create a new section named '.ramfunc' in link scripts,
all functions has __ramfunc keyword saved in thats sections and
will load from flash to sram after the system booted.

Fixes: #10253

Signed-off-by: qianfan Zhao <qianfanguijin@163.com>
This commit is contained in:
qianfan Zhao 2018-09-27 14:14:17 +08:00 committed by Andrew Boie
parent 898973be8a
commit e1cc657941
6 changed files with 53 additions and 1 deletions

View file

@ -77,8 +77,15 @@ void _arch_configure_static_mpu_regions(void)
.start = (u32_t)&_nocache_ram_start,
.size = (u32_t)&_nocache_ram_size,
.attr = K_MEM_PARTITION_P_RW_U_NA_NOCACHE,
}
},
#endif /* CONFIG_NOCACHE_MEMORY */
#if defined(CONFIG_RAM_FUNCTION)
{
.start = (u32_t)&_ramfunc_ram_start,
.size = (u32_t)&_ramfunc_ram_start - (u32_t)&_ramfunc_ram_end,
.attr = K_MEM_PARTITION_P_RX_U_RX,
}
#endif /* CONFIG_RAM_FUNCTION */
};
/* Configure the static MPU regions within firmware SRAM boundaries.

View file

@ -368,6 +368,20 @@ SECTIONS
_nocache_ram_size = _nocache_ram_end - _nocache_ram_start;
#endif /* CONFIG_NOCACHE_MEMORY */
#if defined(CONFIG_RAM_FUNCTION)
SECTION_DATA_PROLOGUE(.ramfunc,,)
{
MPU_ALIGN(_ramfunc_ram_size);
_ramfunc_ram_start = .;
*(.ramfunc)
*(".ramfunc.*")
MPU_ALIGN(_ramfunc_ram_size);
_ramfunc_ram_end = .;
} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
_ramfunc_ram_size = _ramfunc_ram_end - _ramfunc_ram_start;
_ramfunc_rom_start = LOADADDR(.ramfunc);
#endif /* CONFIG_RAM_FUNCTION */
#if defined(CONFIG_APP_SHARED_MEM)
#define APP_SHARED_ALIGN . = ALIGN(_region_min_align);
#define SMEM_PARTITION_ALIGN MPU_ALIGN

View file

@ -239,6 +239,16 @@ extern char _nocache_ram_end[];
extern char _nocache_ram_size[];
#endif /* CONFIG_NOCACHE_MEMORY */
/* Memory owned by the kernel. Start and end will be aligned for memory
* management/protection hardware for the target architecture.
*
* All the functions with '__ramfunc' keyword will be placed into this
* sections.
*/
extern char _ramfunc_ram_start[];
extern char _ramfunc_ram_end[];
extern char _ramfunc_rom_start[];
#endif /* ! _ASMLANGUAGE */
#endif /* ZEPHYR_INCLUDE_LINKER_LINKER_DEFS_H_ */

View file

@ -115,6 +115,16 @@ do { \
#define __in_section_unique(seg) ___in_section(seg, __FILE__, __COUNTER__)
#ifdef CONFIG_RAM_FUNCTION
/* Using this places a function into RAM instead of FLASH.
* Make sure '__ramfunc' are defined only when CONFIG_RAM_FUNCTION,
* so the compiler can report error if used '__ramfunc' but hadn't
* enable CONFIG_RAM_FUNCTION in Kconfig.
*/
#define __ramfunc __attribute__((noinline)) \
__attribute__((long_call, section(".ramfunc")))
#endif
#ifndef __packed
#define __packed __attribute__((__packed__))
#endif

View file

@ -207,6 +207,13 @@ config ERRNO
symbol. The C library must access the per-thread errno via the
_get_errno() symbol.
config RAM_FUNCTION
bool "Enable __ramfunc support"
help
Using '__ramfunc' places a function into RAM instead of Flash.
Code that for example reprograms flash at runtime can't execute
from flash, in that case must placing code into RAM.
choice SCHED_ALGORITHM
prompt "Scheduler priority queue algorithm"
default SCHED_DUMB

View file

@ -173,6 +173,10 @@ void _data_copy(void)
{
(void)memcpy(&__data_ram_start, &__data_rom_start,
((u32_t) &__data_ram_end - (u32_t) &__data_ram_start));
#ifdef CONFIG_RAM_FUNCTION
(void)memcpy(&_ramfunc_ram_start, &_ramfunc_rom_start,
((u32_t) &_ramfunc_ram_end - (u32_t) &_ramfunc_ram_start));
#endif
#ifdef DT_CCM_BASE_ADDRESS
(void)memcpy(&__ccm_data_start, &__ccm_data_rom_start,
((u32_t) &__ccm_data_end - (u32_t) &__ccm_data_start));