本文介绍了命令语言解析 - 如何正式获取?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 嗨: 为TMS320F2812完成足够的串口驱动程序代码后,微控制器与终端通话,我现在正在尝试不同的 接近命令解释。 我有一个非常简单的命令集,包含几个不带参数的单个字母 命令。一些额外的单个字母 命令带参数: 命令语言(有点概括): 命令参数(s)描述 a do action_a b do action_b c do action_c ... n do action_n ... y [var_name] display variable(s) z var_name value set variable to value 其中var_name是变量标识符。 ''''命令允许一个 显示由var_name标识的变量的值。如果未提供var_name ,则此命令将显示所有变量。 e命令 允许将var_name标识的变量的值设置为value。 目前我使用的是最简单但最不灵活的解析方法 命令。我在运行中进行扫描和词法分析,并使用if,否则,如果, 其他逻辑块进行解析。 (我知道,可悲。)这种方法需要 如果,否则if,else阻止命令语言的每个字段。 接下来我打算将词法分析拆分为第一遍,并创建一个 的令牌列表,并进行其他处理,例如将关键字转换为关键字和变量名称以及数字文本字段机器上的数字。 这将消除扫描/ lexing,使 解析代码更具可读性。 然后第二遍解析仍然可以使用if,否则如果, 否则看起来似乎语言有一个固定且相对较小的b $ b小的最大数字每个命令的字段数。 问题是,对于与上述类似的语言和 考虑以下因素: 1.需要在嵌入式微控制器中实现不超过一美元的程序内存K / b 2.不是特别高的sp需要进行解析。 Ccommands将通过115.2kbps的慢速接口间歇性地发出。 3.易于理解和调整代码以适应命令的变化 套是非常有价值的。最有可能的补充是告诉 接受表示存储在uC RAM中的文件/表格为/ b $ b的二进制数据流的命令。 使用if,else if,else block或 进行硬编码解析通常会决定使用更通用的技术,例如 正式化BNR形式的语言描述,并使用词法分析器/解析器 生成工具,如lex / yacc? 我总是找到主题解析器/口译员/编译器 引人入胜,并希望花大量时间了解更多 。然而,我还必须让事情发挥作用。我觉得 就像我最终需要用 不同的解析技术进行相当多的实验来感受最好的选择方法 这个和将来的应用程序。 感谢您的投入。 - 美好的一天! ________________________________________ Christopher R. Carlen 首席激光与电子技师 美国加州桑迪亚国家实验室 cr *************** @ BOGUSsandia.gov 注意,删除文本:RemoveThis和 " BOGUS"从电子邮件地址到回复。Hi:Having completed enough serial driver code for a TMS320F2812microcontroller to talk to a terminal, I am now trying differentapproaches to command interpretation.I have a very simple command set consisting of several single lettercommands which take no arguments. A few additional single lettercommands take arguments:Command language (somewhat generalized):command argument(s) descriptiona do action_ab do action_bc do action_c...n do action_n...y [var_name] display variable(s)z var_name value set variable to valuewhere var_name is a variable identifier. The ''d'' command lets onedisplay the value of a variable identified by var_name. If no var_nameis provide, this command will display all variables. The ''e'' commandlets one set the value of the variable identified by var_name to value.Presently I am using the simplest yet least flexible approach to parsecommands. I scan and lexically analyze on the fly, and use if, else if,else logic blocks to parse. (I know, pathetic.) This approach requiresone if, else if, else block for each field of the command language.Next I plan to split the lexical analysis to a first-pass, and create alist of tokens, with additional processing such as converting keywordsand variable names to keys, and numeric text fields to machine numbers.This will eliminate the scanning/lexing on the fly to make theparsing code much more readable.Then a second pass of parsing could still be done using if, else if,else it seems in the case that a language has a fixed and relativelysmall maximum number of fields per command.The question is then, for a language similar to the above andconsidering these factors:1. need to implement in an embedded microcontroller in not more than afew K of program memory2. not a particularly high speed of parsing is required. Ccommands willbe issued intermittently over a slow interface of perhaps 115.2kbps.3. ease of understanding and adapting the code to changes in the commandset is very valuable. Most likely additions would be a command to tellthe thing to accept a binary data stream representing a file/table to bestored in the uC RAM.Is it common to hardcode parsing with if, else if, else blocks or atwhat point does one decide to use more generalized techniques such asformalizing the language description in BNR form, and using lexer/parsergeneration tools such as lex/yacc ?I have always found the topic of parsers/interpreters/compilersfascinating, and would like to spend considerable time learning moreabout this. Yet I also have to "just get the thing to work." I feellike I will ultimately need to perform quite a few experiments withdifferent parsing techniques to get a feel for the best method to choosefor this and future applications.Thanks for input.--Good day!________________________________________Christopher R. CarlenPrincipal Laser&Electronics TechnologistSandia National Laboratories CA USA cr***************@BOGUSsandia.govNOTE, delete texts: "RemoveThis" and"BOGUS" from email address to reply.推荐答案 2007年8月10日星期五10:12:50 -0700,Chris Carlen < cr *************** @ BOGUSsandia.govwrote:On Fri, 10 Aug 2007 10:12:50 -0700, Chris Carlen<cr***************@BOGUSsandia.govwrote: >完成了足够的串行驱动程序代码TMS320F2812单片机与终端通话,我现在正在尝试不同的命令解释方法。 我有一个非常简单的命令集,由几个单字组成不带参数的命令。一些额外的单个字母命令带有参数: 命令语言(有点概括): 命令参数描述 a action_a b做action_b c做action_c ... n做action_n ... y [var_name] display variable(s) z var_name value set variable to value 其中var_name是变量标识符。 d命令允许一个显示由var_name标识的变量的值。如果未提供var_name ,则此命令将显示所有变量。 ''''命令允许将var_name标识的变量的值设置为value。 目前我使用最简单但最不灵活的方法来解析命令。我在运行中扫描和词法分析,并使用if,否则,如果, else逻辑块进行解析。 (我知道,可悲。)这种方法需要一个if,否则if,else阻止命令语言的每个字段。 接下来我打算将词法分析分成第一个 - 传递,并创建一个令牌列表,并进行额外处理,例如将关键字和变量名转换为键,将数字文本字段转换为机器号。 这将消除动态扫描/ lexing以使解析代码更具可读性。 然后第二遍解析仍然可以使用if,否则如果,似乎如果一种语言每个命令具有固定且相对较小的最大字段数。 那么问题是,对于类似于上述的语言而言,考虑到这些因素: 1。需要在嵌入式微控制器中实现不超过几K的程序存储器2。不需要特别高的解析速度。 Ccommands将通过115.2kbps的慢速接口间歇性地发布。 3。易于理解和调整代码以适应命令的变化设置非常有价值。很可能添加的是一个命令,告诉接受表示存储在uC RAM中的文件/表的二进制数据流。 它是否常见用if,else if,else阻塞或在什么时候决定使用更通用的技术来解析硬编码,例如以BNR形式形式化语言描述,以及使用词法分析器/解析器生成像lex / yacc这样的工具? 我总是发现解析器/解释器/编译器的主题很吸引人,并且想花很多时间学习更多关于这个的知识。然而,我还必须让事情发挥作用。我觉得我最终需要用不同的解析技术进行相当多的实验,以便为这个和未来的应用程序选择最好的方法。>Having completed enough serial driver code for a TMS320F2812microcontroller to talk to a terminal, I am now trying differentapproaches to command interpretation.I have a very simple command set consisting of several single lettercommands which take no arguments. A few additional single lettercommands take arguments:Command language (somewhat generalized):command argument(s) descriptiona do action_ab do action_bc do action_c ...n do action_n ...y [var_name] display variable(s)z var_name value set variable to valuewhere var_name is a variable identifier. The ''d'' command lets onedisplay the value of a variable identified by var_name. If no var_nameis provide, this command will display all variables. The ''e'' commandlets one set the value of the variable identified by var_name to value.Presently I am using the simplest yet least flexible approach to parsecommands. I scan and lexically analyze on the fly, and use if, else if,else logic blocks to parse. (I know, pathetic.) This approach requiresone if, else if, else block for each field of the command language.Next I plan to split the lexical analysis to a first-pass, and create alist of tokens, with additional processing such as converting keywordsand variable names to keys, and numeric text fields to machine numbers. This will eliminate the scanning/lexing on the fly to make theparsing code much more readable.Then a second pass of parsing could still be done using if, else if,else it seems in the case that a language has a fixed and relativelysmall maximum number of fields per command.The question is then, for a language similar to the above andconsidering these factors:1. need to implement in an embedded microcontroller in not more than afew K of program memory2. not a particularly high speed of parsing is required. Ccommands willbe issued intermittently over a slow interface of perhaps 115.2kbps.3. ease of understanding and adapting the code to changes in the commandset is very valuable. Most likely additions would be a command to tellthe thing to accept a binary data stream representing a file/table to bestored in the uC RAM.Is it common to hardcode parsing with if, else if, else blocks or atwhat point does one decide to use more generalized techniques such asformalizing the language description in BNR form, and using lexer/parsergeneration tools such as lex/yacc ?I have always found the topic of parsers/interpreters/compilersfascinating, and would like to spend considerable time learning moreabout this. Yet I also have to "just get the thing to work." I feellike I will ultimately need to perform quite a few experiments withdifferent parsing techniques to get a feel for the best method to choosefor this and future applications.Thanks for input. 克里斯。只是一些评论。 (1) 我不会像你那样设计命令和查询。我喜欢IEEE-488-2的 推荐。其中一个是使用?查询 并使用也可以解析的命令回复此类查询。 例如,在上面的列表中,列出''y ''和''z''用于阅读和 设置变量值。建议的程序是使用 两个动作的相同文本,但是这样: var? foo 会引起以下回复: var foo 5.3 和你' 'd'说: var foo 7 把它改为7. 查询表单只是一个?添加到命令表单的末尾,用 换句话说。 它还建议你实现一个简单的命令 转出当前状态。该状态应该以这样的方式列出,如果它的接收器只是将整个身体直接发送回你的设备,它将具有恢复的效果。状态。 因此,如果您有三个变量代表您设备中所有重要的 状态,请将它们称为S1,S2和S3,然后某人可能 发出以下查询: 州? 并得到以下回复: var S1 4.1 var S2 6.5 var S3 -1.2 如果接收者然后解雇那些直接回来,状态 (无论以前是什么)将恢复到这些值。 (2) 这里是一个可以考虑的选项: for(;;){ auto void(* func)(const char * cmd); auto int status; static char commandname [MAXCOMMANDNAME]; skipwhitespace(); parsecmd(commandn如果((func = commandsearch(commandname))!= 0) status =(* func)(command); 否则 status = NOSUCHCOMMAND; if(status!= SUCCESS){ skipremainderofline(); / *在这里打印某种解析错误* / } } 单独这些行。 ''parsecmd''函数可能使用你已经拥有的 if..else结构。我倾向于使用一个表来列出每个命令/查询的文本以及一个指向 函数的函数指针来调用其余的解析和执行。因为遗产原因,我曾经想过为了同样的效果而给b $ b有几个命令/查询名称。 这样做很容易。 无论如何,只是想一想。 (3) 我不知道你是否打算在解析时做其他事情。在我做的大多数事情中,当我还有其他的工作时,我不会被卡住,嵌套在一些 解析代码中是至关重要的。需要监控。对于 示例,我可能需要在按钮的基础上采取行动 也可能在大约同一时间按下我正在解析串行 端口文本。并且我不能坐在那里等待命令的下一个 字符,代码埋在一些 if..else的中间,而有一个按键也需要注意 现在。 所以我几乎总是包含一些操作的内容 系统,这里。在许多情况下,这可能仅仅是实现具有switchaway()函数的协作任务开关。 换句话说,如果我在中间串口代码,埋在一个if..else里面的,我现在把串口代码叫做 "获取下一个字符"并且它回应说还没有更多 字符......然后我称之为switchaway()函数。当 它返回时,我被允许多一些时间,所以我重新调用串行端口 代码用于该下一个字符的事情。如果它仍然是空的,我再次回想起switchaway()函数。 。等等。这样,我在解析代码中间不会丢失我的位置,但同时我可以将b $ b传递给其他函数,这样他们就可以了可以完成他们的工作。 顺便说一句,实现 这样的功能并不需要多行汇编代码。大多数编译器只留出几个需要在函数调用中保存的寄存器,所以 它只需要推几个寄存器,切换到新的堆栈指针, 然后弹出相同的寄存器并返回。而已。所以它不是很难b $ b,它有助于保持代码清洁。否则,你必须以某种方式保存你的解析函数的状态,从它返回所以 其他工作可以完成,然后以某种方式将你自己倒回到一些 下次你在它的顶部被调用时讨厌的位置。或者只是 坐在那里,在等待下一个 串口字符到达时忽略其他所有内容。 最好的好运, JonHi, Chris. Just a few comments.(1)I wouldn''t design the commands and queries as you did. I like therecommendations of IEEE-488-2. One of them is to use a ? for queriesand to reply to such queries with a command that can also be parsed.For example, in your above list, you list ''y'' and ''z'' for reading andsetting variable values. The recommended procedure would be to usethe same text for both actions, but in this way:var? foowhich would cause the following reply:var foo 5.3and you''d say:var foo 7to change it to 7.The query form is just a ? added to the end of a command form, inother words.It also recommends that you implement a single, simple command thatdumps out the current state. That state should be listed out in sucha way that if the receiver of it simply sent the entire body straightback to your device, it would have the effect of restoring the state.So if you had three variables that represented all of the importantstate in your device, call them S1, S2, and S3, then someone mightissue the following query:state?and get the following response:var S1 4.1var S2 6.5var S3 -1.2and that if the receiver then fired those straight back in, the state(no matter what it was before) would be restored to those values.(2)Here''s an option to consider:for ( ; ; ) {auto void (*func)( const char * cmd );auto int status;static char commandname[MAXCOMMANDNAME];skipwhitespace( );parsecmd( commandname, MAXCOMMANDNAME );if ( (func= commandsearch( commandname )) != 0 )status= (*func)( command );elsestatus= NOSUCHCOMMAND;if ( status != SUCCESS ) {skipremainderofline( );/* print some kind of parsing error here */}}Something alone these lines. The ''parsecmd'' function might use theif..else structure you already have. I tend to use a table that liststhe text of each command/query along with a function pointer to thefunction to call for the rest of the parsing and execution. Therehave been times in my life when, for legacy reasons, I''ve wanted tohave several command/query names for the same effect, for example, andthis makes that pretty easy to do.Anyway, just a thought.(3)I don''t know if you intend to do other things, while parsing. In moststuff I do, it''s essential that I don''t get stuck, nested down in someparsing code, when there is other work that also needs monitoring. Forexample, I may need to take action on the basis of a push button thatmight also be pressed at about the same time I''m down parsing serialport text. And I can''t afford to sit around waiting for the nextcharacter of a command, with the code buried in the middle of someif..else, while there is a keypress that is also demanding attentionright now.So I almost always include something along the lines of an operatingsystem, here. In many cases, this might be nothing more than justimplementing cooperating task switches with a switchaway() function.In other words, if I''m in the middle of the serial port code, burieddown inside an if..else, and I''m now calling the serial port code to"get the next character" and it responds that there are no morecharacters just yet... then I call this switchaway() function. Whenit returns, I''m allowed some more time so I re-call the serial portcode for that ''next character'' thing. If it is still empty, I recallthe switchaway() function, again. And so on. That way, I don''t losemy place in the middle of my parsing code but at the same time I canpass along the cpu to other functions so they can get their work done.It doesn''t take more than a few lines of assembly code to implementsuch a function, by the way. Most compilers set aside only a fewregisters that need to be saved across a function call like that, soit only needs to push a few registers, switch to a new stack pointer,and then pop the same registers and return. That''s it. So it isn''thard and it helps keep your code clean. Otherwise, you''d have tosomehow save the state of your parsing function, return from it soother work can get done, then somehow rewind yourself back into somenasty position the next time you get called at the top of it. Or justsit there and ignore everything else while you wait for the nextserial port character to arrive.Best of luck,Jon在文章< f9 ******** @ news4.newsguy.com>中,Chris Carlen说...In article <f9********@news4.newsguy.com>, Chris Carlen says... 嗨: 已经为TMS320F2812完成了足够的串行驱动程序代码 微控制器与终端通话,我现在尝试不同的方法来解释命令。 我有一个非常简单的命令集,由几个单字母组成 命令不带参数。一些额外的单个字母 命令带参数:Hi:Having completed enough serial driver code for a TMS320F2812microcontroller to talk to a terminal, I am now trying differentapproaches to command interpretation.I have a very simple command set consisting of several single lettercommands which take no arguments. A few additional single lettercommands take arguments: 对于一个简单的人(而不是机器)接口,我经常使用一个 简单的查找表,由命令名/函数指针对组成。 简单的强力查找,你可以为每个添加一个简单的帮助字符串 命令。函数本身负责解析任何 参数。 简单但有限。 Robert - 通过 http://www.teranews.comFor a simple human (as opposed to machine) interface I''ve often used asimple lookup table composed of command name/function pointer pairs.Simple brute force lookup, and you can add a simple help string for eachcommand. The functions themselves were responsible for parsing anyarguments.Simple but limited.Robert--Posted via a free Usenet account from http://www.teranews.com Jonathan Kirwan写道:Jonathan Kirwan wrote: 周五,2007年8月10日10:12:50 -0700,Chris Carlen < cr *************** @ BOGUSsandia.govwrote :On Fri, 10 Aug 2007 10:12:50 -0700, Chris Carlen<cr***************@BOGUSsandia.govwrote: >> [edit] 命令语言(略有概括): 命令参数说明 a action_a b做action_b c做action_c ... n做action_n ... y [var_name]显示变量 z var_name value将变量设置为值 问题是,对于与上述类似的语言,并考虑以下因素: 1。需要在嵌入式微控制器中实现不超过几K的程序存储器2。不需要特别高的解析速度。 Ccommands将通过115.2kbps的慢速接口间歇性地发布。 3。易于理解和调整代码以适应命令的变化设置非常有价值。最有可能的补充是告诉接受表示存储在uC RAM中的文件/表的二进制数据流的命令。 [edit]>>[edit]Command language (somewhat generalized):command argument(s) descriptiona do action_ab do action_bc do action_c ...n do action_n ...y [var_name] display variable(s)z var_name value set variable to value[edit]The question is then, for a language similar to the above andconsidering these factors:1. need to implement in an embedded microcontroller in not more than afew K of program memory2. not a particularly high speed of parsing is required. Ccommands willbe issued intermittently over a slow interface of perhaps 115.2kbps.3. ease of understanding and adapting the code to changes in the commandset is very valuable. Most likely additions would be a command to tellthe thing to accept a binary data stream representing a file/table to bestored in the uC RAM.[edit] 克里斯。只是一些评论。 (1) 我不会像你那样设计命令和查询。我喜欢IEEE-488-2的 推荐。其中一个是使用?查询 并使用也可以解析的命令回复此类查询。 例如,在上面的列表中,列出''y ''和''z''用于阅读和 设置变量值。建议的程序是使用 两个动作的相同文本,但是这样: var? foo 会引起以下回复: var foo 5.3 和你' 'd'说: var foo 7 把它改为7. 查询表单只是一个?添加到命令表单的末尾,用 换句话说。Hi, Chris. Just a few comments.(1)I wouldn''t design the commands and queries as you did. I like therecommendations of IEEE-488-2. One of them is to use a ? for queriesand to reply to such queries with a command that can also be parsed.For example, in your above list, you list ''y'' and ''z'' for reading andsetting variable values. The recommended procedure would be to usethe same text for both actions, but in this way: var? foowhich would cause the following reply: var foo 5.3and you''d say: var foo 7to change it to 7.The query form is just a ? added to the end of a command form, inother words. 感谢您的意见。 有趣的建议。我想,因为我有0个设计命令语言的经验,所以大多数建议看起来很有趣:-) 实际上,我已经从这个命令集中汲取了灵感来自DOS调试。 我也在用Python写一个十六行编辑器(作为Python学习 练习),它也使用这个单字母业务。 我刚下载了IEEE-488.2好悲伤!我经常回避 标准,因为它们总是很长并且很难阅读。为了熟悉这个,我们需要花费几个月的时间。所以我没有兴趣制作完全符合488标准的小工具 。看起来你好像不是你想要的那样。 我曾想过要熟悉SCPI,看看它是不是 也适用于该项目。它似乎太复杂了。Thanks for the input.Interesting suggestion. I suppose since I have 0 experience withdesigning command languages, most suggestinos will seem interesting :-)Actually, I have taken inspiration for this command set from DOS debug.I''m also writing a hex line editor in Python (as a Python learningexercise) which also uses this single letter business.I just downloaded IEEE-488.2 Good grief! I have often shyed away fromstandards since they are always long and agonizing to read. Would takemonths just to get familiar with this. So I have no interest in makingthe gadget fully 488 compliant. It doesn''t appear that you wereimplying that I should.I had thought about becoming familiar with SCPI to see if it would beapplicable to this project as well. It just all seems way too complicated. 它还建议你实现一个简单的命令,即转出当前状态。该状态应该以这样的方式列出,如果它的接收器只是将整个身体直接发送回你的设备,它将具有恢复的效果。状态。 因此,如果您有三个变量代表您设备中所有重要的 状态,请将它们称为S1,S2和S3,然后某人可能 发出以下查询: 州? 并得到以下回复: var S1 4.1 var S2 6.5 var S3 -1.2 如果接收者然后解雇那些直接回来,状态 (无论以前是什么)将恢复到这些值。It also recommends that you implement a single, simple command thatdumps out the current state. That state should be listed out in sucha way that if the receiver of it simply sent the entire body straightback to your device, it would have the effect of restoring the state.So if you had three variables that represented all of the importantstate in your device, call them S1, S2, and S3, then someone mightissue the following query: state?and get the following response: var S1 4.1 var S2 6.5 var S3 -1.2and that if the receiver then fired those straight back in, the state(no matter what it was before) would be restored to those values. 这很酷。This is pretty cool. (2) 这里'可以选择考虑: for(;;){ auto void(* func)(const char * cmd); auto int status; static char commandname [MAXCOMMANDNAME];(2)Here''s an option to consider: for ( ; ; ) { auto void (*func)( const char * cmd ); auto int status; static char commandname[MAXCOMMANDNAME]; 命令名将由parsecmd()填充命令关键字?commandname will get filled with a command keyword by parsecmd()? skipwhitespace(); parsecmd(commandname,MAXCOMMANDNAME); skipwhitespace( ); parsecmd( commandname, MAXCOMMANDNAME ); parsecmd()基本上是一个提取下一个单词的词法分析器?parsecmd() is basically a lexer which extracts the next word ? if((func = commandsearch(commandname))!= 0) status =(* func)(command); if ( (func= commandsearch( commandname )) != 0 ) status= (*func)( command ); 查找并执行一个函数来执行该命令的操作。Lookup and execute a function to perform the action of that command. else status = NOSUCHCOMMAND; else status= NOSUCHCOMMAND; if(status!= SUCCESS){ skipremainderofline(); / *在这里打印某种解析错误* / } } 单独这些行。 ''parsecmd''函数可能使用你已经拥有的 if..else结构。我倾向于使用一个表来列出每个命令/查询的文本以及一个指向 函数的函数指针来调用其余的解析和执行。因为遗产原因,我曾经想过为了同样的效果而给b $ b有几个命令/查询名称。 这样做很容易。 无论如何,只是想一想。 if ( status != SUCCESS ) { skipremainderofline( ); /* print some kind of parsing error here */ } }Something alone these lines. The ''parsecmd'' function might use theif..else structure you already have. I tend to use a table that liststhe text of each command/query along with a function pointer to thefunction to call for the rest of the parsing and execution. Therehave been times in my life when, for legacy reasons, I''ve wanted tohave several command/query names for the same effect, for example, andthis makes that pretty easy to do.Anyway, just a thought. 需要相当多的考虑。我会得到你的代码所做的。 只是有点模糊。我想我可以在这里提出很多想法。It will take considerable thought. I sort of get what your code does.Just a little vague. I think I can come up with lots of ideas here, though. (3) 我不知道你是否打算在解析时做其他事情。在我做的大多数事情中,当我还有其他的工作时,我不会被卡住,嵌套在一些 解析代码中是至关重要的。需要监控。对于 示例,我可能需要在按钮的基础上采取行动 也可能在大约同一时间按下我正在解析串行 端口文本。并且我不能坐在那里等待命令的下一个 字符,代码埋在一些 if..else的中间,而有一个按键也需要注意 现在。 所以我几乎总是包含一些操作的内容 系统,这里。在许多情况下,这可能仅仅是实现具有switchaway()函数的协作任务开关。 换句话说,如果我在中间串口代码,埋在一个if..else里面的,我现在把串口代码叫做 "获取下一个字符"并且它回应说还没有更多 字符......然后我称之为switchaway()函数。当 它返回时,我被允许多一些时间,所以我重新调用串行端口 代码用于该下一个字符的事情。如果它仍然是空的,我再次回想起switchaway()函数。 。等等。这样,我在解析代码中间不会丢失我的位置,但同时我可以将b $ b传递给其他函数,这样他们就可以了可以完成他们的工作。 顺便说一句,实现 这样的功能并不需要多行汇编代码。大多数编译器只留出几个需要在函数调用中保存的寄存器,所以 它只需要推几个寄存器,切换到新的堆栈指针, 然后弹出相同的寄存器并返回。而已。所以它不是很难b $ b,它有助于保持代码清洁。否则,你必须以某种方式保存你的解析函数的状态,从它返回所以 其他工作可以完成,然后以某种方式将你自己倒回到一些 下次你在它的顶部被调用时讨厌的位置。或者只是 坐在那里,在等待下一个 串口字符到达时忽略其他所有内容。(3)I don''t know if you intend to do other things, while parsing. In moststuff I do, it''s essential that I don''t get stuck, nested down in someparsing code, when there is other work that also needs monitoring. Forexample, I may need to take action on the basis of a push button thatmight also be pressed at about the same time I''m down parsing serialport text. And I can''t afford to sit around waiting for the nextcharacter of a command, with the code buried in the middle of someif..else, while there is a keypress that is also demanding attentionright now.So I almost always include something along the lines of an operatingsystem, here. In many cases, this might be nothing more than justimplementing cooperating task switches with a switchaway() function.In other words, if I''m in the middle of the serial port code, burieddown inside an if..else, and I''m now calling the serial port code to"get the next character" and it responds that there are no morecharacters just yet... then I call this switchaway() function. Whenit returns, I''m allowed some more time so I re-call the serial portcode for that ''next character'' thing. If it is still empty, I recallthe switchaway() function, again. And so on. That way, I don''t losemy place in the middle of my parsing code but at the same time I canpass along the cpu to other functions so they can get their work done.It doesn''t take more than a few lines of assembly code to implementsuch a function, by the way. Most compilers set aside only a fewregisters that need to be saved across a function call like that, soit only needs to push a few registers, switch to a new stack pointer,and then pop the same registers and return. That''s it. So it isn''thard and it helps keep your code clean. Otherwise, you''d have tosomehow save the state of your parsing function, return from it soother work can get done, then somehow rewind yourself back into somenasty position the next time you get called at the top of it. Or justsit there and ignore everything else while you wait for the nextserial port character to arrive. 我的小工具上有两个关键线程,一个非关键线程 这是串行接口。排名第一的优先级是 非抢占,定时器中断驱动的周期性线程。保证在某个有限的最长时间内完成,但是它的周期可以根据可能受用户影响的参数而变化。 界面。基本上,它是一个波形合成器,具有可变的时钟周期。它有一个最大时钟频率。关于 接下来是#2,一个preemptable(由顶级线程)周期性线程,它是 也是定时器中断驱动的。第二个有一个简短的汇编介绍 尽快重新启用中断,这样它就不会阻止#1超过几个周期的。这是硬件用户界面(面板按钮) 轮询线程。它可以容忍被#1砍掉。它还有一个 有限的最大执行时间。 因此,串行代码可以根据需要阻止。 唯一重要的是它不会阻塞自身足够长的时间,以至于在FIFO溢出之前无法清除串行接收FIFO。 我计划使用所有内容的最大执行时间及其 周期来计算设备的最大波特率 在确定永远不会错过角色时收到。至少我认为 这可以确定。 这就是我的操作系统。只有几个线程,很容易让定时器 触发重要的线程,然后绕过其余部分。 - 美好的一天! ________________________________________ Christopher R. Carlen 首席激光与电子技师 美国加州桑迪亚国家实验室 cr ********* ******@BOGUSsandia.gov 注意,删除文本:RemoveThis和 " BOGUS"从电子邮件地址到回复。I have two critical threads on my gadget, and a non-critical threadwhich is the serial interface. The top #1 priority is anon-preemptable, timer interrupt driven periodic thread. It isguaranteed to finish in some finite maximum time, but it''s period canvary according to parameters which can be influenced by the userinterface. Basically, it''s a waveform synthesizer with variableclocking period. It''s got a max clocking freq. of aboutNext is #2, a preemptable (by the top thread) periodic thread which isalso timer interrupt driven. This second one has a brief assembly introwhich reenables interrupts ASAP so that it can''t block #1 for more thana few cycles. This is the hardware user interface (panel buttons)polling thread. It can tolerate being chopped up by #1. It also has afinite maximum exec time.Thus, the serial code can block for as long as it likes. The only thingthat matters is that it doesn''t block itself long enough to fail toclear out the serial receive FIFO before the FIFO overflows.I plan to use the maximum exec times for all the stuff and theirperiodicities to compute the maximum baud rate at which the device canreceive while being certain never to miss characters. At least I thinkthis can be determined.So that''s my OS. With only a few threads, it''s easy to just let timerstrigger the important ones, and round-robin the rest.--Good day!________________________________________Christopher R. CarlenPrincipal Laser&Electronics TechnologistSandia National Laboratories CA USA cr***************@BOGUSsandia.govNOTE, delete texts: "RemoveThis" and"BOGUS" from email address to reply. 这篇关于命令语言解析 - 如何正式获取?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
09-03 11:22