RT-Thread交互接口finish框架分析

RT-Thread的Finsh实现学习 如下是最简单的“hello world"函数, 在函数定义下面有一行宏,纸面意思是Finsh函数导出,下面对宏进行分析\n");先看下RT-Thread官方文档/* else分支下的宏定义 */{ \/* 上面宏定义中调用的宏的定义 *//* 上面宏定义中使用的结构体定义 *//* 上面宏定义中使用的函数指针定义 */ 阅读详情

RT-Thread的经典的shell框架分析,在使用单片机或其他MCU开发的时候交互式必不可少的,一般都采用串口交互的方式。

linux 的shell是属于脚本类的语言风格,finsih shell的语言风格明显是c的。毕竟c比较偏底层,资源占用少,这个对于资源贫瘠的嵌入式系统而言是非常适合的。finish shell从usart获取文本信息,在根据一定的语法规矩将文本语言重新按执行顺序组织一遍,最后再将重新组织的语句翻译成汇编指令,最后交由cpu执行指令。当然finsih shell的汇编指令都是伪汇编指令,而且执行的环境也是虚拟出来的,而这个是编译执行过程,我之后再提。

    语句的执行是以数据为基础的。受限于系统的架构,finish shell里面的数据类型并不多,整体来说分成以下几个部分

数据类型

    针对上述的代码,在int a中,int是指代变量类型,a是变量名,因为这条指令是在串口中读取的,所以a是动态申请的变量,隶属于VAR中。像‘1’‘2’‘3’是属于int型常量,而“+”“*”“-”是符号。而SYS_VAR和SYS_CALL是在编译的时候生成的,分别通过宏FINSH_VAR_EXPORT和FINSH_FUNCTION_EXPORT添加到系统中的。

long hello()
{
   rt_kprintf("Hello RT-Thread!\n");
   return 0;
}
FINSH_FUNCTION_EXPORT(hello, say hello world);

    对于上述的hello函数,通过调用FINSH_FUNCTION_EXPORT就可以添加到finish shell中,在终端中输入hello(),串口就可以打印"Hello RT-Thread!"。

#define FINSH_FUNCTION_EXPORT(name, desc)                     \
        const char __fsym_##name##_name[] = #name;                     \
        const char __fsym_##name##_desc[] = #desc;                     \
        const struct finsh_syscall __fsym_##name SECTION("FSymTab")= \
        {                            \
            __fsym_##name##_name,    \
            __fsym_##name##_desc,    \
            (syscall_func)&name        \
        };

    具体分析FINSH_FUNCTION_EXPORT(hello, say hello world),其实这个宏就是申请了3个变量_fsym_hello_name[]=’hello’,_fsm_hello_desc[]=’Hello RT-Thread!\n’,

   _fsym_hello={_fsym_hello_name,,_fsm_hello_desc,hello}。说穿了就是_fsym_hello里有3个4字节的指针,分别指向_fsym_hello_name,_fsm_hello_desc[]和hello()函数。那_fsym_hello是如何和SYS_CALL扯上关系的呢?这就要从SECTION("FSymTab")说起了。SECTION()是一个宏变量,针对不同的编译平台对于不同的操作,但无论编译平台如何其作用是相同的。本人编译平台是MDK,打开rtthread-stm32.sct文件我们可以看到

LR_IROM1 0x08000000 0x00080000 { ; load region size_region
  ER_IROM1 0x08000000 0x00080000 { ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x00010000 { ; RW data
   .ANY (+RW +ZI)
  }
}

     这个文件作用主要是指出了编译工程后链接文件的各个段的地址空间。我们知道编译程序一般会生成text,rodata,data,bss以及一些其他的段,我们可以通过sct将某个函数的代码段放到某个地址空间,也可以将它的数据段放到另一个地址空间。一般来说,我们不会蛋疼的去安排每个.c文件或是函数的链接地址空间,因为系统已经默认优化好了但是我们必须知道是可以通过修改sct来改变链接地址空间的。这个相信研究过linux内核编译的同学一定心领神会。然后再看rtthread-stm32.map文件,我截取了与FSymTab相关的一段。

FSymTab$$Base       0x08013614   Number   0 led.o(FSymTab)
 __fsym_led         0x08013614   Data    12 led.o(FSymTab)
 __fsym_list_mem    0x08013620   Data    12 mem.o(FSymTab)
 __fsym_hello       0x0801362c   Data    12 cmd.o(FSymTab)
 __fsym_version     0x08013638   Data    12 cmd.o(FSymTab)
 __fsym_list_sem    0x08013644   Data    12 cmd.o(FSymTab)
 __fsym_list_event  0x08013650   Data    12 cmd.o(FSymTab)
 __fsym_list_mutex  0x0801365c   Data    12 cmd.o(FSymTab)
 __fsym_list_mailbox  0x08013668 Data    12 cmd.o(FSymTab)
 __fsym_list_msgqueue 0x08013674 Data    12 cmd.o(FSymTab)
 __fsym_list_mempool  0x08013680 Data    12 cmd.o(FSymTab)
 __fsym_list_timer  0x0801368c   Data    12 cmd.o(FSymTab)
 __fsym_list_device 0x08013698   Data    12 cmd.o(FSymTab)
 __fsym_list        0x080136a4   Data    12 cmd.o(FSymTab)
 __fsym_ls          0x080136b0   Data    12 dfs_raw.o(FSymTab)
 __fsym_mkdir       0x080136bc   Data    12 dfs_raw.o(FSymTab)
 __fsym_rm          0x080136c8   Data    12 dfs_raw.o(FSymTab)
 __fsym_cat         0x080136d4   Data    12 dfs_raw.o(FSymTab)
 __fsym_mkfs        0x080136e0   Data    12 dfs_elm.o(FSymTab)
FSymTab$$Limit      0x080136ec   Number   0 dfs_elm.o(FSymTab)
Region$$Table$$Base 0x080136ec   Number   0 anon$$obj.o(Region$$Table)
Region$$Table$$Limit 0x0801370c  Number   0 anon$$obj.o(Region$$Table)
VSymTab$$Base        0x0801370c  Number   0 cmd.o(VSymTab)
  __vsym_dummy      0x0801370c   Data    16 cmd.o(VSymTab)
VSymTab$$Limit      0x0801371c   Number   0 cmd.o(VSymTab)

   相信大家找到了_fsym_hello了吧,所谓的SECTION("FSymTab")也就是把_fsym_hello这个12个字节的常量,保存在FsymTab这个段内,链接的时候根据sct文件安排按顺序将FSymTab放到Flash的地址空间里去。也就是说,无论我在这个或那个文件用调用了FINSH_FUNCTION_EXPORT,说生成的_fsym***一定是连续分布在flash的地址空间了。FINSH_VAR_EXPORT的执行原理和FINSH_FUNCTION_EXPORT一样,只不过存的是变量的地址,我就不再重复说明了。

  至于为什么要这么大费周章的将FSymTab和VSymTab的变量放到一起,就是为了方便生成syscall_table和sysvar_table。在finsh_system_init中有两个函数

finsh_system_function_init(&FSymTab$$Base, &FSymTab$$Limit);

finsh_system_var_init(&VSymTab$$Base, &VSymTab$$Limit);

void finsh_system_function_init(void* begin, void* end)
{
    _syscall_table_begin = (struct finsh_syscall*) begin;
    _syscall_table_end = (struct finsh_syscall*) end;
}

void finsh_system_var_init(void* begin, void* end)
{
    _sysvar_table_begin = (struct finsh_sysvar*) begin;
    _sysvar_table_end = (struct finsh_sysvar*) end;
}

    再看一下rtthread-stm32.map,是不是找到了FSymTab$$Base,FSymTab$$Limit和VSymTab$$Base, VSymTab$$Limit,就这样我们生成了syscall_table和sysvar_table,而这系统就是用这两个表来查找SYS_CALL和SYS_VAR变量的。

    除了静态的生成SYS_CALL函数外,rt_thread也支持动态的加载SYS_CALL函数。

void finsh_syscall_append(const char* name, syscall_func func)
{
    /* create the syscall */
    struct finsh_syscall_item* item;

    item = (struct finsh_syscall_item*)rt_malloc(sizeof(struct finsh_syscall_item));
    if (item != RT_NULL)
    {
        item->next = NULL;
        item->syscall.name = strdup(name);
        item->syscall.func = func;

        if (global_syscall_list == NULL)
        {
            global_syscall_list = item;
        }
        else
        {
            item->next = global_syscall_list;
            global_syscall_list = item;
        }
    }
}

     注意这里将函数添加到了global_syscall_list链表中了,而这个链表的功能是相当于syscall_table的,只不过它是负责动态生成的SYS_CALL。与之对应的有global_sysvar_list链表,其对应的是SYS_VAR。

好用的shell工具——finalShell3.9.5 好用的shell工具——finalShell3.9.5 软件下载安装 激活 专业版功能 在这里记录一下这款shell工具,主要是一换环境就需要重新安装,记在csdn上方便以后自己查看 软件下载安装 因为finalshell下载后需要激活,目前的激活程序只能到3.9.5版本,这里给一个3.9.5版本的地址吧,官网地址是最新的 3.9.5下载地址 阅读详情

相关推荐

用水晶报表插件实现打印

思路: (1) 下载水晶报表插件 (2) 给项目引用水晶报表插件 (3) 创建数据集 (4) 绘画水晶报表 (5) 代码处理打印 首先我们是引用水晶报表来打印的那么我们就要下载水晶报表插件并引用 下面就是引用水晶报表插件的截图 在项目里点击添加新建项弹出这个页面就点击Reporting添加水晶报表插件就行了 前提是要安装了水晶报表插件 接着就是添加数据集了 数据集是用来接收需要打印的数据的必需创...

weixin_44549995的博客 914

[RTT例程练习] 6.2 在 Finsh 中运行自定义函数

可以直接在Finsh中运行自己定义的函数。官方有三种方式,我觉得第二种比较方便,其他就不介绍了。 首先需要在application.c 中包含 finsh.h 头文件,然后在函数下方添加宏 FINSH_FUNCTION_EXPORT(fun_with_arg, function with a argument); 程序 #include <rtthread.h&g...

weixin_30367543的博客 364

C# 水晶报表问题的一些总结(持续更新)

1.数据从DataSet导入到报表中不能直接oRpt.SetDataSource(ds);            应该oRpt.SetDataSource(ds.Tables[0]);            或者oRpt.SetDataSource(ds.Tables["表名"]);2.ArrayList 二维数组的应用      例子:      原思路:将得到的每条二进制图片数据byte[]

Rommen的专栏 4788

剖析RT-Thread中console与finsh组件实现(3)

最后,我们看一下一个cmd命令是怎么加入到命令空间里的: 关键在于宏定义 MSH_CMD_EXPORT ,内容如下: 这里在cmd名称前加了 __cmd_ 刚好可以与之前匹配代码相印证。 宏定义 FINSH_FUNCTION_EXPORT_CMD 内容如下: 和之前自动初始化那里很相似,这里是把cmd的名字和注释变量的数组存于段.rodata.name内。而把cmd结构体填充之后存于段名FSymTab内。 为了更加直观,我把参数都替换一下,实际内容如下: FINSH_FUNCTION_EXPORT_C

飞临云的博客 1356

水晶报表打印

水晶报表打印 开发工具与关键技术:VS、 作者:#33 撰写时间:撰写时间:2019年05月02日 在老师MVC教学中学习关于水晶报表打印的知识,自己再理清思路做了一遍。方法步骤: 01、安装水晶报表插件——02、项目引入安装的插件并创建空白报表模板——03、创建数据集——04、设置报表模板——05、控制器写查询方法——06、视图水晶报表打印方法(显示页面) 安装水晶报表插件: 0...

weixin_44484621的博客 446

RT-Thread 入门与实战 - 第11章:FinSH 控制台开发

系统调试接口查看/修改系统参数调用系统函数执行自定义命令\n");关键点说明内置命令使用掌握list_thread/free等调试命令推荐的自定义命令方式参数处理argc/argv的规范使用方法线程安全避免在命令中执行耗时操作扩展阅读《RT-Thread编程指南》FinSH章节FinSH源码分析(components/finsh)

2301_79143213的博客 694

【水晶报表实战】不同的子报表对应不同的页眉

<br />本文为:http://topic.youkuaiyun.com/u/20100726/15/83a97e4a-1e17-4d0d-be69-529f85644191.html所作。<br /><br />整理命题如下:<br /><br />页面内容比较复杂,需要来源于多个静态页面及多个动态数据页面<br />使用子报表进行数据组合,每页要显示一个 【第N页,共M页】的标记<br />而且不同的子报表,页眉内容也不同。<br />但是因为水晶报表本身的问题,子报表中的第N页,共M页的计数是错误的<br

阿泰的软件实用主义 5088

水晶报表图表实战:C#中柱形图、折线图、面积图、饼图实现指南

在工业数据可视化与企业报表场景中,柱形图、折线图、面积图与饼图是呈现对比、趋势与占比最直观的方式。很多C#项目仍基于Crystal Reports(水晶报表)维护大量模板,如何在不替换旧系统的前提下嵌入图表成为关键。水晶报表内置图表引擎,其核心原理是读取分组汇总数据而非明细记录,因此正确设置分组与汇总字段是图表显示的基础。通过C#调用ReportDocument对象动态绑定DataTable,并利用ICrystalChartObject接口实现图表类型切换,可让老报表快速拥有交互式可视化能力。本文从图表数据

weixin_30899023的博客 163

通用水晶报表模板创建实例

通用水晶报表模板创建实例1.背景目的    当有一大批报表需要你通过水晶报表来实现其打印、导出功能时,你不得不为这些具有相似结构的报表创建一一对应模板(rpt文件)而感到烦恼,其实,对于每一个编程人员来说,内心早就有一种想法:能不能通过一个通用的报表模板来实现这些报表所需要的功能呢?下面就从这个念头入手,解决这个烦人的问题。 2.方法思路    仔细研究一下水晶报表模板rpt的

xiaobaigz的专栏 2392

C#水晶报表图表开发指南:柱形图、线形图、面积图与饼图实战

数据可视化在企业管理系统中至关重要,报表工具通常通过图表直观呈现数据。本文从基础概念出发,介绍水晶报表(Crystal Reports)在C#开发环境中的图表解决方案,阐述其工作原理:图表组件与分组汇总字段绑定,并自动随报表导出。针对柱形图、线形图、面积图和饼图,给出了不同业务场景下的选择策略,以及从报表设计器到代码层DataTable数据绑定的完整实现路径。同时讨论了中文标签乱码、图表空白、饼图单扇区等常见问题的排查方法,帮助开发者在财务、生产管理等传统系统中高效落地图表功能。

weixin_31315567的博客 232

RT thread在STM32F429实现finish shell功能

在STM32F429上实现RT thread的外部SDRAM拉起finish shell线程实现功能,通过串口接收和发送

水晶报表中几种交叉表的实现方法

水晶报表中几种交叉表的实现方法 交叉表,顾名思义,就是行和列交叉,用于将行上的数据,作为列指标来呈现。 用一个图直观的说明一下,就是将图1中的数据样式 最终呈现为如图2的效果 实际在使用中,我们可以用两种方式来实现这个效果 一是在数据库端用SQL将数据组织成交叉表,然后对这个数据以普通的报表形式呈现。 在这里,我摘录了网上一篇写的比较直白的文章,请参考此链接

军哥博客欢迎您 3303

RabbitMq安装

本文详细介绍了在CentOS7系统上离线部署RabbitMQ4.3.2的完整流程。主要内容包括:1)准备RabbitMQ安装包、Erlang依赖和socat网络工具;2)安装系统编译依赖并编译安装Erlang;3)部署RabbitMQ服务,配置环境变量和socat依赖;4)启用Web管理插件并创建管理员账号;5)配置防火墙放行端口;6)设置Systemd开机自启服务;7)提供常用运维命令。文档特别强调离线部署注意事项,包括socat依赖、版本兼容性、账号安全及主机名配置等问题,为生产环境部署提供完整解决方案

