介绍 一个简洁方便的的u***2can调试器,可用于can总线数据调试和一般的can总线故障排查。在基于RT-Thread和N32G457的软硬件平台的基础上,使用SLCAN协议配合USB CDC类通信 可以实现将can数据转发到PC或者上位机上,供上位机软件进行分析。 主要功能 可以实现接收can总线数据收发功能,从can总线发送到u***上位机或者从u***上位机发送到can总线。 可以设置can波特率,支持扩展帧和远程帧。 slcan通用协议,ascii字符可以直接通过串口查看数据,linux工具can-uti ls中的slcan_attach、slcand、slcanpty可以直接驱动此协议转换成linux下的socketcan。 u*** cdc免驱可以实现win10、linux即插即用。 同时还有 python-can 、cantact-app等多种工具实现can数据采集分析。
硬件和软件框架 硬件上使用 国民技术提供的N32G45XVL-STB v1.1开发版加上一个TJA1050的can收发器。
[td]硬件
描述
芯片型号 N32G457VEL7 CPU ARM Cortex M4 主频 144M 180DMIPS 片内SRAM 144K 片内FLASH 512K 串口 7路 (UART4路 USART3路) USB 全速USB 2.0接口 CAN 2路 CAN 2.0A/B总线接口
从硬件到软件 硬件上主要使用USB和CAN功能。
USB作为USB device设备,实现一个全速的u*** cdc功能,再通过rtthread的device框架注册成为一个字符设备 vcom 。上层应用可以通过vcom设备直接与PC上位机通信。 CAN接口,原本N32G457应该有两路can接口,但是由于使用了u*** device,can1和u***是公用fifo和中断号的所以没法同时使用。所以只使用了can2,同样can2也是注册到rtthread的device框架上的。可以直接通过rtdevice的api进行读写配置波特率等操作,这也方便后面的slcan进行配置can参数。同时slcan的核心代码可移植性更高。
从软件到硬件 硬件部分实现好后,软件部分通过rtthread的api就可以完成大部分操作了。主要驱动代码和应用层代码,逻辑处理代码。
USB CDC驱动代码,主要是u*** cdc的vcom驱动,因为暂时还没有N32G457的u*** device驱动能注册到rtdevice去,所以直接用N32G457的SDK提供的例程做出来的USB CDC,然后在此基础上注册一个字符设备vcom到rtdevice框架上,提供对cdc的读写接口。
can驱动,还有就是can驱动。在做这个东西的时候发现没有can驱动,于是参考sdk的例程写了一个驱动注册到rtdevice框架上。
slcan代码,接下来就是最重要的slcan应用层代码了。
应用层代码主要通过一个rt_slcan_t结构体记录slcan的配置和上下文状态。然后通过启动一个线程用来监听vcom和can的数据,接收到数据立马处理。
如果是来自vcom端的数据,是以r结尾ascii字符串,需要做一个帧完整性判断用来判断是不是接收到完整的一帧ascii字符数据包。接收完整性判断通过后再判断发送的哪些命令,然后根据具体的命令需要发送CAN数据包到CAN控制器的发送到can设备去,需要执行命令的执行命令然后返回ack。
主要的ascii命令格式是
[td]第一个字节
格式
描述
t 发送11bit ID的数据帧 r 发送11bit ID的远程帧 T 发送29bit ID的数据帧 R 发送29bit ID的远程帧 O 打开can C 关闭can V 显示版本号 N 显示串口号 F 读取can状态 s 设置can波特率 0 - 8 Z 设置ascii数据是否带时间
命令, 1个字节
can的id,标准帧3个字节,扩展帧8个字节,hex表示
数据,根据dlc长度从0字节到16字节变化,hex表示
时间,4个字节,hex表示
常见slcan命令示例:
[td]ascii命令
描述
t123166 标准canid 0x123, 长度1, 数据 0x66 T123456783112233 扩展canid 0x12345678, 长度3, 数据 0x11 0x22 0x33 r1260 标准canid 0x126, 长度 0, 远程请求帧 T12345679 扩展canid 0x12345679, 长度0, 远程请求帧
如果是来自can设备端的数据,就直接打包成ascii通过vcom发送出去就可以了。
软硬件架构图
slcan逻辑图
演示图片 使用串口工具直接打开串口,就可以看到can总线发送的数据,并且已经十六进制ascii格式,很方便阅读。发送数据到can总线也只需要按格式发送即可,每个命令结尾必须是0x0d。
python程序采集can数据。
通过python-can库可以很方便打开slcan协议的设备获取数据,还可以将采集到的数据保存到日志文件中。脚本放在git仓库的test目录,安装号库就可以使用了。
复制
import can
import threading
import time
import random
def print_message(msg):
print(msg)
if __name__ == "__main__":
# RX part
#bus_rx = can.interface.Bus('virtual_ch', bustype='virtual')
canbus = can.interface.Bus('COM32', bustype='slcan')
logger = can.Logger("logfile.asc") # save log to asc file
listeners = [
print_message, # Callback function, print the received messages
logger, # save received messages to asc file
]
notifier = can.Notifier(canbus, listeners)
running = True
while running:
input()
running = False
# It's important to stop the notifier in order to finish the writting of asc file
notifier.stop()
# stops the bus
canbus.shutdown()
演示视频 代码地址