====嵌入式Linux系统中的UART串口通信==== 在嵌入式Linux系统中,UART是最常用的一种接口。UART包含TTL电平的串口和RS232电平的串口,在Digi的开发套件/单板计算机上,您可以找到这两种电平的接口。i.MX6UL支持最高5Mbps的各种标准或非标波特率。 串口通常在Linux中被看成终端设备(tty),用户可以通过/dev下的对应的终端设备描述符来访问串口。注意串行终端只是终端设备中的一种,i.MX系列处理器的串口通常以ttymxcN来命名,我们可以在系统中用ls /dev/tty*来查看可用的串口号。 * [[#cc6ul-uart|ConnectCore 6UL串口]] * [[#cc6-uart|ConnectCore 6/6+串口]] * [[#cc8x-uart|ConnectCore 8x串口]] https://www.digi.com/resources/documentation/digidocs/embedded/dey/dey-2.4/cc6ul/yocto-bsp_r_uart_6ul \\ 在CC6UL模块上,除uart1用于内部蓝牙片子接口外,剩下的uart都可以供外部电路使用。 \\ 在CC6UL SBC Express单板机上,uart4在扩展槽上,uart5用作console口。\\ 在cc6ul SBC Pro单板机上,uart2和uart3在扩展槽上,并与CAN复用。uart5用作console口。 \\ [[https://www.digi.com/resources/documentation/digidocs/embedded/dey/dey-2.4/cc6/yocto-bsp_r_uart_cc6cc6qp|官方文档]] \\ 在CC6/6+模块上,默认地您可以使用UART1,UART3,UART5三个串口。而UART2在模块内部用于连接蓝牙片子,UART4则作为console口使用。 \\ 在单板机上,串口扩展槽上接出了uart1,uart3两个RS232电平带流控的接口和一个TTL电平的uart5, uart5同时也连接到XBee插槽上。 \\ https://www.digi.com/resources/documentation/digidocs/embedded/dey/dey-2.4/cc8x/yocto-bsp_r_uart_8x \\ 在ConnectCore 8X模块上,LPUART1连到内部蓝牙片子上,LPUART0, LPUART2, 和LPUART3可供外部使用,协处理器M4上的UART0也可被外部使用。 \\ 在ConnectCore 8X SBC Express单板机上,LPUART0连接到XBee插座上,与CAN0复用。LPUART2用作console口,LPUART3连到树霉派扩展槽上和和M4的uart复用接口槽。\\ 在ConnectCore 8X SBC Pro单板机上,LPUART0连接到扩展接口上与CAN0复用,LPUART2用作console口,LPUART3通过485收发片子连到扩展接口,并同CAN2复用。\\ ---- 测试嵌入式板卡上的串口,最简单的方法是用stty工具软件,比如要测试uart1,可以用下面的命令, stty -F /dev/ttymxc0 115200 echo test > /dev/ttymxc0 上面命令把uart1的波特率设置为115200,然后发送"test"字符串,如果我们连接到电脑的串口上,用终端打开一个115200波特率的串口,就可以接收到相应的字符串。 在程序中访问串口,除了设置串口用了termios结构外,其它可以像访问文件一样进行打开或读写操作,一般的操作流程是:打开串口,串口初始化,读写串口,关闭串口。事实上Linux下的串口编程都是一样的方法,网上有大量的例程,您也可以参考下面这个简单的例程。\\ /* file name: dey-uart-test.c */ #include #include #include #include #include #include #include #include volatile int stop=0; void sigalrm_handler( int sig ) { stop = 1; } int set_interface_attribs(int fd, int speed) { struct sigaction sact; sigemptyset (&sact.sa_mask); sact.sa_flags = 0; sact.sa_handler = sigalrm_handler; sigaction(SIGALRM, &sact, NULL); alarm(60); /* Request SIGALRM in 60 seconds */ struct termios tty; if (tcgetattr(fd, &tty) < 0) { printf("Error from tcgetattr: %s\n", strerror(errno)); return -1; } cfsetospeed(&tty, (speed_t)speed); cfsetispeed(&tty, (speed_t)speed); tty.c_cflag |= (CLOCAL | CREAD); /* ignore modem controls */ tty.c_cflag &= ~CSIZE; tty.c_cflag |= CS8; /* 8-bit characters */ tty.c_cflag &= ~PARENB; /* no parity bit */ tty.c_cflag &= ~CSTOPB; /* only need 1 stop bit */ tty.c_cflag &= ~CRTSCTS; /* no hardware flowcontrol */ /* setup for non-canonical mode */ tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); tty.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); tty.c_oflag &= ~OPOST; /* fetch bytes as they become available */ tty.c_cc[VMIN] = 1; tty.c_cc[VTIME] = 1; if (tcsetattr(fd, TCSANOW, &tty) != 0) { printf("Error from tcsetattr: %s\n", strerror(errno)); return -1; } return 0; } void set_mincount(int fd, int mcount) { struct termios tty; if (tcgetattr(fd, &tty) < 0) { printf("Error tcgetattr: %s\n", strerror(errno)); return; } tty.c_cc[VMIN] = mcount ? 1 : 0; tty.c_cc[VTIME] = 5; /* half second timer */ if (tcsetattr(fd, TCSANOW, &tty) < 0) printf("Error tcsetattr: %s\n", strerror(errno)); } int main() { /*if you need test other port,change portname here */ char *portname = "/dev/ttymxc0"; int fd; int wlen; fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC); if (fd < 0) { printf("Error opening %s: %s\n", portname, strerror(errno)); return -1; } /*baudrate 115200, 8 bits, no parity, 1 stop bit */ set_interface_attribs(fd, B115200); //set_mincount(fd, 0); /* set to pure timed read */ /* simple output */ wlen = write(fd, "Hello!\n", 7); if (wlen != 7) { printf("Error from write: %d, %d\n", wlen, errno); } tcdrain(fd); /* delay for output */ /* simple noncanonical input */ while (!stop) { unsigned char buf[80]; int rdlen; rdlen = read(fd, buf, sizeof(buf) - 1); if (rdlen > 0) { #ifdef DISPLAY_STRING buf[rdlen] = 0; printf("Read %d: \"%s\"\n", rdlen, buf); #else /* display hex */ unsigned char *p; printf("Read %d:", rdlen); for (p = buf; rdlen-- > 0; p++) printf(" 0x%x", *p); printf("\n"); #endif } else if (rdlen < 0) { printf("Error from read: %d: %s\n", rdlen, strerror(errno)); } /* repeat read to get full message */ } close(fd); exit(0); } 该例程默认在一分钟内将接收到的字串以十六进制显示,如果您需要看ASCII码,可以在编译选项中加入DISPLAY_STRING,如 ~> touch Makefile 输入以下内容: BINARY := dey-uart-test CFLAGS += -Wall -O0 -DDISPLAY_STRING .PHONY: all all: $(BINARY) $(BINARY): dey-uart-test.o .PHONY: clean clean: -rm -f *.o $(BINARY) {{ :digi:arm-embedded:linux:dey:devices-interfaces:dey-uart-test.zip |download dey-uart-test.zip}}