当前位置: 首页 > 科技观察

使用RT-Thread的FinSH编程硬件

时间:2023-03-19 20:50:40 科技观察

由于物联网(IoT)的兴起,编程硬件变得越来越普遍。RT-Thread允许您使用FinSH从Linux命令行与设备通信。RT-Thread是一种用于编程物联网(IoT)设备的开源实时操作系统。FinSH是RT-Thread的命令行组件,它提供了一套操作界面,让用户可以通过命令行与设备进行通信。主要用于调试或查看系统信息。通常,开发调试使用硬件调试器和printf日志来显示。但在某些情况下,这两种方法不是很有用,因为它是从正在运行的东西中抽象出来的,而且它们可能很难解析。然而RT-Thread是一个多线程系统,当你想知道正在运行的线程的状态,或者手动控制系统的当前状态时,这很有用。因为它是多线程的,所以您可以拥有一个交互式shell,您可以在其中直接在设备上输入命令、调用函数以获取所需信息或控制程序的行为。如果你只习惯于像Linux或BSD这样的现代操作系统,这对你来说可能显得平淡无奇,但对于硬件黑客来说,这是一种奢侈的奢侈,远远超过将串行电缆直接连接到板上以获得一丝错误方法.FinSH有两种模式。C语言的解释器模式,称为c-style。传统的命令行模式,称为msh(moduleshell)。在C语言解释器模式下,FinSH可以解析和执行大多数C语言表达式,并使用函数调用来访问系统上的函数和全局变量。它还可以从命令行创建变量。在msh模式下,FinSH的运行方式类似于传统的shell,例如Bash。GNU命令标准在开发FinSH时,我们了解到在编写命令行应用程序之前需要熟悉GNU命令行标准。这种标准实践框架有助于为界面带来熟悉感,这有助于开发人员在使用它时感到舒适和高效。一个完整的GNU命令主要由四部分组成。命令名(可执行文件):命令行程序的名称;子命令:命令程序的子函数名。options:子命令功能的配置选项。参数:子命令功能配置选项的相应参数。您可以在任何命令中看到这一点。以Git为例:gitreset--hardHEAD~1可以分解为:GNU命令行标准的可执行命令为git,子命令为reset,使用的选项为--head,参数为HEAD~1.又如:systemctlenable--nowfirewalld可执行命令为systemctl,子命令为enable,选项为--now,参数为firewalld。假设您想使用RT-Thread编写一个符合GNU的命令行程序。FinSH拥有您需要的一切,并将按预期运行您的代码。更好的是,您可以依赖这种合规性,因此您可以自信地移植您最喜欢的Linux程序。编写一个优雅的命令行程序下面是一个RT-Thread开发者每天使用的RT-Thread运行命令的例子:usage:env.pypackage[-h][--force-update][--update][--list][--wizard][--upgrade][--printenv]可选参数:-h,--help显示此帮助消息并退出--force-update强制更新和清理包,安装或删除包您在menuconfig中的设置--update更新包,通过您在menuconfig中的设置安装或删除包--list列出目标包--wizard使用向导创建一个新包--upgrade从gitrepo升级本地包列表和ENV脚本--printenv打印要检查的环境变量如您所见,它看起来很熟悉,并且其行为与您可能已经在Linux或BSD上运行的大多数POSIX应用程序相似。当使用不正确或不充分的语法时,它会有所帮助,并且它支持长选项和短选项。任何使用过Unix终端的人都会熟悉这个通用的用户界面。选项选项的种类很多,按长度可分为两类。短选项:它由一个连字符后跟一个字母组成,例如pkgs-h中的-h选项。长选项:由两个连字符后跟一个单词或字母组成,例如scons---target-mdk5中的--target选项。您可以根据它们是否有参数将这些选项分为三类。无参数:该选项后面不能跟参数。参数是必需的:选项后面必须跟参数。参数是可选的:选项后面可以有参数,但不是必需的。正如您对大多数Linux命令所期望的那样,FinSH的选项解析非常灵活。它可以根据空格或等号作为分隔符来区分选项和参数,或者简单地通过提取选项本身并假设后面是一个参数(换句话说,根本没有分隔符)。wavplay-v50wavplay-v50wavplay--vol=50使用optparse如果您曾经编写过命令行程序,您可能知道,一般来说,您选择的语言有一个名为optparse的库或模块。它提供给程序员,以便作为命令的一部分输入的选项(例如-v或--verbose)可以与命令的其余部分一起解析。这有助于您的代码从子命令或参数中获取选项。为FinSH编写命令时,optparse包需要这种格式:MSH_CMD_EXPORT_ALIAS(pkgs,pkgs,thisistestcmd.);您可以使用长格式或短格式,或同时使用两者作为选项。例如:staticstructoptparse_longlong_opts[]={{"help",'h',OPTPARSE_NONE},//长命令:help,对应短命令h,不带参数。{"force-update",0,OPTPARSE_NONE},//长命令:强制更新,不带参数{"update",0,OPTPARSE_NONE},{"list",0,OPTPARSE_NONE},{"wizard",0,OPTPARSE_NONE},{“升级”,0,OPTPARSE_NONE},{“printenv”,0,OPTPARSE_NONE},{NULL,0,OPTPARSE_NONE}};创建选项后,写下每个选项及其参数的命令和描述:staticvoidusage(void){rt_kprintf("usage:env.pypackage[-h][--force-update][--update][--list][--wizard]\n");rt_kprintf("[--升级][--printenv]\n\n");rt_kprintf("可选参数:\n");rt_kprintf("-h,--help显示此帮助信息并退出\n");rt_kprintf("--force-update强制更新和清理包,安装或删除\n");rt_kprintf("根据您在menuconfig中的设置打包\n");rt_kprintf("--update更新包,安装或删除你的包\n");rt_kprintf("菜单配置中的设置\n");rt_kprintf("--list列出目标包\n");rt_kprintf("--wizardcreateanewpackagewithwizard\n");rt_kprintf("--upgrade从gitrepo升级本地包列表和ENV脚本\n");rt_kprintf("--printenvprintenvironmentvariablestocheck\n");}下一步是解析虽然你还没有实现它的功能,但是解析出来的代码框架是一样的:intpkgs(intargc,char**argv){intch;intoption_index;结构optparse选项;如果(argc==1){用法();返回RT_EOK;}optparse_init(&options,argv);while((ch=optparse_long(&options,long_opts,&option_index))!=-1){ch=ch;rt_kprintf("\n");rt_kprintf("optopt=%c\n",options.optopt);rt_kprintf("optarg=%s\n",options.optarg);rt_kprintf("optind=%d\n",options.optind);rt_kprintf("option_index=%d\n",option_index);}rt_kprintf("\n");returnRT_EOK;}这是函数头文件:#include"optparse.h"#include"finsh.h"然后,编译并下载到设备。输出硬件黑客编程硬件可能看起来令人生畏,但随着物联网的发展,它变得越来越普遍。并非所有东西都可以或应该在RaspberryPi上运行,但在RT-Thread上,FinSH让您保持熟悉的Linux感觉。如果您对在裸机上编码感到好奇,请尝试一下RT-Thread。