您尚未登录。

楼主 # 2021-12-28 17:21:47

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 565
积分: 570
个人网站

[求助]RTT组件自动统一初始化宏INIT_EXPORT

如题,我写了个简单的设备管理器,
    每个设备,写完之后,应该有个注册函数,
    我想让这个注册函数自动被管理器调用。
    参考到了RTT的宏,指定这些函数在某一个特定的代码段,
   按顺序排列起来,然后从头到尾,逐个调用。

#define INIT_EXPORT(fn, level)        \
        const init_fn_t __rt_init_##fn RT_SECTION(".rti_fn."level) = fn
#define INIT_BOARD_EXPORT(fn)                		INIT_EXPORT(fn, "1")
#define INIT_CPU_EXPORT(fn)                    	INIT_EXPORT(fn, "2")
#define INIT_DEVICE_EXPORT(fn)                	INIT_EXPORT(fn, "3")
#define INIT_COMPONENT_EXPORT(fn)         			INIT_EXPORT(fn, "4")
#define INIT_FS_EXPORT(fn)                      INIT_EXPORT(fn, "5")
#define INIT_APP_EXPORT(fn)                    	INIT_EXPORT(fn, "6")

    参考这篇文章: RT-Thread 学习笔记(七)
    我从中抄袭了这些代码
(1)头文件代码

/*自动初始化模块*/
#define RT_SECTION(x)               __attribute__((section(x)))
#define RT_UNUSED                   __attribute__((unused))
#define RT_USED                     __attribute__((used))

typedef int (*init_fn_t)(void);
#define INIT_EXPORT(fn, level)        \
        const init_fn_t __rt_init_##fn RT_SECTION(".rti_fn."level) = fn
					
#define INIT_BOARD_EXPORT(fn)                		INIT_EXPORT(fn, "1")
#define INIT_CPU_EXPORT(fn)                    	INIT_EXPORT(fn, "2")
#define INIT_DEVICE_EXPORT(fn)                	INIT_EXPORT(fn, "3")
#define INIT_COMPONENT_EXPORT(fn)         			INIT_EXPORT(fn, "4")
#define INIT_FS_EXPORT(fn)                      INIT_EXPORT(fn, "5")
#define INIT_APP_EXPORT(fn)                    	INIT_EXPORT(fn, "6")

(2)c文件代码

static int rti_start(void)
{
        return 0;
}
INIT_EXPORT(rti_start, "0");
static int rti_end(void)
{
        return 0;
}
INIT_EXPORT(rti_end,"7");


void rt_components_init(void)
{
        const init_fn_t* fn_ptr;
        for (fn_ptr = &__rt_init_rti_start; fn_ptr < &__rt_init_rti_end; )
        {
                (*fn_ptr)();
                fn_ptr ++;
        }
}

(3)调用:
①初始化设备管理器的时候,调用rt_components_init()函数,
②修饰注册函数

INIT_COMPONENT_EXPORT(register_hw_dev_led);

(4)串口打印,没有看到register_hw_dev_led()函数的调用打印。

最近编辑记录 LinjieGuo (2021-12-28 17:22:55)

离线

楼主 #1 2021-12-28 17:32:36

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 565
积分: 570
个人网站

Re: [求助]RTT组件自动统一初始化宏INIT_EXPORT

编译环境:Keil 5
(1)map文件关键信息

__rt_init_rti_start                      0x08011ce0   Data           4  hw_action.o(.rti_fn.0)
__rt_init_rti_end                        0x08011ce4   Data           4  hw_action.o(.rti_fn.7)

hw_action.o(.text) refers to hw_action.o(.rti_fn.0) for __rt_init_rti_start
hw_action.o(.text) refers to hw_action.o(.rti_fn.7) for __rt_init_rti_end
hw_action.o(.rti_fn.0) refers to hw_action.o(.text) for rti_start
hw_action.o(.rti_fn.7) refers to hw_action.o(.text) for rti_end
hw_dev_led.o(.rti_fn.4) refers to hw_dev_led.o(.text) for register_hw_dev_led

Removing hw_dev_led.o(.rti_fn.4), (4 bytes).

0x08011ce0   0x08011ce0   0x00000004   Data   RO         2106    .rti_fn.0           hw_action.o
0x08011ce4   0x08011ce4   0x00000004   Data   RO         2107    .rti_fn.7           hw_action.o

离线

楼主 #2 2021-12-28 17:40:55

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 565
积分: 570
个人网站

Re: [求助]RTT组件自动统一初始化宏INIT_EXPORT

继续描述场景
(1)优化等级-O0
(2)不勾选One ELF Section per Function
编译后,想要自动调用的宏还是没有被调用。
因为是公司代码,不方便上传,先上次map文件:
CMSIS-RTOS2-free_map.zip
如果大神们不好诊断,明天,我可以用其他单板实现这个框架,发代码出来。

