linux串口代理服务器,Linux串口调试(编程)总结(ARM通信)

最近在linux系统中写了个串口通信的程序,主要是PC机和ARM-mini2440开发板的串口进行通信(当然在开发板上也是跑的Linux操作系统),PC和开发板都要进行接收和发送。发送端要发送从0x00~0xFF中的任意字符,(包括不可见字符)但接收端某些字符老接收不到,而接收端是使用的是软中断的方式,也就是使用的信号SIGIO,进行数据的接收,但是在收到SIGIO信号后,总是接收不到数据,分析及其解决方法如下:

一、接收数据时

写数据时,直接调用write函数就可以了,但是在用read读数据时,就会有一定的规则了。解决这些问题之前我们先看终端I/O的两种输入处理模式:

(1)规范方式输入处理。

在这种方式中,终端输入以行为单位进行处理。对于每个读要求,终端驱动程序最多返回一行。只有遇到NL,EOL,EOL2,和EOF。此类表示一行结束的特殊字符时,才会read到真正的数据,否则即使收到SIGIO信号,当调用read函数进行读串口时,一样读不到数据。就是在这里,自己调试了好长时间,只到设置了newio.c_lflag& =~ICANON .这上面的5个行定界符中,其中只有一个EOF字符在终端驱动程序对其处理后即被删除。其他4个字符则作为该行的最后一个字符返回给调用者。

0x0a即'\n',以NL来表示,也就是说类似按了enter键,本行数据才输出,所以必须修改,将终端设置在非规范方式输入处理。

(2)非规范方式输入处理。输入字符不以行为单位进行装配。

如果不作特殊处理,则默认方式是规范方式。例如:若shell的标准输入、输出是终端,在用read和write将标准输入复制到标准输出时,终端以规范方式进行工作,每次read最多返回一行。处理整个屏幕的程序,例如vi编辑程序使用非规范方式,其原因是其命令是由不以新行符终止的一个或几个字符组成的。另外,该编辑程序使用了若干特殊字符作为编辑命令,所以它也不希望系统对特殊字符进行处理。例如,Ctrl+D字符通常是终端的文件结束符,但在vi中它是向下滚动半个屏幕的命令。

POSIX.1定义了11个特殊输入字符,其中9个可以改变。

关闭termios结构中中c_lflag字段的ICANO标志就使终端处于非规范模式。在非规范模式中,输入数据并不组成行,不处理下列特殊字符:ERASE,KILL、EOF、NL、EOL、EOL2、CR、REPRINT、STATUS和WERASE。不处理的意思就是,不会对这些特殊的字符,进行特殊的处理。

在规范模式下,系统每次返回一行,但在非规范模式下,系统怎样才能知道在什么时候将数据返回给我们呢?如果它一次返回一个字节,那么系统开销就会很大。在启动读数据时,往往不知道要读多少数据,所以系统不能总是一次返回多个字节。

解决方法:当已读了指定量的数据后,或者已经过了给定的时间后,即通知系统返回,这种技术使用了termios结构中的c_cc数组的两个变量:MIN和TIME。c_cc数组中的这两个元素下标名为VMIN和VTIME。MIN说明一个read返回前的最小字节数据,TIME说明等待数据到达的分秒数(秒的十分之一是分秒)。

有下列四种情形:

情形A:MIN>0,TIME>0

TIME说明字节间的计时器,在接到第一个字节时才启动它,在该计时器超时之前,若已接到MIN个字节,则read返回MIN个字节。如果在接到MIN个字节之前,该计时器已超时,则read返回已经接收到的字节,因为只有在接收到第一个字节时才启动,所以在计时器超时时,至少返回一个字节。这种情形中,在接到第一个字节之前,调用者阻塞。如果在调用read时数据已经可用,则这如同在read后数据立即被接收到一样。

情形B:MIN>0,TIME==0

已经接到了MIN个字节时,read才返回,这可以造成read的无限期阻塞

情形C:MIN == 0,TIME>0

TIME指定了一个调用read时启动的读计时器,在接收到一个字节或者该计时器超时时,read即返回,如果是计时器超时,则read返回0.

情形D:MIN == 0,TIME ==0

如果有数据可用,则read最多返回所要求的字节数。如果无数据可用,则read立即返回0.

在中,有如下定义

struct termios {

tcflag_t c_iflag;/* input mode flags */

tcflag_t c_oflag;/* output mode flags */

tcflag_t c_cflag;/* control mode flags */

tcflag_t c_lflag;/* local mode flags */

cc_t c_line;/* line discipline */

cc_t c_cc[NCCS];/* control characters */

};

