python-can中Notifier类的实现报文的实时分发
作者:名字太俊不提也罢
文章介绍了利用python-can库中的Notifier类创建一个线程来从总线读取CAN消息,并通过回调函数将消息分发给监听对象,具有一定的参考价值,感兴趣的可以了解一下
前言
这个问题之前很早之前就解决了,今天记录一下这个相关知识点,防止后续遗忘
一、Notifier是什么类
Notifier 是 python-can 库中的消息分发器,它创建后台线程从 CAN 总线持续读取消息,并实时分发给所有注册的监听器(Listeners)
Notifier 对象用作总线的消息分发器。Notifier 创建一个线程来从总线读取消息并将它们分发给需要监听的对象
核心工作流程
CAN 总线 → Notifier(后台线程) → Listener1 → 处理逻辑
→ Listener2 → 日志记录
→ Listener3 → 队列缓存二、具体实现代码
代码如下(示例):
class CanTool():
def __init__(self):
self.__mq = queue.Queue(50)
self.__bus = None
self.__notifier = None
def notifier_init(self):
"""
功能:初始化报文消息得回调函数
"""
logger = can.Logger("logfile.asc")
listeners = [
self.put_mq, # 回调函数,通过队列返回报文消息
logger, # 保存log日志,asc格式
]
self.__notifier = can.Notifier(self.__bus, listeners) #接收来自self.__bus的报文,分发给listeners对象
def bus_init(self, device: Optional[str], channel:Optional[str], bitrate:Optional[int]):
"""
功能:初始化总线设备
param1:设备名。str
param2:通道,str
param3:波特率,int
"""
try:
self.__bus = can.interface.Bus(bustype=device, channel=channel, bitrate=bitrate)
self.notifier_init()
return self.__bus
except Exception:
return self.__bus
def put_mq(self,msg: Optional[can.Message]):
"""
功能:接收报文得回调函数
param1:分发得到的报文对象
"""
if not self.__mq.full():
self.__mq.put_nowait(msg) #通过队列进行传输
def busclose(self):
"""
功能:结束总线收发,回收资源
"""
self.__notifier.stop() #停止分发
self.__bus.shutdown() #停止这个bus
总结
由于Python语言本身的问题,当程序读取写较大的总线消息时,会存在各种各样的问题,本文中的方案,结合前面的报文筛选功能,能解决大部分这相关的问题。
重要注意事项
| 要点 | 说明 |
|---|---|
| 必须调用 stop() | 否则监听器可能无法刷新缓冲区,导致数据丢失 |
| 线程安全 | 自定义监听器的 on_message_received 需考虑线程安全 |
| 避免阻塞 | 监听器中的处理应尽量快速,耗时操作请用队列 |
| 异常处理 | 监听器可实现 on_error() 来捕获异常 |
写在结尾
到此这篇关于python-can中Notifier类的实现报文的实时分发的文章就介绍到这了,更多相关python-can报文实时分发内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