离线

楼主 #3 2021-12-29 08:26:28

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 565
积分: 570
个人网站

Re: [求助]RTT组件自动统一初始化宏INIT_EXPORT

通过下载RTT主线代码,借助STM32F407的RTT keil工程,他是没有指定sct文件的,也就是说,是自动生成的。
RTT_Project.png

离线

楼主 #4 2021-12-29 09:29:43

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 565
积分: 570
个人网站

Re: [求助]RTT组件自动统一初始化宏INIT_EXPORT

我把代码移植到ITX-190,也是一样,没有看到注册函数的打印。
附上代码:
(1)whycan下载
(2)站外免费下载(右键另存为)

最近编辑记录 LinjieGuo (2021-12-29 09:48:29)

离线

#5 2021-12-29 10:00:44

aozima
会员
所在地: 深圳
注册时间: 2019-05-25
已发帖子: 451
积分: 318.5
个人网站

Re: [求助]RTT组件自动统一初始化宏INIT_EXPORT

方案1 链接脚本让其保留
方案2 属性里面加强制保留属性,你再仔细看下

离线

#6 2021-12-29 10:01:56

aozima
会员
所在地: 深圳
注册时间: 2019-05-25
已发帖子: 451
积分: 318.5
个人网站

Re: [求助]RTT组件自动统一初始化宏INIT_EXPORT

ITX-190 是啥?

离线

楼主 #7 2021-12-29 10:50:38

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 565
积分: 570
个人网站

Re: [求助]RTT组件自动统一初始化宏INIT_EXPORT

aozima 说:

ITX-190 是啥?

哈哈,是我之前做的一款M0开发板。用的是SWM190单片机。
参考文章里作者提过你,现在看到本尊了。久仰久仰。

最近编辑记录 LinjieGuo (2021-12-29 10:52:03)

离线

楼主 #8 2021-12-31 13:48:40

LinjieGuo
Moderator
注册时间: 2019-07-24
已发帖子: 565
积分: 570
个人网站

Re: [求助]RTT组件自动统一初始化宏INIT_EXPORT

问题已经解决,在keil下,关键代码如下:
(1)h文件

/*自动初始化模块*/
#define RT_SECTION(x)               __attribute__((section(x)))
#define RT_UNUSED                   __attribute__((unused))
#define RT_USED                     __attribute__((used))


typedef int (*init_fn_t)(void);
#ifdef _MSC_VER /* we do not support MS VC++ compiler */
#pragma section("rti_fn$f",read)


        struct rt_init_desc
        {
            const char* level;
            const init_fn_t fn;
        };
        #define INIT_EXPORT(fn, level)                                  \
                                const char __rti_level_##fn[] = level"__rt_init_"#fn;   \
                                __declspec(allocate("rti_fn$f"))                        \
                                RT_USED const struct rt_init_desc __rt_init_msc_##fn =  \
                                {__rti_level_##fn, fn };
				
#else

        #define INIT_EXPORT(fn, level)                                                       \
            RT_USED const init_fn_t __rt_init_##fn RT_SECTION(".rti_fn." level) = fn
#endif
				
/* board init routines will be called in board_init() function */
#define INIT_BOARD_EXPORT(fn)           INIT_EXPORT(fn, "1")

/* pre/device/component/env/app init routines will be called in init_thread */
/* components pre-initialization (pure software initilization) */
#define INIT_PREV_EXPORT(fn)            INIT_EXPORT(fn, "2")
/* device initialization */
#define INIT_DEVICE_EXPORT(fn)          INIT_EXPORT(fn, "3")
/* components initialization (dfs, lwip, ...) */
#define INIT_COMPONENT_EXPORT(fn)       INIT_EXPORT(fn, "4")
/* environment initialization (mount disk, ...) */
#define INIT_ENV_EXPORT(fn)             INIT_EXPORT(fn, "5")
/* appliation initialization (rtgui application etc ...) */
#define INIT_APP_EXPORT(fn)             INIT_EXPORT(fn, "6")

(2)c文件

static int rti_start(void)
{
        return 0;
}
INIT_EXPORT(rti_start, "0");
static int rti_end(void)
{
        return 0;
}
INIT_EXPORT(rti_end,"7");


void rt_components_init(void)
{
        const init_fn_t* fn_ptr;
        for (fn_ptr = &__rt_init_rti_start; fn_ptr < &__rt_init_rti_end; )
        {
                (*fn_ptr)();
                fn_ptr ++;
        }
}

以上代码源自RTT bsp,以及1楼参考的文章。
成功的工程:ITX_190_HWA.zip

最近编辑记录 LinjieGuo (2021-12-31 13:51:23)

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn