当前位置: 首页 > news >正文

RT-Thread MSH_CMD_EXPORT分析

RT-Thread MSH_CMD_EXPORT分析

1. 源码分析

在rt-thread中,使用FinSH,可以支持命令行。在源码中,使用MSH_CMD_EXPORT导出函数到对应命令。

extern void rt_show_version(void);
long version(void)
{rt_show_version();return 0;
}
MSH_CMD_EXPORT(version, show RT-Thread version information);

MSH_CMD_EXPORT是一个宏:

#define MSH_CMD_EXPORT(command, desc)   \MSH_FUNCTION_EXPORT_CMD(command, command, desc)#define MSH_FUNCTION_EXPORT_CMD(name, cmd, desc)                      \const char __fsym_##cmd##_name[] rt_section(".rodata.name") = #cmd;    \const char __fsym_##cmd##_desc[] rt_section(".rodata.name") = #desc;   \rt_used const struct finsh_syscall __fsym_##cmd rt_section("FSymTab")= \{                           \__fsym_##cmd##_name,    \__fsym_##cmd##_desc,    \(syscall_func)&name     \};

嵌套定义为MSH_FUNCTION_EXPORT_CMD

这里的rt_section也是一个宏:

#define rt_section(x)               __attribute__((section(x)))

在ARM中,这是编译器识别的一个符号。用来指定编译后数据存放的位置。

这里相当于是定义__fsym_version_name__fsym_version_desc,将其放到.rodata.name段中。这两个字符串分别是命令对应的名称和描述。又定义了一个结构体__fsym_version,用来存放命令的名称,描述和函数指针。

struct finsh_syscall
{const char     *name;       /* the name of system call */
#if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)const char     *desc;       /* description of system call */
#endifsyscall_func func;      /* the function address of system call */
};

函数指针指向的函数和命令同名。将定义的finsh_syscall放到FSymTab段中。

没导出一个命令,就会在.rodata.name段中多两个字符串,FSymTab段中多一个struct finsh_syscall结构体。

导出所有需要的命令后,这里FSymTab可以看做是一个数组,元素类型是struct finsh_syscall,长度是所有命令的总和。

2. map文件

编译时,可以指定生成.map文件。KEIL默认会输出map文件到编译目录。

在map文件中搜索__fsym_version,可以找到version命令的名称和描述字符串变量的链接地址和段位置。链接地址是:0x0800ff690x0800ff71,链接段是.rodata.name,与前面分析一致。可以看到上面和下面确实也是其它命令的名称和描述。

在这里插入图片描述

还能搜索到__fsym_version 结构体的链接地址和段。地址是0x080100c4,段是FSymTab。这里可以看到,所有命令的结构体都存到这个段的,间隔也是正好是12个字节,和struct finsh_syscall结构体长度一致。看这个情况,应该是照编译时的按顺序摆放所有结构体到这个段中。

在这里插入图片描述

这里通过编译时,将这个段的起始地址给到msh,然后通过查这个表来对比命令的名称,匹配上了,就执行相应的函数指针,从而就能够执行对应的命令的函数。

查表:

static cmd_function_t msh_get_cmd(char *cmd, int size)
{struct finsh_syscall *index;cmd_function_t cmd_func = RT_NULL;for (index = _syscall_table_begin;index < _syscall_table_end;FINSH_NEXT_SYSCALL(index)){if (strncmp(index->name, cmd, size) == 0 &&index->name[size] == '\0'){cmd_func = (cmd_function_t)index->func;break;}}return cmd_func;
}

_syscall_table_begin_syscall_table_end 变量对应就是FSymTab 段的起始地址。

void finsh_system_function_init(const void *begin, const void *end)
{_syscall_table_begin = (struct finsh_syscall *) begin;_syscall_table_end = (struct finsh_syscall *) end;
}
int finsh_system_init(void)
{extern const int FSymTab$$Base;extern const int FSymTab$$Limit;finsh_system_function_init(&FSymTab$$Base, &FSymTab$$Limit);
}

这里这两个全局变量找不到定义的位置。查找资料得知,FSymTab$$Base表示FSymTab段的开始地址,FSymTab$$Limit表示FSymTab段的结束地址。

参考:https://www.cnblogs.com/King-Gentleman/p/4573652.html

3. bin文件

前面分析得到了__fsym_version_name__fsym_version_desc的地址,分别是0x0800ff690x0800ff71__fsym_version 的地址是0x080100c40x08开始的地址表示ROM上的地址,即FLASH地址空间。

打开编译生成的rtthread.bin文件,搜索versionversion符号出现的地址正好是ff69,是字符串 “version”,紧接着是描述部分内容 “show RT-Thread version information”。由于是bin文件,是相对地址,因此地址前面没有0x08

