前言
上一篇解决了常用的波特率的设置,但是实际使用中,总会遇到些奇葩的甚至串口工具都无法帮到忙的的波特率,比如10兆?研究非标准的波特率时误打误撞,再加上一个残暴的解决办法,终于是给强行凑出来了(Linux内核版本4.14.0)
第一步:内核部分需要改3处,相关文件共两个
分别是drivers/tty 目录下 tty_baudrate.c,和/include/uapi/asm-generic 目录下 termbits.h
#define sparc static const speed t baud table[] = { 日,50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,19200,38400,57600,115200,230400,460800,#ifdef_sparc_ 76800,153600,307200,614400,921600#else 50000日, 576000, 921600,1000000,1152000,1500000,2000000,2500000,3000000,3500000,4000000#endif}; #ifndef sparc static const tcflag t baud bits[] = { B0,B50,B75,B110,B134,B150,B200,B300,B600, B1200,B1800,B2400,B4800,B9600,B19200,B38400, B57600, B115200,B230400,B460800,B500000, B576000 B921600,B1000000,B1152000, B1500000, B2000000, B2500000, B3000000,B3500000, B4000000}; #else static const tcflag t baud bits[] = { BO,B50,B75,B110,B134,B150,B200,B300,B600, B1200,B1800,B2400,B4800,B9600,B19200,B38400, B57600,B115200,B230400,B460800,B76800,B153600, B307200,B614400,B921600}; #endif Hx--1024
第一处,打开 sparc 宏定义( tty_baudrate.c)
在上图所示的位置打开宏定义,里面就会有几个非标准的波特率可以选择的,我选择了614400的基础上进行替换(本来只是想试试不同的波特率,天知道怎么瞎猫碰到了死耗子一下就改成功了,替换掉还不行,当真是一个bug(或许不是bug?就当是一个黑盒子好了)撑起来整个代码结构),不说废话了,这里只需要添加:
#define __sparc__
第二处,修改输入输出速率:( tty_baudrate.c)
我们很容易知道,配置速率的函数都会调用到cfsetispeed和cfsetospeed,往上层找,不难发现ispeed和ospeed在这里用ibaud和obaud进行了赋值(主要是这个c文件的名字也太像专门用来改波特率的了)那么尝试直接在这里暴力赋值(所幸调试串口并没有受到惨烈的波及,仅仅在内核打印部分在这一句往后会乱码,不影响登录后的命令发送,而且dmesg还是可以看到完整信息的)
在这里尝试修改后,有趣的现象发生了,理想状态下应该所有的波特率都会改变,但是在用上一篇编好的测试代码测试时,发现居然波特率还是115200,只是用命令行发送的波特率是10兆(开机后的第一次是9600默认值,也没找出来哪来的,再次运行就“正常”了),这就意味着对波特率的设置仍然是可控的!于是就有了修改上一处的想法。
void tty termios encode baud rate(struct ktermios *termios, speed t ibaud, speed t obaud) { int i = 0; int ifound =-1,ofound =-1; // printk("ibaud is ad,obaud is ad",ibaud,obaud); ibaud = 10000000; obaud = 10000000; // printk("ibaud2 is ad,obaud2 is *d",ibaud,obaud); int iclose = ibaud/50, oclose = obaud/50; int ibinput = 日; if (obaud == 0) /* CD dropped */ ibaud = 0; /* Clear ibaud to be sure */ termios->c ispeed = ibaud; termios->c ospeed = obaud; Hx--1024
第三处:需要修改termbits.h,
为了防止内核编译报错,需要注意的这里应该是8进制的,随便加了几个
146 #define B115200 0010002 147 #define B230400 0010003 148 #define B460800 0010004 149 #define B500000 0010005 150 #define B576000 0010006 151 #define B921600 0010007 152 #define B1000000 0010010 153 #define B1152000 0010011 154 #define B1500000 0010012 155 #define B2000000 0010013 156 #define B2500000 0010014 157 #define B3000000 0010015 158 #define B3500000 0010016 159 #define B4000000 0010017 160 #define B76800 0010020 161 #define B153600 0010021 162 #define B307200 0010022 163 #define B614400 0010023 Hx--1024
第二步:应用部分需要改
应用层可能是没包含有些内核库还是编译什么的问题,保险起见将刚刚宏定义的部分在应用层做了一样的粘贴(确保和内核是连接上了)
然后就是在之前设置的部分,设置非标准波特率的标志位了
//修改控制模式,保证程序不会占用串口 options.c cflag |= CLOCAL; //修改控制模式,使得能够从串口中读取输入数据 options.c cflag |= CREAD; //清bit位 关闭字符映射 0x0a 0x0d options.c iflag &=~(INLCR|ICRNL);//清bit位 关闭流控字符 0x11 0x13 options.c iflag &=~(IXON); options.c cflag = CBAUDEX;//设置特定波特率的标志位. //设置数据流控制 switch(flow ctrl) { case日 ://不使用流控制 options.c cflag &= ~CRTSCTS; break; case 1 ://使用硬件流控制 options.c cflag |= CRTSCTS; break; case 2 ://使用硬件流控制DTR/DSR options.c cflag &=~CRTSCTS; break; case 3 ://使用软件流控制 options.c cflag |= IXON | IXOFF | IXANY; break; Hx--1024
接下来再改就是改上一篇里的固定数组了,加入614400,然后初始化值挑一路串口设置,发送0x55,用示波器一量,嘎嘎好使,就这样东拼西凑,应个急是肯定了;以后有时间研究清楚再次补充吧