ARM LINUX 系统(NUC980 )如何支持更高的波特率 比如1M 2M
NUC980 LINUX 4.4 系统下串口最大的波特率是多少?有坛友知道吗 ? 目前我测试只能支持921600 看规格书上是可以支持3M 的 我想问如何在LINUX 系统上使用 2M工3M这种特殊波特率呢查看内核中的tty_ioctl.c 文件中 可以看到是可以更高的/*
* Routine which returns the baud rate of the tty
*
* Note that the baud_table needs to be kept in sync with the
* include/asm/termbits.h file.
*/
static const speed_t baud_table[] = {
0, 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
500000, 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[] = {
B0, 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
static int n_baud_table = ARRAY_SIZE(baud_table);
/**
* tty_termios_baud_rate
* @termios: termios structure
*
* Convert termios baud rate data into a speed. This should be called
* with the termios lock held if this termios is a terminal termios
* structure. May change the termios data. Device drivers can call this
* function but should use ->c_speed directly as they are updated.
*
* Locking: none
*/ 980串口这么高波特率,你得开启dma不然接收可能丢包 设定波特率时,在nuc980的串口驱动中,uart_get_baud_rate判断设定的波特率要小于port->uartclk / 11:
nuc980serial_set_termios
-->baud = uart_get_baud_rate(port, termios, old, port->uartclk / 0xffff, port->uartclk / 11);
而port->uartclk 是在nuc980serial_init_ports中直接写死了:
up->port.uartclk = 12000000;
这样看的话,串口波特率不能超过1090000。
如果要超过这个波特率的话,可以试试更改串口的时钟分频设置,然后配合修改串口驱动程序。
thepresent 发表于 2024-9-21 21:40
设定波特率时,在nuc980的串口驱动中,uart_get_baud_rate判断设定的波特率要小于port->uartclk / 11:
而 ...
(引用自3楼)
谢谢回复,问了原厂说是最高公支持 921600 波特率。 三年模拟 发表于 2024-9-21 16:17
980串口这么高波特率,你得开启dma不然接收可能丢包
(引用自2楼)
LINUX 系统是内核驱动 DMA 写好的吧 980的dma需要开启 刚调了T113,1.5M完全没问题,不过这没什么,另一边5,6块钱的ESP32也完全能应付得过来。 yyts 发表于 2024-9-23 20:27
刚调了T113,1.5M完全没问题,不过这没什么,另一边5,6块钱的ESP32也完全能应付得过来。 ...
(引用自7楼)
我的项目是要将udp的socket数据转串口。双向转发。串口太慢了。还有一个问题就是,串口收到数据,串口响应要5毫秒。哪怕是10字节也要五毫秒,现在感觉是无解。准备用SPI代替串口来做。不知道有没有坑。有啥好的方案吗? 三年模拟 发表于 2024-9-23 20:25
980的dma需要开启
(引用自6楼)
有这方面的资料吗?我第一次用nuc 980之前都没跑Linux系统。之前用裸奔的方式还可以。没遇到什么问题。现在做linux的应用编程的用户态编程效率太低了。 // 主处理函数
void *io_thread(void *args)
{
thread_args* ptr =(thread_args*)args;
int udp_sockfd = ptr->sockfd;
int serial_fd = ptr->serfd;
int i=0;
int len=0;
struct timeval timeout;
timeout.tv_sec = 0;// 设置为0秒
timeout.tv_usec = 100;//100; // 设置为100微秒
fcntl(udp_sockfd, F_SETFL, O_NONBLOCK);
fcntl(serial_fd, F_SETFL, O_NONBLOCK);
printf("sockaddr_in005 \n");
fd_set read_fds;
char udpbuffer;
char buffer;
struct sockaddr_in client_addr;
socklen_t addr_len = sizeof(client_addr);
printf("run while006 \n");
while (1)
{
FD_ZERO(&read_fds);
FD_SET(udp_sockfd, &read_fds);
FD_SET(serial_fd, &read_fds);
int max_fd = (udp_sockfd > serial_fd) ? udp_sockfd : serial_fd;
// 监控文件描述符
if (select(max_fd + 1, &read_fds, NULL, NULL, &timeout) < 0)
//if (select(max_fd + 1, &read_fds, NULL, NULL, NULL) < 0)
{
perror("select error");
break;
}
// 处理 UDP 数据
if (FD_ISSET(udp_sockfd, &read_fds))
{
ssize_t len = recvfrom(udp_sockfd, udpbuffer, sizeof(udpbuffer), 0, (struct sockaddr *)&client_addr, &addr_len);
if (len > 0)
{
write(serial_fd, udpbuffer, len);
}
}
// 处理串口数据
else if (FD_ISSET(serial_fd, &read_fds))
{
// ssize_t len = read(serial_fd, buffer, sizeof(buffer));
ssize_t len = read(serial_fd, buffer, 128);
if (len > 0)
{
sendto(udp_sockfd, buffer, len, 0, (struct sockaddr *)&client_addr, sizeof(client_addr));
}
}
}
close(serial_fd);
close(udp_sockfd);
return NULL;
}
三年模拟 发表于 2024-9-23 20:25
980的dma需要开启
(引用自6楼)
现在是串口收到的数据 产生IO 更新到用户空间会延时 3-5MS 如何加快这个速度呢 有偿请教。 liuzhijun2008 发表于 2024-9-23 23:44
我的项目是要将udp的socket数据转串口。双向转发。串口太慢了。还有一个问题就是,串口收到数据,串口响 ...
(引用自8楼)
我的数据包,延时要求没那么高,有个队列缓存起来后面再按顺序收完都可以。 yyts 发表于 2024-9-24 13:39
我的数据包,延时要求没那么高,有个队列缓存起来后面再按顺序收完都可以。 ...
(引用自12楼)
我这个要求很高 对响应要求 高不能通过 环形缓冲这样会更慢, 现在主要是网口将数据通过NUC980主机串口发出去之后从机设备在 600US 内就将数据返回给NUC980 LINUX 串口了,但LINUX用户空间收到这一帧数据是 5MS 之后。 希望将这个数据做到 1MS 以内5MS 就太慢了,如果是 5MS不如直接用 115200
页:
[1]