在这里插入图片描述

在跳到100c4地址:

在这里插入图片描述

这里开始的12个字节,对应的就是__fsym_version结构体中各个字段的内容。注意大小端转换,命令的名称地址69 ff 00 08,即0x0800ff69,描述对应的地址是71 ff 00 08,即0x0800ff71。函数指针对应的地址是4d ea 00 08,即0x0800ea4d,和map文件中链接的地址一致。

在这里插入图片描述

相关文章:

RT-Thread MSH_CMD_EXPORT分析

RT-Thread MSH_CMD_EXPORT分析 1. 源码分析 在rt-thread中&#xff0c;使用FinSH&#xff0c;可以支持命令行。在源码中&#xff0c;使用MSH_CMD_EXPORT导出函数到对应命令。 extern void rt_show_version(void); long version(void) {rt_show_version();return 0; } MSH_CM…...

电脑麦克风没声音怎么办?这3招就可以解决!

最近有用户在使用电脑麦克风进行视频录制时&#xff0c;发现麦克风没有声音。这是什么原因&#xff1f;电脑麦克风没有声音怎么办&#xff1f;关于解决方案&#xff0c;我专门整理了三种方法来帮你们&#xff0c;一起来看看吧&#xff01; 操作环境&#xff1a; 演示机型&#…...

【C++】运算符重载

运算符重载 C为了增强代码的可读性引入了运算符重载&#xff0c;运算符重载是具有特殊函数名的函数&#xff0c;也具有其返回值类型&#xff0c;函数名以及参数列表。其返回值类型和参数列表与普通的函数类型。 函数名字为&#xff1a;关键字operator后面接需要重载的运算符号…...

什么是眼图?(扫盲向)

什么是眼图&#xff1f;&#xff08;扫盲向&#xff09; Ref: What’s eye diagram? 1 基础图示 眼图 2 用途 常用于评估差分链路中的信号传输质量 "眼睛"张得越开&#xff0c;链路信号质量越好 3 观测原理 眼图是传输信号序列在时域上的叠加 4 观测参数 4…...

【C++】类与对象(二)

前言 在前一章时我们已经介绍了类与对象的基本知识&#xff0c;包括类的概念与定义&#xff0c;以及类的访问限定符&#xff0c;类的实例化&#xff0c;类的大小的计算&#xff0c;以及C语言必须传递的this指针&#xff08;C中不需要我们传递&#xff0c;编译器自动帮我们实现&…...

【软考】系统集成项目管理工程师(二十一)项目收尾管理

1. 项目验收2. 项目总结3. 系统维护4. 项目后评价补充:人员转移和资源遣散广义的系统集成项目收尾管理工作通常包含四类典型的工作:项目验收工作、项目总结工作、系统维护工作 以及 项目后评价工作,此外项目团队成员的后续工作也应在收尾管理时妥善安排;狭义的系统集成项目…...

关于公钥与私钥的一点看法

故事的起源 私密性 之前&#xff0c;用户a想给用户b发消息&#xff0c;a希望他自己发出现的消息&#xff0c;只能被b读懂。也就是说a希望发出去的数据是被加密过的&#xff0c;收到消息的人可以是b&#xff0c;c&#xff0c;d&#xff0c;e等等。但是只有b能被读懂。 这个需求…...

深入React源码揭开渲染更新流程的面纱

转前端一年半了&#xff0c;平时接触最多的框架就是React。在熟悉了其用法之后&#xff0c;避免不了想深入了解其实现原理&#xff0c;网上相关源码分析的文章挺多的&#xff0c;但是总感觉不如自己阅读理解来得深刻。于是话了几个周末去了解了一下常用的流程。也是通过这篇文章…...

32个关于FPGA的学习网站

语言类学习网站 1、HDLbits 网站地址&#xff1a;https://hdlbits.01xz.net/wiki/Main_Page 在线作答、编译的学习Verilog的网站&#xff0c;题目很多&#xff0c;内容丰富。非常适合初学Verilog的人&#xff01;&#xff01;&#xff01; 2、牛客网 网站地址&#xff1a;http…...

5分钟快速上手Promise使用

promise 是处理异步编程的一种处理方式&#xff0c;可以将异步操作按照同步操作的方式编写。是一个对象或者构造函数&#xff0c;里面存放着某个未来才会执行的结果的方法&#xff08;一般就是异步操作&#xff09; 自己身上有all、reject、resolve这几个方法&#xff0c;原型上…...

大客户市场:阿里云、腾讯云、华为云“贴身肉搏”

