Linux驱动之串口驱动配置
簡介
I.MX6ULL 的 UART 驅動 NXP 已經編寫好了,所以不需要我們編寫關于IMX6ULL 開發板UART程序, 以下為UART3作為rs232使用。
串口驅動配置
1、 UART3 IO 節點創建
UART3 用到了 UART3_TXD 和 UART3_RXD 這兩個 IO,因此要先在 iomuxc 中創建 UART3對應的 pinctrl 子節點,在 iomuxc 中添加如下內容:
pinctrl_uart3: uart3grp { fsl,pins = < MX6UL_PAD_UART3_TX_DATA__UART3_DCE_TX 0X1b0b1 MX6UL_PAD_UART3_RX_DATA__UART3_DCE_RX 0X1b0b1>;};最后檢查一下 UART3_TX 和 UART3_RX 這兩個引腳有沒有被用作其他功能,如果有用作其它功能的話要將其屏蔽掉,保證這兩個 IO 只用作 UART3
2、添加 uart3 節點
默認情況下 imx6ull-alientek-emmc.dts 中只有 uart1 和 uart2 這兩個節點,如下圖所示:
uart1 是 UART1 的,在 I.MX6ull開發板上沒有用到 UART2,而且 UART2默認用到了 UART3 的 IO,因此需要將 uart2 這個節點刪除掉,然后加上 UART3 對應的 uart3,uart3 節點內容如下:
完成以后重新編譯設備樹并使用新的設備樹啟動 Linux, 如果設備樹修改成功的話,系統啟動以后就會生成一個名為“/dev/ttymxc2”的設備文件, ttymxc2 就是 UART3 對應的設備文件,應用程序可以通過訪問 ttymxc2 來實現對 UART3 的操作。
串口應用程序編寫
#include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <termios.h> #include <errno.h>int set_opt(int,int,int,char,int); void main() {int fd,nByte,flag=1;char *uart3 = "/dev/ttymxc2"; //"/dev/ttymxc2"是COM3char buffer[512];char *uart_out = "Please input,waiting....\r\n";char *uart_demo = "Linux uart demo\r\n";memset(buffer, 0, sizeof(buffer));//if((fd = open(uart3, O_RDWR|O_NOCTTY))<0)//默認為阻塞讀方式if((fd = open(uart3, O_RDWR|O_NONBLOCK))<0)//非阻塞讀方式printf("open %s is failed",uart3);else{set_opt(fd, 115200, 8, 'N', 1);write(fd,uart_demo, strlen(uart_demo));write(fd,uart_out, strlen(uart_out));while(1){while((nByte = read(fd, buffer, 512))>0){buffer[nByte+1] = '\0'; write(fd,buffer,strlen(buffer));memset(buffer, 0, strlen(buffer));nByte = 0;}}} }int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop) {struct termios newtio,oldtio;if ( tcgetattr( fd,&oldtio) != 0) { perror("SetupSerial 1");return -1;}bzero( &newtio, sizeof( newtio ) );newtio.c_cflag |= CLOCAL | CREAD;newtio.c_cflag &= ~CSIZE;switch( nBits ){case 7:newtio.c_cflag |= CS7;break;case 8:newtio.c_cflag |= CS8;break;}switch( nEvent ){case 'O':newtio.c_cflag |= PARENB;newtio.c_cflag |= PARODD;newtio.c_iflag |= (INPCK | ISTRIP);break;case 'E': newtio.c_iflag |= (INPCK | ISTRIP);newtio.c_cflag |= PARENB;newtio.c_cflag &= ~PARODD;break;case 'N': newtio.c_cflag &= ~PARENB;break;}switch( nSpeed ){case 2400:cfsetispeed(&newtio, B2400);cfsetospeed(&newtio, B2400);break;case 4800:cfsetispeed(&newtio, B4800);cfsetospeed(&newtio, B4800);break;case 9600:cfsetispeed(&newtio, B9600);cfsetospeed(&newtio, B9600);break;case 115200:cfsetispeed(&newtio, B115200);cfsetospeed(&newtio, B115200);break;case 460800:cfsetispeed(&newtio, B460800);cfsetospeed(&newtio, B460800);break;default:cfsetispeed(&newtio, B9600);cfsetospeed(&newtio, B9600);break;}if( nStop == 1 )newtio.c_cflag &= ~CSTOPB;else if ( nStop == 2 )newtio.c_cflag |= CSTOPB;newtio.c_cc[VTIME] = 100;///* 設置超時10 seconds*/newtio.c_cc[VMIN] = 0;tcflush(fd,TCIFLUSH);if((tcsetattr(fd,TCSANOW,&newtio))!=0){perror("com set error");return -1;}// printf("set done!\n\r");return 0; }串口用編程函數介紹
1、讀取當前參數函數:
int tcgetattr(int fd,struct termios *termios_p) fd:open操作后返回的文件句柄 *termios_p:為前面介紹的結構體 初始化開始前調用這個函數.2、獲取當前波特率函數:
int speed_t cfgetispeed(const struct termios *termios_p) int speed_t cfgetospeed(const struct termios *termios_p) *termios_p:為前面介紹的結構體 成功返回0,失敗返回-13、波特率設置函數:
int cfsetispeed(struct termios *termios_p,speed_t speed) int cfsetospeed(struct termios *termios_p,speed_t speed) *termios_p:為前面介紹的結構體 speed:波特率,常用B2400,B4800,B9600,B115200,B460800 成功返回0,失敗返回-14、清空buffer數據函數:
int tcflush(int fd,int queue_selector) queue_selector:有三個常用宏定義TCIFLUSH:清空正讀的數據,且不會讀出TCOFLUSH:清空正寫入的數據,且不會發送到終端TCIOFLUSH:清空所有正在發生的I/O數據.成功返回0,失敗返回-15、設置串口參數函數:
int tcsetattr(int fd,int optional_actions,cons struct termios *termios_p) optional_actions:有三個常用宏定義TCSANOW:不等數據傳輸完畢,立即改變屬性TCSADRAIN:等所有數據傳輸完畢,再改變屬性TCSAFLUSH:清空輸入輸出緩沖區才改變屬性 成功返回0,失敗返回-1串口號介紹
PC的默認串口為ttyS0;
嵌入式設備的默認串口為ttymxc*(代表數字);
注:嵌入式設備Samsung Artik 710架構的則是ttySAC(*代表數字)
檢查串口是否可以
通過echo 命令直接往/dev/ttyN 設備寫字符,如果有被寫字符輸出顯示的話,就說明這個tty設備可用。例如下圖中就可以看到/dev/ttyAMA0這個設備可用
總結
以上是生活随笔為你收集整理的Linux驱动之串口驱动配置的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: canvas动画之三 -- 黑客
- 下一篇: linux查看串口驱动