聊城推广网站,婚庆公司怎么开店,南京医疗网站建设,茂名网站建设解决方案为什么80%的码农都做不了架构师#xff1f; 在Linux环境下#xff0c;串口名从ttyS0开始依次是ttyS1、ttyS2等。在本程序中#xff0c;使用ttyS0作为通信串口。在打开ttyS0的时候选项 O_NOCTTY 表示不能把本串口当成控制终端#xff0c;否则用户的键盘输入信… 为什么80%的码农都做不了架构师 在Linux环境下串口名从ttyS0开始依次是ttyS1、ttyS2等。在本程序中使用ttyS0作为通信串口。在打开ttyS0的时候选项 O_NOCTTY 表示不能把本串口当成控制终端否则用户的键盘输入信息将影响程序的执行 O_NDELAY表示打开串口的时候程序并不关心另一端 的串口是否在使用中。 在Linux中打开串口设备和打开普通文件一样使用的是open()系统调用。比如我么打开串口设备1也就是COM1只需要 fd open(/dev/ttyS0, O_RDWR | O_NOCTTY | O_NDELAY ); 打开的串口设备有很多设置选项。本文中使用int setup_com(int fd)设置。在系统头文件中 定义了终端控制结构struct termiostcgetattr()和tcsetattr()两个系统函数获得和设置这些属性。结构 struct termios中的域描述的主要属性包括 c_cflag 控制选项 c_lflag 线选项 c_iflag 输入选项 c_oflag 输出选项 c_cc 控制字符 c_ispeed 输入数据波特率 c_ospeed 输出数据波特率 如果要设置某个选项那么就使用|运算如果关闭某个选项就使用和~运算。本文使用的各个选项的意义定义如下 c_cflag CLOCAL 本地模式不改变端口的所有者 CREAD 表示使能数据接收器 PARENB 表示偶校验 PARODD 表示奇校验 CSTOPB 使用两个停止位 CSIZE 对数据的bit使用掩码 CS8 数据宽度是8bit c_lflag ICANON 使能规范输入否则使用原始数据本文使用 ECHO 回送(echo)输入数据 ECHOE 回送擦除字符 ISIG 使能SIGINTRSIGSUSP SIGDSUSP和 SIGQUIT 信号 c_iflag IXON 使能输出软件控制 IXOFF 使能输入软件控制 IXANY 允许任何字符再次开启数据流 INLCR 把字符NL(0A)映射到CR(0D) IGNCR 忽略字符CR(0D) ICRNL 把CR(0D)映射成字符NR(0A) c_oflag OPOST 输出后处理如果不设置表示原始数据本文使用原始数据 c_cc[VMIN] 最少可读数据 c_cc[VTIME] 等待数据时间(10秒的倍数) 根据以上设置的定义串口端口设置函数setup_com()定义如下 int setup_com(int fd){ struct termios options; tcgetattr(fd, options); /* Set the baud rates to 38400...*/ cfsetispeed(options, B38400); cfsetospeed(options, B38400); /* Enable the receiver and set local mode...*/ options.c_cflag | (CLOCAL | CREAD); /* Set c_cflag options.*/ options.c_cflag | PARENB; options.c_cflag ~PARODD; options.c_cflag ~CSTOPB; options.c_cflag ~CSIZE; options.c_cflag | CS8; /* Set c_iflag input options */ options.c_iflag ~(IXON | IXOFF | IXANY); options.c_iflag ~(INLCR | IGNCR | ICRNL); options.c_lflag ~(ICANON | ECHO | ECHOE | ISIG); /* Set c_oflag output options */ options.c_oflag ~OPOST; /* Set the timeout options */ options.c_cc[VMIN] 0; options.c_cc[VTIME] 10; tcsetattr(fd, TCSANOW, options); return 1; } 6.7.2 设置串口通信参数 串口通信参数指的是波特率、数据位、奇偶校验位和停止位。对串口实现控制的时候同样要用到termio结构体。下面将结合具体的代码说明如何设置这些参数。 1波特率设置 获得端口波特率信息是通过cfgetispeed函数和cfgetospeed函数来实现的。cfgetispeed函数用于获得结构体 termios_p中的输入波特率信息而cfgetospeed函数用于获得结构体termios_p 中的输出波特率信息。这两个函数的具体信息如表 6.9所示。 表6.9 cfgetispeed函数和cfgetospeed函数 头文件 函数形式 speed_t cfgetispeed(const struct termios *termios_p); speed_t cfgetospeed(const struct termios *termios_p); 返回值 是否设置errno 返回termios_p结构中的输入/输出端口的波特率 cfsetispeed函数和cfsetospeed函数用于设置端口的输入/输出波特率。一般情况下输入和输出波特率是相等的。cfsetispeed函数和cfsetospeed函数的函数声明信息如表6.10所示。 表6.10 cfsetispeed函数和cfsetospeed函数 头文件 函数形式 int cfsetispeed(struct termios *termios_p, speed_t speed); int cfsetospeed(struct termios *termios_p, speed_t speed); 返回值 是否设置errno 返回termios_p结构中的输入/输出端口的波特率 cfsetispeed函数和cfsetospeed函数会修改结构体termios_p中的波特率信息其中参数speed可以使用表6.11中所列出的宏。 表6.11 speed参数常用波特率信息 宏 定 义 波特率单位bit/s 宏 定 义 波特率单位bit/s B1800 1800 B50 B2400 2400 B75 B4800 4800 B110 110 B9600 9600 B134 134 B19200 19200 B150 150 B38400 38400 B200 200 B57600 57600 B300 300 B115200 115200 B600 600 B230400 230400 B1200 1200 使用cfsetispeed函数和cfsetospeed函数进行串口波特率设置具体代码如下所示 #include //头文件定义 #include #include termios.h …… struct termios opt /*定义指向termios 结构类型的指针opt*/ …… //获得串口指向termios结构的指针 tcgetattr(fd, Opt); cfsetispeed(optB9600 ) /*指定输入波特率9600bps*/ cfsetospeed(optB9600)/*指定输出波特率9600bps*/ //将修改后的termios数据设置到串口中 tcsetattr(fd,TCANOW,Opt); …… 2数据位 数据位指的是每字节中实际数据所占的比特数。要修改数据位可以通过修改termios结构体中c_cflag成员来实现。CS5、CS6、CS7和CS8分别表示数据位为5、6、7和8。值得注意的是在设置数据位时必须先使用CSIZE做位屏蔽。具体设置代码如下 #include //头文件定义 #include #include termios.h …… struct termios opt /*定义指向termios 结构类型的指针opt*/ ....... //获得串口指向termios结构的指针 tcgetattr(fd, Opt); … //屏蔽其他标志 Opt.c_cflag~CSIZE; //将数据位修改为8bit Opt.c_cflag |CS8; … //将修改后的termios数据设置到串口中 tcsetattr(fd,TCANOW,Opt); …… 3奇偶校验位 奇偶校验可以选择偶校验、奇校验、空格等方式也可以不使用校验。如果要设置为偶校验的话首先要将termios结构体中c_cflag设置 PARENB标志并清除PARODD标志。如果要设置奇校验要同时设置termios结构体中c_cflag设置PARENB标志和PARODD标 志。如果不想使用任何校验的话清除termios结构体中c_cflag的PARENB位。表6.12所示为设置奇偶校验的具体方法。 表6.12 设置奇偶校验位 设 置 具 体 代 码 无校验 opt.c_cflag ~PARENB; 奇校验 opt.c_cflag | (PARODD | PARENB); 偶校验 opt.c_cflag ~ PARENB; opt.c_cflag ~PARODD; opt.c_cflag ~PARENB; opt.c_cflag ~CSTOPB; 下面给出将串口通信的奇偶校验设置为偶校验的例子具体代码如下 #include //头文件定义 #include #include termios.h …… struct termios opt /*定义指向termios 结构类型的指针opt*/ …… //获得串口指向termios结构的指针 tcgetattr(fd, Opt); … opt.c_cflag ~ PARENB; opt.c_cflag ~PARODD; … //将修改后的termios数据设置到串口中 tcsetattr(fd,TCANOW,Opt); …… 4数据流控制 数据流控制指是使用何种方法来标志数据传输的开始和结束。可以选择不使用数据流控制、使用硬件进行流控制和使用软件进行流控制。数据流控制设置如表6.13所示。 表6.13 数据流控制设置 设 置 具 体 代 码 不使用数据流控制 opt.c_cflag ~CRTSCTS opt.c_cflag | CRTSCTS opt.c_cflag | IXON|IXOFF|IXANY 由于使用硬件流控制需要相应连接的电缆常用的流控制方法还是使用软件进行流控制。下面给出了设置不使用数据流控制的相关代码 #include //头文件定义 #include #include termios.h …… struct termios opt /*定义指向termios 结构类型的指针opt*/ …… //获得串口指向termios结构的指针 tcgetattr(fd, opt); … opt.c_cflag ~CRTSCTS… //将修改后的termios数据设置到串口中 tcsetattr(fd,TCANOW,Opt); …… 串口操作采用UNIX类似的方式打开/关闭/发送/接收等基本操作采用类 似文件系统的方式进行而一些属性的设置和控制则使用termios来进行。 串口对应的设备文件名为”/dev/ttyS0”。 1. 打开串口 fd open(“/dev/ttyS0”, O_RDWR); 如果只发送数据可以使用O_WRONLY 如果只接收数据可以 设置成O_RDONLY。 2. 关闭串口 close(fd); 3. 接收数据 ret read(fd, buf, 100); 串口默认的打开方式是非阻塞的因此本函数只是接收缓冲中的数 据而并非直接操作IO。如果要加入一些IO的属性请参见”使用 超时”和”设置串口属性”。 如果缓冲中有接收到的数据那么本函数将返回实际接收到的数据 长度当然不会超过指定的100字节。 如果缓冲中没有数据那么将返回0。 如果接收失败那么将返回-1错误代码放在errno中。 4. 发送数据 ret write(fd, buf, 100); 返回值表示实际发送的数据长度。 5. 设置串口属性 tcgetattr(int fd, struct termios *termios_p); tcsetattr(int fd, int optional_actions, struct termios *termios_p); 串口打开后使用的串口属性实际上是上一次关闭串口前的设置。 这个设置也就是一个结构struct termios其中主要有以下的属性 tcflag_t c_iflag // 输入属性 tcflag_t c_oflag // 输出属性 tcflag_t c_cflag // 控制属性 tcflag_t c_lflag // 本地属性 cc_t c_cc[NCCS] // 控制字 c_iflag IGNBRK 忽略接收到的break信号 BRKINT 如果IGNBRK被设置break信号将被忽 略否则如果BRKINT被设置接收到 break信号将导致输入/输出队列被清空并 且当前控制串口的前台进程将收到一个 SIGINT信号。如果IGNBRK和BRKINT都 没有被设置 收到的break信号将被接收为 NULL即{post.content}。但是如果PARMARK被设 置接收到的break信号将被接收为7{post.content} IGNPAR 忽略帧错误或奇偶校验错。 PARMARK 如果没有设置IGNPAR设置本属性表示在 接收到的带有错误的帧格式或奇偶校验的字符将被前缀 377{post.content}。如果两者都没有设置带有错误的帧格式或奇偶 校验的字符将被接收为{post.content}。 INPCK 打开输入数据的奇偶校验。 ISTRIP 滤掉第8位。 INLCR 将接收到的NL(换行)转换成CR(回车)。 IGNCR 忽略接收到的CR。 ICRNL 将收到的CR转换成NL(除非设置了 IGNCR)。 IUCLC 将接收到的大写字符转换成小写。 IXON 打开输出的XON/XOFF控制。 IXOFF 打开输入的XON/XOFF控制。 c_oflag OLCUC 将小写字符转换成大写后输出。 ONLCR 将NL转换成CR-NL后输出。 OCRNL 将CR转换成NL后输出。 ONLRET 不发送CR。 c_cflag CBAUD 波特率掩码可以设置为 B2400 B4800 B9600 B19200 B38400 B57600 B115200 CSIZE 字符长度掩码可以设置为 CS5 CS6 CS7 CS8 CSTOPB 设置为两个停止位。默认为1个 CREAD 打开接收功能。 PARENB 打开发送的奇偶校验生成功能和接收的奇偶 校验检查功能,默认的是偶校验。 PARODD 使用奇校验。 CLOCAL 忽略modem信号线。 CRTSCTS 打开RTS/CTS硬件流控。 c_lflag 由于使用该类属性不多因此在此不作介绍。 c_cc 常用的是c_cc[VMIN]表示调用read函数时等待接收 的最少字符个数。例如设置为1时read函数至少要读 到1个字符才会返回。 optional_actions 可以设置为 TCSANOW 立即更新当前的设置。 TCSADRAIN 在当前发送缓冲的所由数据发送 完毕后再更新当前设置。 TCSAFLUSH 同TCSADRAIN只是在更新前 所有为被读取的收到的数据将被丢弃。 6. 使用超时 int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); 此函数用于控制接收、发送或异常出现之前的超时。 fd_set是句柄的集合其中的句柄都是被监测的对象。 readfds表示需要监测其中句柄代表的设备是 否可以从中读取数据。 writefds表示需要监测其中句柄代表的设备 是否可以向其写入数据。 exceptfds表示需要监测其中句柄代表的设备 是否出现异常。 timeout是这样一个结构 struct timeval{ long tv_sec; // 秒 long tv_usec; // 微秒 n则是所有监测的句柄中的最大值加一。 系统提供一些定义号的操作来操作fd_set FD_CLR(int fd, fd_set *fds); 将fd从fds集合中去掉。 FD_ISSET(int fd, fd_set *fds); 检查fd是否在fds集合中。 FD_SET(int fd, fd_set *fds); 将fd加入fds集合中。 FD_ZERO(fd_set *fds); 将fds集合清空。 7. 其它串口操作 int tcdrain(int fd); 等待所有发送缓冲的数据全部发送出去后返回。 int tcflush(int fd, int queue_selector); queue_selector: TCIFLUSH 丢弃所有未读取的接收到的数据。 TCOFLUSH 丢弃所有为发送的发送缓冲的数据。 TCIOFLUSH 丢弃上面两种数据。 #include #include #include #include int main() int fd; struct termios attr; fd_set fds; struct timeval tv; unsigned char buf[1024]; // 打开串口 fd open(“/dev/ttyS0”, O_RDWR); if (fd -1) return -1; // 读取串口当前属性 tcgetattr(fd, attr); // 设置最少接收字符个数为0 attr.c_cc[VMIN] 0; // 不处理iflag、oflag和lflag attr.c_iflag 0; attr.c_oflag 0; attr.c_lflag 0; // 设置波特率为9600字符长度为8位偶校验允许接收 attr.c_cflag B9600 | CS8 | PARENB | CLOCAL | CREAD; // 设置串口属性 tcsetattr(fd, TCSANOW, attr); // 发送字符串 write(fd, “12345\n”, 6); // 清除监测集合 FD_ZERO(fds); // 将串口句柄加入到监测集合中 FD_SET(fd, fds); // 设置超时为5秒 tv.tv_sec 5; tv.tv_usec 0; // 监测串口是否有数据接收到超时为5秒 if (select(fd1, fds, NULL, NULL, tv) 0) return -1; // 接收最多100个字符 read(fd, buf, 100); // 关闭串口 close(fd); return 0; } termios结构体内容 成员 描述 ------------------------------------------- c_cflag 控制模式标志 c_lflag 本地模式标志 c_iflag 输入模式标志 c_oflag 输出模式标志 c_line line discipline c_cc[NCCS] 控制字符 c_ispeed 输入波特率 c_ospeed 输出波特率 在termios结构中的四个标志控制了输入输出的四个不同部份。输入模式标志c_iflag决定如何解释和处理接收的字符。输出模式标 志 c_oflag决定如何解释和处理发送到tty设备的字符。控制模式标志决定设备的一系列协议特征这一标志只对物理设备有效。本地模式标 志 c_lflag决定字符在输出前如何收集和处理。 在串口传输中用波特率来表示传输的速度1波特表示在1秒钟内可以传输1个码元。波特率设置可以使用 cfsetispeed( new_termios,B19200)和 cfsetospeed(new_termios,B19200)这两个函数来完成默认的波特率为 9600baud。 cfsetispeed()函数用来设置输入的波特率cfsetospeed()函数用来设置输出的波特率。B19200是 termios.h头文件 里定义的一个宏表示19200的波特率。 CLOCAL和CREAD是c_cflag成员中与速率相关的标志在串口编程中这两个标志一定要有效以确保程序在突发的作业控制或挂起时不会成为端口的占有都同时串口的接收驱动会自动读入数据。设置方法如下 termios_new.c_cflag | CLOCAL; //保证程序不会成为端的占有者 termios_new.c_cflag | CREAD; //使端口能读取输入的数据 设置串口属性不能直接赋值要通过对termios不同成员进行与和或操作来实现。在termios.h文件定义了各种常量如上面介 绍的CLOCALCREAD。这些常量的值是掩码通过把这些常量与termios结构成员进行逻辑操作就可实现串口属性的设置。在编程时用|来 启用属性用~来取消属性。 9.3. c_iflag输入标志说明 BRKINT和IGNBRK 如果设置了IGNBRK中断条件被忽略。如果没有设置IGNBRK而设置了BRKINT中断条件清空输入输出队列中所有的数据并且向tty 的前台进程组中所有进程发送一个SIGINT信号。如果这两个都没有设置中断条件会被看作一个0字符。这时如果设置了PARMRK当检测到一个帧误 差时将会向应用程序发送三个字节\377\0\0而不是只发送一个\0。 * PARMRK和IGNPAR 如果设定了IGNPAR则忽略接收到的数据的奇偶检验错误或帧错误除了前面提到的中断条件。如果没有设置IGNPAR而设置了 PARMRK当接收到的字节存在奇偶检验错误或帧错误的时候。将向应用程序发送一个三字节的\377\0\n错误报告。其中n表示所接收到 的字节。如果两者都没有设置除了接收到的字节存在奇偶检验错误或帧误差之外的中止条件都会向应用程序发送一个单字节\0的报告。 * INPCK 如果设置则进行奇偶校验。如果不进行奇偶检验PARMRK和IGNPAR将对存在的奇偶校验错误不产生任何的影响。 * ISTRIP 如果设置所接收到的所有字节的高位将会被去除保证它们是一个7位的字符。 * INLCR 如果设置所接收到的换行字符\n将会被转换成回车符\r。 * IGNCR 如果设置则会忽略所有接收的回车符\r。 * ICRNL 如果设置但IGNCR没有设置接收到的回车符向应用程序发送时会变换成换行符。 * IUCLC 如果IUCLC和IEXTEN都设置接收到的所有大写字母发送给应程序时都被转换成小写字母。POSIX中没有定义该标记。 * IXOFF 如果设置为避免tty设备的输入缓冲区溢出tty设备可以向终端发送停止符^S和开始符^Q要求终端停止或重新开始向计算机发送数据。通 过停止符和开始符来控制数据流的方式叫软件流控制软件流控制方式较少用我们主要还是用硬件流控制方式。硬件流控制在c_cflag标志中设置。 * IXON 如果设置接收到^S后会停止向这个tty设备输出接收到^Q后会恢复输出。 * IXANY 如果设置则接到任何字符都会重新开始输出而不仅仅是^Q字符。 * IMAXBEL 如果设置当输入缓冲区空间满时再接收到的任何字符就会发出警报符\a。POSIX中没有定义该标记。 9.4. c_oflag输出标志说明 OPOST是POSIX定义的唯一一个标志只有设置了该标志后其它非POSIX的输出标记才会生效。 OPOST 开启该标记后面的输出标记才会生效。否则不会对输出数据进行处理。 * OLCUC 如果设置大写字母被转换成小写字母输出。 * ONLCR 如果设置在发送换行符\n前先发送回车符\r。 * ONOCR 如果设置当current column为0时回车符不会被发送也不会被处理。 * OCRNL 如果设置回车符会被转换成换行符。另外如果设置了ONLRET则current column会被设为0. * ONLRET 如果设置当一个换行符或回车符被发送的时候current column会被设置为0。 * OXTABS 如果设置制表符会被转换成空格符。 9.5. c_cflag控制模式标志说明 CLOCAL 如果设置modem的控制线将会被忽略。如果没有设置则open()函数会阻塞直到载波检测线宣告modem处于摘机状态为止。 * CREAD 只有设置了才能接收字符该标记是一定要设置的。 * CSIZE 设置传输字符的位数。CS5表示每个字符5位CS6表示每个字符6位CS7表示每个字符7位CS8表示每个字符8位。 * CSTOPB 设置停止位的位数如果设置则会在每帧后产生两个停止位如果没有设置则产生一个停止位。一般都是使用一位停止位。需要两位停止位的设备已过时了。 * HUPCL 如果设置当设备最后打开的文件描述符关闭时串口上的DTR和RTS线会减弱信号通知Modem挂断。也就是说当一个用户通过Modem拔号登录系统然后注销这时Modem会自动挂断。 * PARENB和PARODD 如果设置PARENB会产生一个奇偶检验位。如果没有设置PARODD则产生偶校验位如果设置了PARODD则产生奇校验位。如果没有设置PARENB则PARODD的设置会被忽略。 * CRTSCTS 使用硬件流控制。在高速19200bps或更高传输时使用软件流控制会使效率降低这个时候必须使用硬件流控制。 9.6. c_cc[]控制字符说明 只有在本地模式标志c_lflag中设置了IEXITEN时POSIX没有定义的控制字符才能在Linux中使用。每个控制字符都对应一个按键组合^C、^H等但VMIN和VTIME这两个控制字符除外它们不对应控制符。这两个控制字符只在原始模式下才有效。 c_cc[VINTR] 默认对应的控制符是^C作用是清空输入和输出队列的数据并且向tty设备的前台进程组中的每一个程序发送一个SIGINT信号对SIGINT信号没有定义处理程序的进程会马上退出。 * c_cc[VQUIT] 默认对应的控制符是^\作用是清空输入和输出队列的数据并向tty设备的前台进程组中的每一个程序发送一个SIGQUIT信号对SIGQUIT信号没有定义处理程序的进程会马上退出。 * c_cc[verase] 默认对应的控制符是^H或^?作用是在标准模式下删除本行前一个字符该字符在原始模式下没有作用。 * c_cc[VKILL] 默认对应的控制符是^U在标准模式下删除整行字符该字符在原始模式下没有作用。 * c_cc[VEOF] 默认对应的控制符是^D在标准模式下使用read()返回0标志一个文件结束。 * c_cc[VSTOP] 默认对应的控制字符是^S作用是使用tty设备暂停输出直到接收到VSTART控制字符。或者如果设备了IXANY则等收到任何字符就开始输出。 * c_cc[VSTART] 默认对应的控制字符是^Q作用是重新开始被暂停的tty设备的输出。 * c_cc[VSUSP] 默认对应的控制字符是^Z使当前的前台进程接收到一个SIGTSTP信号。 * c_cc[VEOL]和c_cc[VEOL2] 在标准模式下这两个下标在行的末尾加上一个换行符\n标志一个行的结束从而使用缓冲区中的数据被发送并开始新的一行。POSIX中没有定义VEOL2。 * c_cc[VREPRINT] 默认对应的控制符是^R在标准模式下如果设置了本地模式标志ECHO使用VERPRINT对应的控制符和换行符在本地显示并且重新打印当前缓冲区中的字符。POSIX中没有定义VERPRINT。 * c_cc[VWERASE] 默认对应的控制字符是^W在标准模式下删除缓冲区末端的所有空格符然后删除与之相邻的非空格符从而起到在一行中删除前一个单词的效果。POSIX中没有定义VWERASE。 * c_cc[VLNEXT] 默认对应的控制符是^V作用是让下一个字符原封不动地进入缓冲区。如果要让^V字符进入缓冲区需要按两下^V。POSIX中没有定义VLNEXT。 要禁用某个控制字符只需把它设置为_POSIX_VDISABLE即可。但该常量只在Linux中有效所以如果程序要考虑移植性的问题请不要使用该常量。 9.7. c_lflag本地模式标志说明 ICANON 如果设置则启动标准模式如果没有设置则启动原始模式。 * ECHO 如果设置则启动本地回显。如果没有设置则除了ECHONL之外其他以ECHO开头的标记都会失效。 * ECHOCTL 如果设置则以^C的形式打印控制字符如按CtrlC显示^C按Ctrl显示^?。 * ECHOE 如果在标准模式下设定了ECHOE标志则当收到一个ERASE控制符时将删除前一个显示字符。 * ECHOK和ECHOKE 在标准模式下当接收到一个KILL控制符则在缓冲区中删除当前行。如果ECHOK、ECHOKE和ECHOE都没有设置则用ECHOCTL表示的KILL字符^U将会在输出终端上显示表示当前行已经被删除。 如果已经设置了ECHOE和ECHOK但没有设置ECHOKE将会在输出终端显示ECHOCTL表示的KILL字符紧接着是换行如果设置了OPOST将会通过OPOST处理程序进行适当的处理。 如果ECHOK、ECHOKE和ECHOE都有设置则会删除当前行。 在POSIX中没有定义ECHOKE标记在没有定义ECHOKE标记的系统中设置ECHOK则表示同时设置了ECHOKE标志。 * ECHONL 如果在标准模式下设置了该标志即使没有设置ECHO标志换行符还是会被显示出来。 * ECHOPRT 如果设置则字符会被简单地打印出来包括各种控制字符。在POSIX中没有定义该标志。 * ISIG 如果设置与INTR、QUIT和SUSP相对应的信号SIGINT、SIGQUIT和SIGTSTP会发送到tty设备的前台进程组中的所有进程。 * NOFLSH 一般情况下当接收到INTR或QUIT控制符的时候会清空输入输出队列当接收到SUSP控制符时会清空输入队列。但是如果设置了NOFLUSH标志则所有队列都不会被清空。 * TOSTOP 如果设置则当一个非前台进程组的进程试图向它的控制终端写入数据时信号SIGTTOU会被被发送到这个进程所在的进程组。默认情况下这个信号会使进程停止就像收到SUSP控制符一样。 * IEXIEN 默认已设置我们不应修改它。在Linux中IUCLC和几个与删除字符相关的标记都要求在设置了IEXIEN才能正常工作。 9.8. 下面介绍一些常用串口属性的设置方法。 设置流控制 termios_new.c_cflag ~CRTSCTS; //不使用流控制 termios_new.c_cflag | CRTSCTS; //使用硬件流控制 termios_new.c_iflag | IXON|IXOFF|IXANY; //使用软件流控制 屏蔽字符大小位 termios_new.c_cflag ~CSIZE; 设置数据位大小 termios_new.c_cflag | CS8; //使用8位数据位 termios_new.c_cflag | CS7; //使用7位数据位 termios_new.c_cflag | CS6; //使用6位数据位 termios_new.c_cflag | CS5; //使用5位数据位 设置奇偶校验方式 termios_new.c_cflag ~PARENB; //无奇偶校验 termios_new.c_cflag | PARENB; //奇校验 termios_new.c_cflag ~PARODD; termios_new.c_cflag | PARENB; //偶校验 termios_new.c_cflag ~PARODD; 停止位 termios_new.c_cflag | CSTOPB; //2位停止位 termios_new.c_cflag ~CSTOPB; //1位停止位 输出模式 termios_new.c_cflag ~OPOST; //原始数据RAW输出 控制字符 termios_new.c_cc[VMIN] 1; //读取字符的最小数量 termios_new.c_cc[VTIME] 1; //读取第一个字符的等待时间 关闭终端回显键盘输入的字符不会在终端窗口显示。 #include #include #include #include int main(void) { struct termios ts,ots; char passbuf[1024]; tcgetattr(STDIN_FILENO,ts); /* STDIN_FILENO的值是1,表示标准输入的文件描述符 */ ots ts; ts.c_lflag ~ECHO; /* 关闭回终端回显功能*/ ts.c_lflag | ECHONL; tcsetattr(STDIN_FILENO,TCSAFLUSH,ts); /* 应用新终端设置 */ fgets(passbuf,1024,stdin); /* 输入字符不会在终端显示 */ printf(you input character %s\n,passbuf); tcsetattr(STDIN_FILENO,TCSANOW,ots); /* 恢复旧的终端设备 */ } Chapter 10. 安全 Table of Contents 10.1. 内核漏洞介绍 Linux内核以稳定和安全著称但随着Linux使用范围的不断扩展各种漏洞也慢慢被内核开发人员或黑客发现。这里介绍有关Linux内核和基于Linux的开源软件的安全问题。 10.1. 内核漏洞介绍 权限提升类 * 拒绝服务类 * 溢出类 * IP地址欺骗类 Chapter 11. 数据结构(Data Structure) Table of Contents 11.1. 基础概念 11.2. 线性数据结构 11.1. 基础概念 在实际解决问题的时候各种数据都不是孤立的数据之间总是存在关系这种数据之间的关系叫做数据结构。我们可以把数据结构的形式归并为四种 集合数据之间没有对应关系但同属于一个集合。如汽车是一个集合编程语言也是一个集合。 * 线性结构各数据有一一对应的关系有前驱也有后续。 * 树形结构各数据间存在一对多的关系有一个前驱但有多个后续。 * 图各数据间有多对多的关系对前驱和后续没有限制。 数据类型是一个值的集合和定义在这个值集上的一组操作的总称。 数据类型可分两类一类是每个对象仅由单值组成称为原子类型如整型、字符型等。另一类是由某种结构组成的类型叫结构类型如数组、字符串等。 抽象数据结构Abstract Data TypeADT是一种数据类型及在这个类型上定义的一组合法的操作。 算法Algorithm是一个有穷规则或语句、指令的有序集合。通俗地说就是计算机解决问题的过程。算法应具备以下几个重要的特性 输入一个算法有零个或多个输入。 * 输出一个算法至少有一个输出这种输出是同输入有着某些特定关系的量。没有输出的算法是没有意义的。 * 有穷性一个算法必须总是在执行有穷步之后结束且每一步都在有穷时间内完成。 * 确定性算法中每条指令的含义都必须明确无二义性。对相同的输入必须有相同的结果。 * 可行性算法中的每条指令的执行时间都是有限的。 描述算法的工具自然语言、流程图、形式化语言和程序设计语言。 由瑞士科学家Niklaus Wirthrn提出的计算机界公认的公式算法 数据结构 程序 算法设计的要求正确、可读、健壮、快速、节省存储空间。 11.2. 线性数据结构 线性结构中的数据元素之间是一种线性关系数据元素一个接一个地排列。如排除的队列、表格中一行行的记录等。数据元素可以包含多个数据项字段包含多个数据项的数据元素叫做记录。由大量记录组成的线性表又称为文件。 线性表的数学表示模型a0,a1,a2,...an-1。 顺序连续存放的线性表是最简单的称为顺序存储结构线性表。它在内存开辟一片连续的存储空间让线性表的第一个元素存放在内存空间的第一个位置 第二个元素存放在第二个位置其它元素以此类推。数据元素间的前驱和后继关系表现在存放位置的前后关系上。顺序存储结构线性表算法在插入或删除操作时的效 率不高。平均起来每插入或删除一个元素需要移动一半的元素最坏的情况更要移动全部的元素。另外顺序表不利于存储空间的分配。在经常需要进入插入或删 除操作的线性表中使用顺序存储结构线性表是不合适的。所以我们有了链式存储结构线性表。 [Note] 数组就是顺序存储结构的程序实现。 链式存储结构线性表由结点组成每个节点由一个数据元素和一个指向下个结点的指针组成。每个结点中如果只有一个指向后续指针的链表叫单链表。由于链表通过指针指向下一个结点所以数据元素可以分散存储。 单链表的建立是一种动态内在管理操作表中的每个节点占用的存储空间无需预先指定而是在运行时动态申请。 单链表一旦创建就可对链表进行操作。 查找值为x的节点并返回该节点地址。算法分析从单链表的第一个节点开始判断当前节点的数据域的值是否为x若是则返回该节点的指针域否则依据指针域内的指针查找下一节点直至表结束。若找不到则返回空。 * 查找第i个节点返回期指针。算法分析从单链表的第一个节点开始依次判断当前节点是否为第i个节点若是则返回其指针否则依据指针域内的指针查找下一节点直至表结束。若找不到则返回空。 Chapter 12. 网络编程 Table of Contents 12.1. TCP/IP协议分析 12.2. 入门示例程序 12.1. TCP/IP协议分析 EthernetII帧的结构DMACSMACTypeDataCRCEthernetII帧的大小是有限制的最小不能小于64字节最大不能超过1518字节否则帧会被丢弃。一个EthernetII帧包括的内容有 DMAC目的MAC地址占48个bit共6个字节。 * SMAC源MAC地址占48个bit共6个字节。 * Type帧类型如ip,arp等。占16个bit共2个字节。 * Data帧数据容量是变化的但最大不能越过1500个字节最小不能小于46个字节。 * CRC校验码占32个bit共4个字节。 IP包结构 tcgetattr(fd0,ts0);//把fd0(ttyS0)的属性赋值给ts0 //如果要设置某个选项那么就使用|运算:| //如果关闭某个选项就使用和~运算: ~ ts0.c_cflag | B9600 | CS7 | CLOCAL | CREAD | PARENB ; //波特率为9600 | 数据位为7位 | 保证程序不会成为端口的占有者 | 使能端口读取输入的数据 | ts0.c_cflag ~CRTSCTS;//取消流控制 | CRTSCTS 为硬件流控制 //| IXON | IXOFF |IXANY; 为软件流控制 ts0.c_lflag ~ECHO; //取消回显输入字符/* | IEXTEN | ISIG); */ ts0.c_lflag ~ECHONL; ts0.c_iflag ~IXOFF;//同下一行为取消软件流控制 ts0.c_iflag ~IXON; ts0.c_cflag ~CSIZE;//屏蔽字符大小位 ts0.c_cflag | CS7;//数据位为7位 ts0.c_cflag | PARENB; //ts0.c_cflag ~PARENB;//无校验 /* 无校验 ts0.c_cflag ~PARENB; 奇校验 ts0.c_cflag | (PARODD | PARENB); 偶校验 ts0.c_cflag ~ PARENB;opt.c_cflag ~PARODD; 空格 ts0.c_cflag ~PARENB;opt.c_cflag ~CSTOPB; */ ts0.c_lflag ~ICANON; ts0.c_oflag ~ONLCR; ts0.c_iflag ~INLCR; /* ISIG 当接收到字符INTRQUITSUSP或DSUSP时产生相应的信号。 XCASE 不属于POSIXLINUX下不支持如果同时设置了ICANON终端只有大写。输入被 转换为小写除了以\前缀的字符。输出时大写字符被前缀\小写字符被转换成大写。 ECHO 回显输入字符。 ECHOE 如果同时设置了ICANON字符ERASE擦除前一个输入字符WERASE擦除前一个词。 ECHOK 如果同时设置了ICANON字符KILL删除当前行。 ECHONL 如果同时设置了ICANON回显字符NL即使没有设置ECHO。 ECHOCTL 不属于POSIX如果同时设置了ECHO除了TABNLSTART和STOP之外的ASCII 控制信号被回显为^x这里X是比控制信号大0x40的ASCII码。例如字符0x08(BS)被回显为 ^H。 ECHOPRT 不属于POSIX如果同时设置了ICANON和IECHO字符在删除的同时被打印。 ECHOKE 不属于POSIX如果同时设置了ICANON回显KILL时将删除一行中的每个字符 如同指定了ECHOE和ECHORPT一样。 DEFECHO 不属于POSIX只在一个进程读的时候回显。 FLUSHO 不属于POSIXLINUX不支持输出被刷新。这个标志可以通过键入字符DISCARD 来打开和关闭。 NOFLSH 禁止产生SIGINTSIGQUIT和SIGSUSP信号时刷新输入和输出队列。 TOSTOP 向试图写控制终端的后台进程组发送SIGTTOU信号。 PENDIN 不属于POSIXLINUX不支持在读入一个字符时输入队列中的所有字符被重新 输出。bash用他来处理typeahead。 IEXTEN 启用实现自定义的输入处理。这个标志必须与ICANON同时使用才能解释特殊字符 EOL2,LNEXTREPRINT和WERASEIUCLC标志才有效。 ts0.c_cc[VMIN] 0; ts0.c_cc[VTIME] 0; /* IGNBRK 忽略接收到的break信号 BRKINT 如果IGNBRK被设置break信号将被忽 略否则如果BRKINT被设置接收到 break信号将导致输入/输出队列被清空并 且当前控制串口的前台进程将收到一个 SIGINT信号。如果IGNBRK和BRKINT都 没有被设置 收到的break信号将被接收为 NULL即{post.content}。但是如果PARMARK被设 置接收到的break信号将被接收为7{post.content} IGNPAR 忽略帧错误或奇偶校验错。 PARMARK 如果没有设置IGNPAR设置本属性表示在 接收到的带有错误的帧格式或奇偶校验的字符将被前缀 377{post.content}。如果两者都没有设置带有错误的帧格式或奇偶 校验的字符将被接收为{post.content}。 INPCK 打开输入数据的奇偶校验。 ISTRIP 滤掉第8位。 INLCR 将接收到的NL(换行)转换成CR(回车)。 IGNCR 忽略接收到的CR。 ICRNL 将收到的CR转换成NL(除非设置了 IGNCR)。 IUCLC 将接收到的大写字符转换成小写。 IXON 打开输出的XON/XOFF控制。 IXOFF 打开输入的XON/XOFF控制。 c_oflag OLCUC 将小写字符转换成大写后输出。 ONLCR 将NL转换成CR-NL后输出。 OCRNL 将CR转换成NL后输出。 ONLRET 不发送CR */ ts0.c_cflag ~CSTOPB; ts0.c_iflag | IGNBRK; ts0.c_lflag ~IEXTEN; ts0.c_lflag | NOFLSH; rc cfsetospeed(ts0,B9600); rc tcsetattr(fd0,TCSAFLUSH,ts0); 转载于:https://my.oschina.net/lwaif/blog/1826600