ATSAME51 CAN驱动无编译优化正常,开启优化后出现格式错误
问题描述
在Microchip IGAT开发板上为ATSAME51编写了CAN驱动,无编译优化时程序可正常收发数据;开启任意等级编译优化后,总线报错(Error Passive、Error Warning、Bus Off位均置位),协议状态寄存器(PSR)的Last Error Code(LEC)为0x2(格式错误:接收帧的固定格式部分格式错误)。
已排查CAN寄存器、GCLK寄存器、IO复用寄存器,无编译优化和开启优化时这些寄存器状态一致;FIFO地址处于系统RAM前64KB的有效区域,且调试确认can_tx_immediate函数已将数据正确写入FIFO,目前无法定位问题,寻求技术帮助。
相关代码
main.c
#include "sam.h" #include "drivers/drivers.h" int main(void) { system_config_all_clk(); io_set_pin_mux(PORTB, PORT_PB12, SET_PIN_MUX_H); io_set_pin_mux(PORTB, PORT_PB13, SET_PIN_MUX_H); can_init(CAN1); /* Replace with your application code */ while (1) { can_test(); } }
canbus.c
#define CAN_TX_FIFO_SIZE 2 #define CONF_CAN1_BTP_TSEG2 2 #define CONF_CAN1_BTP_TSEG1 13 #define CONF_CAN1_BTP_BRP 1 #define CONF_CAN1_BTP_SJW 1 volatile static uint8_t can1_rx_fifo[CAN1_RX_FIFO_ELEMENTS * 16] __attribute__((__aligned__(4))); volatile static uint8_t can1_tx_fifo[CAN1_RX_FIFO_ELEMENTS * 16] __attribute__((__aligned__(4))); void can_init(Can* canbus) { /*Unlocks CAN1 for editing.*/ canbus->CCCR.bit.INIT = 1; while (canbus->CCCR.bit.INIT != 1) {} canbus->CCCR.bit.CCE = 1; /*Defines memory priority for message RAM access as not sensitive operation (lowest priority).*/ canbus->MRCFG.reg = CAN_MRCFG_QOS_DISABLE; /*Sets up the time quanta timing for normal speed operation (1Mbps).*/ canbus->NBTP.reg = CAN_NBTP_NBRP(CONF_CAN1_BTP_BRP - 1) | CAN_NBTP_NTSEG1(CONF_CAN1_BTP_TSEG1 - 1) | CAN_NBTP_NTSEG2(CONF_CAN1_BTP_TSEG2 - 1) | CAN_NBTP_NSJW(CONF_CAN1_BTP_SJW - 1); /*RX FIFO 0 configuration, blocking mode, watermark interrupt disabled, sets buffer size and start address.*/ canbus->RXF0C.reg = CAN_RXF0C_F0S(CAN1_RX_FIFO_ELEMENTS) | CAN_RXF0C_F0SA((uint32_t)can1_rx_fifo); /*Sets the size of data field for the RX/TX FIFO, operating in CAN2.0B not FD, so this is always 8 bytes.*/ canbus->RXESC.reg = CAN_RXESC_F0DS_DATA8; canbus->TXESC.reg = CAN_TXESC_TBDS_DATA8; /*Sets the size and start address of the TX FIFO.*/ canbus->TXBC.reg = CAN_TXBC_TFQS(CAN1_RX_FIFO_ELEMENTS) | CAN_TXBC_TBSA((uint32_t)can1_tx_fifo); /*Reset the CCE and INIT bits to start CAN operation.*/ canbus->CCCR.bit.CCE = 0; canbus->CCCR.bit.INIT = 0; while (canbus->CCCR.bit.INIT != 0) {} } int32_t can_tx_immediate(Can* canbus, can_tx_fifo_entry_t* message) { volatile can_tx_fifo_entry_t* f = NULL; uint32_t put_index; /*Check if FIFO is full.*/ if (canbus->TXFQS.bit.TFQF != 0) { return -1; } /*Determine which index to put the new msg at.*/ put_index = canbus->TXFQS.bit.TFQPI; if (canbus == CAN1) { /*Set the address of f based on the put index.*/ f = (can_tx_fifo_entry_t*)(can1_tx_fifo + put_index * 16); } if (f == NULL) { return -1; } /*Copy into FIFO.*/ memcpy(f, message, 16); /*Request the transmission.*/ canbus->TXBAR.reg = 1 << put_index; } void can_test() { volatile can_tx_fifo_entry_t new_msg; /*Initialize these to zero.*/ new_msg.T0.val = 0; new_msg.T1.val = 0; new_msg.data[0] = 0x00; new_msg.data[1] = 0x01; new_msg.data[2] = 0x02; new_msg.data[3] = 0x03; new_msg.T0.bit.ESI = 0; new_msg.T0.bit.XTD = 0; //Standard length ID. new_msg.T0.bit.RTR = 0; //Standard frame. new_msg.T0.bit.ID = 0x69 << 18; //Standard length ID needs to be passed down 18 bits. new_msg.T1.bit.DLC = 4; //4 bytes of data. new_msg.T1.bit.FDF = 0; //Not FD mode. new_msg.T1.bit.BRS = 0; //No bit rate switching. new_msg.T1.bit.EFC = 0; //Dont store events. can_tx_immediate(CAN1, &new_msg); }
总线状态对比
无编译优化时CAN总线运行状态

开启编译优化时CAN总线运行状态
开启优化后总线会进入Bus Off模式,Error Passive、Error Warning、Bus Off位均置位,LEC为0x2。
内容的提问来源于stack exchange,提问作者Alex Jegers
相关产品推荐
相关产品推荐