c_iflag由终端设备驱动程序用来控制输入特性(剥除输入字节的第8位,允许输

入奇偶校验等等)

c_oflag则控制输出特性(执行输出处理,将新行映照为C R / L F等)

c_cflag影响到UART串行线(忽略调制解调器的状态线,每个字符的一个或两个停止位等等),

c_lflag影响驱动程序和用户之间的界面(回送的开或关,可视的擦除符,允许终端产生的信

号,对后台作业输出的控制停止信号等)。

修改非规范方式输入处理,如下:struct termios options;

tcgetattr( fd,&options)

options.c_lflag &= ~(ICANON );

通过修改c_lflag本地模式,将ICANON属性去掉,ICANON就是规范化方式。

二、接收到数据:

其余数据全正确

03以前的数据全部没有,而0x03相当于^c,即CTRL+C,^c, ^?由ISIG来控制,那么去除该控制,应该就

可以显示03了,再次修改为:

options.c_lflag &= ~(ICANON |ISIG);

三、接收到数据:

00 01 02 03 04 05 06 07 08 09 0a 0b

0c0a 0e 0f ……

其余数据全部正确

看,0d变成了0a

c_iflag模式中,有ICRNL项,IGNCR项,将两者去掉:

options.c_iflag &= ~(ICRNL|IGNCR)

至此:串口能接收到所有的数据。