配图来自Canva可画 近年来&#xff0c;随着中国逐渐进入数字化经济快车道&#xff0c;国内企业数字化、智能化升级已是刻不容缓。而为了帮助自身或其他企业实现数字化转型升级&#xff0c;阿里、腾讯、百度、京东、字节、网易、华为等众多国内知名企业早在多年以前&#xff0c…...

华为OD机试 - 求字符串中所有整数的最小和(Python)| 真题+思路+代码

求字符串中所有整数的最小和 题目 说明 字符串 s,只包含 a-z A-Z + - ;合法的整数包括 1) 正整数 一个或者多个0-9组成,如 0 2 3 002 102 2)负整数 负号 - 开头,数字部分由一个或者多个0-9组成,如 -0 -012 -23 -00023输入 包含数字的字符串 输出 所有整数的最小和 …...

企业电子招投标采购系统源码之首页设计

​​ 功能模块&#xff1a; 待办消息&#xff0c;招标公告&#xff0c;中标公告&#xff0c;信息发布 描述&#xff1a; 全过程数字化采购管理&#xff0c;打造从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通供应商门户具备内外协同的能力&#xff0c;为…...

浅谈一下前端工作中全流程多层次的四款测试工具

在应届生找工作的时候&#xff0c;我们经常会见到一条招聘要求&#xff1a;要求实习经历。或者 有实习经历者优先。 为什么大部分公司在招聘时&#xff0c;都要求你必须有实习经历&#xff1f; 商业项目与个人项目不同&#xff0c;一段实习经历&#xff0c;能够熟悉公司中成熟…...

【运算放大器】反相放大电路仿真应用

目录 一、反相放大电路原理&#xff08;简化电路&#xff09; 二、反相放大电路电路原理&#xff08;实际特性&#xff09; 2.1原理图 2.2实际电路 三、虚短 虚断 3.1 虚短 3.2 虚断 四、作业 4.1 &#xff08;反相&#xff09;放大电路设计 4.2 LM741芯片 五、标准…...

数组的操作

1.splice 1.splice 是数组的一个方法&#xff0c;使用这个方法会改变原来的数组结构&#xff0c;splice&#xff08;index &#xff0c;howmany &#xff0c; itemX&#xff09;&#xff1b;这个方法接受三个参数&#xff0c;我们在使用的时候可根据自己的情况传递一个参数&…...

Python - 文件基础操作

目录 文件的读取 open()打开函数 read类型 read()方法 readlines()方法 readline()方法 for循环读取文件行 close() 关闭文件对象 with open 语法 文件的写入 文件的追加 文件的读取 操作 功能 文件对象 open(file, mode, encoding) 打开文件获得文件对象 文件…...

react的useState源码分析

前言 简单说下为什么React选择函数式组件&#xff0c;主要是class组件比较冗余、生命周期函数写法不友好&#xff0c;骚写法多&#xff0c;functional组件更符合React编程思想等等等。更具体的可以拜读dan大神的blog。其中Function components capture the rendered values这句…...

SharpImpersonation:一款基于令牌和Shellcode注入的用户模拟工具

关于SharpImpersonation SharpImpersonation是一款功能强大的用户模拟工具&#xff0c;该工具基于令牌机制和Shellcode注入技术实现其功能&#xff0c;可以帮助广大研究人员更好地对组织内部的网络环境和系统安全进行分析和测试。 该工具基于 Tokenvator的代码库实现其功能&a…...

华为OD机试 - 最大相连男生数(Python)| 真题+思路+代码

最大相连男生数 题目 学校组织活动,将学生排成一个矩形方阵。 请在矩形方阵中找到最大的位置相连的男生数量。 这个相连位置在一个直线上,方向可以是水平的、垂直的、成对角线的或者反对角线的。 注:学生个数不会超过 10000。 输入 输入的第一行为矩阵的行数和列数,接下…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

centos 7 部署awstats 网站访问检测

一、基础环境准备&#xff08;两种安装方式都要做&#xff09; bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats&#xff0…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

k8s从入门到放弃之HPA控制器

k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率&#xff08;或其他自定义指标&#xff09;来调整这些对象的规模&#xff0c;从而帮助应用程序在负…...

全面解析数据库:从基础概念到前沿应用​

在数字化时代&#xff0c;数据已成为企业和社会发展的核心资产&#xff0c;而数据库作为存储、管理和处理数据的关键工具&#xff0c;在各个领域发挥着举足轻重的作用。从电商平台的商品信息管理&#xff0c;到社交网络的用户数据存储&#xff0c;再到金融行业的交易记录处理&a…...

【WebSocket】SpringBoot项目中使用WebSocket

1. 导入坐标 如果springboot父工程没有加入websocket的起步依赖&#xff0c;添加它的坐标的时候需要带上版本号。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dep…...