更新OTA功能,config独立成文件统一定义

refactor(build): 更新项目配置和链接器设置
- 修改GD32C103CB的ROM基地址和大小配置
- 更新系统时钟向量表偏移量设置
- 在cproject.yml中添加BIN输出格式支持
- 增加-O3优化级别和代码移除选项
- 更新csolution版本依赖

feat(device): 优化ADC采样和配置管理
- 将DengFOC依赖替换为FOC模块
- 从config.h引入配置常量
- 重命名FILTER_SIZE为ADC_FILTER_SIZE以提高清晰度
- 优化温度和电流采样滤波实现

refactor(algorithm): 简化FOC控制函数接口
- 为angle_control、velocity_control等函数移除不必要的参数
- 统一函数指针类型定义
- 优化电流计算函数的代码格式
- 调整PID控制器初始化参数
This commit is contained in:
cbb
2026-01-04 22:26:22 +08:00
parent abd64da360
commit d0198fdff7
26 changed files with 716 additions and 439 deletions
+88
View File
@@ -0,0 +1,88 @@
#ifndef __CONFIG_H
#define __CONFIG_H
#include <stdint.h>
// 如果使用CMSIS DSP库,需要定义ARM_MATH_CM4
// #define ARM_MATH_CM4
#define EEP_DEBUG 1
// BOOT 相关
constexpr u32 BOOTLOADER_START_ADDR = 0x08000000; // BOOT起始地址
constexpr u32 OTA_CONFIG_NUM = 6;
constexpr u32 n_APP_LATEST_AVAL_ADDR = 0x0801D000;
constexpr u32 n_APP_BACKUP_AVAL_ADDR = 0x0801D004;
constexpr u32 n_APP_LATEST_EN_ADDR = 0x0801D008;
constexpr u32 n_APP_BACKUP_EN_ADDR = 0x0801D00C;
constexpr u32 n_APP_LATEST_CHECK_ADDR = 0x0801D010;
constexpr u32 n_APP_BACKUP_CHECK_ADDR = 0x0801D014;
constexpr u32 OTA_NOT_AVAL = 0xFFFFFFFF;
constexpr u32 OTA_AVAL = 0x00000000; // 全零表示可用
// 参数配置
constexpr u8 PP = 11;
constexpr float DIR = 1.0;
constexpr u16 REDUCTION_RATIO = 25;
constexpr float CURRENT_OFFSET = -1.615f; // 当前电流传感器的零点偏移
constexpr float HOLD_PWM_DUTY = 0.95f;
constexpr u32 CANFD_BOOT_ID = 0x00000000;
constexpr u32 CANFD_STATUS_ID = 0x00010100;
constexpr u32 CANFD_CONFIG_ID = 0x00010101;
constexpr u32 CANFD_CMD_ID = 0x00010200;
constexpr u32 CANFD_RESET_ID = 0x00010301;
// 常量定义
constexpr u8 SIZE_FLOAT = sizeof(float);
constexpr u8 SIZE_U32 = sizeof(uint32_t);
constexpr float ADC_MAX = 65536.0f;
constexpr float PI = 3.14159265358979323846f;
constexpr float ANGLE_FACTOR = 25.0f / 360.0f * 2.0f * PI;
constexpr float DEG2RAD = 1.0f / 360.0f * 2 * PI;
constexpr float RAD2DEG = 360.0f / 2 * PI;
constexpr float _1_SQRT3 = 0.57735026919f; // 1/sqrt(3)
constexpr float sqrt3dv2 = 0.86602540378f; // sqrt(3)/2的预计算值
constexpr u8 DEFAULT_VALUE = 0;
constexpr u8 CONFIG_SAVED_NUM = 6;
// 三角函数快速计算LUT
constexpr u16 LUT_SIZE = 1024;
constexpr u16 LUT_MASK = (LUT_SIZE - 1);
constexpr u16 LUT_SCALE = (LUT_SIZE / (2.0f * PI));
// CAN相关
constexpr u16 DEV_CAN0_ID = 0x0000;
constexpr u16 DEV_CAN0_MASK = 0x0000;
constexpr u16 DEV_CAN_LOOPBACK_ID = 0x0000;
// ADC
constexpr u8 ADC_FILTER_SIZE = 6;
constexpr u8 BLOCK_SIZE = ADC_FILTER_SIZE * SIZE_FLOAT;
constexpr float ERROR_ADC_VAL = 255.0f;
constexpr float MAX_TEMP = 150.0f;
constexpr float MIN_TEMP = -40.0f;
constexpr float MAX_CURRENT = 40.0f;
constexpr float MIN_CURRENT = -40.0f;
constexpr float MAX_VCC = 65.0f;
constexpr float MIN_VCC = -0.1f;
// ang_sensor
constexpr u16 VEL_FILTER_SIZE = 4;
constexpr u16 DEFAULT_COMMAND = 0x0000;
constexpr u16 FAULT_RECEIVE = 0xFFFF;
constexpr float ANGLE_WRAP_THRESHOLD = 300.0f;
constexpr float ANGLE_WRAP_VALUE = 360.0f;
constexpr float RAD_FACTOR = 1.0f / ADC_MAX * 2.0f * PI;
constexpr float ANGLESENS_FACTOR = 1.0f / ADC_MAX * 360.0f;
// TIMER2-任务调度
constexpr int TIMER2_PRESCALER = 119; // 120MHz / 120 = 1MHz
constexpr int TIMER2_PERIOD = 99; // 1MHz / 100 = 100us
// TIMER1-PWM
constexpr int TIMER1_PRESCALER = 0; // 不分频,计数器时钟为120MHz
constexpr int TIMER1_PERIOD = 5999; // 120MHz / (0+1) / (5999+1) = 20kHz
constexpr int TIMER1_DEFAULT_PULSE = 0;
constexpr int TIMER1_CH3_COMPARE_VALUE =
(TIMER1_PERIOD + 1) * 0.5 - 1; // PWM周期50%位置触发中断
#endif
+226 -51
View File
@@ -1,26 +1,28 @@
#include "flash.h"
#include "DengFOC.h"
#include "FOC.h"
#include "ang_sensor.h"
#include "config.h"
#include "gd32c10x.h"
#include "gd32c10x_crc.h"
#include "gd32c10x_fmc.h"
#include "math.h"
#include <Can.h>
#include <Filter.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <stdint.h>
FlashEEPROM flashEEP = FlashEEPROM();
extern angle_sensor KTH7823;
extern CAN_transmiter CAN0_transmiter;
extern FOC_Controlroller FOC; // FOC控制
constexpr u8 SIZE_U32 = sizeof(uint32_t);
constexpr u8 SIZE_FLOAT = sizeof(float);
constexpr u8 DEFAULT_VALUE = 0;
constexpr u8 NUM_SAVED = 6;
#define EEPDEBUG 0
inline fmc_state_enum write_ADDRESS(u32 address, u32 data) {
fmc_unlock();
fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_PGAERR | FMC_FLAG_WPERR);
// 确保使用对齐地址
fmc_state_enum fmc_status = fmc_word_program(address, data);
fmc_lock();
return fmc_status;
}
// FlashEEPROM类实现
FlashEEPROM::FlashEEPROM() {
// 构造函数可以为空,或者做一些初始化工作
@@ -56,8 +58,8 @@ u8 FlashEEPROM::init() {
u8 FlashEEPROM::read_saved_system_config(void) {
// 读取保存的参数
u32 CRC_NUM = 0x0000;
FlashEepromStatus status_read[NUM_SAVED + 1] = {FLASH_EEPROM_OK};
float data[NUM_SAVED] = {0.0f};
FlashEepromStatus status_read[CONFIG_SAVED_NUM + 1] = {FLASH_EEPROM_OK};
float data[CONFIG_SAVED_NUM] = {0.0f};
// 尝试从Flash读取参数,如果不存在则使用默认值
status_read[1] = readFloat(ADDR_CONTROL_MODE, &data[0]);
status_read[2] = readFloat(ADDR_VOLTAGE_LIMIT, &data[1]);
@@ -67,7 +69,7 @@ u8 FlashEEPROM::read_saved_system_config(void) {
status_read[6] = readFloat(ADDR_TARGET_VEL, &data[5]);
// 读取失败则使用默认值
for (u8 i = 1; i < NUM_SAVED + 1; i++) {
for (u8 i = 1; i < CONFIG_SAVED_NUM + 1; i++) {
if (status_read[i] ==
FLASH_EEPROM_DATA_NOT_FOUND) { // 首次读取,不保存报错
data[i - 1] = DEFAULT_VALUE;
@@ -99,13 +101,13 @@ u8 FlashEEPROM::read_saved_system_config(void) {
}
crc_data_register_reset(); // 确保CRC计算从初始状态开始
CRC_NUM = crc_block_data_calculate((uint32_t *)data, NUM_SAVED);
CRC_NUM = crc_block_data_calculate((uint32_t *)data, CONFIG_SAVED_NUM);
#if EEPDEBUG
#if EEP_DEBUG
printf("CRC cmp1,0x%X_0x%x \r\n", CRC_NUM, *((u32 *)next_address));
#endif
if (CRC_NUM != *((u32 *)next_address)) { // CRC错误
for (u8 i = 0; i < NUM_SAVED; i++) {
for (u8 i = 0; i < CONFIG_SAVED_NUM; i++) {
data[i] = DEFAULT_VALUE;
}
EEPROMStatus = FLASH_EEPROM_CRC_ERROR;
@@ -185,7 +187,7 @@ FlashEepromStatus FlashEEPROM::readFloat(u8 virtualAddr, float *data) const {
u32 float_data = data_word & DATA_FLOAT_MASK;
// 使用内存拷贝将处理后的数据解释为float
memcpy(data, &float_data, SIZE_FLOAT);
#if EEPDEBUG
#if EEP_DEBUG
printf("read:0x%x=%f\r\n", address, *data);
#endif
return FLASH_EEPROM_OK;
@@ -218,7 +220,7 @@ FlashEepromStatus FlashEEPROM::write(u8 virtualAddr, u16 data) {
if ((data_read & DATA_ADDR_MASK) == (u32)virtualAddr) { // 虚拟地址相同
if ((data_read & DATA_U16_MASK) ==
(data & DATA_U16_MASK)) { // 数据相同
#if EEPDEBUG
#if EEP_DEBUG
data_read = data_read & DATA_U16_MASK;
u16 float_data_read = *((u16 *)&data_read);
printf("Found data in:0x%x=%u\r\n", address, data_read);
@@ -249,19 +251,14 @@ FlashEepromStatus FlashEEPROM::write(u8 virtualAddr, u16 data) {
if (next_address < EEPROM_END_ADDRESS) {
u32 data_word = ((u32)data << 16) | (u32)virtualAddr;
// 使用GD32库函数进行安全编程
fmc_unlock();
fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_PGAERR | FMC_FLAG_WPERR);
fmc_state_enum fmc_status =
fmc_word_program(next_address, data_word); // 写入数据
fmc_lock();
fmc_state_enum fmc_status = write_ADDRESS(next_address, data_word);
if (fmc_status != FMC_READY) {
return FLASH_EEPROM_WRITE_ERROR;
}
return FLASH_EEPROM_OK;
} else { // 空间不足,需要格式化页面
#if EEPDEBUG
#if EEP_DEBUG
printf("no enough space\r\n");
#endif
FlashEepromStatus status = format();
@@ -301,7 +298,7 @@ FlashEepromStatus FlashEEPROM::writeFloat(u8 virtualAddr, float data) {
(u32)virtualAddr) { // 虚拟地址相同
if ((data_word_read & DATA_FLOAT_MASK) ==
(data_word & DATA_FLOAT_MASK)) { // 数据相同
#if EEPDEBUG
#if EEP_DEBUG
data_word_read = data_word_read & DATA_FLOAT_MASK;
float float_data_read = *((float *)&data_word_read);
printf("Found data in:0x%x=%f\r\n", address, float_data_read);
@@ -330,15 +327,8 @@ FlashEepromStatus FlashEEPROM::writeFloat(u8 virtualAddr, float data) {
// 如果有足够空间,直接写入
if (next_address < EEPROM_END_ADDRESS) {
// 使用GD32库函数进行安全编程
fmc_unlock();
fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_PGAERR | FMC_FLAG_WPERR);
// 确保使用对齐地址
fmc_state_enum fmc_status = fmc_word_program(next_address, data_word);
fmc_lock();
#if EEPDEBUG
fmc_state_enum fmc_status = write_ADDRESS(next_address, data_word);
#if EEP_DEBUG
u32 data_word_c = *((u32 *)next_address);
data_word_c = data_word_c & DATA_FLOAT_MASK;
float float_data = *((float *)&data_word_c);
@@ -350,7 +340,7 @@ FlashEepromStatus FlashEEPROM::writeFloat(u8 virtualAddr, float data) {
return FLASH_EEPROM_OK;
} else {
// 空间不足,需要格式化页面
#if EEPDEBUG
#if EEP_DEBUG
printf("no enough space\r\n");
#endif
FlashEepromStatus status = format();
@@ -370,7 +360,7 @@ FlashEepromStatus FlashEEPROM::writeFloat(u8 virtualAddr, float data) {
*/
FlashEepromStatus FlashEEPROM::format() {
fmc_state_enum fmc_status;
#if EEPDEBUG
#if EEP_DEBUG
printf("擦除页面\r\n");
#endif
@@ -395,9 +385,10 @@ FlashEepromStatus FlashEEPROM::format() {
*/
FlashEepromStatus FlashEEPROM::save_system_config(bool saved) {
u32 CRC_NUM = 0x0000;
float data[NUM_SAVED] = {(float)FOC.control_mode, FOC.limit_voltage,
FOC.limit_velocity, FOC.rt_angle,
FOC.target_angle, FOC.target_velocity};
float data[CONFIG_SAVED_NUM] = {
(float)FOC.control_mode, FOC.limit_voltage,
FOC.limit_velocity, FOC.rt_angle,
FOC.target_angle, FOC.target_velocity};
// 如果系统配置标记已保存,则无需再次保存
if (system_config_saved) {
@@ -445,10 +436,10 @@ FlashEepromStatus FlashEEPROM::save_system_config(bool saved) {
}
// 创建用于CRC计算的模拟数据数组,模拟实际存储到Flash中的数据格式
u32 crc_data_words[NUM_SAVED];
u32 crc_data_words[CONFIG_SAVED_NUM];
// 按照writeFloat函数的方式处理数据
for (u8 i = 0; i < NUM_SAVED; i++) {
for (u8 i = 0; i < CONFIG_SAVED_NUM; i++) {
// 将完整的float数据复制到32位变量中
memcpy(&crc_data_words[i], &data[i], SIZE_FLOAT);
// 去除最后2位精度
@@ -456,7 +447,7 @@ FlashEepromStatus FlashEEPROM::save_system_config(bool saved) {
}
crc_data_register_reset(); // 确保CRC计算从初始状态开始
CRC_NUM = crc_block_data_calculate(crc_data_words, NUM_SAVED);
CRC_NUM = crc_block_data_calculate(crc_data_words, CONFIG_SAVED_NUM);
writeCRC(CRC_NUM, saved);
EEPROMStatus = FLASH_EEPROM_OK;
@@ -501,14 +492,10 @@ FlashEepromStatus FlashEEPROM::writeCRC(u32 CRC_NUM, bool saved) {
if (*((u32 *)next_address) != CRC_NUM) {
// 如果有足够空间,直接写入crc值
if (next_address > EEPROM_START_ADDRESS) {
fmc_unlock();
fmc_flag_clear(FMC_FLAG_PGERR | FMC_FLAG_PGAERR | FMC_FLAG_WPERR);
fmc_state_enum fmc_status = fmc_word_program(next_address, CRC_NUM);
fmc_lock();
#if EEPDEBUG
fmc_state_enum fmc_status = write_ADDRESS(next_address, CRC_NUM);
#if EEP_DEBUG
printf("CRC cmp1,0x%X_0x%x \r\n", CRC_NUM, *((u32 *)next_address));
#endif
// 检查写入是否成功
if (fmc_status != FMC_READY) {
EEPROMStatus = fmc_status;
@@ -516,7 +503,7 @@ FlashEepromStatus FlashEEPROM::writeCRC(u32 CRC_NUM, bool saved) {
}
} else {
// 空间不足,需要格式化页面
#if EEPDEBUG
#if EEP_DEBUG
printf("no enough space\r\n");
#endif
FlashEepromStatus status = format();
@@ -539,4 +526,192 @@ FlashEepromStatus FlashEEPROM::writeCRC(u32 CRC_NUM, bool saved) {
EEPROMStatus = FLASH_EEPROM_CRC_ERROR; // 设置EEPROM错误状态
return FLASH_EEPROM_CRC_ERROR;
}
}
u8 OTA_SET(u32 addr, bool enable) {
fmc_state_enum fmc_status;
u32 temp_val[OTA_CONFIG_NUM];
u32 data = enable ? OTA_NOT_AVAL : OTA_AVAL;
volatile u32 *flash_ptr = (volatile u32 *)addr;
temp_val[0] = *flash_ptr;
if (temp_val[0] == data) { // 如果相同
return FLASH_EEPROM_OK; // 成功
}
fmc_unlock();
// 如果不同,且要写0,直接写
if (data == OTA_AVAL) {
fmc_status = write_ADDRESS(addr, data);
fmc_lock();
if (fmc_status == FMC_READY) {
return FLASH_EEPROM_OK; // 成功可以直接退出
}
}
// 如果不同或写入出错,要写1,需要重置,然后再写
flash_ptr = (volatile u32 *)n_APP_LATEST_AVAL_ADDR;
temp_val[0] = *flash_ptr;
flash_ptr = (volatile u32 *)n_APP_BACKUP_AVAL_ADDR;
temp_val[1] = *flash_ptr;
flash_ptr = (volatile u32 *)n_APP_LATEST_EN_ADDR;
temp_val[2] = *flash_ptr;
flash_ptr = (volatile u32 *)n_APP_BACKUP_EN_ADDR;
temp_val[3] = *flash_ptr;
flash_ptr = (volatile u32 *)n_APP_BACKUP_CHECK_ADDR;
temp_val[4] = *flash_ptr;
flash_ptr = (volatile u32 *)n_APP_BACKUP_CHECK_ADDR;
temp_val[5] = *flash_ptr;
#if EEP_DEBUG
printf("OTA_SET\r\n");
printf("0x%x_0x%x_0x%x_0x%x\r\n", temp_val[0], temp_val[1], temp_val[2],
temp_val[3]);
#endif
fmc_status = fmc_page_erase(n_APP_LATEST_AVAL_ADDR); // 擦除页
if (fmc_status != FMC_READY) {
return FLASH_EEPROM_ERASE_ERROR; // 擦除错误退出
}
for (int i = 0; i < OTA_CONFIG_NUM; i++) {
if (temp_val[i] == OTA_AVAL and
n_APP_LATEST_AVAL_ADDR + 4 * i != addr) {
fmc_status = write_ADDRESS(n_APP_LATEST_AVAL_ADDR + 4 * i,
OTA_AVAL); // 把需要写入0的写入0
if (fmc_status != FMC_READY) {
fmc_lock();
return FLASH_EEPROM_WRITE_ERROR; // 写入错误退出
}
}
}
fmc_lock();
return FLASH_EEPROM_OK;
}
/**
* @brief 跳转应用处理模块
* @param 无
* @retval 无
*/
void jumpToBOOT() {
OTA_SET(n_APP_LATEST_EN_ADDR, OTA_NOT_AVAL); // 设置APP为不激活
// 1. 关闭所有中断
__disable_irq();
for (int i = 0; i < 8; i++) {
NVIC->ICER[i] = 0xFFFFFFFF;
}
// 2. 重置外设(特别是CAN,防止冲突)
can_deinit(CAN0);
// 3. 重置系统时钟到默认状态
rcu_system_clock_source_config(RCU_CKSYSSRC_IRC8M);
// 4. 关闭一些关键外设时钟
rcu_periph_clock_disable(RCU_GPIOA);
rcu_periph_clock_disable(RCU_GPIOB);
rcu_periph_clock_disable(RCU_GPIOC);
rcu_periph_clock_disable(RCU_USART0);
rcu_periph_clock_disable(RCU_CAN0);
rcu_periph_clock_disable(RCU_TIMER0);
rcu_periph_clock_disable(RCU_DMA0);
// 5. 设置中断向量表偏移到应用程序起始地址
SCB->VTOR = BOOTLOADER_START_ADDR;
// 6. 设置MSP并跳转
uint32_t msp_value = *(__IO uint32_t *)BOOTLOADER_START_ADDR;
uint32_t reset_handler = *(__IO uint32_t *)(BOOTLOADER_START_ADDR + 4);
typedef void (*AppEntryFunc)(void);
AppEntryFunc app_entry = (AppEntryFunc)reset_handler;
__set_MSP(msp_value);
// 7. 跳转
app_entry();
// 如果程序执行到这里,说明跳转失败
printf("Jump to application failed!\r\n");
}
/**
* @brief 将0x08011000地址后0xC000大小区域内的数据搬运到0x08050000地址
* @param None
* @retval fmc_state_enum: 操作状态
*/
fmc_state_enum move_app_data() {
// 源地址: 0x08011000
// 目标地址: 0x08050000
// 数据大小: 0xC000 (49152字节)
uint32_t src_addr = 0x08011000;
uint32_t dst_addr = 0x08050000;
uint32_t size = 0xC000; // 48KB
fmc_state_enum fmc_status = FMC_READY;
// 计算源数据的CRC
rcu_periph_clock_enable(RCU_CRC);
crc_deinit();
crc_data_register_reset();
// 临时缓冲区用于计算CRC
uint32_t word_count = size / 4;
uint32_t src_crc, dst_crc;
// 计算源数据CRC
src_crc = crc_block_data_calculate((uint32_t *)src_addr, word_count);
// 关闭全局中断以防止Flash操作期间的中断干扰
__disable_irq();
fmc_unlock();
// 首先擦除目标地址的Flash页面
// 计算需要擦除的页面数量(GD32C103的Flash页大小为1KB)
uint32_t page_size = 1024; // 1KB per page
uint32_t num_pages = (size + page_size - 1) / page_size; // 向上取整
for (uint32_t i = 0; i < num_pages; i++) {
uint32_t page_addr = dst_addr + i * page_size;
// 擦除页面
fmc_status = fmc_page_erase(page_addr);
if (fmc_status != FMC_READY) {
fmc_lock();
__enable_irq(); // 重新开启中断
return fmc_status;
}
}
// 复制数据 - 按字(32位)进行复制以提高效率
for (uint32_t offset = 0; offset < size; offset += 4) {
uint32_t src_data = *(volatile uint32_t *)(src_addr + offset);
// 检查源地址是否为有效的Flash数据(非0xFFFFFFFF表示有数据)
if (src_data != 0xFFFFFFFF) {
fmc_status = fmc_word_program(dst_addr + offset, src_data);
if (fmc_status != FMC_READY) {
fmc_lock();
__enable_irq(); // 重新开启中断
return fmc_status;
}
}
}
fmc_lock();
// 重新开启全局中断
__enable_irq();
// 计算目标数据的CRC
crc_data_register_reset();
dst_crc = crc_block_data_calculate((uint32_t *)dst_addr, word_count);
// 比较源数据和目标数据的CRC
if (src_crc != dst_crc) {
// 如果CRC不匹配,可以选择返回错误状态
// 这里我们返回一个特殊值表示CRC校验失败
return (fmc_state_enum)0xFF; // 自定义错误码表示CRC校验失败
}
// 设置备份应用可用标志
OTA_SET(n_APP_BACKUP_AVAL_ADDR, OTA_AVAL);
OTA_SET(n_APP_BACKUP_CHECK_ADDR, OTA_AVAL);
return fmc_status;
}
+5
View File
@@ -2,6 +2,8 @@
#define __FLASH_H
#include <stdint.h>
#include "gd32c10x.h" // 添加GD32主头文件以确保外设函数声明可用
// 修改后 - 强制4字节对齐
#define ALIGN_4BYTE(addr) ((addr) & 0xFFFFFFFC) // 4字节对齐
@@ -69,4 +71,7 @@ class FlashEEPROM {
};
void flash_eeprom_example_main(void);
u8 OTA_SET(u32 addr, bool enable);
fmc_state_enum move_app_data(void);
#endif /* __FLASH_H */
+4 -2
View File
@@ -1,9 +1,11 @@
#include "health.h"
#include "config.h"
#include <stdint.h>
#include "Can.h"
#include "DengFOC.h"
#include "FOC.h"
#include "adc.h"
#include "flash.h"
#include <stdint.h>
extern sampler sampler;
extern CAN_transmiter CAN0_transmiter;
+20 -1
View File
@@ -1,7 +1,10 @@
#include "initial.h"
#include "config.h"
#include "flash.h"
#include "gd32c10x.h"
#include "gd32c10x_gpio.h"
#include "gd32c10x_rcu.h"
#include "gd32c10x_fmc.h"
#include <cstdio>
#include <stdint.h>
#include <stdio.h>
@@ -27,7 +30,6 @@ u8 watchdog_init(u32 time) {
return status;
}
int fputc(int ch, FILE *f) throw() {
usart_data_transmit(EVAL_COM0, (uint8_t)ch);
while (RESET == usart_flag_get(EVAL_COM0, USART_FLAG_TBE))
@@ -91,3 +93,20 @@ u16 get_reset_cause(void) {
// printf("cause:%d\r\n", cause);
return cause;
}
void OTA_initial(void) {
// 确认当前APP可用
OTA_SET(n_APP_LATEST_CHECK_ADDR, true);
volatile u32 *flash_ptr = (volatile u32 *)n_APP_BACKUP_AVAL_ADDR;
u32 back_aval = *flash_ptr;
flash_ptr = (volatile u32 *)n_APP_BACKUP_CHECK_ADDR;
u32 back_check = *flash_ptr;
// 如果BACK不可用
if (back_aval == OTA_NOT_AVAL) {
move_app_data();
} else if (back_aval == OTA_AVAL &&
back_check == OTA_NOT_AVAL) { // BACK已刷写,但未检查
move_app_data();
}
}
+11 -13
View File
@@ -5,23 +5,11 @@
extern "C" {
#endif
#include "config.h"
#include "gd32c10x_eval.h"
#include "stdint.h"
#include <stdio.h>
constexpr u16 REDUCTION_RATIO = 25;
constexpr float DEG2RAD = 1.0f / 360.0f * 6.28318530718f;
constexpr float RAD2DEG = 360.0f / 6.28318530718f;
void rcu_config(void);
static volatile uint32_t timer_delay_count = 0; // volatile 很重要!
int fputc(int ch, FILE *f); // 声明fputc函数以重载标准库实现
u8 USART0_init(void);
u8 watchdog_init(u32 time);
u16 get_reset_cause(void);
void unused_pin_init();
// 任务标志定义
typedef enum {
TASK_MOTOR_CONTROL = 0,
@@ -37,6 +25,16 @@ typedef enum {
TASK_COUNT
} SystemTask;
void rcu_config(void);
static volatile uint32_t timer_delay_count = 0; // volatile 很重要!
int fputc(int ch, FILE *f); // 声明fputc函数以重载标准库实现
u8 USART0_init(void);
u8 watchdog_init(u32 time);
u16 get_reset_cause(void);
void unused_pin_init();
void OTA_initial(void);
// 任务管理结构
typedef struct {
volatile u32 taskFlags; // 任务标志位(每个位代表一个任务)
+6 -1
View File
@@ -83,7 +83,6 @@ void delay_1ms(uint32_t count) {
delay = count;
while (0U != delay) {
fwdgt_counter_reload();
fwdgt_counter_reload();
}
}
@@ -177,4 +176,10 @@ void EXTI5_9_IRQHandler(void) {
printf("MCU wake up\r\n");
system_soft_reset();
}
}
void OTA_initial(){
}