feat(cproject): 移除CAN DMA相关代码并优化编译配置
- 移除了CAN模块中的DMA相关代码,包括can_dma_init函数、 DMA中断处理函数以及相关的全局变量和头文件包含 - 更新了项目构建配置,将优化级别从balanced改为size以减小 固件体积 - 添加了-fno-exceptions和-fno-rtti编译选项以进一步优化代码 - 升级了GD32C10x_DFP包版本至1.5.0 - 调整了OTA跳转逻辑,增加了更安全的中断和外设关闭处理 - 修复了Flash写入时的重复包处理逻辑,增加错误标志清理机制 - 将AES加密算法中的gf_mul函数标记为noinline属性
This commit is contained in:
+3
-3
@@ -414,11 +414,11 @@ CompileFlags:
|
||||
- '-IG:/Robot_v2/BOOT/Robot_V2/RTE/_Release_GD32C103CB'
|
||||
- '-IC:/Users/cbb/AppData/Local/arm/packs/ARM/CMSIS/4.5.0/CMSIS/Include'
|
||||
- >-
|
||||
-IC:/Users/cbb/AppData/Local/arm/packs/GigaDevice/GD32C10x_DFP/1.0.1/Device/Firmware/Peripherals/inc
|
||||
-IC:/Users/cbb/AppData/Local/arm/packs/GigaDevice/GD32C10x_DFP/1.5.0/Device/Firmware/Peripherals/inc
|
||||
- >-
|
||||
-IC:/Users/cbb/AppData/Local/arm/packs/GigaDevice/GD32C10x_DFP/1.0.1/Device/Include
|
||||
-IC:/Users/cbb/AppData/Local/arm/packs/GigaDevice/GD32C10x_DFP/1.5.0/Device/Include
|
||||
- >-
|
||||
-IC:/Users/cbb/AppData/Local/arm/packs/GigaDevice/GD32C10x_DFP/1.0.1/Device/Utilities
|
||||
-IC:/Users/cbb/AppData/Local/arm/packs/GigaDevice/GD32C10x_DFP/1.5.0/Device/Utilities
|
||||
- '-IG:/Robot_v2/BOOT/Robot_V2'
|
||||
- '-IG:/Robot_v2/BOOT/Robot_V2/sys'
|
||||
- '-IG:/Robot_v2/BOOT/Robot_V2/device'
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#define __ROM0_BASE 0x08000000
|
||||
// <o> Region size [bytes] <0x0-0xFFFFFFFF:8>
|
||||
// <i> Defines size of memory region. Default: 0x00020000
|
||||
#define __ROM0_SIZE 0x08006000
|
||||
#define __ROM0_SIZE 0x00006000
|
||||
// </h>
|
||||
|
||||
// <h> __ROM1 (unused)
|
||||
|
||||
@@ -21,14 +21,10 @@
|
||||
#define RTE_DEVICE_STDPERIPHERALS_CRC
|
||||
/* GigaDevice::Device:GD32C10x_StdPeripherals:DBG@1.3.0 */
|
||||
#define RTE_DEVICE_STDPERIPHERALS_DBG
|
||||
/* GigaDevice::Device:GD32C10x_StdPeripherals:DMA@1.3.0 */
|
||||
#define RTE_DEVICE_STDPERIPHERALS_DMA
|
||||
/* GigaDevice::Device:GD32C10x_StdPeripherals:EXTI@1.3.0 */
|
||||
#define RTE_DEVICE_STDPERIPHERALS_EXTI
|
||||
/* GigaDevice::Device:GD32C10x_StdPeripherals:FMC@1.3.0 */
|
||||
#define RTE_DEVICE_STDPERIPHERALS_FMC
|
||||
/* GigaDevice::Device:GD32C10x_StdPeripherals:FWDGT@1.3.0 */
|
||||
#define RTE_DEVICE_STDPERIPHERALS_FWDGT
|
||||
/* GigaDevice::Device:GD32C10x_StdPeripherals:GPIO@1.3.0 */
|
||||
#define RTE_DEVICE_STDPERIPHERALS_GPIO
|
||||
/* GigaDevice::Device:GD32C10x_StdPeripherals:MISC@1.3.0 */
|
||||
|
||||
@@ -23,7 +23,6 @@ project:
|
||||
- component: ARM::CMSIS:CORE
|
||||
- component: Device:Startup
|
||||
- component: Device:GD32C10x_StdPeripherals:CAN
|
||||
- component: Device:GD32C10x_StdPeripherals:DMA
|
||||
- component: Device:GD32C10x_StdPeripherals:FMC
|
||||
- component: Device:GD32C10x_StdPeripherals:GPIO
|
||||
- component: Device:GD32C10x_StdPeripherals:MISC
|
||||
@@ -31,7 +30,6 @@ project:
|
||||
- component: Device:GD32C10x_StdPeripherals:RCU
|
||||
- component: Device:GD32C10x_libopt
|
||||
- component: Device:EVAL:GD32C10x
|
||||
- component: Device:GD32C10x_StdPeripherals:FWDGT
|
||||
- component: Device:GD32C10x_StdPeripherals:DBG
|
||||
- component: Device:GD32C10x_StdPeripherals:EXTI
|
||||
- component: Device:GD32C10x_StdPeripherals:USART
|
||||
@@ -50,6 +48,8 @@ project:
|
||||
C-CPP:
|
||||
- -fshort-enums
|
||||
- -fshort-wchar
|
||||
- -fno-exceptions
|
||||
- -fno-rtti
|
||||
- -D__MICROLIB
|
||||
- -Wno-register
|
||||
C:
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include "config.h"
|
||||
#include "gd32c10x.h"
|
||||
#include "gd32c10x_can.h"
|
||||
#include "gd32c10x_dma.h"
|
||||
#include "gd32c10x_gpio.h"
|
||||
#include "main.h"
|
||||
#include <stdint.h>
|
||||
@@ -14,12 +13,6 @@ CAN_transmiter CAN0_transmiter; // CAN初始化
|
||||
extern BootloaderSystem sys;
|
||||
extern OTAHandler ota;
|
||||
|
||||
// 添加DMA相关变量
|
||||
dma_parameter_struct dma_rx_parameter;
|
||||
dma_parameter_struct dma_tx_parameter;
|
||||
uint8_t can_rx_buffer[64]; // CAN接收缓冲区(支持CAN FD最大64字节)
|
||||
uint8_t can_tx_buffer[64]; // CAN发送缓冲区(支持CAN FD最大64字节)
|
||||
|
||||
// CAN发送队列结构
|
||||
#define CAN_TX_QUEUE_SIZE 8
|
||||
typedef struct {
|
||||
@@ -59,49 +52,6 @@ u8 can_gpio_init() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief 初始化CAN DMA
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void can_dma_init(void) {
|
||||
// 使能DMA时钟
|
||||
rcu_periph_clock_enable(RCU_DMA0);
|
||||
|
||||
// 配置接收DMA
|
||||
dma_struct_para_init(&dma_rx_parameter);
|
||||
dma_rx_parameter.periph_addr =
|
||||
(uint32_t)(&CAN_RFIFOMDATA0(CAN0, CAN_FIFO0)); // CAN接收数据寄存器地址
|
||||
dma_rx_parameter.memory_addr = (uint32_t)can_rx_buffer; // 接收缓冲区地址
|
||||
dma_rx_parameter.direction = DMA_PERIPHERAL_TO_MEMORY; // 外设到内存
|
||||
dma_rx_parameter.memory_width = DMA_MEMORY_WIDTH_8BIT; // 内存宽度8位
|
||||
dma_rx_parameter.periph_width = DMA_PERIPHERAL_WIDTH_8BIT; // 外设宽度8位
|
||||
dma_rx_parameter.priority = DMA_PRIORITY_HIGH; // 高优先级
|
||||
dma_rx_parameter.number = 8; // 传输字节数
|
||||
dma_rx_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE; // 外设地址不递增
|
||||
dma_rx_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE; // 内存地址递增
|
||||
dma_init(DMA0, DMA_CH4, &dma_rx_parameter); // 使用DMA通道4
|
||||
|
||||
// 配置发送DMA
|
||||
dma_struct_para_init(&dma_tx_parameter);
|
||||
dma_tx_parameter.periph_addr =
|
||||
(uint32_t)(&CAN_TMI0(CAN0)); // CAN发送数据寄存器地址
|
||||
dma_tx_parameter.memory_addr = (uint32_t)can_tx_buffer; // 发送缓冲区地址
|
||||
dma_tx_parameter.direction = DMA_MEMORY_TO_PERIPHERAL; // 内存到外设
|
||||
dma_tx_parameter.memory_width = DMA_MEMORY_WIDTH_8BIT; // 内存宽度8位
|
||||
dma_tx_parameter.periph_width = DMA_PERIPHERAL_WIDTH_8BIT; // 外设宽度8位
|
||||
dma_tx_parameter.priority = DMA_PRIORITY_HIGH; // 高优先级
|
||||
dma_tx_parameter.number = 8; // 传输字节数
|
||||
dma_tx_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE; // 外设地址不递增
|
||||
dma_tx_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE; // 内存地址递增
|
||||
dma_init(DMA0, DMA_CH5, &dma_tx_parameter); // 使用DMA通道5
|
||||
|
||||
// 使能DMA通道
|
||||
dma_channel_enable(DMA0, DMA_CH4);
|
||||
dma_channel_enable(DMA0, DMA_CH5);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief 初始化CAN0 CANFD模式
|
||||
\param[in] none
|
||||
@@ -110,7 +60,6 @@ void can_dma_init(void) {
|
||||
*/
|
||||
void canfd_config(void) {
|
||||
can_gpio_init();
|
||||
can_dma_init();
|
||||
can_parameter_struct can_parameter;
|
||||
can_fdframe_struct can_fd_parameter;
|
||||
can_fd_tdc_struct can_fd_tdc_parameter;
|
||||
@@ -173,9 +122,6 @@ void canfd_config(void) {
|
||||
nvic_irq_enable(CAN0_RX0_IRQn, 1, 0);
|
||||
/* enable can receive FIFO0 not empty interrupt */
|
||||
can_interrupt_enable(CAN0, CAN_INTEN_RFNEIE0);
|
||||
// 使能DMA中断
|
||||
nvic_irq_enable(DMA0_Channel4_IRQn, 1, 1);
|
||||
dma_interrupt_enable(DMA0, DMA_CH4, DMA_INT_FTF);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -194,10 +140,6 @@ u8 CAN_transmiter::init() {
|
||||
// 初始化计数器和标志位
|
||||
can0_receive_count = 0;
|
||||
can0_send_flag = RESET;
|
||||
|
||||
// 初始化DMA缓冲区
|
||||
memset(can_rx_buffer, 0, sizeof(can_rx_buffer));
|
||||
memset(can_tx_buffer, 0, sizeof(can_tx_buffer));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -298,39 +240,6 @@ void CAN0_RX0_IRQHandler(void) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA通道4中断服务程序(CAN接收DMA) - 优化版:支持64字节
|
||||
* @retval 无
|
||||
*/
|
||||
void DMA0_Channel4_IRQHandler(void) {
|
||||
if (dma_interrupt_flag_get(DMA0, DMA_CH4, DMA_INT_FLAG_FTF)) {
|
||||
// 清除DMA传输完成中断标志
|
||||
dma_interrupt_flag_clear(DMA0, DMA_CH4, DMA_INT_FLAG_G);
|
||||
|
||||
// 获取实际接收的数据长度
|
||||
u8 data_len = CAN0_transmiter.receive_message.rx_dlen;
|
||||
if (data_len > 64) data_len = 64; // 安全限制
|
||||
|
||||
// 将DMA缓冲区的数据复制到接收消息结构体(支持最大64字节)
|
||||
for (int i = 0; i < data_len; i++) {
|
||||
CAN0_transmiter.receive_message.rx_data[i] = can_rx_buffer[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA通道5中断服务程序(CAN/CANFD发送DMA)
|
||||
* @retval 无
|
||||
*/
|
||||
void DMA0_Channel5_IRQHandler(void) {
|
||||
if (dma_interrupt_flag_get(DMA0, DMA_CH5, DMA_INT_FLAG_FTF)) {
|
||||
// DMA传输完成,可以在此处执行后续处理
|
||||
// 清除DMA传输完成中断标志
|
||||
dma_interrupt_flag_clear(DMA0, DMA_CH5, DMA_INT_FLAG_FTF);
|
||||
// 可以在此添加后续处理逻辑,如发送下一个数据包等
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 向发送队列添加消息
|
||||
* @param id CAN消息ID
|
||||
|
||||
@@ -11,10 +11,7 @@ extern "C" {
|
||||
|
||||
u8 can_gpio_init(void); // CAN引脚初始化
|
||||
void canfd_config(void); // CANFD初始化
|
||||
void can_dma_init(void); // CAN DMA初始化
|
||||
void CAN0_RX0_IRQHandler(void); // CAN接收中断处理函数
|
||||
void DMA0_Channel4_IRQHandler(void); // DMA通道4中断处理函数(CAN接收)
|
||||
void DMA0_Channel5_IRQHandler(void); // DMA通道5中断处理函数(CAN发送)
|
||||
/*!
|
||||
\brief CAN通信类
|
||||
\note 封装CAN发送和接收功能
|
||||
|
||||
+43
-10
@@ -156,9 +156,6 @@ void OTAHandler::process() {
|
||||
ota_time = 0; // 重置计时器
|
||||
static u8 zero[1] = {0};
|
||||
CAN0_transmiter.CANFD_AsyncSend(CANFD_OTA_WAIT_ID, 0, zero);
|
||||
#if DEBUG_OTA
|
||||
printf("OTA status:%d\r\n", ota_state);
|
||||
#endif
|
||||
delay_1ms(10);
|
||||
return;
|
||||
} else {
|
||||
@@ -224,9 +221,11 @@ bool validateApplication() {
|
||||
void OTAHandler::jumpToApplication() {
|
||||
#if DEBUG_OTA
|
||||
printf("try jump to app\r\n");
|
||||
#endif
|
||||
if (!validateApplication()) {
|
||||
return;
|
||||
}
|
||||
#if DEBUG_OTA
|
||||
printf("jumping1\r\n");
|
||||
#endif
|
||||
fmc_unlock();
|
||||
@@ -234,10 +233,18 @@ void OTAHandler::jumpToApplication() {
|
||||
OTA_SET(n_APP_LATEST_EN_ADDR, OTA_AVAL); // 设置APP为激活
|
||||
fmc_lock();
|
||||
|
||||
/* 1. 关闭 SysTick:VTOR 重指到 APP 后若 SysTick 仍在跑,
|
||||
* 下一拍会打进 APP 尚未就绪的 SysTick_Handler → 硬错误。 */
|
||||
SysTick->CTRL = 0U;
|
||||
SysTick->VAL = 0U;
|
||||
|
||||
/* 2. 关闭并清除所有 NVIC 中断:ICER 只禁能,ICPR 清挂起,
|
||||
* 否则 OTA 期间残留的 CAN RX 挂起会在 APP 使能中断瞬间误触发。 */
|
||||
for (int i = 0; i < 8; i++) {
|
||||
NVIC->ICER[i] = 0xFFFFFFFF;
|
||||
NVIC->ICPR[i] = 0xFFFFFFFF;
|
||||
}
|
||||
// 2. 重置外设(特别是CAN,防止冲突)
|
||||
// 重置外设(特别是CAN,防止冲突)
|
||||
can_deinit(CAN0);
|
||||
|
||||
// 3. 重置系统时钟到默认状态
|
||||
@@ -260,6 +267,8 @@ void OTAHandler::jumpToApplication() {
|
||||
#endif
|
||||
// 5. 设置中断向量表偏移到应用程序起始地址
|
||||
SCB->VTOR = APPLATEST_START_ADDR;
|
||||
__DSB();
|
||||
__ISB();
|
||||
|
||||
// 6. 设置MSP并跳转
|
||||
uint32_t msp_value = *(__IO uint32_t *)APPLATEST_START_ADDR;
|
||||
@@ -271,8 +280,13 @@ void OTAHandler::jumpToApplication() {
|
||||
reset_handler);
|
||||
#endif
|
||||
__set_MSP(msp_value);
|
||||
__DSB();
|
||||
__ISB();
|
||||
// 在跳转前清除复位标志
|
||||
rcu_all_reset_flag_clear();
|
||||
/* 确保全局中断使能:APP 的 Reset_Handler 不会碰 PRIMASK,
|
||||
* 若 BOOT 侧遗留 PRIMASK=1,APP 将永远收不到中断。 */
|
||||
__enable_irq();
|
||||
// 7. 跳转
|
||||
app_entry();
|
||||
|
||||
@@ -340,25 +354,44 @@ void OTAHandler::writeApplicationData(u32 offset, u8 *data, u32 size) {
|
||||
u8 *src = data;
|
||||
|
||||
// 32位对齐写入 - 处理完整的32位字
|
||||
for (; i <= size - 4; i += 4) {
|
||||
fmc_state = fmc_word_program(write_addr + i, *(u32 *)&src[i]);
|
||||
for (; i + 4 <= size; i += 4) {
|
||||
u32 word = *(u32 *)&src[i];
|
||||
volatile u32 *dst = (volatile u32 *)(write_addr + i);
|
||||
/* 重复包幂等:ACK 丢失导致 DCU 重发已写入的包时,目标已是目标值,
|
||||
* 直接跳过。否则对非擦除态 flash 编程会触发 PGERR。 */
|
||||
if (*dst == word) {
|
||||
continue;
|
||||
}
|
||||
/* 每字写前清 FMC 错误标志:一旦 PGERR/WPERR 残留,
|
||||
* fmc_ready_wait 会让后续所有 program 直接返回错误(雪崩)。 */
|
||||
fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_PGAERR | FMC_FLAG_WPERR);
|
||||
fmc_state = fmc_word_program(write_addr + i, word);
|
||||
if (fmc_state != FMC_READY) {
|
||||
printf("FMC_WRITE_ERROR\r\n");
|
||||
/* 清掉本次错误标志,避免毒化后续字的编程 */
|
||||
fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_PGAERR | FMC_FLAG_WPERR);
|
||||
}
|
||||
}
|
||||
|
||||
// 处理剩余字节(如果有的话)
|
||||
// 处理剩余字节(size 非4的倍数时),未用字节补 0xFF(擦除态)
|
||||
if (i < size) {
|
||||
u32 word = 0;
|
||||
u32 word = 0xFFFFFFFF;
|
||||
u8 *word_ptr = (u8 *)&word;
|
||||
u32 remaining_bytes = size - i;
|
||||
|
||||
// 直接复制剩余字节到word变量
|
||||
for (u32 j = 0; j < remaining_bytes; j++) {
|
||||
word_ptr[j] = src[i + j];
|
||||
}
|
||||
|
||||
fmc_word_program(write_addr + i, word);
|
||||
volatile u32 *dst = (volatile u32 *)(write_addr + i);
|
||||
if (*dst != word) {
|
||||
fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_PGAERR | FMC_FLAG_WPERR);
|
||||
fmc_state = fmc_word_program(write_addr + i, word);
|
||||
if (fmc_state != FMC_READY) {
|
||||
printf("FMC_WRITE_ERROR\r\n");
|
||||
fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_PGAERR | FMC_FLAG_WPERR);
|
||||
}
|
||||
}
|
||||
}
|
||||
fmc_lock();
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ void mix_columns(u8 *state) {
|
||||
}
|
||||
|
||||
// 伽罗瓦域乘法 (用于逆列混合)
|
||||
static u8 gf_mul(u8 a, u8 b) {
|
||||
__attribute__((noinline)) static u8 gf_mul(u8 a, u8 b) {
|
||||
u8 p = 0;
|
||||
u8 high_bit;
|
||||
|
||||
|
||||
+15
-3
@@ -1,9 +1,20 @@
|
||||
#ifndef __CONFIG_H__
|
||||
#ifndef __CONFIG_H__
|
||||
#define __CONFIG_H__
|
||||
#include "stdint.h"
|
||||
|
||||
// ============================================================
|
||||
// 固件版本号
|
||||
// ============================================================
|
||||
constexpr u16 BOOT_VERSION_MAJOR = 26;
|
||||
constexpr u16 BOOT_VERSION_MINOR = 7;
|
||||
constexpr u16 BOOT_VERSION_PATCH = 26; // Flash优化: -Oz/ROM护栏/AES去内联/移除CAN DMA无效代码/-fno-exceptions
|
||||
constexpr u16 BOOT_VERSION_BUILD = 0;
|
||||
|
||||
// 编译时间(AC6 编译器自动生成)
|
||||
#define BOOT_BUILD_DATE __DATE__
|
||||
#define BOOT_BUILD_TIME __TIME__
|
||||
#define EEP_DEBUG 0
|
||||
#define DEBUG_OTA 0
|
||||
#define DEBUG_OTA 1
|
||||
#define CAN_DEBUG 0
|
||||
#define SLEEP_DEBUG 0
|
||||
|
||||
@@ -64,4 +75,5 @@ constexpr u32 OTA_TIMEOUT = 10000;
|
||||
constexpr u32 APP_DELAY_BOOT_TIME = 10000; // APP延迟启动时间(毫秒),可配置
|
||||
constexpr u8 SIZE_U32 = sizeof(uint32_t);
|
||||
constexpr u8 SIZE_FLOAT = sizeof(float);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user