sinat_25821779的博客 323

水晶报表中如何动态增加字段

说明:       最近项目中要用到水晶报表,水晶报表的功能的确非常强大,但是有一个问题一直困扰着我,那就是它对于每种数据表结构都必须建一个报表文件。尽管它有两种使用方式,“pull”模式和“push”模式。但是推模式下仍然需要先根据dataset的结构生成相应的报表文件。这样就很不灵活,试想如果之前并不知道数据集dataset的结构,怎么用报表?即便知道有哪些表格,如果表格数太多,对于每个表格生

飘逸软件技术信息服务网 1275

深入解析磁盘性能测试:vdbench与fio的实战对比

本文深入对比了磁盘性能测试两大工具vdbench与fio的核心定位与实战应用。vdbench擅长多客户端、可编排的存储系统集成测试,而fio则以灵活的单机深度定制见长,是测试硬件极限和模拟特定应用IO模型的利器。文章通过安装指南、参数解析和典型场景对比,帮助读者根据需求选择合适工具,精准评估磁盘性能。

weixin_29300931的博客 330

STM32F407硬件SPI驱动ADS1220避坑指南:从寄存器读不到数据到采样值异常的完整解决流程

本文详细解析了STM32F407硬件SPI驱动ADS1220的常见问题与解决方案,包括SPI配置、寄存器读取异常、采样值优化等关键环节。通过CubeMX配置技巧和Keil调试经验,帮助开发者快速排查从通信失败到数据异常的各种问题,实现高精度数据采集系统的稳定运行。

