Rt-thread 代码优化之 Finsh组件
0赞在一些资源受限的MCU中,使用rt-thread时需要进行代码的优化,默认情况下,在map文件中可以看到
6170 156 0 8 0 11738 finsh_compiler.o
56 22 243 64 0 2755 finsh_error.o
552 42 0 8 128 5935 finsh_heap.o
64 6 0 0 0 2100 finsh_init.o
392 8 0 0 320 5966 finsh_node.o
3034 294 196 0 0 25930 finsh_ops.o
2428 32 0 0 0 16363 finsh_parser.o
1644 16 126 0 0 10262 finsh_token.o
296 32 0 4 192 7994 finsh_var.o
176 36 0 12 384 7227 finsh_vm.o
finsh相关的文件占用了很多的flash和ram,
刚开始我找了好久都没有发现是在哪里调用的这些东西,后来才注意到,rt-thread里使用了一些通常MCU代码里不太常用的初始化方式,它使用的是组件的形式,详细介绍可以参考:http://www.cnblogs.com/King-Gentleman/p/4570559.html
核心部分是使用了__attribute__((section(x)))的方式先把一个函数的地址(注意是函数地址,而不是函数本身)输出到一个独立的section中。
然后在rt_hw_board_init ->rt_components_board_init() 直接以函数指针的形式调用的。
/**
* This function will initial STM32 board.
*/
void rt_hw_board_init(void)
{
/* NVIC Configuration */
NVIC_Configuration();
/* Configure the SysTick */
SysTick_Config( SystemCoreClock / RT_TICK_PER_SECOND );
#if STM32_EXT_SRAM
EXT_SRAM_Configuration();
#endif
rt_hw_usart_init();
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
}/**
* RT-Thread Components Initialization for board
*/
void rt_components_board_init(void)
{
#if RT_DEBUG_INIT
int result;
const struct rt_init_desc *desc;
for (desc = &__rt_init_desc_rti_board_start; desc < &__rt_init_desc_rti_board_end; desc ++)
{
rt_kprintf("initialize %s", desc->fn_name);
result = desc->fn();
rt_kprintf(":%d done\n", result);
}
#else
const init_fn_t *fn_ptr;
for (fn_ptr = &__rt_init_rti_board_start; fn_ptr < &__rt_init_rti_board_end; fn_ptr++)
{
(*fn_ptr)();
}
#endif
}INIT_COMPONENT_EXPORT(finsh_system_init); 这句话
#define INIT_COMPONENT_EXPORT(fn) INIT_EXPORT(fn, "3")
#define INIT_EXPORT(fn, level) \
const init_fn_t __rt_init_##fn SECTION(".rti_fn."level) = fn
#define SECTION(x) __attribute__((section(x)))
_attribute_((section(x))) 含义如下
__attribute__((section("name"))) function attribute
| Non-Confidential | ARM DUI0375E | |
| ARM® Compiler v5.04 for µVision armcc User GuideVersion 5 | ||
| Home > Compiler-specific Features > __attribute__((section("name"))) function attribute | ||
9.46 __attribute__((section("name"))) function attribute
The section function attribute enables you to place code
in different sections of the image.
Note
This function attribute is a GNU compiler extension that the ARM compiler supports.
Examples
In the following example, Function_Attributes_section_0 is
placed into the RO section new_section rather than .text.
void Function_Attributes_section_0 (void)
__attribute__((section ("new_section")));
void Function_Attributes_section_0 (void)
{
static int aStatic =0;
aStatic++;
}In the following example, section function
attribute overrides the #pragma arm section setting.
#pragma arm section code="foo"
int f2()
{
return 1;
} // into the 'foo' area
__attribute__((section ("bar"))) int f3()
{
return 1;
} // into the 'bar' area
int f4()
{
return 1;
} // into the 'foo' area
#pragma arm section它也可以指定变量的属性
__attribute__((section("name"))) variable attribute
| Non-Confidential | ARM DUI0375E | |
| ARM® Compiler v5.04 for µVision armcc User GuideVersion 5 | ||
| Home > Compiler-specific Features > __attribute__((section("name"))) variable attribute | ||
9.64 __attribute__((section("name"))) variable attribute
The section attribute specifies that a variable must be
placed in a particular data section.
Normally, the ARM compiler places the objects it generates in
sections like .data and .bss. However, you might
require additional data sections or you might want a variable to appear in a
special section,
for example, to map to special hardware.
If you use the section attribute, read-only variables are placed in
RO data sections, read-write variables are placed in RW data sections unless you
use the zero_init attribute. In this case, the variable is placed
in a ZI section.
Note
This variable attribute is a GNU compiler extension that the ARM compiler supports.
Examples
/* in RO section */
const int descriptor[3] __attribute__((section ("descr"))) = { 1,2,3 };
/* in RW section */
long long rw_initialized[10] __attribute__((section ("INITIALIZED_RW"))) = {5};
/* in RW section */
long long rw[10] __attribute__((section ("RW")));
/* in ZI section */
long long altstack[10] __attribute__((section ("STACK"), zero_init));所以不使用的话 在rtconfig.h 中将以下这句话注释掉即可
#define RT_USING_COMPONENTS_INIT
或者把这句注释掉
INIT_COMPONENT_EXPORT(finsh_system_init);
这样就可以减少很多flash和ram空间了
