EPICS IOC Shell
作者:互联网
1 介绍
EPICS IOC是一个简单的命令解释器,其提供了一个vxWorks shell功能的子集。它被用于解释启动脚本(st.cmd)和在console终端输入的命令。在大多数情况中,vxWorks启动脚本可以被IOC shell解释而不需要更改。在本章以下部分,描述了从用户和程序员视角描述IOC shell的操作。
2 IOC Shell操作
IOC shell读取输入行,并且展开环境变量参数,把行分成命令和参量,接着调用对应解码命令的函数。命令和参量由一个或多个’空白’字符分隔。被解析成空白的字符包括实际空格字符和tab字符以及逗号和开闭括号。因而,命令行:
dbLoadRecords(“db/dbExample1.db”, “user=mrk”)
将被IOC shell解除成带有参数db/dbExample1.db和user=mrk参量的dbLoadRecords命令。
不识别的命令产生一条诊断小写,但否则被忽略。缺失参数:给出一个默认值(对于数值参量是0, 对于字符串参量是NULL)。忽略多余的参量。
不同于vxWorks shell,字符串参量不是必须被包含在引号中,除非它们包含了一个或者多个空白字符,在这种情况下,必须使用在以下部分描述的引号机制之一。
2.1 环境变量展开
不是以一个注释字符(#)开头的输入行被以${name}或$(name)形式搜索宏引用。对应macLib工具的文档描述了对应宏引用的一些可能语法变体。在任何其它运行发生前,这些引用被用它们指定名称的环境变量的值替代。
epics>epicsEnvSet v1 \${v2}
epics>epicsEnvSet v2 \${v3}
epics>epicsEnvSet v3 somePV
epics>dbpr ${v1}
将打印有关somePV过程变量的信息—传给dbpr命令的${v1}展开成${v2},其接着展开成${v3},其又展开成somePV。在定义中的需要反斜杠推迟以下变量的替代,否则在运行epicsEnvSet命令前执行展开。在单引号中出现的宏引用不被展开。
2.2 引号
引号用于移除通常被分配给某些字符的特殊含义,并且可以用于包括在参量中的空白或者引号字符。引号出现在以上描述的宏展开已经被执行后,并且不能用于一条在多行上的命令。
有三种引号机制:反斜杠字符,单引号,和双引号。一个反斜杠保留接下来字符的文字值。在单或双引号中的封闭字符保留在引号中的每个字符(包括反斜杠)的文字值。一个单引号可以出现在双引号之间,一个双引号可以出现在单引号之间。注意:被从shell调用的命令可以在它们的参量字符串上执行其它非转义和宏展开。
2.3 命令行编辑和历史
IOC shell可以使用readline或tecla库从console终端获取输入。这通过由这些库提供的命令行历史功能提供了完整的命令行编辑以及易于访问先前的命令。完整细节,参考readline或tecla库文档。不支持命令和参量补全。
如果没有使用readline或tecla库,仅有的命令行编辑和历史功能将是由底层操作系统提供的那些命令。例如在windows中,console键盘驱动提供了它自己的命令行编辑和历史命令。在VxWorks上,提供了ledLib命令行输入库程序。
2.4 重定向
IOC shell识别一个UNIX shell I/O重定向操作符的子集。重定向操作符可以在一条命令前,或者一条命令中任何地方出现,或者跟着一条命令。按它们出现的顺序从左到右处理重定向。打开或创建一个文件失败使得重定向失败并且这条命令将被忽略。
输入的重定向使得从filename展开产生的名字的文件被打开用于在文件描述符n上读取,或者如果不指定n,标准输入(文件描述符0)。用于重定向输入的一般格式:[n] < filename
作为一个特殊情况,IOC shell作为一个从filename读取命令直到一个exit命令或遇到EOF的请求,识别一个标准输入重定向。IOC shell接着继续从当前源读取命令。从filename读取的命令不被添加到readline命令历史。嵌套级别只受限于可以被同时打开的最大文件数目。
输出重定向使得其名称来自filename展开的文件被打开用于在文件描述符n上写,或者未指定n,标准输出(文件描述符)。如果文件不存在,创建它;如果它存在,截断它为0尺寸。用于重定向输出的一般格式是:[n]>filename
用于追加输出的一般格式是:[n]>>filename
用这种方式的输出重定向引起filename被打开用于在文件描述符n上追加,或者如果不指定n,标准输出。如果文件不存在,创建它。
2.5 工具命令
IOC shell识别以下命令以及在第六章(数据库定义)和第9章(IOC测试工具)描述的命令。如果包含了sequencer,也识别在sequencer文档中描述的命令。
命令 | 描述 |
help[command …] | 显示指定命令的介绍。使用通配符匹配,所以’help db*’显示所有以字母’db’开头的命令的介绍。没有参数,这显示一个所有命令的列表。 |
# | 一个’#’作为在一行上第一个非空白字符标记一个注释的开始,这持续到本行结尾(但一些Base版本可能需要在’#’字符后一个空格来识别它为一个注释) |
exit | 停止读取命令。当顶层命令解释器遇到一个exit命令或者end-of-file(EOF),它返回到它的调用者。 |
cd directory | 切换工作目录到directory |
pwd | 打印工作目录的名称 |
var[name [value]] | 如果两个参量出现,分配这个值到指明名称的变量。如果只出现name参量,打印那个变量的当前值。如果没有参量出现,打印向这个shell注册的所有变量。在应用程序数据库定义中使用variable关键字注册变量。 |
show [-level][task …] | 显示有关指定的任务信息。如果没有参量出现,显示有关所有任务的信息。level参量控制打印的信息量。默认level是0。任务参量可以是任务名或task i.d.编号。 |
system command_string | 发送command_string到系统命令解释器用于执行。这个命令只在某些应用程序数据库定义文件包含registrar(iocshSystemCommand)时才出现,并且如果系统提供了一个合适的命令解释器(vxWorks没有) |
epicsEnvSet name value | 设置环境变量名为指定的值。 |
epicsEnvUnset name | 从环境移除变量名 |
epicsEnvShow [name] | 如果不指定名称,将显示所有环境变量的名称和值。如果指定了一个名称,将显示那个环境变量的值。 |
epicsParamShow | 显示所有EPICS配置参数的名称和值。 |
iocLogInit | 初始化IOC 日志。 |
epicsThreadSleep sec | 暂停IOC shell执行 sec秒。 |
var命令是为了用于简单程序,诸如设置调试标记。需要更复杂表达式初始的程序应该使用cexp包。
一个显示周期活动报告的spy命令在RTEMS上可用,作为RTEMS_UTILS支持模块的部分。必须做以下更改来添加这个命令到一个程序:
- 添加一个RTEMS_UTILS条目到程序configure/RELEASE文件。
- 添加spy.dbd到程序dbd文件的列表并且rtemsutils到在程序Makefile中程序库的列表。
2.6 环境变量
IOC shell使用以下环境变量来控制它的运行。
变量 | 描述 |
IOCSH_PS1 | 提示字符串。默认是’epics>’ |
IOCSH_HISTSIZE | 要记住的先前命令行数目。如果IOCSH_HISTSIZE环境变量没有出现,使用HISTSIZE环境变量。如果两个环境变量都未出现,将记住10条命令行。 |
TERM, INPUTRC | 这些和其它环境变量被readline和termcap库使用并且在对应那些库的文档中描述。 |
2.7 条件
IOC shell不提供操作者条件执行命令,但可以使用宏展开模拟这种作用。最简单的计数是执行一个展开为’#’或’’的宏的命令。以下启动脚本行显示了如何做这件事:
…
$(LOAD_DEBUG=#) $(DEBUG) dbLoadRecords(“db/debugRec.db”, “P=$(P), R=debug”)
…
用正常方式启动这个IOC将导致以上行被注释掉并且忽略debugRec.db文件:./st.cmd
在启动这个IOC前,设置LOAD_DEBUG环境变量为一个空串,将导致debugRec.db文件被装载:LOAD_DEBUG=”” ./st.cmd
可以使用一个类似的技术来条件地执行外部脚本。启动命令文件包含像以下地代码:
epicsEnvSet PILATUS_ENABLE “$(PILATUS_ENABLE=NO)”
…
<Pilatus-$(PILATUS_ENABLE).cmd
如果PILAUTS_ENABLE之前已经被设置成YES,则< Pilatus-YES.cmd
如果PILATUS_ENABLE之前未被设置,则<Pilatus-NO.cmd
3 IOC Shell编程
在本节中地声明被包含在iocsh.h头文件中。
3.1 调用IOC shell
调用IOIC shell命令解释器地原型是:
int iocsh(const char * pathname);
int iocshLoad(const char * pathname, const char * macro);
int iocshCmd(const char * cmd);
int iocshRun(const char * cmd, const char * macros);
传给iocsh函数地路径名参量是文件名称,从其读取命令。如果pathname参量是NULL,从标准输出读取命令并且向标准输出发出提示。命令被读取,直到遇到一个exit命令或者到达文件末尾,到此,iocsh返回一个0值。如果不能打开指定的文件,iocsh返回-1。
IOC shell可以被从vxWorks shell调用,或者从在一个vxWorks启动脚本或者从wxWorks命令行解释器,使用iocsh “script”从IOC shell脚本读取。它也可以不带参数从vxWorks命令行解释器被调用,在这种情况中,IOC shell接管命令行交互的责任。iocshLoad函数是iocsh命令的扩展,它接收一个附加字符串,其由一个宏定义集合组成。IOC shell的这种调用在执行过程中把这些宏当作其它的环境变量,但在这个shell退出后,它们将不存在。
iocshCmd函数接收当个IOC shell命令并且执行它。iocshRun函数用由用户在第二个参数中定义的附加宏替换执行这个命令。这些函数可以被从任何线程调用,但很多命令不是必须线程安全的,所以只能小心使用。这些函数对从一个vxWorks启动脚本或命令行执行单个IOC shell命令最有用,像这样:
iocshCmd “iocsh command string”
iocshRun “iocsh command string” “VAR=VAL”
3.2 注册命令
在命令可以被IOC shell识别前,必须注册它们。通过调用注册函数,实现注册:
void iocshRegister(const iocshFunDef * piocshFuncDef, iocshCallFunc func);
第一个参数是一个指向一个数据结构的指针,其描述了它可以接收的命令和任意参量。第二个参数是一个指向一个函数的指针,当iocsh遇到了对应的命令是,其将被调用。
由iocshFuncDef结构体描述这个命令:
struct iocshFuncDef{
const char * name;
int nargs;
const iocshArgs * const * arg;
};
name元素是这个命令的名称。
arg元素是指向一个指针的数组,这些指针指向定义单个参数的结构体。
args元素声明在指向参量描述的指针数组中条目数目。
如果args是0,arg可以是NULL。定义每个参量的结构体是:
struct iocshArg{
const char * name;
iocshArgType type;
}iocshArg;
name元素由help命令使用来打印这条命令的一个简介。type元素描述这个参量的类型并且接受以下值之一:
Type Specifier | 描述 |
iocshArgInt | 这个参量将被转成一个整数值。 |
iocshArgDouble | 这个参量将被转成一个双精度浮点值。 |
iocArgString | 这个参量将被保留为一个string。用于保存这个string的内存被iocsh所有,并且在这个handler函数返回时将被再次使用。 |
iocArgPersistentString | 将产生这个参量的一个副本,并且指向这个副本的指针将被传递给这个handler。通过使用这个指针作为free()的参量,被调用的函数可以释放这个副本。 |
iocshArgPdbbase | 参量必须是pdbbase |
iocshArgArgv | 预计任意数目的参量。后续的iocshArg结构体将被忽略。 |
当其对应命令被识别时,被调用的’handler’应该是格式:
void showCallFunc(const iocshArgBuf * args);
传给这个handler函数的参量是一个unions的数组。在这个数组中的元素数目等于在描述这个命令的结构体中指定的参数数目。包含参量值的union元素的类型和名称取决于对应参量描述符的’type’元素:
如果一个iocshArgArgv参量类型c出现了,它经常是为这个命令指定的第一个和唯一参量。在这种情况中,args[0].aval.av[0]将是这个命令的名称,args[0].aval.av[1]将是第一个参量,一次类推。
3.3 注册命令注册
通常在一个注册函数中向IOC shell注册命令。程序的数据库描述文件使用registrar关键字指定一个函数,在程序启动过程中,从EPICS初始化代码调用这个函数。这个函数接着调用iocshRegister向这个iocsh注册它的命令。
以下简单的代码段显示了如何为一个示例驱动执行注册。
3.4 自动的命令注册
一个C++ static构造器也可以用于在EPICS程序开始前注册IOC shell命令。以下示例显示了如何描述和注册epicsThreadSleep命令。
标签:EPICS,const,命令,参量,Shell,shell,IOC,环境变量 来源: https://blog.csdn.net/yuyuyuliang00/article/details/118312248