weixin_26878995的博客 158

打印水晶报表

作者:坚定的守猴 撰写日期:2019年5月23日 开发软件和关键技术:VS; 编程软件_CRforVS_13_0_14 在项目里面,实现数据的导入和导出是一种必不可少的功能。然而数据的导入导出的方式有很多种。现在我们就来看一下数据导出的一项功能——打印水晶报表。 之前对于数据的导入或者导出一般的做法都是从外面导入模板进来,然后就再把里面的数据放到模板里面。而水晶报表和它们不一样的是,它有自己的辅助...

weixin_44541267的博客 340

现代SerDes解剖:从CTLE/DFE到PAM4与ADC+DSP架构

高速有线通信的物理层瓶颈,正从并行总线的时钟偏斜转向串行链路的信号完整性挑战。SerDes作为解决这一问题的核心技术,其内部架构远超“并转串”的朴素认知。接收端的CTLE线性均衡与DFE判决反馈均衡,配合CDR时钟恢复,共同构成对抗信道损耗与码间干扰的关键机制。随着速率迈向56G/112G,PAM4调制以电平幅度换取带宽,而ADC+DSP架构则把均衡算法搬入数字域,实现更灵活的非线性补偿。理解这些模块如何协同工作,是调试PCIe、以太网等高速链路、优化眼图余量与抖动预算的基础,也是硬件工程师从盲目调参走向系

