vxWorks tty发送机制

涉及范围

应用层

tty子系统

底层串口驱动程序

框图

write->tywrite

tywrite获取wrtSyncSem信号量

将buf写入发送缓冲

调用tyTxStartup启动发送流程

tyTxStartup判断wrtState.busy即设备发送忙状态,为忙状态,认为处于发送流程中,退出;为空闲状态,调用底层串口设备的启动发送函数ns16550vxbTxStartup

ns16550vxbTxStartup开启发送完成使能,硬件产生一个中断,进入中断ISR,ns16550vxbInt

如果发送缓冲还有空间,释放wrtSyncSem信号量

ns16550vxbInt

如果产生发送完成中断,如果目前没有发送job,添加一个发送job到队列

isrDeferJobTask

从队列获取job,发送job,ns16550vxbIntWr2

ns16550vxbIntWr2判断串口发FIFO是否为空。若为空,从发送缓冲中获取字节,写入发FIFO,同时释放信号量wrtSyncSem

NOTE:该设计最精妙的地方是底层串口驱动的发送与上层写分开,作为两个部分,底层启动一轮发送后,依靠底层串口中断实现循环,不必唤醒上层,去写数据,同时,缓冲池的存在一定程度减缓了上层的阻塞等待时间

遇到的问题

一般情况下串口中断的使用方式为,串口硬件产生中断,中断控制器通知CPU,CPU进入相应的中断服务函数进行处理

在项目上由于某些原因,CPU接收不到串口硬件中断,所以改为CPU主动调用ns16550vxbInt去轮询串口状态,根据串口的IIR寄存器状态,进行下面的相应处理。过程中发现,IIR的发送FIFO空状态不一定能获取到,导致丢失一个发送FIFO空的中断,造成依赖于此的底层串口发送循环中止,本轮发送结束,但如果此时tty子系统的发送缓冲区为满时,会阻塞在信号量wrtSyncSem,而该信号量恰恰需要底层进行释放,而底层本轮发送已经结束,tty子系统便一直阻塞在这。

进一步试验发现,IIR的状态丢失可能与短时间访问有关,或者在IIR寄存器的信号上升阶段,读取该寄存器造成信号清除有关。在两次读取之间添加一段时间延时,该问题得到改善;判断当前阻塞时候的状态,在ns16550vxbInt中进行自我启动,两个方法结合起来,确保万无一失

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值