我让事情复杂化了吗?
我正在构建我的代码,通过UART从8051微型到外围设备进行通信.外设响应来自主机的命令,并且一次只能响应一个命令.这是一个简单的发送和接收协议.(tx1,rx1,tx2,rx2,tx3,rx3)每个TX消息以CR终止,每个响应以>终止.在收到对最后一个的回复之前,我无法发送新消息.如果启用该选项,响应也可以在开头回显打印原始TX消息(但这会导致更多流量)
一个示例消息是:
或者使用echo选项......
选项A getHello等函数由发送和接收组成.并行ISR例程将收集传入的字节,并在收到">"字符时抛出一个标志.
char* getHello(char * buf){
sendMsg("Hello\r");
delay(10ms); //wait a little bit
//wait for receive to come in or timeout to occur
while(!receiveFlag || !timeoutFlag); //thrown by ISR
receiveMsg(buf);
//parse the message and do some other stuff
return buf;
}
Run Code Online (Sandbox Code Playgroud)
优点:
缺点:
选项B 采用并行方法.将创建两个单独的功能.一个用于发送消息,另一个用于在收到ISR的响应时顶点.
void sendHello(){
sendMsg("Hello\r");
//do some other stuff if needed
}
char* receiveMsg(char * buf){
//figure out from echo print what the tx message …
Run Code Online (Sandbox Code Playgroud) 在串行通信链路中,首选的成帧/同步方法是什么?
它是一个嵌入式系统,使用从UART到内存的DMA数据传输.我认为使用SOF的框架方法最具吸引力,但也许另一个方法足够好?
有没有人对这两种方法有利有弊?
大家好,我正在使用Ubuntu下的高速RS422 pci板(OXPCIe958).该设备可以工作高达15Mbps.我需要以10Mbps的速度工作,但我注意到在Linux下,如果我们使用termois,可以指定的最大速度是B4000000(4 Mbps).
有没有办法在linux中指定自定义波特率?我试图改变termois.h中的值:
#define B1152000 0010011
#define B1500000 0010012
#define B2000000 0010013
#define B2500000 0010014
#define B3000000 0010015
#define B3500000 0010016
#define B4000000 0010017 --> by default this is the last value
#define B4500000 0010018 --> Added
#define B5000000 0010020 --> Added
//#define __MAX_BAUD B4000000 --> Default value
#define __MAX_BAUD B10000000
Run Code Online (Sandbox Code Playgroud)
但改变不起作用.我无法理解分配给BXXXXXX的值的含义!!
该设备本机在Linux上运行,不必指定驱动程序.查看器件的数据表,我看到要指定目标波特率,我们必须设置一些寄存器来改变预分频器,锁存器除数和采样时钟.
根据数据表,tha baund率由下式给出:
Baundrate = inputclok /(sampleClock*divisor*prescaler)
有没有办法在linux下设置这个寄存器?驱动程序位于8250.c和8250_pci.c中
提前致谢
寻找一些帮助来测试具有OMAP L138的硬件流控制的UART实现。为了测试实现,我使用minicom
了模拟串行链接的另一端的方法,并且正在寻找一些有关如何配置它的见解。
我有一个简单的应用程序,它通过UART将消息从OMAP发送到minicom。如果OMAP和minicom均配置为不使用硬件流控制,则此操作将按预期进行。当我打开硬件流控制时,在minicom上看不到任何输出。
这是我遵循的步骤列表:
stty
我启用rts / cts握手stty -F /dev/ttyS1 crtscts
。使用命令,stty -F /dev/ttyS1 -a
我可以确认已启用crtscts。上面的两个更改确保在终端程序和UART驱动程序中启用了硬件流控制。OMAP上的UART也已配置为使用硬件流控制。
但是,上面列出的对minicom的更改似乎不足以使流量控制正常工作。启动应用程序后,来自OMAP的RTS(发送请求)信号变低,从而向minicom指示它要发送数据。如果配置正确,minicom应将OMAP的CTS(清除发送)信号拉低,并开始接受数据,直到达到指定的接收缓冲区阈值为止。这不会发生。OMAP的CTS输入始终为高。只是为了踢一下,我尝试在OMAP和voila上将RTS与CTS短路,期望的消息确实会在minicom上显示!这是一张图像,显示了两者如何连接。
从我的尝试来看,好像我在配置minicom的方式中缺少了一些东西。任何建议表示赞赏。
我正在尝试通过 COM 端口在单板计算机和 PC 之间进行通信。在单板计算机上,我运行的是 Debian Linux,有两个 UART 可供我使用。在其中一个 UART ( ttyS1 ) 上,我可以毫无问题地进行通信(发送和接收)。当我尝试在另一个 UART ( ttyS0 )上进行通信时,发送工作正常,但是接收丢失了第一个字节(向 PC 上的控制台发送一条错误消息,说输入的字符不是命令),然后所有正确接收未来的字符。
如果我从接收切换到发送,然后再切换回接收,也会发生同样的情况。如果我保持在接收模式,我可以在不丢失数据的情况下接收任意长的字符。从发送到接收的转换似乎导致了这种情况的发生。
正如我之前提到的,我在另一个 UART (ttyS1) 上没有看到这个问题。我开始寻找两个端口不同的原因。我使用相同的程序为两个 UARTS 设置发送和接收,因此问题不在程序设置中。当我输入命令时,我确实发现了一件事,我dmesg |grep tty
得到以下信息:
[ 0.000000] Kernel command line: console=ttyS0,115200 root=/dev/mmcblk0p2 roo twait loglevel=8 panic=10
[ 0.446780] sunxi-uart.1: ttyS0 at MMIO 0x1c28400 (irq = 2) is a U6_16550A
[ 1.114996] console [ttyS0] enabled
[ 1.154643] sunxi-uart.3: ttyS1 at MMIO 0x1c28c00 (irq = 4) is a U6_16550A
Run Code Online (Sandbox Code Playgroud)
我看到 ttyS0 具有与之关联的“控制台 …
我正在尝试让 UART 传输在 stm32f405 上通过 DMA 工作。我的应用程序的这一部分旨在作为命令行界面发送文本字符串。我让 UART 的 RX 部分与 DMA 配合良好(使用 1 字节循环 DMA 来处理传入的任何内容),但 TX 端被证明有点棘手。
我可以使用以下方式发送数据字符串:HAL_UART_Transmit_DMA(&handle, pData[], strlen(pData))
前提是函数的连续调用之间存在延迟。一旦我的程序决定依次发送两个字符串,新的数据指针就会被忽略。
通过使用,while(HAL_UART_Transmit_DMA(...) != HAL_OK){}
我可以让程序等待所需的时间并发送连续的字符串。
这可以工作一段时间(几十次传输),然后由于 HAL_NOT_OK 而卡住。
作为参考,我的 DMA 设置是:DMA2 stream 7
, channel 4
, mem to periph
, periph inc disabled
, mem inc enabled
, mem and periph align byte
, normal mode (not circular)
, low priority
, fifo disabled
。
UART 设置为9600 baud
, 8 bit word
, …
我正在尝试使用DMA为RX和TX与UART外设进行通信.我正在使用ST提供的HAL库(使用STCubeMX生成).
我正在处理一个1.5MBaud的UART通道 - 所以为了不丢失任何数据,我已经在直接模式下配置DMA,使用循环缓冲器,并处理半传输中断以处理数据,并保持DMA在线获取更多数据.
问题是有时我可以在UART的状态寄存器中看到帧错误位是打开的,有时溢出错误标志也是打开的.
我可以处理丢失的字节(在结构化数据包上使用crc),但问题是外设停止接收数据 - 但DMA不会引发错误,或停止传输.
因此,如果我尝试接收数据,并且系统上的标志挂起.
我看到HAL提供了一个应该处理UART_Error的__weak函数,但它永远不会被调用 - 并且HAL句柄中的状态保持正常.只看一下注册表就可以看出存在问题.
我该如何检测/处理这类错误?
谢谢
Linux中什么时候发生控制台和UART绑定,是否可以在运行时从控制台解除UART绑定并将其绑定到其他模块(GPS)。
我的主板有一个 UART,我可以在运行时在控制台和 GPS 之间切换吗?如果是,我该怎么做?如果不是,我需要做什么?
我正在尝试配置我的串行端口(/dev/ttyS0)以自动控制 RTS 引脚。我已经可以通过 ioctl TIOCM_RTS 标志切换从用户空间执行此操作,但在我的情况下它太慢 - 从设备响应太快,我错过了它。
我尝试通过启用 RS485 模式来实现它,但最终出现以下错误:
unable to set IOCTL:: Inappropriate ioctl for device
Run Code Online (Sandbox Code Playgroud)
我的实现
port_fd = open(port.c_str(), O_RDWR);
if (port_fd != -1) {
struct serial_rs485 rs485conf={0};
rs485conf.flags |= SER_RS485_ENABLED;
rs485conf.flags |= SER_RS485_RTS_ON_SEND;
rs485conf.delay_rts_before_send = 0;
int rv = ioctl(port_fd,TIOCSRS485, &rs485conf);
if(rv){
printf("rv = %d\n", rv);
perror("unable to set IOCTL:");
}
Run Code Online (Sandbox Code Playgroud)
dmesq 输出:
[ 0.000000] console [tty0] enabled
[ 1.338716] 00:01: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A
[ …
Run Code Online (Sandbox Code Playgroud) 我在raspberry pi 3上安装了lineage os 14我连接了一个带有UART端口的gps模块,然而,GPS的波特率是9600但是/ dev/ttyS0的波特率是115200我想改变ttyS0的波特率以便读取GPS数据我试过stty命令
stty -F /dev/ttyS0 9600
Run Code Online (Sandbox Code Playgroud)
但是,当我再次使用此命令检查
stty -F /dev/ttyS0
速度值为115200 时,这不会改变波特率.如何更改/ dev/ttyS0的波特率我也找到了一些带有串行命令的解决方案serial /dev/ttyS0 9600
但是它不存在于adb shell.任何帮助都会感激不尽
uart ×10
linux ×4
serial-port ×3
c ×2
dma ×2
embedded ×2
flow-control ×2
android ×1
architecture ×1
console ×1
fifo ×1
gpio ×1
gps ×1
hardware ×1
linux-kernel ×1
omap ×1
rs485 ×1
stm32 ×1
termios ×1