树莓派CAN FD无法接收 BRS=1的数据,会出现错误帧

2024-01-02 16:26:36 提问

我配置的是Canfd,用CanOE工具发,树莓派扩展的这个CanFd模块收,但我发送的Canfd数据BRS=0时,树莓派是可以正常收到的,如果BRS=1,CanOE工具会显示错误帧,树莓派也是错误帧,我BitTimingFd配置也跟Canoe配置对比了确实是一样的,不知道为什么就是BRS=1,就是不通,能帮忙解答一下吗

CanOe发送

树莓派接收到的Can数据:

代码:

可以肯定的是BitTimingFd配置跟CanOe上是一致的

from email.policy import strict
from enum import Flag
import os
import can
import threading
import time
from pprint import pprint
from threading import Lock
import cantools
from pprint import pprint
import traceback

exitSig = ''

mux = Lock()

os.system('sudo ip link set can1 up type can bitrate 500000 dbitrate 4000000 restart-ms 1000 berr-reporting on fd on')

bit_timingfd = can.BitTimingFd(
    f_clock=80_000_000,
    nom_brp=2,
    nom_tseg1=55,
    nom_tseg2=24,
    nom_sjw=2,
    data_brp=2,
    data_tseg1=6,
    data_tseg2=3,
    data_sjw=1,
    strict = False,
)
print(bit_timingfd)

can1 = can.interface.Bus(channel = 'can1', bustype = 'socketcan', bit_timing_fd = bit_timingfd, fd = True)# socketcan_native
#can1 = can.ThreadSafeBus(channel = 'can1', bustype = 'socketcan', bit_timing_fd = bit_timingfd, fd = True)# socketcan_native
send_msg = can.Message(is_extended_id=False, arbitration_id=0x580, data=[0, 0, 0, 0, 0, 0, 0, 0], is_fd = False, is_rx = False, bitrate_switch = False, channel = 'can1')



db = cantools.database.load_file('/home/Public/FAW_E001R_PCDU_CANMatrix_V0.9_20230616.dbc') #Open a dbc file. (arxml, dbc)
    
def Can1SendCbk(msg):
    msg.timestamp = time.time()
    print(msg)

def PackDbcMsg():
    example_message = db.get_message_by_name('VDC_Config')
    print(example_message.signal_tree)
    data = example_message.encode({'VDC_OTAMode': 6, 'VDC_PowerMode': 12, 'Reserved28':0, 'Reserved30':0, 'Reserved29':0})
    message = can.Message(arbitration_id=example_message.frame_id, data=data)
    return message
    
def Can1SendMsgMain(arg_send_msg, period, num):
    task = can1.send_periodic(arg_send_msg, period, num*period, modifier_callback = Can1SendCbk)
    assert isinstance(task, can.CyclicSendTaskABC)
    return task
    
'''
Receive can message and switch to dbc file output.
'''
duty = 0
frequency = 0
wakeupId = 0
def OuputDbcMsg(revMsg):
    global duty
    global frequency
    global wakeupId
    if revMsg.arbitration_id != 0x3EE and revMsg.arbitration_id != 0x585:
        return
        
    if revMsg.arbitration_id == 0x3EE:
        exList = [0,0,0,0,0,0,0,0]
        revMsg.data.extend(exList) #data tail append many member
        print(revMsg)
        try:
            dbMsg = db.decode_message(revMsg.arbitration_id, revMsg.data)
        except:
            #Output error
            traceback.print_exc()
        else:
            duty = dbMsg['Charger_CPPWMDuty']
            frequency = dbMsg['Charger_CPfrequency']
             
    elif revMsg.arbitration_id == 0x585:
        print(revMsg)
        try:
            dbMsg = db.decode_message(revMsg.arbitration_id, revMsg.data)
        except:
            #Output error
            traceback.print_exc()
        else:
            wakeupId = dbMsg['CCU_Source_Node_ID']
    else:
        pass
    
    print('Charger_CPPWMDuty:', duty)
    print('Charger_CPfrequency:', frequency)
    print('CCU_Source_Node_ID:', wakeupId)
                
    
def Can1ReceiveMsgMain():
    global exitSig
    while True:
        mux.acquire()
        if exitSig == "#":
            mux.release()
            return
            
        msg = can1.recv(5.0)
        if msg is None:
            print('Timeout occurred, no message.')
        else:
            OuputDbcMsg(msg)
            if msg.arbitration_id != 0x088:
                print(msg)
        mux.release()

        
def enxitFunc():
    global exitSig
    while True:
        exitSig = input()
        if exitSig == '#':
            break
    print("Close cmd:", exitSig)


def main():
    t2 = threading.Thread(target=Can1ReceiveMsgMain)
    t3 = threading.Thread(target=enxitFunc)

    # 启动线程
    t2.start()
    t3.start()
    
    #Can1SendMsgMain(send_msg, 1.0, 0)


    # 等待线程执行完成
    t2.join()
    t3.join()
    can1.stop_all_periodic_tasks()

    can1.shutdown()
    os.system('sudo ifconfig can1 down')
    print("======CLOSE======")
    
if __name__ == '__main__':
    main()


我来答
浏览 277 次
已有2个回答
斑梨游客95f04
回答时间:
2024-01-02 18:06:29

已解决

虽然都配置OK了,但是我换了个CanFd设备,

对应的数据域的波特率跟树莓派的不匹配导致了这个问题

点赞0

举报

斑梨用户8
回答时间:
2024-01-02 18:09:17

请确认下外接的CAN FD模块和2-CH CAN FD HAT模块的对应BRS设置

和其他CAN FD配置参数是否均一致,

另外可以用can-utils工具,即用candsend和candump指令直接收发测试看看(不用代码的方式)。

点赞0

举报

价格: ¥239
型号: 2-CH-CAN-FD-HAT
制造商: 斑梨电子