weixin_29194817的博客 300

C#在水晶报表中加载ArcEngine地图

 在水晶报表中加载ArcEngine地图         众所周知        水晶报表中动态更新        只能通过与数据库的连接实现         于是得出        若要将地图窗口的视图动态打印出来        可以通过以下这种思路:        1.构建数据表,最好是在本地,避免网络耗时;在其中添加blob字段。        2.程

yanleigis的专栏 2173

Quartus Prime 软件 USB-blaster 驱动安装失败【已解决】

一、安装步骤 1、将FPGA 开发板插入电脑时,未安装驱动的电脑会提示安装usb-Blaster驱动。Windows搜索框打开设备管理器,在“其他设备”下会发现黄色感叹号的“USB-Blaster”的设备驱动。 2、Quartus系列软件的安装目录下自带USB-blaster的驱动程序,右键更新驱动,选择驱动目录:(D:\intelFPGA\18.1\quartus\drivers\usb-blaster,文件位置和版本请按照自己安装的路径选择),点击Next开始安装。 3、安装成功,重启电脑即可使

adolphwang_909086的博客 6万+

搜索引擎——ElasticSearch汇总

汇总——ElasticSearch篇 全文检索 问题1:什么是全文检索? 基本概念:对**非结构化数据/结构化数据**先建立**索引**,再对索引进行搜索**文档**的过程叫做全文检索。 什么是非结构化与结构化数据? - 非结构化数据:没有固定的格式的数据(html,word,excel)---没有固定长度,字段约束,描述,散列数据 - 结构化数据:有固定的格式的数据(如:数据库数据)---有固定长度(varchar(50)),字段类型,描述修饰数据 搜索算法:顺序扫描法、倒排索引法 - 顺序