101204174142.jpg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
简单说明 工具支持:串口通讯、串口代理、TCP、UDP、Telnet、Ping、TFtp等通讯测试 1、本工具支持固定预定义命令,命令可以进行分组,由树形控件管理。点击“命令编辑”即可编辑预定义命令, 编辑保存后点击“命令更新”按钮,新命令即显示在左侧“命令树”中,预定义命令支持ASCII码字符串格式 、十六进制格式与转义(混合)命令格式(如"abc\r\n12345\xAB \x45"); 2、支持动态命令,如命令中含有帧长度、校验等数据项目,命令可以进行分组,由树形控件管理。方法上采用 Lua脚本语言进行扩展,扩展的界面内容包含终端窗口的右键菜单、脚本窗口的按钮事件、扩展的树命令; 3、支持命令终端模式,功能类似Windows下的超级终端,可以进行复制、粘贴等操作,可以上下翻页滚动; 在终端窗口可以通过鼠标滚轮上下滚动,可以通过“Ctrl+箭头”、“Ctrl+翻页键”上下翻页操作; 4、工具支持ZModem协议进行文件下载、上传,方便与Linux终端间交换数据; 5、支持用Lua脚本对接收到的数据进行解析,支持用脚本语言直接进行发送操作; 6、支持数据触发模式,当串口(Socket)接收到预定义格式的数据时,可以直接触发脚本内指定的函数事件; 7、支持串口回环模式,发出的数据自动返回,便于脚本调试; 8、支持常用工具嵌入到本界面内部,由脚本定制具体程序名称,如计算器、Dnw、记事本、命令行等,在操作上 形同一个整体; 9、具有串口数据记录功能,每天记录一个文件,可以加上时间标记,方便查看历史操作、历史数据; 10、可以采用脚本进行定时发送、循环发送、总线循访等操作流程; 11、Lua脚本支持发送字节到串口(Socket)、发送字符串到串口(Socket)、延时、定时器、事件触发、界面定制等操作; 12、支持命令行内容自动滚动记录功能,方便使用历史命令; 13、支持窗口总在最前模式(top on most),方便在进行其它任务,监通讯操作; 14、支持脚本扩展的语音提示功能(播放指定的Wav文件),可以用在接收到指定数据、帧错误、校验错、定时 操作完毕、超时等场合,方便提醒调试人员; 15、支持发送文件操作,包含每次发送的长度、间隔时间等,也可以通过脚本语言读取文件进行自定义格式发送, 如包含同步、长度、校验等信息。 ... ------------lua 可调用的服务函数--------------------------------- SendByte 向串口(Socket)发送一个字节 SendString 向串口(Socket)发送字符串 SendHexString 向串口(Socket)发送字符串,例子:SendHexString("12 34 56 AB 5F"); GetString 通过录入窗口获取字符串 Sleep 休眠 Wait 等待,事件继续触发 GetDateTimeStr 取得当前时间字符串 Print 打印输出信息到输出窗口 print 打印输出信息到输出窗口 PrintToCommWin 打印输出信息到串口信息窗口 PrintAsChar 打印输出信息到输出窗口(数据类型转换为字符型) ClearOutput 清除输出窗口内容 IntToChar 数据类型转换为字符型 SetButtonText 设置按钮文本 WinExec 运行外部应用程序 WinExecInWindow 运行外部应用程序(嵌入到窗口内部) GetExeDir 取得应用程序的路径 SetMenuItemText 设置终端模式下的串口(Socket)信息窗口的弹出菜单内容 GetClipboardText 获取剪贴板数据 CopyToClipboard 复制数据到剪贴板 AddLuaTreeNode 在扩展命令树中增加一个节点 PlayWave 播放语音文件 SetCmdLineText 设置命令输入行内容 GetCmdLineText 获取命令输入行内容 IntToHex 数据转换为十六进制字符串 IntToStr 数据转换为字符串 StrToInt 字符串转换为整形 bit_not 数据取反 bit_and 数据相与 bit_or 数据相或 bit_xor 数据相异或 bit_shl 数据左移 bit_shr 数据右移 GetFileName 获取文件名 inet_addr ip地址转换 SubString 取得子字符串 SetLuaTreeNodeText 设置树节点文字 SetLuaTreeNodeParam 设置树节点参数 ShowVclForm 显示扩展界面 ShowOutputForm 显示输出界面 ShowCodeForm 关闭代码窗口 HideCodeForm 关闭代码窗口 HideSendForm 关闭发送窗口 ShowSendForm 显示发送窗口 GetPathName 通过GUID获取设备名称 FileOpen 打开文件 FileSeek 移动文件指针 FileRead 读取文件 FileWrite 写文件 FileClose 关闭文件 AllocMem 分配内存 FillMem 填充1个字节到内容 GetMem 获取1字节内容内容 FreeMem 是否内存 SaveParam 保存参数到UserParam.ini GetParam 读取参数,从UserParam.ini AddBufDat 对内存内容按字节累加求和,通常用于计算校验 Update 界面刷新 ShowMessage 消息窗口 ShowLeftTools 显示左边工具栏 ShowRightTools 显示右边工具栏 ShowTerminal 显示终端窗口 HideLeftTools 隐藏左边工具栏 HideRightTools 隐藏右边工具栏 HideTerminal 隐藏终端窗口 ClearCommWin 清除通讯窗口内容 GotoCommWin 设置坐标 PrintToTerminal 打印信息到终端窗口 GetSendWinSelText 取得发送窗口中选中的数据 ClearVclControls 清除脚本语言创建的控件 ------------lua 事件----------------------------------- ReceivedByte 串口(Socket)接收到一个字节数据 ReceivedTrigData 串口(Socket)接收到特定格式数据 ProcessTrigData 串口(Socket)接收完特定格式数据后进行一次性处理 Timer100ms 100毫秒定时器事件 Timer500ms 1500毫秒定时器事件 Timer1000ms 1000毫秒定时器事件 Button1Clicked 按钮1单击事件 Button2Clicked 按钮2单击事件 Button3Clicked 按钮3单击事件 Button4Clicked 按钮4单击事件 Button5Clicked 按钮5单击事件 Button6Clicked 按钮6单击事件 Button7Clicked 按钮7单击事件 Button8Clicked 按钮8单击事件 MenuItem0Clicked 弹出菜单项0单击事件 MenuItem1Clicked 弹出菜单项1单击事件 MenuItem2Clicked 弹出菜单项2单击事件 MenuItem3Clicked 弹出菜单项3单击事件 MenuItem4Clicked 弹出菜单项4单击事件 MenuItem5Clicked 弹出菜单项5单击事件 MenuItem6Clicked 弹出菜单项6单击事件 MenuItem7Clicked 弹出菜单项7单击事件 MenuItem8Clicked 弹出菜单项8单击事件 MenuItem9Clicked 弹出菜单项9单击事件 MenuItem10Clicked 弹出菜单项10单击事件 MenuItem11Clicked 弹出菜单项11单击事件 MenuItem12Clicked 弹出菜单项12单击事件 MenuItem13Clicked 弹出菜单项13单击事件 MenuItem14Clicked 弹出菜单项14单击事件 MenuItem15Clicked 弹出菜单项15单击事件 MenuItem16Clicked 弹出菜单项16单击事件 MenuItem17Clicked 弹出菜单项17单击事件 MenuItem18Clicked 弹出菜单项18单击事件 MenuItem19Clicked 弹出菜单项18单击事件 转义字符 含义 ASCII码(16/10进制) \n 换行符(LF) 0AH/10 \r 回车符(CR) 0DH/13 \\ 反斜杠 5CH/92 \ddd 任意字符 1~3位十进制 \xhh 任意字符 1~2位十六进制 继续完善中,欢迎提出宝贵意见。 本软件版本:V1.25 作者:baohongjie@126.com

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值