打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
【精品博文】Rt-thread 代码优化之 Finsh组件
在一些资源受限的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_sectionrather 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空间了

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
分析kernel的initcall函数 - Linux Kernel
源码解读·RT-Thread操作系统从开机到关机
代码编译到内核和编译成模块在代码中的区别
MACHINE_START宏(内核启动相关) - 东海的日志 - 网易博客
利用gcc的__attribute__编译属性section子项构建初始化函数表
linux内核及驱动开发中有关__init,__exit和__initdata的用法
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服