alonewolf_99的博客 1839

【原创】基于WinForm的水晶报表开发

1. 出现以下错误 CS1061 “Settings”未包含“DatabaseConnectionString”的定义,并且找不到可接受第一个“Settings”类型参数的可访问扩展方法“DatabaseConnectionString”(是否缺少 using 指令或程序集引用?) 直接删除飙红的代码,类似:this._connection.ConnectionString = global::xxxxx.Properties.Settings.Default.Dat...

jam12315的专栏 1888

“探索thumbdata4文件的奥秘:编程中的神秘存在“

综上所述,thumbdata4文件在编程中是一个常见的存在,与图库应用程序和图片浏览器密切相关。通过使用适当的库和工具,我们可以读取和处理thumbdata4文件中的缩略图数据,以提供更好的用户体验。我们首先读取8字节的块头,其中包含了下一个缩略图块的大小。你可以根据自己的需求来定义对块数据的处理方式,例如将其保存为图像文件或进行其他的分析操作。thumbdata4文件通常以二进制格式存储,其中包含着设备上浏览过的图片的缩略图。因此,你可能需要根据具体的thumbdata4文件结构进行适当的解析和处理。

JieLun_C的博客 792

.NET下水晶报表传递数据的两种模式

摘自:http://hi.baidu.com/xbzhu/blog/item/95158d5066d3f16785352427.html   摘 要 本文介绍了水晶报表的数据传递的两种模式,指出了这两种模式的优缺点及适合的情况,最后实例的方式具体实现。 关键词 水晶报表,推模式,拉模式,数据集     水晶报表(Crystal Reports)是世界领先的用于创建交互报表的软件包,报表可以

