整理了main 函数
This commit is contained in:
+80
-1
@@ -6,23 +6,102 @@
|
|||||||
* 创建日期:2026-07-19
|
* 创建日期:2026-07-19
|
||||||
* 修改记录:
|
* 修改记录:
|
||||||
* v1.0 2026-07-19 王建锋 创建初始版本
|
* v1.0 2026-07-19 王建锋 创建初始版本
|
||||||
|
* v1.1 2026-08-29 王建锋 将原 main.c 中各外设初始化统一收归 app_main_init,
|
||||||
|
* 并按"时间子系统优先"的顺序编排启动流程
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "app_main.h"
|
#include "app_main.h"
|
||||||
#include "app_cfg.h"
|
#include "app_cfg.h"
|
||||||
|
|
||||||
|
#include "main.h" /* ST_DIR4_GPIO_Port / ST_DIR4_Pin 等 CubeMX 宏 */
|
||||||
|
#include "usart.h" /* huart5 */
|
||||||
|
#include "rs485.h"
|
||||||
|
#include "sd2506.h"
|
||||||
|
#include "sys_clock.h"
|
||||||
|
#include "gd5f2gq5ue.h"
|
||||||
|
#include "tpafe5160.h"
|
||||||
|
|
||||||
#define DBG_TAG "[APP]"
|
#define DBG_TAG "[APP]"
|
||||||
#include "dbg_log.h"
|
#include "dbg_log.h"
|
||||||
|
|
||||||
|
/* g_rs485 由 rs485.c 定义,经 rs485.h 的 extern 引用;接收缓冲内聚于句柄 rx_buf */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 函数功能:应用层初始化
|
* 函数功能:应用层初始化
|
||||||
* 入口参数:无
|
* 入口参数:无
|
||||||
* 返 回 值:0 - 成功,-1 - 失败
|
* 返 回 值:0 - 成功,-1 - 失败
|
||||||
* 限定条件:CubeMX 外设初始化已完成
|
* 限定条件:CubeMX 外设初始化已完成
|
||||||
* 函数说明:在 CubeMX 外设初始化之后、FreeRTOS 调度器启动之前调用
|
* 函数说明:在 CubeMX 外设初始化之后、FreeRTOS 调度器启动之前调用。
|
||||||
|
* 启动顺序以"时间子系统优先"为原则,使后续所有日志均带时间戳:
|
||||||
|
* 1) 时间子系统(SD2506 RTC → 墙钟基准)
|
||||||
|
* 2) RS-485
|
||||||
|
* 3) GD5F NAND
|
||||||
|
* 4) TPAFE5160 ADC
|
||||||
|
* 5) SD2506 诊断信息
|
||||||
|
* 6) 触发首次 ADC 转换
|
||||||
*/
|
*/
|
||||||
int app_main_init(void)
|
int app_main_init(void)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* 1) 时间子系统初始化(尽早完成,后续所有日志带时间戳)
|
||||||
|
* sd2506_init() 从 RTC 读取初始时间
|
||||||
|
* sys_clock_init() 将 RTC 时间转为 Unix epoch,建立墙钟基准
|
||||||
|
*/
|
||||||
|
sd2506_init();
|
||||||
|
sys_clock_init();
|
||||||
|
|
||||||
|
/* 2) RS-485 初始化(UART5 + PD0 方向控制),初始化即自动开启接收 */
|
||||||
|
rs485_init(&g_rs485, &huart5, ST_DIR4_GPIO_Port, ST_DIR4_Pin);
|
||||||
|
DBG_INFO("RS485 init: OK (UART5, DE=PD0)");
|
||||||
|
|
||||||
|
/* 3) GD5F 初始化测试 */
|
||||||
|
int ret = gd5f2gq5ue_init();
|
||||||
|
DBG_INFO("NAND init: %s",
|
||||||
|
(ret == GD5F_OK) ? "OK" :
|
||||||
|
(ret == GD5F_ERROR) ? "ERROR" :
|
||||||
|
(ret == GD5F_BUSY_TIMEOUT) ? "BUSY TIMEOUT" :
|
||||||
|
(ret == GD5F_ECC_ERROR) ? "ECC ERROR" :
|
||||||
|
(ret == GD5F_PROGRAM_FAIL) ? "PROGRAM FAIL" :
|
||||||
|
(ret == GD5F_ERASE_FAIL) ? "ERASE FAIL" :
|
||||||
|
(ret == GD5F_ID_MISMATCH) ? "ID MISMATCH" : "UNKNOWN");
|
||||||
|
|
||||||
|
/* 4) TPAFE5160 ADC 测试 */
|
||||||
|
int tp_ret = tpafe5160_init();
|
||||||
|
DBG_INFO("ADC init: %s",
|
||||||
|
(tp_ret == TPAFE5160_OK) ? "OK" : "TIMEOUT");
|
||||||
|
|
||||||
|
/* 5) SD2506 RTC 诊断信息 */
|
||||||
|
{
|
||||||
|
/* 读取 ID */
|
||||||
|
uint8_t sd_id[8];
|
||||||
|
sd2506_get_id(sd_id);
|
||||||
|
DBG_INFO("SD2506 ID: %02X%02X%02X%02X%02X%02X%02X%02X",
|
||||||
|
sd_id[0], sd_id[1], sd_id[2], sd_id[3],
|
||||||
|
sd_id[4], sd_id[5], sd_id[6], sd_id[7]);
|
||||||
|
|
||||||
|
/* 读取当前时间 */
|
||||||
|
sd2506_time_t sd_time;
|
||||||
|
sd2506_get_time(&sd_time);
|
||||||
|
DBG_INFO("SD2506 time: %04d-%02d-%02d %02d:%02d:%02d (week %d)",
|
||||||
|
sd_time.year, sd_time.month, sd_time.day,
|
||||||
|
sd_time.hour, sd_time.minute, sd_time.second,
|
||||||
|
sd_time.week);
|
||||||
|
|
||||||
|
/* 读取温度 */
|
||||||
|
int8_t sd_temp;
|
||||||
|
sd2506_get_temperature(&sd_temp);
|
||||||
|
DBG_INFO("SD2506 temp: %d C", sd_temp);
|
||||||
|
|
||||||
|
/* 读取电池电压 */
|
||||||
|
uint16_t sd_vbat;
|
||||||
|
sd2506_get_battery_voltage(&sd_vbat);
|
||||||
|
DBG_INFO("SD2506 battery: %d.%02d V",
|
||||||
|
sd_vbat / 1000, (sd_vbat % 1000) / 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 6) 启动第一次转换(CubeMX 已配置 BUSY EXTI 中断) */
|
||||||
|
tpafe5160_start_conv_irq();
|
||||||
|
|
||||||
DBG_INFO("App init OK");
|
DBG_INFO("App init OK");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -31,7 +31,7 @@ volatile uint8_t g_net_ready = 0;
|
|||||||
* 返 回 值:0 - 成功,-1 - 失败
|
* 返 回 值:0 - 成功,-1 - 失败
|
||||||
* 函数说明:net_init → MAC 打印 → PHY 强制 100M 全双工 → 置 g_net_ready。
|
* 函数说明:net_init → MAC 打印 → PHY 强制 100M 全双工 → 置 g_net_ready。
|
||||||
* NET 层模式由 netTask 调用;硬件层模式(阶段 1~5)netTask 不创建,
|
* NET 层模式由 netTask 调用;硬件层模式(阶段 1~5)netTask 不创建,
|
||||||
* 由 ch395fTestTask 调用后独占 CH395F。
|
* 由 testTask 调用后独占 CH395F。
|
||||||
*/
|
*/
|
||||||
int net_stack_bring_up(void)
|
int net_stack_bring_up(void)
|
||||||
{
|
{
|
||||||
@@ -89,7 +89,7 @@ int net_task_init(void)
|
|||||||
* 函数说明:启动后先调用 net_stack_bring_up() 初始化 CH395F 协议栈,
|
* 函数说明:启动后先调用 net_stack_bring_up() 初始化 CH395F 协议栈,
|
||||||
* 再进入轮询循环处理网络事件。
|
* 再进入轮询循环处理网络事件。
|
||||||
* 仅 NET 层测试模式(阶段 6~10)会创建本任务;
|
* 仅 NET 层测试模式(阶段 6~10)会创建本任务;
|
||||||
* 硬件层模式下 netTask 不创建,CH395F 由 ch395fTestTask 独占。
|
* 硬件层模式下 netTask 不创建,CH395F 由 testTask 独占。
|
||||||
*/
|
*/
|
||||||
void net_task_func(void const *arg)
|
void net_task_func(void const *arg)
|
||||||
{
|
{
|
||||||
|
|||||||
+1
-1
@@ -18,7 +18,7 @@ extern "C" {
|
|||||||
|
|
||||||
/* CH395F 协议栈一次性初始化(net_init + MAC 打印 + PHY 配置 + g_net_ready 置位)。
|
/* CH395F 协议栈一次性初始化(net_init + MAC 打印 + PHY 配置 + g_net_ready 置位)。
|
||||||
* 返回 0 成功 / -1 失败。NET 层模式由 netTask 调用;硬件层模式(阶段 1~5)
|
* 返回 0 成功 / -1 失败。NET 层模式由 netTask 调用;硬件层模式(阶段 1~5)
|
||||||
* netTask 不创建,由 ch395fTestTask 调用后独占 CH395F。 */
|
* netTask 不创建,由 testTask 调用后独占 CH395F。 */
|
||||||
int net_stack_bring_up(void);
|
int net_stack_bring_up(void);
|
||||||
|
|
||||||
int net_task_init(void);
|
int net_task_init(void);
|
||||||
|
|||||||
+64
-33
@@ -14,27 +14,10 @@
|
|||||||
|
|
||||||
#include "rs485.h"
|
#include "rs485.h"
|
||||||
|
|
||||||
/* ======================== 内部辅助函数 ======================== */
|
/* ======================== 全局实例 ======================== */
|
||||||
|
|
||||||
/*
|
/* RS-485 全局实例(接收缓冲内聚于句柄的 rx_buf 字段) */
|
||||||
* 函数功能:DWT 微秒级延时
|
rs485_handle_t g_rs485;
|
||||||
* 入口参数:us - 延时微秒数 uint32_t 1 - N
|
|
||||||
* 返回值:无
|
|
||||||
* 限定条件:无(首次调用自动初始化 DWT CYCCNT)
|
|
||||||
* 函数说明:利用 Cortex-M4 DWT CYCCNT 实现精确微秒延时,168MHz 下 1us = 168 计数。
|
|
||||||
* 首次调用时自动使能 DWT 和 CYCCNT,后续只读 CYCCNT 寄存器,不影响其他模块。
|
|
||||||
*/
|
|
||||||
static void delay_us(uint32_t us)
|
|
||||||
{
|
|
||||||
if (!(CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk)) {
|
|
||||||
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
|
|
||||||
DWT->CYCCNT = 0;
|
|
||||||
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
|
|
||||||
}
|
|
||||||
uint32_t start = DWT->CYCCNT;
|
|
||||||
uint32_t ticks = us * (SystemCoreClock / 1000000uL);
|
|
||||||
while ((DWT->CYCCNT - start) < ticks) { ; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ======================== 方向控制宏 ======================== */
|
/* ======================== 方向控制宏 ======================== */
|
||||||
|
|
||||||
@@ -51,7 +34,8 @@ static void delay_us(uint32_t us)
|
|||||||
* dir_pin - 方向控制 GPIO 引脚号(如 GPIO_PIN_0) uint16_t
|
* dir_pin - 方向控制 GPIO 引脚号(如 GPIO_PIN_0) uint16_t
|
||||||
* 返回值:无
|
* 返回值:无
|
||||||
* 限定条件:UART 和 GPIO 须先由 CubeMX 完成初始化
|
* 限定条件:UART 和 GPIO 须先由 CubeMX 完成初始化
|
||||||
* 函数说明:初始化后默认处于接收状态(DE 引脚拉低)
|
* 函数说明:初始化后默认处于接收状态(DE 引脚拉低),
|
||||||
|
* 并自动启动 IDLE 中断接收,无需再手动调用 rs485_receive_start。
|
||||||
*/
|
*/
|
||||||
void rs485_init(rs485_handle_t *p_handle,
|
void rs485_init(rs485_handle_t *p_handle,
|
||||||
UART_HandleTypeDef *p_huart,
|
UART_HandleTypeDef *p_huart,
|
||||||
@@ -64,6 +48,9 @@ void rs485_init(rs485_handle_t *p_handle,
|
|||||||
p_handle->rx_size = 0;
|
p_handle->rx_size = 0;
|
||||||
|
|
||||||
RS485_DIR_RX(p_handle);
|
RS485_DIR_RX(p_handle);
|
||||||
|
|
||||||
|
/* 自动开启 IDLE 中断接收(后续在回调中重新开启) */
|
||||||
|
(void)rs485_receive_start(p_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -76,14 +63,15 @@ void rs485_init(rs485_handle_t *p_handle,
|
|||||||
* HAL_TIMEOUT - 发送超时
|
* HAL_TIMEOUT - 发送超时
|
||||||
* HAL_ERROR - 发送错误
|
* HAL_ERROR - 发送错误
|
||||||
* 限定条件:须在主循环或 FreeRTOS 任务中调用,不可在 UART 中断中调用
|
* 限定条件:须在主循环或 FreeRTOS 任务中调用,不可在 UART 中断中调用
|
||||||
* 函数说明:发送前拉高 DE,等待 50us 确保 RS485 收发器驱动使能稳定后再启动 UART 发送。
|
* 函数说明:发送前拉高 DE,等待 HAL 时基延时确保 RS485 收发器驱动使能稳定后再启动
|
||||||
|
* UART 发送(HAL 时基最小粒度 1ms,此处延时 1ms,远大于 50us 的 DE 建立时间)。
|
||||||
* HAL_UART_Transmit 内部等待 TC(发送完成)标志,确保最后一字节完全移出后
|
* HAL_UART_Transmit 内部等待 TC(发送完成)标志,确保最后一字节完全移出后
|
||||||
* 再拉低 DE 切回接收状态。
|
* 再拉低 DE 切回接收状态。
|
||||||
*/
|
*/
|
||||||
HAL_StatusTypeDef rs485_transmit(rs485_handle_t *p_handle,
|
HAL_StatusTypeDef rs485_transmit(rs485_handle_t *p_handle,
|
||||||
const uint8_t *p_data,
|
const uint8_t *p_data,
|
||||||
uint16_t len,
|
uint16_t len,
|
||||||
uint32_t timeout)
|
uint32_t timeout)
|
||||||
{
|
{
|
||||||
HAL_StatusTypeDef status = HAL_OK;
|
HAL_StatusTypeDef status = HAL_OK;
|
||||||
|
|
||||||
@@ -93,7 +81,8 @@ HAL_StatusTypeDef rs485_transmit(rs485_handle_t *p_handle,
|
|||||||
|
|
||||||
RS485_DIR_TX(p_handle);
|
RS485_DIR_TX(p_handle);
|
||||||
|
|
||||||
delay_us(50);
|
/* DE 建立延时:HAL 时基为 1ms 粒度,1ms 已充分覆盖收发器驱动使能稳定时间 */
|
||||||
|
HAL_Delay(1);
|
||||||
|
|
||||||
status = HAL_UART_Transmit(p_handle->huart,
|
status = HAL_UART_Transmit(p_handle->huart,
|
||||||
(uint8_t *)p_data,
|
(uint8_t *)p_data,
|
||||||
@@ -108,22 +97,19 @@ HAL_StatusTypeDef rs485_transmit(rs485_handle_t *p_handle,
|
|||||||
/*
|
/*
|
||||||
* 函数功能:启动中断方式接收(IDLE 空闲帧检测)
|
* 函数功能:启动中断方式接收(IDLE 空闲帧检测)
|
||||||
* 入口参数:p_handle - RS-485 句柄指针 rs485_handle_t*(非空)
|
* 入口参数:p_handle - RS-485 句柄指针 rs485_handle_t*(非空)
|
||||||
* p_buf - 接收缓冲区 uint8_t*(非空)
|
|
||||||
* buf_size - 缓冲区大小 uint16_t
|
|
||||||
* 返回值:HAL_OK - 启动成功 HAL_StatusTypeDef
|
* 返回值:HAL_OK - 启动成功 HAL_StatusTypeDef
|
||||||
* HAL_ERROR - 启动失败
|
* HAL_ERROR - 启动失败
|
||||||
* 限定条件:UART 须已开启全局中断(NVIC 使能)
|
* 限定条件:UART 须已开启全局中断(NVIC 使能)
|
||||||
* 函数说明:使用 HAL_UARTEx_ReceiveToIdle_IT 实现变长帧接收。
|
* 函数说明:使用 HAL_UARTEx_ReceiveToIdle_IT 实现变长帧接收,
|
||||||
|
* 接收缓冲固定使用句柄内部的 rx_buf(RS485_RX_BUF_SIZE)。
|
||||||
* 当 UART 总线空闲超过 1 个字符时间后硬件触发 IDLE 中断,
|
* 当 UART 总线空闲超过 1 个字符时间后硬件触发 IDLE 中断,
|
||||||
* HAL 自动调用 HAL_UARTEx_RxEventCallback 并返回已接收字节数。
|
* HAL 自动调用 HAL_UARTEx_RxEventCallback 并返回已接收字节数。
|
||||||
* 用户须在回调中重新调用本函数重新开启接收。
|
* 用户须在回调中重新调用本函数重新开启接收。
|
||||||
*/
|
*/
|
||||||
HAL_StatusTypeDef rs485_receive_start(rs485_handle_t *p_handle,
|
HAL_StatusTypeDef rs485_receive_start(rs485_handle_t *p_handle)
|
||||||
uint8_t *p_buf,
|
|
||||||
uint16_t buf_size)
|
|
||||||
{
|
{
|
||||||
p_handle->rx_size = 0;
|
p_handle->rx_size = 0;
|
||||||
return HAL_UARTEx_ReceiveToIdle_IT(p_handle->huart, p_buf, buf_size);
|
return HAL_UARTEx_ReceiveToIdle_IT(p_handle->huart, p_handle->rx_buf, RS485_RX_BUF_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -150,3 +136,48 @@ uint16_t rs485_rx_get_size(const rs485_handle_t *p_handle)
|
|||||||
{
|
{
|
||||||
return p_handle->rx_size;
|
return p_handle->rx_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ======================== HAL 回调(UART5 / RS-485 专属) ======================== */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 应用层接收钩子默认实现(弱符号,可被应用重定义)。
|
||||||
|
* 在中断上下文调用,仅做占位,业务解析由应用提供。
|
||||||
|
*/
|
||||||
|
__weak void rs485_on_rx(uint8_t *buf, uint16_t size)
|
||||||
|
{
|
||||||
|
(void)buf;
|
||||||
|
(void)size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* HAL UART 扩展接收回调(IDLE 空闲帧中断触发)。
|
||||||
|
* 当 RS-485 总线空闲超过 1 个字符时间后触发,由 HAL 自动调用。
|
||||||
|
* 注意:回调按实例分发,仅处理本驱动绑定的 UART,不写死 UART5。
|
||||||
|
*/
|
||||||
|
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
|
||||||
|
{
|
||||||
|
if (huart == g_rs485.huart) {
|
||||||
|
rs485_rx_set_size(&g_rs485, Size);
|
||||||
|
|
||||||
|
/* 通知应用处理本次接收(中断上下文,应尽快返回) */
|
||||||
|
rs485_on_rx(g_rs485.rx_buf, Size);
|
||||||
|
|
||||||
|
/* 重新开启接收 */
|
||||||
|
rs485_receive_start(&g_rs485);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* HAL UART 错误回调(ORE/NE/FE/PE 等)。
|
||||||
|
* 读 SR + DR 清除错误标志后重新开启接收,避免中断锁死。
|
||||||
|
*/
|
||||||
|
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
|
||||||
|
{
|
||||||
|
if (huart == g_rs485.huart) {
|
||||||
|
/* STM32F4 通过读 SR + DR 清除 ORE/NE/FE/PE 错误标志 */
|
||||||
|
(void)huart->Instance->SR;
|
||||||
|
(void)huart->Instance->DR;
|
||||||
|
/* 重新开启接收 */
|
||||||
|
rs485_receive_start(&g_rs485);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ extern "C" {
|
|||||||
* 常量定义
|
* 常量定义
|
||||||
*/
|
*/
|
||||||
#define RS485_TIMEOUT_DEFAULT 1000U /* 默认发送超时(ms) */
|
#define RS485_TIMEOUT_DEFAULT 1000U /* 默认发送超时(ms) */
|
||||||
|
#define RS485_RX_BUF_SIZE 256U /* 接收缓冲区大小 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RS-485 句柄结构体
|
* RS-485 句柄结构体
|
||||||
@@ -34,6 +35,7 @@ typedef struct {
|
|||||||
GPIO_TypeDef *dir_port; /* 方向控制 GPIO 端口 */
|
GPIO_TypeDef *dir_port; /* 方向控制 GPIO 端口 */
|
||||||
uint16_t dir_pin; /* 方向控制 GPIO 引脚号 */
|
uint16_t dir_pin; /* 方向控制 GPIO 引脚号 */
|
||||||
volatile uint16_t rx_size; /* 最近一次接收的字节数 */
|
volatile uint16_t rx_size; /* 最近一次接收的字节数 */
|
||||||
|
uint8_t rx_buf[RS485_RX_BUF_SIZE]; /* 接收缓冲区 */
|
||||||
} rs485_handle_t;
|
} rs485_handle_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -48,7 +50,8 @@ typedef struct {
|
|||||||
* dir_pin - 方向控制 GPIO 引脚号(如 GPIO_PIN_0)
|
* dir_pin - 方向控制 GPIO 引脚号(如 GPIO_PIN_0)
|
||||||
* 返回值:无
|
* 返回值:无
|
||||||
* 限定条件:UART 和 GPIO 须先由 CubeMX 完成初始化
|
* 限定条件:UART 和 GPIO 须先由 CubeMX 完成初始化
|
||||||
* 函数说明:初始化后默认处于接收状态(DE 引脚拉低)
|
* 函数说明:初始化后默认处于接收状态(DE 引脚拉低),并自动启动 IDLE
|
||||||
|
* 中断接收,无需再手动调用 rs485_receive_start。
|
||||||
*/
|
*/
|
||||||
void rs485_init(rs485_handle_t *p_handle,
|
void rs485_init(rs485_handle_t *p_handle,
|
||||||
UART_HandleTypeDef *p_huart,
|
UART_HandleTypeDef *p_huart,
|
||||||
@@ -73,18 +76,16 @@ HAL_StatusTypeDef rs485_transmit(rs485_handle_t *p_handle,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* 函数功能:启动中断方式接收(IDLE 空闲帧检测)
|
* 函数功能:启动中断方式接收(IDLE 空闲帧检测)
|
||||||
* 入口参数:handle - RS-485 句柄指针
|
* 入口参数:handle - RS-485 句柄指针
|
||||||
* buf - 接收缓冲区
|
|
||||||
* buf_size - 缓冲区大小
|
|
||||||
* 返回值:HAL_OK / HAL_ERROR
|
* 返回值:HAL_OK / HAL_ERROR
|
||||||
* 限定条件:UART 须已开启全局中断,NVIC 中须使能对应 UART 中断
|
* 限定条件:UART 须已开启全局中断,NVIC 中须使能对应 UART 中断
|
||||||
* 函数说明:使用 HAL_UARTEx_ReceiveToIdle_IT 实现变长帧接收,
|
* 函数说明:使用 HAL_UARTEx_ReceiveToIdle_IT 实现变长帧接收,
|
||||||
* 收到完整帧后在 RxEventCallback 中通知用户。
|
* 接收缓冲固定使用句柄内部的 rx_buf(RS485_RX_BUF_SIZE)。
|
||||||
* 用户须在回调中重新调用本函数重新开启接收
|
* 当 UART 总线空闲超过 1 个字符时间后硬件触发 IDLE 中断,
|
||||||
|
* HAL 自动调用 HAL_UARTEx_RxEventCallback 并返回已接收字节数。
|
||||||
|
* 用户须在回调中重新调用本函数重新开启接收。
|
||||||
*/
|
*/
|
||||||
HAL_StatusTypeDef rs485_receive_start(rs485_handle_t *p_handle,
|
HAL_StatusTypeDef rs485_receive_start(rs485_handle_t *p_handle);
|
||||||
uint8_t *p_buf,
|
|
||||||
uint16_t buf_size);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 函数功能:将 RS-485 句柄与 HAL 回调关联
|
* 函数功能:将 RS-485 句柄与 HAL 回调关联
|
||||||
@@ -103,6 +104,21 @@ void rs485_rx_set_size(rs485_handle_t *p_handle, uint16_t size);
|
|||||||
*/
|
*/
|
||||||
uint16_t rs485_rx_get_size(const rs485_handle_t *p_handle);
|
uint16_t rs485_rx_get_size(const rs485_handle_t *p_handle);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 全局 RS-485 实例(由 rs485.c 定义,应用层通过 extern 引用)。
|
||||||
|
* 接收缓冲已内聚到 rs485_handle_t 的 rx_buf 字段,随实例统一管理。
|
||||||
|
*/
|
||||||
|
extern rs485_handle_t g_rs485;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 应用层接收钩子:RS-485 收到完整帧(IDLE 空闲帧)后由驱动回调调用,
|
||||||
|
* 传入本次接收缓冲区与有效字节数。默认弱实现为空,应用可重定义此函数
|
||||||
|
* 处理业务数据。
|
||||||
|
* 注意:此函数在 UART 中断上下文执行,应尽快拷贝数据后返回,不要在内部
|
||||||
|
* 调用阻塞式 API(如 rs485_transmit 会切换 DE 并等待 TC)。
|
||||||
|
*/
|
||||||
|
void rs485_on_rx(uint8_t *buf, uint16_t size);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -2014,6 +2014,11 @@
|
|||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<FilePath>..\test\ch395f_test_task.c</FilePath>
|
<FilePath>..\test\ch395f_test_task.c</FilePath>
|
||||||
</File>
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>test_config.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\test\test_config.c</FilePath>
|
||||||
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<FileName>net_test_task.c</FileName>
|
<FileName>net_test_task.c</FileName>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
|
|||||||
+49
-48
@@ -1,76 +1,77 @@
|
|||||||
*** Using Compiler 'V5.06 update 7 (build 960)', folder: 'C:\Keil_v5\ARM\ARMCC\Bin'
|
*** Using Compiler 'V5.06 update 7 (build 960)', folder: 'C:\Keil_v5\ARM\ARMCC\Bin'
|
||||||
Rebuild target 'STM32F407-Demo'
|
Rebuild target 'STM32F407-Demo'
|
||||||
assembling startup_stm32f407xx.s...
|
assembling startup_stm32f407xx.s...
|
||||||
compiling crc.c...
|
|
||||||
compiling ringbuf.c...
|
compiling ringbuf.c...
|
||||||
compiling stm32f4xx_it.c...
|
compiling crc.c...
|
||||||
compiling app_main.c...
|
|
||||||
compiling dma.c...
|
|
||||||
compiling stm32f4xx_hal_flash_ramfunc.c...
|
compiling stm32f4xx_hal_flash_ramfunc.c...
|
||||||
compiling i2c.c...
|
|
||||||
compiling sys_clock.c...
|
|
||||||
compiling stm32f4xx_hal_timebase_tim.c...
|
|
||||||
compiling stm32f4xx_hal_gpio.c...
|
|
||||||
compiling stm32f4xx_hal_dma_ex.c...
|
|
||||||
compiling stm32f4xx_hal_dma.c...
|
|
||||||
compiling stm32f4xx_hal_flash_ex.c...
|
compiling stm32f4xx_hal_flash_ex.c...
|
||||||
compiling stm32f4xx_hal_pwr.c...
|
compiling i2c.c...
|
||||||
compiling spi.c...
|
compiling app_main.c...
|
||||||
|
compiling stm32f4xx_hal_gpio.c...
|
||||||
|
compiling dma.c...
|
||||||
|
compiling stm32f4xx_hal_dma_ex.c...
|
||||||
compiling stm32f4xx_hal_msp.c...
|
compiling stm32f4xx_hal_msp.c...
|
||||||
compiling stm32f4xx_hal_rcc.c...
|
|
||||||
compiling stm32f4xx_hal_flash.c...
|
|
||||||
compiling gpio.c...
|
compiling gpio.c...
|
||||||
compiling usart.c...
|
compiling spi.c...
|
||||||
compiling stm32f4xx_hal_tim_ex.c...
|
compiling stm32f4xx_it.c...
|
||||||
compiling net_task.c...
|
|
||||||
compiling freertos.c...
|
|
||||||
compiling stm32f4xx_hal_rcc_ex.c...
|
compiling stm32f4xx_hal_rcc_ex.c...
|
||||||
|
compiling stm32f4xx_hal_flash.c...
|
||||||
|
compiling usart.c...
|
||||||
|
compiling stm32f4xx_hal_timebase_tim.c...
|
||||||
|
compiling sys_clock.c...
|
||||||
|
compiling net_task.c...
|
||||||
compiling rs485_task.c...
|
compiling rs485_task.c...
|
||||||
compiling main.c...
|
|
||||||
compiling adc_task.c...
|
|
||||||
compiling time_sync.c...
|
compiling time_sync.c...
|
||||||
compiling lftpd_string.c...
|
compiling adc_task.c...
|
||||||
compiling croutine.c...
|
compiling stm32f4xx_hal_rcc.c...
|
||||||
|
compiling main.c...
|
||||||
|
compiling freertos.c...
|
||||||
|
compiling stm32f4xx_hal_tim_ex.c...
|
||||||
compiling stm32f4xx_hal_tim.c...
|
compiling stm32f4xx_hal_tim.c...
|
||||||
compiling list.c...
|
compiling lftpd_string.c...
|
||||||
|
compiling stm32f4xx_hal_dma.c...
|
||||||
|
compiling croutine.c...
|
||||||
compiling event_groups.c...
|
compiling event_groups.c...
|
||||||
compiling queue.c...
|
compiling list.c...
|
||||||
compiling stream_buffer.c...
|
|
||||||
compiling timers.c...
|
|
||||||
compiling tasks.c...
|
|
||||||
compiling heap_4.c...
|
|
||||||
compiling port.c...
|
|
||||||
compiling stm32f4xx_hal_pwr_ex.c...
|
|
||||||
compiling journal.c...
|
|
||||||
compiling map.c...
|
|
||||||
compiling ff.c...
|
|
||||||
compiling stm32f4xx_hal.c...
|
compiling stm32f4xx_hal.c...
|
||||||
compiling system_stm32f4xx.c...
|
compiling stm32f4xx_hal_pwr_ex.c...
|
||||||
compiling lftpd_io.c...
|
compiling stream_buffer.c...
|
||||||
compiling stm32f4xx_hal_cortex.c...
|
compiling queue.c...
|
||||||
compiling stm32f4xx_hal_i2c_ex.c...
|
compiling timers.c...
|
||||||
compiling stm32f4xx_hal_exti.c...
|
compiling stm32f4xx_hal_exti.c...
|
||||||
|
compiling tasks.c...
|
||||||
|
compiling stm32f4xx_hal_pwr.c...
|
||||||
|
compiling stm32f4xx_hal_cortex.c...
|
||||||
|
compiling heap_4.c...
|
||||||
|
compiling map.c...
|
||||||
|
compiling journal.c...
|
||||||
|
compiling port.c...
|
||||||
|
compiling stm32f4xx_hal_i2c_ex.c...
|
||||||
|
compiling stm32f4xx_hal_i2c.c...
|
||||||
|
compiling ff.c...
|
||||||
compiling rs485.c...
|
compiling rs485.c...
|
||||||
compiling tpafe5160.c...
|
compiling system_stm32f4xx.c...
|
||||||
compiling sd2506.c...
|
compiling sd2506.c...
|
||||||
compiling ch395f.c...
|
|
||||||
compiling nand_ftl.c...
|
|
||||||
compiling stm32f4xx_hal_spi.c...
|
|
||||||
compiling lftpd_inet.c...
|
|
||||||
compiling gd5f2gq5ue.c...
|
compiling gd5f2gq5ue.c...
|
||||||
compiling net_select.c...
|
compiling ch395f.c...
|
||||||
|
compiling stm32f4xx_hal_spi.c...
|
||||||
|
compiling lftpd_io.c...
|
||||||
|
compiling nand_ftl.c...
|
||||||
compiling stm32f4xx_hal_uart.c...
|
compiling stm32f4xx_hal_uart.c...
|
||||||
|
compiling net_select.c...
|
||||||
|
compiling tpafe5160.c...
|
||||||
|
compiling lftpd_inet.c...
|
||||||
compiling lftpd.c...
|
compiling lftpd.c...
|
||||||
compiling net_socket.c...
|
compiling net_socket.c...
|
||||||
compiling stm32f4xx_hal_i2c.c...
|
|
||||||
compiling cmsis_os2.c...
|
compiling cmsis_os2.c...
|
||||||
compiling ch395f_test_task.c...
|
compiling ch395f_test_task.c...
|
||||||
compiling net_test_task.c...
|
|
||||||
compiling gd5f_test_task.c...
|
compiling gd5f_test_task.c...
|
||||||
compiling storage_test_task.c...
|
compiling test_config.c...
|
||||||
compiling sd2506_test_task.c...
|
compiling sd2506_test_task.c...
|
||||||
|
compiling net_test_task.c...
|
||||||
|
compiling storage_test_task.c...
|
||||||
linking...
|
linking...
|
||||||
Program Size: Code=64436 RO-data=3936 RW-data=420 ZI-data=51868
|
Program Size: Code=59916 RO-data=2552 RW-data=412 ZI-data=51868
|
||||||
FromELF: creating hex file...
|
FromELF: creating hex file...
|
||||||
".\STM32F407-Demo\STM32F407-Demo.axf" - 0 Error(s), 0 Warning(s).
|
".\STM32F407-Demo\STM32F407-Demo.axf" - 0 Error(s), 0 Warning(s).
|
||||||
Build Time Elapsed: 00:00:14
|
Build Time Elapsed: 00:00:16
|
||||||
|
|||||||
+1
-1
@@ -72,7 +72,7 @@ Dma.USART1_TX.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphData
|
|||||||
FREERTOS.FootprintOK=true
|
FREERTOS.FootprintOK=true
|
||||||
FREERTOS.IPParameters=Tasks01,configENABLE_FPU,FootprintOK,configTOTAL_HEAP_SIZE,Queues01
|
FREERTOS.IPParameters=Tasks01,configENABLE_FPU,FootprintOK,configTOTAL_HEAP_SIZE,Queues01
|
||||||
FREERTOS.Queues01=netMsgQueue,8,net_msg_t,0,Dynamic,NULL,NULL
|
FREERTOS.Queues01=netMsgQueue,8,net_msg_t,0,Dynamic,NULL,NULL
|
||||||
FREERTOS.Tasks01=defaultTask,24,512,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL;netTask,24,1024,StartNetTask,Default,NULL,Dynamic,NULL,NULL;ftpTask,24,1024,StartFtpTask,As weak,NULL,Dynamic,NULL,NULL;ch395fTestTask,16,4096,StartCh395fTestTask,As weak,NULL,Dynamic,NULL,NULL
|
FREERTOS.Tasks01=defaultTask,24,512,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL;netTask,24,1024,StartNetTask,Default,NULL,Dynamic,NULL,NULL;ftpTask,24,1024,StartFtpTask,As weak,NULL,Dynamic,NULL,NULL;testTask,16,4096,start_test_task,As weak,NULL,Dynamic,NULL,NULL
|
||||||
FREERTOS.configENABLE_FPU=1
|
FREERTOS.configENABLE_FPU=1
|
||||||
FREERTOS.configTOTAL_HEAP_SIZE=30720
|
FREERTOS.configTOTAL_HEAP_SIZE=30720
|
||||||
File.Version=6
|
File.Version=6
|
||||||
|
|||||||
+13
-15
@@ -84,10 +84,10 @@ const osThreadAttr_t ftpTask_attributes = {
|
|||||||
.stack_size = 1024 * 4,
|
.stack_size = 1024 * 4,
|
||||||
.priority = (osPriority_t) osPriorityNormal,
|
.priority = (osPriority_t) osPriorityNormal,
|
||||||
};
|
};
|
||||||
/* Definitions for ch395fTestTask */
|
/* Definitions for testTask */
|
||||||
osThreadId_t ch395fTestTaskHandle;
|
osThreadId_t testTaskHandle;
|
||||||
const osThreadAttr_t ch395fTestTask_attributes = {
|
const osThreadAttr_t testTask_attributes = {
|
||||||
.name = "ch395fTestTask",
|
.name = "testTask",
|
||||||
.stack_size = 4096 * 4,
|
.stack_size = 4096 * 4,
|
||||||
.priority = (osPriority_t) osPriorityBelowNormal,
|
.priority = (osPriority_t) osPriorityBelowNormal,
|
||||||
};
|
};
|
||||||
@@ -105,7 +105,7 @@ const osMessageQueueAttr_t netMsgQueue_attributes = {
|
|||||||
void StartDefaultTask(void *argument);
|
void StartDefaultTask(void *argument);
|
||||||
void StartNetTask(void *argument);
|
void StartNetTask(void *argument);
|
||||||
void StartFtpTask(void *argument);
|
void StartFtpTask(void *argument);
|
||||||
void StartCh395fTestTask(void *argument);
|
void start_test_task(void *argument);
|
||||||
|
|
||||||
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
|
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
|
||||||
|
|
||||||
@@ -148,11 +148,9 @@ void MX_FREERTOS_Init(void) {
|
|||||||
|
|
||||||
/* creation of ftpTask */
|
/* creation of ftpTask */
|
||||||
ftpTaskHandle = osThreadNew(StartFtpTask, NULL, &ftpTask_attributes);
|
ftpTaskHandle = osThreadNew(StartFtpTask, NULL, &ftpTask_attributes);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* creation of ch395fTestTask */
|
/* creation of testTask */
|
||||||
ch395fTestTaskHandle = osThreadNew(StartCh395fTestTask, NULL, &ch395fTestTask_attributes);
|
testTaskHandle = osThreadNew(start_test_task, NULL, &testTask_attributes);
|
||||||
|
|
||||||
/* USER CODE BEGIN RTOS_THREADS */
|
/* USER CODE BEGIN RTOS_THREADS */
|
||||||
#ifdef ENABLE_NET_LAYER_TESTS
|
#ifdef ENABLE_NET_LAYER_TESTS
|
||||||
@@ -243,22 +241,22 @@ __weak void StartFtpTask(void *argument)
|
|||||||
/* USER CODE END StartFtpTask */
|
/* USER CODE END StartFtpTask */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* USER CODE BEGIN Header_StartCh395fTestTask */
|
/* USER CODE BEGIN Header_start_test_task */
|
||||||
/**
|
/**
|
||||||
* @brief Function implementing the ch395fTestTask thread.
|
* @brief Function implementing the testTask thread.
|
||||||
* @param argument: Not used
|
* @param argument: Not used
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
/* USER CODE END Header_StartCh395fTestTask */
|
/* USER CODE END Header_start_test_task */
|
||||||
__weak void StartCh395fTestTask(void *argument)
|
__weak void start_test_task(void *argument)
|
||||||
{
|
{
|
||||||
/* USER CODE BEGIN StartCh395fTestTask */
|
/* USER CODE BEGIN start_test_task */
|
||||||
/* Infinite loop */
|
/* Infinite loop */
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
osDelay(1);
|
osDelay(1);
|
||||||
}
|
}
|
||||||
/* USER CODE END StartCh395fTestTask */
|
/* USER CODE END start_test_task */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Private application code --------------------------------------------------*/
|
/* Private application code --------------------------------------------------*/
|
||||||
|
|||||||
+5
-98
@@ -59,10 +59,7 @@
|
|||||||
/* Private variables ---------------------------------------------------------*/
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
|
||||||
/* USER CODE BEGIN PV */
|
/* USER CODE BEGIN PV */
|
||||||
/* RS-485 通信实例(UART5: PC12=TX, PD2=RX, PD0=DE) */
|
/* RS-485 实例与接收缓冲已收归 rs485.c(见 rs485.h 的 extern 导出) */
|
||||||
rs485_handle_t g_rs485;
|
|
||||||
#define RS485_RX_BUF_SIZE 256
|
|
||||||
uint8_t g_rs485_rx_buf[RS485_RX_BUF_SIZE];
|
|
||||||
/* USER CODE END PV */
|
/* USER CODE END PV */
|
||||||
|
|
||||||
/* Private function prototypes -----------------------------------------------*/
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
@@ -117,71 +114,8 @@ int main(void)
|
|||||||
/* USER CODE BEGIN 2 */
|
/* USER CODE BEGIN 2 */
|
||||||
HAL_Delay(100);
|
HAL_Delay(100);
|
||||||
|
|
||||||
/*
|
/* 应用层初始化(时间子系统优先,详见 app_main_init) */
|
||||||
* 时间子系统初始化(尽早完成,后续所有日志带时间戳)
|
|
||||||
* sd2506_init() 从 RTC 读取初始时间
|
|
||||||
* sys_clock_init() 将 RTC 时间转为 Unix epoch,建立墙钟基准
|
|
||||||
*/
|
|
||||||
app_main_init();
|
app_main_init();
|
||||||
sd2506_init();
|
|
||||||
sys_clock_init();
|
|
||||||
|
|
||||||
/* RS-485 初始化(UART5 + PD0 方向控制) */
|
|
||||||
rs485_init(&g_rs485, &huart5, ST_DIR4_GPIO_Port, ST_DIR4_Pin);
|
|
||||||
DBG_INFO("RS485 init: OK (UART5, DE=PD0)");
|
|
||||||
|
|
||||||
/* 启动第一次 RS-485 接收 */
|
|
||||||
rs485_receive_start(&g_rs485, g_rs485_rx_buf, RS485_RX_BUF_SIZE);
|
|
||||||
|
|
||||||
/* GD5F 初始化测试 */
|
|
||||||
int ret = gd5f2gq5ue_init();
|
|
||||||
DBG_INFO("NAND init: %s",
|
|
||||||
(ret == GD5F_OK) ? "OK" :
|
|
||||||
(ret == GD5F_ERROR) ? "ERROR" :
|
|
||||||
(ret == GD5F_BUSY_TIMEOUT) ? "BUSY TIMEOUT" :
|
|
||||||
(ret == GD5F_ECC_ERROR) ? "ECC ERROR" :
|
|
||||||
(ret == GD5F_PROGRAM_FAIL) ? "PROGRAM FAIL" :
|
|
||||||
(ret == GD5F_ERASE_FAIL) ? "ERASE FAIL" :
|
|
||||||
(ret == GD5F_ID_MISMATCH) ? "ID MISMATCH" : "UNKNOWN");
|
|
||||||
|
|
||||||
/* TPAFE5160 ADC 测试 */
|
|
||||||
int tp_ret = tpafe5160_init();
|
|
||||||
DBG_INFO("ADC init: %s",
|
|
||||||
(tp_ret == TPAFE5160_OK) ? "OK" : "TIMEOUT");
|
|
||||||
|
|
||||||
/* SD2506 RTC 诊断信息 */
|
|
||||||
{
|
|
||||||
/* 读取 ID */
|
|
||||||
uint8_t sd_id[8];
|
|
||||||
sd2506_get_id(sd_id);
|
|
||||||
DBG_INFO("SD2506 ID: %02X%02X%02X%02X%02X%02X%02X%02X",
|
|
||||||
sd_id[0], sd_id[1], sd_id[2], sd_id[3],
|
|
||||||
sd_id[4], sd_id[5], sd_id[6], sd_id[7]);
|
|
||||||
|
|
||||||
/* 读取当前时间 */
|
|
||||||
sd2506_time_t sd_time;
|
|
||||||
sd2506_get_time(&sd_time);
|
|
||||||
DBG_INFO("SD2506 time: %04d-%02d-%02d %02d:%02d:%02d (week %d)",
|
|
||||||
sd_time.year, sd_time.month, sd_time.day,
|
|
||||||
sd_time.hour, sd_time.minute, sd_time.second,
|
|
||||||
sd_time.week);
|
|
||||||
|
|
||||||
/* 读取温度 */
|
|
||||||
int8_t sd_temp;
|
|
||||||
sd2506_get_temperature(&sd_temp);
|
|
||||||
DBG_INFO("SD2506 temp: %d C", sd_temp);
|
|
||||||
|
|
||||||
/* 读取电池电压 */
|
|
||||||
uint16_t sd_vbat;
|
|
||||||
sd2506_get_battery_voltage(&sd_vbat);
|
|
||||||
DBG_INFO("SD2506 battery: %d.%02d V",
|
|
||||||
sd_vbat / 1000, (sd_vbat % 1000) / 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 启动第一次转换(CubeMX 已配置 BUSY EXTI 中断) */
|
|
||||||
tpafe5160_start_conv_irq();
|
|
||||||
|
|
||||||
/* CH395F 测试已全部移至 ch395fTestTask */
|
|
||||||
/* USER CODE END 2 */
|
/* USER CODE END 2 */
|
||||||
|
|
||||||
/* Init scheduler */
|
/* Init scheduler */
|
||||||
@@ -252,37 +186,10 @@ void SystemClock_Config(void)
|
|||||||
/* USER CODE BEGIN 4 */
|
/* USER CODE BEGIN 4 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* HAL UART 扩展接收回调(IDLE 空闲帧中断触发)
|
* RS-485 的 HAL UART 回调(HAL_UARTEx_RxEventCallback / HAL_UART_ErrorCallback)
|
||||||
* 当 RS-485 总线空闲超过 1 个字符时间后触发
|
* 已收归 rs485.c 实现,本文件不再定义它们。如需处理接收到的 RS-485 数据,
|
||||||
|
* 请重定义 rs485.h 中的弱钩子 rs485_on_rx(uint8_t *buf, uint16_t size)。
|
||||||
*/
|
*/
|
||||||
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
|
|
||||||
{
|
|
||||||
if (huart->Instance == UART5) {
|
|
||||||
rs485_rx_set_size(&g_rs485, Size);
|
|
||||||
|
|
||||||
/* TODO: 在此处处理接收到的 RS-485 数据
|
|
||||||
* g_rs485_rx_buf[0 .. Size-1] 为有效数据
|
|
||||||
* 例如:rs485_transmit(&g_rs485, g_rs485_rx_buf, Size, 0);
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* 重新开启接收 */
|
|
||||||
rs485_receive_start(&g_rs485, g_rs485_rx_buf, RS485_RX_BUF_SIZE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* HAL UART 错误回调
|
|
||||||
*/
|
|
||||||
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
|
|
||||||
{
|
|
||||||
if (huart->Instance == UART5) {
|
|
||||||
/* STM32F4 通过读 SR + DR 清除 ORE/NE/FE/PE 错误标志 */
|
|
||||||
(void)huart->Instance->SR;
|
|
||||||
(void)huart->Instance->DR;
|
|
||||||
/* 重新开启接收 */
|
|
||||||
rs485_receive_start(&g_rs485, g_rs485_rx_buf, RS485_RX_BUF_SIZE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* USER CODE END 4 */
|
/* USER CODE END 4 */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
BIN
Binary file not shown.
+2
-2
@@ -38,8 +38,8 @@ extern "C" {
|
|||||||
* 阶段使能开关(取消注释即启用对应阶段)
|
* 阶段使能开关(取消注释即启用对应阶段)
|
||||||
*
|
*
|
||||||
* 构建模式互斥(详见 docs/CH395F_Test_Guide.md「构建模式与执行顺序」):
|
* 构建模式互斥(详见 docs/CH395F_Test_Guide.md「构建模式与执行顺序」):
|
||||||
* 硬件层模式(阶段 1~5):netTask 不创建,ch395fTestTask 独占 CH395F
|
* 硬件层模式(阶段 1~5):netTask 不创建,testTask 独占 CH395F
|
||||||
* NET 层模式 (阶段 6~11):完整网络栈,netTask 轮询 + ch395fTestTask 监听循环
|
* NET 层模式 (阶段 6~11):完整网络栈,netTask 轮询 + testTask 监听循环
|
||||||
*
|
*
|
||||||
* 注意:同层内可多选(Phase 6~10 共享 testTask 循环);
|
* 注意:同层内可多选(Phase 6~10 共享 testTask 循环);
|
||||||
* Phase 4 (DHCP) 会改变 IP,必须独立运行;
|
* Phase 4 (DHCP) 会改变 IP,必须独立运行;
|
||||||
|
|||||||
+5
-17
@@ -1345,13 +1345,12 @@ static void phase5_run(void) {
|
|||||||
TEST_REPORT("Phase 5");
|
TEST_REPORT("Phase 5");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
void StartCh395fTestTask(void *argument)
|
/*
|
||||||
|
* CH395F 测试套件入口(由 test_config.c 的 start_test_task 统一调度)。
|
||||||
|
* 此处只负责 CH395F 自身的硬件层 / NET 层逻辑,套件选择已上移到 test_config.c。
|
||||||
|
*/
|
||||||
|
void ch395f_test_run(void)
|
||||||
{
|
{
|
||||||
(void)argument;
|
|
||||||
|
|
||||||
DBG_INFO("Test task started, suite=%s", TEST_SUITE_NAME);
|
|
||||||
|
|
||||||
#if defined(TEST_SUITE_CH395F)
|
|
||||||
#if defined(ENABLE_HW_LAYER_TESTS)
|
#if defined(ENABLE_HW_LAYER_TESTS)
|
||||||
/* 硬件层模式(阶段 1~5):netTask 未创建,由本任务完成一次性协议栈
|
/* 硬件层模式(阶段 1~5):netTask 未创建,由本任务完成一次性协议栈
|
||||||
* 初始化并独占 CH395F —— 无 net_poll() 并发读取中断,无 SPI 并发事务 */
|
* 初始化并独占 CH395F —— 无 net_poll() 并发读取中断,无 SPI 并发事务 */
|
||||||
@@ -1391,16 +1390,5 @@ void StartCh395fTestTask(void *argument)
|
|||||||
#else
|
#else
|
||||||
net_layer_test_main();
|
net_layer_test_main();
|
||||||
#endif
|
#endif
|
||||||
#endif /* TEST_SUITE_CH395F */
|
|
||||||
#elif defined(TEST_SUITE_STORAGE)
|
|
||||||
storage_test_run();
|
|
||||||
#elif defined(TEST_SUITE_GD5F)
|
|
||||||
gd5f_test_run();
|
|
||||||
#elif defined(TEST_SUITE_RTC)
|
|
||||||
sd2506_test_run();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
osDelay(1000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void StartCh395fTestTask(void *argument);
|
void start_test_task(void *argument);
|
||||||
|
void ch395f_test_run(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* 模块名称:CH395F NET 层测试(Phase 6~11)
|
* 模块名称:CH395F NET 层测试(Phase 6~11)
|
||||||
* 模块功能:基于 BSD Socket API(单连接模式)的 NET 层测试,由 ch395fTestTask
|
* 模块功能:基于 BSD Socket API(单连接模式)的 NET 层测试,由 testTask
|
||||||
* 任务内的 net_layer_test_main() / net_layer_client_test_main() 事件
|
* 任务内的 net_layer_test_main() / net_layer_client_test_main() 事件
|
||||||
* 循环驱动,需 PC 配合。
|
* 循环驱动,需 PC 配合。
|
||||||
* 包含 Phase 6(TCP Echo) / 7(TCP Client) / 8(大文件) / 9(Select) /
|
* 包含 Phase 6(TCP Echo) / 7(TCP Client) / 8(大文件) / 9(Select) /
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* NET 层测试事件循环入口(定义于 net_test_task.c)。
|
/* NET 层测试事件循环入口(定义于 net_test_task.c)。
|
||||||
* 由 ch395fTestTask 在 NET 层构建模式下调用,内部创建单连接 TCP 监听
|
* 由 testTask 在 NET 层构建模式下调用,内部创建单连接 TCP 监听
|
||||||
* 并驱动 Phase 6/8~11 依次执行,连接断开后自动重新 listen。 */
|
* 并驱动 Phase 6/8~11 依次执行,连接断开后自动重新 listen。 */
|
||||||
void net_layer_test_main(void);
|
void net_layer_test_main(void);
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -37,7 +37,7 @@ extern sd2506_test_stats_t g_sd2506_test_stats;
|
|||||||
g_sd2506_test_stats.failed); \
|
g_sd2506_test_stats.failed); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/* 测试入口:由 StartCh395fTestTask 经 TEST_SUITE_RTC 调度,顺序执行 Phase 1~3 */
|
/* 测试入口:由 start_test_task 经 TEST_SUITE_RTC 调度,顺序执行 Phase 1~3 */
|
||||||
void sd2506_test_run(void);
|
void sd2506_test_run(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
* 当前测试:Phase 1 基本读写(init / 读 / 写 / 回读一致 / 走时),
|
* 当前测试:Phase 1 基本读写(init / 读 / 写 / 回读一致 / 走时),
|
||||||
* 结束后自动恢复板子原始时间。
|
* 结束后自动恢复板子原始时间。
|
||||||
* 入口:sd2506_test_run()(由 StartCh395fTestTask 经 TEST_SUITE_RTC 调度)
|
* 入口:sd2506_test_run()(由 start_test_task 经 TEST_SUITE_RTC 调度)
|
||||||
* 创建日期:2026-08-28
|
* 创建日期:2026-08-28
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* 模块名称:Storage Test Suite
|
* 模块名称:Storage Test Suite
|
||||||
* 模块功能:FTL + FatFS 存储测试的声明与断言宏。实现见 storage_test_task.c,
|
* 模块功能:FTL + FatFS 存储测试的声明与断言宏。实现见 storage_test_task.c,
|
||||||
* 统一由 ch395fTestTask 调度;正常产品构建下由 defaultTask 调用,
|
* 统一由 testTask 调度;正常产品构建下由 defaultTask 调用,
|
||||||
* 行为与原 defaultTask 内联逻辑一致。
|
* 行为与原 defaultTask 内联逻辑一致。
|
||||||
* 适用平台:STM32F4 系列
|
* 适用平台:STM32F4 系列
|
||||||
* 作者:王建锋
|
* 作者:王建锋
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* 模块名称:Storage Test Task
|
* 模块名称:Storage Test Task
|
||||||
* 模块功能:FTL + FatFS 存储测试,从 defaultTask 迁入,统一由 ch395fTestTask
|
* 模块功能:FTL + FatFS 存储测试,从 defaultTask 迁入,统一由 testTask
|
||||||
* 调度运行。正常产品构建下由 defaultTask 调用,行为与原内联逻辑一致。
|
* 调度运行。正常产品构建下由 defaultTask 调用,行为与原内联逻辑一致。
|
||||||
* 作者:王建锋
|
* 作者:王建锋
|
||||||
* 创建日期:2026-08-26
|
* 创建日期:2026-08-26
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* 模块名称:统一测试任务调度器(Test Config)
|
||||||
|
* 模块功能:所有测试任务的唯一入口。FreeRTOS 的 testTask 仅调用本文件
|
||||||
|
* 的 start_test_task(),由本文件根据 test_config.h 中启用的
|
||||||
|
* TEST_SUITE_* 宏,将测试分发到对应套件的运行函数。
|
||||||
|
*
|
||||||
|
* 各套件运行函数(ch395f_test_run / storage_test_run / gd5f_test_run
|
||||||
|
* / sd2506_test_run)各自实现具体测试逻辑,本文件只负责"选哪个跑",
|
||||||
|
* 不掺杂任何具体测试细节,使测试入口界限清晰、易于维护。
|
||||||
|
* 作者:王建锋
|
||||||
|
* 创建日期:2026-08-29
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#define DBG_TAG "[TEST_CFG]"
|
||||||
|
#include "cmsis_os.h"
|
||||||
|
#include "dbg_log.h"
|
||||||
|
|
||||||
|
#include "test_config.h"
|
||||||
|
|
||||||
|
#include "ch395f_test_task.h"
|
||||||
|
#include "storage_test.h"
|
||||||
|
#include "gd5f_test.h"
|
||||||
|
#include "sd2506_test.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 测试任务统一入口(FreeRTOS start_test_task 线程函数)。
|
||||||
|
* 根据编译期选中的 TEST_SUITE_* 调度对应套件,其余时间挂起。
|
||||||
|
*/
|
||||||
|
void start_test_task(void *argument)
|
||||||
|
{
|
||||||
|
(void)argument;
|
||||||
|
|
||||||
|
DBG_INFO("Test task started, suite=%s", TEST_SUITE_NAME);
|
||||||
|
|
||||||
|
#if defined(TEST_SUITE_CH395F)
|
||||||
|
ch395f_test_run();
|
||||||
|
#elif defined(TEST_SUITE_STORAGE)
|
||||||
|
storage_test_run();
|
||||||
|
#elif defined(TEST_SUITE_GD5F)
|
||||||
|
gd5f_test_run();
|
||||||
|
#elif defined(TEST_SUITE_RTC)
|
||||||
|
sd2506_test_run();
|
||||||
|
#else
|
||||||
|
DBG_INFO("No test suite selected (normal product build)");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
osDelay(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* 模块名称:统一测试套件选择
|
* 模块名称:统一测试套件选择
|
||||||
* 模块功能:集中选择当前构建要运行的测试套件。所有测试统一由
|
* 模块功能:集中选择当前构建要运行的测试套件。所有测试统一由
|
||||||
* ch395fTestTask(StartCh395fTestTask)调度,defaultTask 在测试
|
* testTask(start_test_task)调度,defaultTask 在测试
|
||||||
* 构建下空闲,正常产品构建下仅运行存储挂载/测试。
|
* 构建下空闲,正常产品构建下仅运行存储挂载/测试。
|
||||||
* 适用平台:STM32F4 系列
|
* 适用平台:STM32F4 系列
|
||||||
* 作者:王建锋
|
* 作者:王建锋
|
||||||
|
|||||||
Reference in New Issue
Block a user