嵌入式调试技巧-代码自动初始化

news2024/11/25 4:36:50

代码自动初始化

概述

在嵌入式开发过程中,可能会遇到初始化代码自动初始化,比如RTT中就运用到这项技术。那么初始化代码是如何做到自动化调用的呢?

在嵌入式实际开发过程中,往往需要对 bsp 部分进行外设配置,以及一些模块、参数进行初始化,常见的方法如下:

  • 将各个部分的初始化代码分别封装成一个单独的函数,然后再main函数刚开始的地方进行调用已实现初始化;
    该方法简单粗暴,但是此方法存在一些不足
  • 所有初始化均需要在main函数内调用,不能做到彻底解耦
  • 框架设计不友好,部分非业务部分初始化,如软件框架类的初始化,往往不希望还需要业务在main函数内调用初始化

那有没有一种方法能解决上述的问题呢?
答案是肯定的,本文将向大家介绍一种自动初始化的实现方式。注意,此方案在不同的平台,由于链接器使用的链接脚本可能不一致,容易出现问题,需要大家重点注意,细节在下文中将详细介绍。

案例讲解

为了更好的阐述代码自动初始化的技术,本文通过一个demo程序进行讲解如何实现该技术,以下是该demo程序:

typedef void (*init_func)(void);

#define INIT_EXPORT(fn, level)    const init_func init_##fn __attribute__((used, section(".init."level))) = fn
void start(void)
{
    return;
}
INIT_EXPORT(start, "1");
void end(void)
{
    return;
}
INIT_EXPORT(end, "4");

接下来分析上述代码:

关于宏定义:#define INIT_EXPORT(fn, level) const init_func init_##fn attribute((used, section(".init."level))) = fn的代码分析如下:

  • 首先定义一个函数指针typedef void (*init_func)(void);用于所有初始化函数的指针类型;
  • 定义宏INIT_EXPORT(fn, level) 作为一个函数接口,后续的初始化函数可通过此接口加入自动初始化列表内
    • const init_func init_##fn,其中##为连接符,假设参数fn为test,则init_##fn为init_test;init_func 为指令类型
    • const init_func init_##fn与const int *p是同一个概念,只不过数据的类型不一样
  • const init_func init_##fn定义了一个init_func类型的指针变量,此指针还没有赋值初始化,因此将参数fn赋值给此变量,宏定义可以简化为#define INIT_PORT(fn, level) const init_func init_##fn = fn(__attribute__先忽略)
  • attribute((used, section(".init."level))) 这是一个关键字进行修饰,可以做如下拆解:
    • attribute((used))用来告诉编译器,此函数如果没有被调用,也不要被优化
    • attribute((section(".init."level)))用来修饰的内容放入指定的段“.init.”level中(编译器在你编程的时候自动完成),注意level为宏的第二个传入参数,传入来的时候是一个字符串,所以不用加#加进行拼接,C语言中两个字符串会自动拼接。

综述分析:宏#define INIT_EXPORT(fn, level) const init_func init_##fn attribute((used, section(".init.“level))) = fn,其实定义了一个init_func类型的函数指针,并将此函数指针通过__attribute__((used, section(”.init."level)))指定存放到特定的段内。

demo程序中定义了两个函数:

  • void start(void)
  • void end(void)
    并通过宏INIT_EXPORT(fn,level)添加到自动初始化段内
  • INIT_EXPORT(start, “1”);
  • INIT_EXPORT(end, “6”);

注意事项:

  1. level参数是一个字符串,而不是数字
  2. 用户自定义初始化函数编译器会自动添加到start和end的level值中间,是由于编译器采用__attribute__((section(".init."level))) 指定放入到指定段的时候会针对其进行排序,keil默认采用根据名称的方式排序,因此需要放置在用户自定义的,放置在用 start 和 end 中间,方便后续遍历 start 和 end 中间部分进行完整初始化

最后的vhdl_board_init初始化函数:

void vhdl_board_init(void)
{

    const init_func *fn_ptr = NULL;

    for (fn_ptr = &init_start; fn_ptr < &init_end; fn_ptr++)
    {
        (*fn_ptr)();
    }
}

此函数在main函数中调用,通过for循环遍历start和end中间的段,并调用进行初始化。

通过上述一系列的操作,用户初始化函数时只需要调用宏INIT_EXPORT(fn,level)即可完成自动初始化。

为了针对不同类型的初始化,可以将start和end之间距离拉大点,用作区别不同类型的初始化,如下所示

INIT_EXPORT(start, "1");
INIT_EXPORT(end, "6");

并且对外开放相应的接口宏

#define INIT_BSP_PORT(func)		INIT_EXPORT(func, "2");
#define INIT_DATA_PORT(func)	INIT_EXPORT(func, "3");

