当前位置: 首页 > 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。 输入 输入的第一行为矩阵的行数和列数,接下…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

LLMs 系列实操科普(1)

写在前面&#xff1a; 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容&#xff0c;原视频时长 ~130 分钟&#xff0c;以实操演示主流的一些 LLMs 的使用&#xff0c;由于涉及到实操&#xff0c;实际上并不适合以文字整理&#xff0c;但还是决定尽量整理一份笔…...

MySQL 8.0 事务全面讲解

以下是一个结合两次回答的 MySQL 8.0 事务全面讲解&#xff0c;涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容&#xff0c;并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念&#xff08;ACID&#xff09; 事务是…...

绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化

iOS 应用的发布流程一直是开发链路中最“苹果味”的环节&#xff1a;强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说&#xff0c;这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发&#xff08;例如 Flutter、React Na…...

React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构

React 实战项目&#xff1a;微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇&#xff01;在前 29 篇文章中&#xff0c;我们从 React 的基础概念逐步深入到高级技巧&#xff0c;涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...

Java后端检查空条件查询

通过抛出运行异常&#xff1a;throw new RuntimeException("请输入查询条件&#xff01;");BranchWarehouseServiceImpl.java // 查询试剂交易&#xff08;入库/出库&#xff09;记录Overridepublic List<BranchWarehouseTransactions> queryForReagent(Branch…...

【阅读笔记】MemOS: 大语言模型内存增强生成操作系统

核心速览 研究背景 ​​研究问题​​&#xff1a;这篇文章要解决的问题是当前大型语言模型&#xff08;LLMs&#xff09;在处理内存方面的局限性。LLMs虽然在语言感知和生成方面表现出色&#xff0c;但缺乏统一的、结构化的内存架构。现有的方法如检索增强生成&#xff08;RA…...