VS_URL的专栏 2734

015、架构_配置文件_管理节点(proxymanager.ini)

该配置文件中的参数在后台配置,两种生效方式:*所有参数重启生效。*部分参数可以使用工具dbtool动态生效。动态生效命令为:dbtool-pm-load-config。配置文件“proxymanager.ini”用于设置元数据管理模块的信息。文件路径为“~/etc”。配置文件“proxymanager.ini”是普通的文本文件。默认值proxymanager-alarmconfutf8.txt。配置错误或不配置,PM无法连接MDS,无法服务。获取元数据失败超时处理时间。异常时请求启动对等回滚。

Oracle/MySQL 到 国产信创数据库|迁移 · 调优 · 信创替换 329

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

水晶报表

 有很多很多次被问到: 为什么水晶报表那么麻烦,每做一张报表都要选表,画线画格子,有没有一种方法可以一劳永逸? 做一个模板,然后用不同的表都能用? 还有就是能不能动态选择列,而且选择列后能报表能自动适用这个变化? 甚至有些人也因为放弃了水晶报表,实际上这些都是水晶报表可以做到的。 我之前曾零散地写过几篇,在论坛和博客中都曾反复讲解过思路,但是并没有系统地去解决这个问题,在这里,我来讲解一下原理和实

caodaxuan的专栏 382

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

上一篇: I2C驱动调试
下一篇: 华为--嵌入式软件工程师面试题汇总(转)
逐梦,无惧!
博客等级 码龄16年 8848粉丝 61原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值