本次测试会将FDCAN配置为FDCAN模式 仲裁段波特率为1Mbps 数据段为8Mbps,基本工程可以参考上一版本中FDCAN配置成classic模式通信的代码
主频调整至96Mbps
配置参数如下
| 参数 |
仲裁段 (1 Mbps) |
数据段 (8 Mbps) |
| Prescaler |
1 |
1 |
| TSEG1 |
63 |
7 |
| TSEG2 |
32 |
4 |
| SJW |
32 |
4 |
|
|
| Mode |
Normal |
| Frame Format |
FD with BRS (FD + Bit Rate Switching) |
| Auto Retransmission |
Enable |
| Transmit Pause |
Disable |
| Protocol Exception |
Enable |
注意 模式要配置成Bit Rate Switching
初始化代码如下
void MX_FDCAN1_Init(void)
{
/* USER CODE BEGIN FDCAN1_Init 0 */
/* USER CODE END FDCAN1_Init 0 */
/* USER CODE BEGIN FDCAN1_Init 1 */
/* USER CODE END FDCAN1_Init 1 */
hfdcan1.Instance = FDCAN1;
hfdcan1.Init.ClockDivider = FDCAN_CLOCK_DIV1;
hfdcan1.Init.FrameFormat = FDCAN_FRAME_FD_BRS;
hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
hfdcan1.Init.AutoRetransmission = ENABLE;
hfdcan1.Init.TransmitPause = DISABLE;
hfdcan1.Init.ProtocolException = ENABLE;
hfdcan1.Init.NominalPrescaler = 1;
hfdcan1.Init.NominalSyncJumpWidth = 32;
hfdcan1.Init.NominalTimeSeg1 = 63;
hfdcan1.Init.NominalTimeSeg2 = 32;
hfdcan1.Init.DataPrescaler = 1;
hfdcan1.Init.DataSyncJumpWidth = 4;
hfdcan1.Init.DataTimeSeg1 = 7;
hfdcan1.Init.DataTimeSeg2 = 4;
hfdcan1.Init.StdFiltersNbr = 1;
hfdcan1.Init.ExtFiltersNbr = 0;
hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK)
{
Error_Handler();
}
还有滤波器配置
void MX_FDCAN1_Config(void)
{
FDCAN_FilterTypeDef sFilterConfig;
/* Configure standard filter: accept all standard IDs into Rx FIFO 0 */
sFilterConfig.IdType = FDCAN_STANDARD_ID;
sFilterConfig.FilterIndex = 0;
sFilterConfig.FilterType = FDCAN_FILTER_MASK;
sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
sFilterConfig.FilterID1 = 0x000;
sFilterConfig.FilterID2 = 0x000;
if (HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
/* Set global filter: reject non-matching std/ext frames, filter remote frames */
if (HAL_FDCAN_ConfigGlobalFilter(&hfdcan1, FDCAN_REJECT, FDCAN_REJECT,
FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE) != HAL_OK)
{
Error_Handler();
}
/* Tx delay compensation (required for FD + BRS data rates >= 8 Mbps).
TdcOffset = DataTimeSeg1 = 7 (SSP position in data phase), TdcFilter = 0 */
if (HAL_FDCAN_ConfigTxDelayCompensation(&hfdcan1, 7, 0) != HAL_OK)
{
Error_Handler();
}
if (HAL_FDCAN_EnableTxDelayCompensation(&hfdcan1) != HAL_OK)
{
Error_Handler();
}
/* Start FDCAN module */
if (HAL_FDCAN_Start(&hfdcan1) != HAL_OK)
{
Error_Handler();
}
}
以上为FDCAN初始化部分 为了测试最大总线负载,我们发送字节填充为64字节
TxHeader.Identifier = 0x123;
TxHeader.IdType = FDCAN_STANDARD_ID;
TxHeader.TxFrameType = FDCAN_DATA_FRAME;
TxHeader.DataLength = FDCAN_DLC_BYTES_64;
TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
TxHeader.BitRateSwitch = FDCAN_BRS_ON;
TxHeader.FDFormat = FDCAN_FD_CAN;
TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
TxHeader.MessageMarker = 0;
for (uint8_t i = 0; i < 64; i++) {
TxData[i] = i;
}
在main主循环中暴力发送
if (HAL_FDCAN_GetTxFifoFreeLevel(&hfdcan1) > 0) {
if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, TxData) != HAL_OK) {
BSP_LED_Toggle(LED_RED);
} else {
BSP_LED_Toggle(LED_GREEN);
}
FDCAN盒为busmaster X2 最大支持12Mbps


实测性能如下 数据段为64字节 峰值发送10K帧/S
理论上限计算
64 字节 FD 帧 + BRS 模式下,一帧的总线上时间消耗:
| 阶段 |
内容 |
比特数 |
速率 |
时间 |
| 仲裁段 |
SOF + ID(11) + RRS + IDE + FDF + BRS + ESI + DLC(4) + 填充 |
~26 bits |
1 Mbps |
~26 µs |
| 数据段 |
64×8=512 位数据 + 21 位 CRC + 填充 |
~600 bits |
8 Mbps |
~75 µs |
| 帧尾 |
ACK + DELIM + EOF(7) + IFS(3) + 填充 |
~14 bits |
1 Mbps |
~14 µs |
单帧总计 ≈ 115 µs(典型),理论最优 ≈ 100 µs(零填充)
- 100 µs/帧 →10,000 fps (理论极限)
- 115 µs/帧 →~8,700 fps (典型实际)
总体性能已经十分接近理论极限
如果使用FDCAN来进行IAP升级
假设固件大小为128KB
总线仅需要传输2048帧,消耗时间约为0.21S 则剩下瓶颈全在flash擦写上,性能十分可观。
测试源码见链接
https://1811627153.share.123pan.cn/123pan/ZVgRVv-vSgt3?pwd=LZzc#