前言

  1. 借鉴rt-thread组件自动初始化功能,实现一个组件初始化的模板

代码

头文件

/*
 * Copyright (c) 2024-2024,shchl
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-4-9     shchl   first version
 *
 * @note 链接文件添加
    __os_init_start = .;
    KEEP(*(SORT(.bsp_init_fn*)))
    __os_init_end = .;
 */

#ifndef APP_THREADX_NETXDUO_BSP_AUTO_INIT_H
#define APP_THREADX_NETXDUO_BSP_AUTO_INIT_H
#define bsp_section(x)               __attribute__((section(x)))
#define bsp_used                     __attribute__((used))
typedef int (*init_fn_t)(void);

#define     INIT_EXPORT(fn, level)                                                       \
            bsp_used const init_fn_t __os_init_##fn bsp_section(".bsp_init_fn." level) = fn

void bsp_components_app_init(const init_fn_t *start_ptr,const init_fn_t *end_ptr);

#endif //APP_THREADX_NETXDUO_BSP_AUTO_INIT_H

原文件

/*
 * Copyright (c) 2024-2024,shchl
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-4-9     shchl   first version
 */

#include "bsp.h"

/**
 * @brief 自定义app区间初始化
 * @param start_ptr 起始函数指针地址
 * @param end_ptr   结束函数指针地址
 */
void bsp_components_app_init(const init_fn_t *start_ptr,const init_fn_t *end_ptr) {
    volatile const init_fn_t *fn_ptr;
    for (fn_ptr = start_ptr; fn_ptr < end_ptr; fn_ptr++) {
        (*fn_ptr)();
    }
}

链接文件修改

在这里插入图片描述

示例 以netx duo 应用组件为例(模拟tcp client)

相关宏定义

#define NET_X_APP_EXPORT(fn)    INIT_EXPORT(fn, "8.1")

源文件

static int net_x_duo_component_init_start() {
    /* 初始化NetX */
    nx_system_initialize();
    return NX_SUCCESS;
}

INIT_EXPORT(net_x_duo_component_init_start, "8.0");


static int nex_x_duo_component_init_end() {
    return NX_SUCCESS;
}

INIT_EXPORT(nex_x_duo_component_init_end, "9.0");



/**
  * @brief  Application NetXDuo Initialization.
  * @param memory_ptr: memory pointer
  * @retval int
  */
UINT MX_NetXDuo_Init() {

    bsp_components_app_init(&__os_init_net_x_duo_component_init_start,
                            &__os_init_nex_x_duo_component_init_end);

    return NX_SUCCESS;
}

组件注入

int app_netx_tcp_client_init() {

    tx_log("app_netx_tcp_client_init\r\n");

    return NX_SUCCESS;
}

NET_X_APP_EXPORT(app_netx_tcp_client_init);

通过map映射文件也可以观察出函数地址之间的关系

在这里插入图片描述

执行结果(解耦成功)

在这里插入图片描述

keil里面的话(xxx.sct文件,这个就是连接文件)

在这里插入图片描述

在这里插入图片描述

验证

将组件注入的代码添加到keil工程中

  1. 这里为了简单点,直接添加到main文件中
#include "system.h"
#include "SysTick.h"
#include "usart.h"	
#include "led.h"
#include "tftlcd.h"
#include "picture.h"
#define bsp_section(x)               __attribute__((section(x)))
#define bsp_used                     __attribute__((used))
typedef int (*init_fn_t)(void);

#define     INIT_EXPORT(fn, level)                                                       \
            bsp_used const init_fn_t __os_init_##fn bsp_section(".bsp_init_fn." level) = fn


#define NET_X_APP_EXPORT(fn)    INIT_EXPORT(fn, "8.1")
						
						
						
void bsp_components_app_init(const init_fn_t *start_ptr,const init_fn_t *end_ptr) {
    volatile const init_fn_t *fn_ptr;
    for (fn_ptr = start_ptr; fn_ptr < end_ptr; fn_ptr++) {
        (*fn_ptr)();
    }
}
						
						
static int net_x_duo_component_init_start() {
    /* 初始化NetX */
    
    return 0;
}

INIT_EXPORT(net_x_duo_component_init_start, "8.0");


static int nex_x_duo_component_init_end() {
    return 0;
}

INIT_EXPORT(nex_x_duo_component_init_end, "9.0");


int app_netx_tcp_client_init() {

    printf("app_netx_tcp_client_init\r\n");

    return 0;
}

NET_X_APP_EXPORT(app_netx_tcp_client_init);

/*******************************************************************************
* 函 数 名         : main
* 函数功能		   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
int main()
{
	u8 i=0;
	u16 color=0;
	
	HAL_Init();                     //初始化HAL库 
	SystemClock_Init(8,336,2,7);   //设置时钟,168Mhz
	SysTick_Init(168);
	USART1_Init(115200);
	
 bsp_components_app_init(&__os_init_net_x_duo_component_init_start,
                            &__os_init_nex_x_duo_component_init_end);



	while(1)
	{

		delay_ms(10);		
	}
}

查看keil的map文件

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

结论

在keil中,不需要去修改链接文件,也可以实现组件自动注入,唯一的耦合,就是需要在合适的地方调用bsp_components_app_init 函数即可

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