用户通过调用 BSP_INIT_PORT 和 DATA_INIT_PORT 进行注册

检测初始是否成功??

检测MAP文件

在上述方法中,我们使用 attribute((section(".init."level))) 将数据存入指定的段内,那么是否成功了呢,以及排序方式是否符合我们的预期呢?接下来我们需要通过检查map文件进行确认。

keil / MDK 环境检查

keil/mdk编译完程序之后,双击工程栏处的工程,可以查看map文件,还不知道的可以网上搜下

以下是上述demo的map文件中关键字段,我们可以看到我们需要的数据存放在正确的段内,并且排序也是正常的,注意一定要检查排序和字段是否完整!
在这里插入图片描述

gcc 环境检查

详细过程见gcc环境检查

综上所述:按照demo程序编写初始化代码是不是变得更见简单了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/596447.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

springboot+vue+java在线考试系统 试题库组卷系统

这次开发的精品在线试题库系统有管理员&#xff0c;教师&#xff0c;学生三个角色。管理员功能有个人中心&#xff0c;专业管理&#xff0c;学生管理&#xff0c;教师管理&#xff0c;试卷管理&#xff0c;试题管理&#xff0c;考试管理。教师可以管理试题和试卷&#xff0c;查…

基于C#制作一个贪吃蛇小游戏

基于C#制作一个贪吃蛇小游戏,简单耐玩,操作简单。 一、项目创建1.1、创建1.2、素材准备1.3、界面绘制1.4、设置定时器1.5、获取键盘事件1.6、游戏结束事件二、帮助类2.1、坐标DTO2.2、果实DTO2.3、移动DTO结语一、项目创建 1.1、创建 打开Visual Studio,右侧选择创建新项目…

AutoGPT 使用教程及上手体验(一分钟配置可用)

ChatGPT 是新一代 AI 文本助手&#xff0c;可以帮助解决我们在多个领域的问题。 在某些复杂问题上&#xff0c;ChatGPT 需要经过不断的调教与沟通&#xff0c;才能得到接近正确的答案。 当你是某个领域的专家时&#xff0c;你很容易做到这一点。 但是&#xff0c;在你不熟悉…

【Linux】文件的压缩和解压

欢迎来到博主 Apeiron 的博客&#xff0c;祝您旅程愉快 &#xff01; 时止则止&#xff0c;时行则行。动静不失其时&#xff0c;其道光明。 目录 1、压缩格式 2、压缩软件 3、tar 命令简介 4、tar 命令压缩 5、总结 1、压缩格式 在市面上有非常多的压缩格式&#xff0c;…

蓝牙技术|苹果Apple Watch新专利,可监测用户更多健康指标

根据美国商标和专利局&#xff08;USPTO&#xff09;近日公示的清单&#xff0c;苹果获得了一项 Apple Watch 相关的专利&#xff0c;可以在表带嵌入 NFC、RFID 和蓝牙等组件&#xff0c;从而实现某些特定功能。 在苹果的构想中&#xff0c;未来的 Apple Watch 可以“识别”表…

BR 5AP920.1505-01 模拟电阻式触摸屏

材料编号: 5AP920.1505-01 描述: 15英寸XGA彩色TFT显示屏模拟电阻式触摸屏安装深度小无风扇运行可以用显示链接卡或PPC300升级 自动化面板AP920&#xff0c;15英寸XGA彩色TFT显示屏&#xff0c;带触摸屏(电阻式)&#xff0c;3个USB 2.0接口&#xff0c;用于自动化面板链接的…

万方 protobuf 反序列化

protobuf 是一种轻便高效的结构化数据存储格式&#xff0c;可以用于结构化数据串行化&#xff0c;或者说序列化。 在网络传输方面&#xff0c;相比传统的json&#xff0c;有着更快、更小&#xff0c;且加密性好的特点。 在实际应用中&#xff0c;万方数据库官网发送的请求&…

03 【数据代理 事件处理】

03 【数据代理 事件处理】 1.数据代理 了解数据代理需要js的一些知识&#xff1a;Object.defineProperty()&#xff0c;属性标志&#xff0c;属性描述符&#xff0c;getter&#xff0c;setter。。。 1.1数据代理 建议学习文章地址&#xff1a; https://zh.javascript.info/p…

MathType7.4永久中文Mac+Win全平台版本

MathType7.4版是一款功能强大、专业实用、应用范围广的数学公式编辑器软件&#xff0c;这款软件采用了简体中文操作界面并且完美兼容office、wps等一系列常见办公工具&#xff0c;这样就能够很好的为相关用户省去了许多繁琐的操作步骤&#xff0c;用户在这里可以轻轻松松进行公…

最小编译器和 UI 框架「GitHub 热点速览」

