工具/软件: sdk-10.00.07.04
当配置为 DMA 时、与 不使用 DMA 时相比、AM62x 的串行端口在连续数据传输中表现出较低的效率。
详细步骤如下:
DTS 中的配置
uart4==>/dev/ttyS6
uart5==>/dev/ttyS7
&main_uart4 { bootph-all; status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&main_uart4_pins_default>; //dmas = <&main_pktdma 0x4404 0>, <&main_pktdma 0xc404 0>; //dma-names = "rx", "tx"; }; &main_uart5 { bootph-all; status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&main_uart5_pins_default>; dmas = <&main_pktdma 0x4405 0>, <&main_pktdma 0xc405 0>; dma-names = "rx", "tx"; };
2.测试代码
#include <stdio.h> #include <pthread.h> #include <unistd.h> #include <stdlib.h> //exit() #include <signal.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <termios.h> #include <time.h> #define SEND_PKG_SIZE 10000 #define BUF_SIZE 70 int baudSetOpt(int fd,int nSpeed,int nBits,char nEvent,int nStop); int main(int argc, char *argv[]) { int uart_fd = 0; int baudrate = 0; //int sendCount = 0; int sendSize = BUF_SIZE; int count = 0; int ret = 0; int i = 0; unsigned char wBuf[BUF_SIZE]; for(i = 0; i < BUF_SIZE; i++) { wBuf[i] = i & 0xFF; } //for(i = 0; i < BUF_SIZE; i++) //{ // if(i%16 == 0) // printf("\n"); // printf("%d ", wBuf[i]); //} if(argc != 3) { printf("param error !\n"); printf("please input: ./main /dev/ttyS7 460800\n"); return -1; } baudrate = atoi(argv[2]); uart_fd = open(argv[1], O_RDWR | O_NONBLOCK); if(uart_fd < 0) { printf("%s open file !\n",argv[1]); return -1; } ret = baudSetOpt(uart_fd, baudrate, 8, 'N', 1); if(ret == -1) { printf("%s set baudrate fail !\n", argv[1]); return -1; } long long int err_sum = 0; //记录时间戳 unsigned long long int start_time = 0; time_t get_time = 0; time(&get_time); //时间 start_time = get_time; for(i=0; i<SEND_PKG_SIZE; i++) { count = 0; while(sendSize != count) { ret = write(uart_fd, &wBuf[count], sendSize-count); if(ret >= 0) { count += ret; } else { err_sum++; //printf("ret = %d count = %d \n", ret, count); usleep(10000); //10ms //perror("write"); //continue; } } //printf(" count = %d \n", count); } time(&get_time); //时间 printf(" error times %lld, elapsed time %lld s\n", err_sum, get_time - start_time); close(uart_fd); return 0; } int baudSetOpt(int fd,int nSpeed,int nBits,char nEvent,int nStop) { struct termios newtio; bzero( &newtio, sizeof( newtio ) ); cfmakeraw(&newtio); tcflush(fd,TCIFLUSH); newtio.c_cflag &= ~CRTSCTS; // no stream ctrl newtio.c_cflag |= CLOCAL | CREAD; /* | CRTSCTS //stream strl*/ newtio.c_cflag &= ~CSIZE; switch( nBits ) { case 7: newtio.c_cflag |= CS7; break; case 6: newtio.c_cflag |= CS6; break; case 5: newtio.c_cflag |= CS5; break; default: newtio.c_cflag |= CS8; break; } switch( nEvent ) { case 'o': case 'O': newtio.c_cflag |= PARENB; newtio.c_cflag |= PARODD; // newtio.c_iflag |= (INPCK | ISTRIP); break; case 'e': case 'E': newtio.c_cflag |= PARENB; newtio.c_cflag &= ~PARODD; break; case 'n': case 'N': newtio.c_cflag &= ~PARENB; break; default: newtio.c_cflag |= PARENB; newtio.c_cflag &= ~PARODD; break; } switch( nSpeed ) { case 300: cfsetispeed(&newtio, B300); cfsetospeed(&newtio, B300); break; case 600: cfsetispeed(&newtio, B600); cfsetospeed(&newtio, B600); break; case 1200: cfsetispeed(&newtio, B1200); cfsetospeed(&newtio, B1200); break; 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 19200: cfsetispeed(&newtio, B19200); cfsetospeed(&newtio, B19200); break; case 38400: cfsetispeed(&newtio, B38400); cfsetospeed(&newtio, B38400); break; case 57600: cfsetispeed(&newtio, B57600); cfsetospeed(&newtio, B57600); 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] = 1; newtio.c_cc[VMIN] = 1; newtio.c_oflag = 0; newtio.c_lflag |= 0; newtio.c_oflag &= ~OPOST; newtio.c_cc[VTIME] = 1; /* unit: 1/10 second. */ newtio.c_cc[VMIN] = 1; /* minimal CHARacters for reading */ if((tcsetattr(fd,TCSANOW,&newtio))!=0) { return -1; } return 0; }
aarch64-oe-linux-gcc -mbranch-protection=standard --sysroot=/opt/arago-2023.10/sysroots/aarch64-oe-linux main.c -o main
3.测试结果
在460,800bps 下发送700,000字节。
root@am62xx-evm:/mnt/nfs/am62x# ./main /dev/ttyS6 460800 error times 1500, elapsed time 15 s root@am62xx-evm:/mnt/nfs/am62x# ./main /dev/ttyS7 460800 error times 31604, elapsed time 318 s
错误时间表示写入失败返回-1次、写入失败后、帐户+1、睡眠10ms、然后再次写入。
使用 DMA 的 UART 需要更长时间、请帮助分析。