作者&#xff1a;HelloGitHub-小鱼干 如果有一个关键词来概述本周的 GitHub 热门项目的话&#xff0c;大概就是 van 和 sectorc 都用到的 smallest。只不过一个是前端的响应式框架&#xff0c;一个是搞编译的 C 编译器。它们除了轻量化这个共同特点之外&#xff0c;还有好用&am…

解决无法ssh命令登录wsl问题

本地主机ssh登录wsl报错被拒绝访问 C:\Users\jiangcheng> ssh rootxxx.xx.xxx.xx -p 22 ssh: connect to host xxx.xx.xxx.xx port 22: Connection refused 解决步骤如下&#xff1a; 1&#xff0c;解决密码不对的问题 wsl默认用户名root的密码是随机的&#xff0c;需要…

【深度学习】yolov7 pytorch模型转onnx,转ncnn模型和mnn模型使用细节

文章目录 前言1.前置1.1 安装必要的库1.2 .pt 权重转ncnn 和mnn所需要的权重 2、编码C项目1.ncnn2.mnn 总结 前言 yolov7 pytorch模型转onnx&#xff0c;转ncnn模型和mnn模型使用细节&#xff0c;记录一下 git仓库&#xff1a; yolov7 https://github.com/WongKinYiu/yolov7 n…

如何基于G6进行双树流转绘制? | 京东云技术团队

1. 背景 业务背景&#xff1a;CRM系统随着各业务条线对线索精细化分配的诉求逐渐增加&#xff0c;各个条线的流向规则会越来越复杂&#xff0c;各个条线甚至整个CRM的线索流转规则急需一种树形的可视化的图来表达。 技术背景&#xff1a;在开发之前考虑了三种方案&#xff0c;…

选什么样的软件平台开发能让办公效率得到提升?

在当今快节奏的时代中&#xff0c;办公自动化发展已成为趋势&#xff0c;采用什么样的软件平台开发能让办公效率得到大大提升&#xff1f;面对众多粉丝朋友提出的问题&#xff0c;作为低代码开发平台服务商&#xff0c;流辰信息有责任有义务与大家分享好产品。因为这是能提升办…

GPT现状终于有人讲清楚了!OpenAI大牛最新演讲爆火,还得是马斯克钦点的天才

量子位 | 公众号 QbitAI 继Windows Copilot发布后&#xff0c;微软Build大会热度又被一场演讲引爆。 前特斯拉AI总监Andrej Karpathy在演讲中认为思维树&#xff08;tree of thoughts&#xff09;与AlphaGo的蒙特卡洛树搜索&#xff08;MCTS&#xff09;有异曲同工之妙&#…

MySQL数据库 4.SQL通用语法及分类

目录 &#x1f914;SQL通用语法&#xff1a; &#x1f60a;语句&#xff1a; &#x1f60a;注释&#xff1a; &#x1f914;SQL语句分类&#xff1a; &#x1f60a;1.DDL语句&#xff1a; &#x1f60a;2.DML语句&#xff1a; &#x1f60a;3.DQL语言&#xff1a; &…

springboot+vue+element-ui在线招投标系统

本在线招投标系统管理员管理个人中心&#xff0c;投标人管理&#xff0c;招标人管理&#xff0c;评标人管理&#xff0c;招标信息管理&#xff0c;投标信息管理&#xff0c;评标信息管理&#xff0c;中标信息管理&#xff0c;系统管理。管理员负责所有的管理信息&#xff0c;招…

DAY06_Mybatis

目录 1 MyBatis1.1 快速入门1.1.1 创建user表&#xff0c;添加数据1.1.2 创建模块&#xff0c;导入坐标1.1.3 编写 MyBatis 核心配置文件1.1.4 编写 SQL 映射文件1.1.5 编码 1.2 解决SQL映射文件的警告提示1.3 Mapper代理开发1.3.1 定义与SQL映射文件同名的Mapper接口&#xff…

NFS网络文件挂载【虚拟机到开发板】

注意&#xff1a;首先要确保虚拟机和开发板之间可以互相访问&#xff0c;即配置桥接网卡&#xff0c;如果在同一个网段下但是无法ping通可能是防火墙的问题。可以查看博文解决&#xff1a;vmware虚拟机设置双网卡 注意&#xff1a;当前虚拟机版本为18.04&#xff0c;若虚拟机版…

焊接铁件的一些常识

焊接整体过程 简单来说就是通过各种方式将金属熔化后冷却结合。而焊接过程中一般会有保护气体&#xff0c;例如氩气&#xff0c;二氧化碳。就是常听到的氩弧焊和二保焊。而最常见的是药皮包裹着金属心的焊条&#xff0c;而焊条的药皮就是加热后产生了保护气。弧光是焊条和焊件…