#include "app_init.h"
#include "app_init/task_lock.h"
#include "mylog/mylog.h"
#include "bms/bms_task.h"
#include "collect_ctrl/collect_task.h"
#include "flowctrl/flowctrl_task.h"
#include "fault_cheak/faultcheck_task.h"
#include "mdu_comm/mdu_comm_task.h"
#include "plat_comm/plat_comm_task.h"
#include "ui/ui_task.h"
#include "wdt_task/wdt_task.h"
#include "meter_calculate/meter_coll_task.h"
#include "meter_calculate/calculate_task.h"
#include "tcp_ser/tcp_ser_task.h"
#include "sys_drv_init.h"
#include "publicdata/publicdata.h"
#include "bsp_include.h"
#if SYSTEM_TYPE == SYSTEM_TYPE_CCU601E_D
extern struct netif gnetif;
#include "adc/app_adc.h"
#include "app_fatfs/fatfs_init.h"
#include "net_lwip/ethernetif.h"
#elif SYSTEM_TYPE == SYSTEM_TYPE_CCU621_M
#include "netconf.h"
#include "net_init.h"
#include "eth_link.h"
#include "sub_comm/sub_comm_task.h"
#else
#endif
#if SD_CARD_EN
#include "sdmmc/sdmmc_sd_drv.h"
#include "sdmmc/app_sdmmc.h"
#endif
#if(MY_SHELL_EN) //Shell 使能
#include "letter_shell/shell_port.h"
#endif
void v_fault_blink_code_loop(uint32_t blink_count)
{
uint32_t i;
if (blink_count == 0U) {
blink_count = 1U;
}
for (;;) {
for (i = 0U; i < blink_count; i++) {
RUN_LED_ON();
delay_ms(200U);
RUN_LED_OFF();
delay_ms(200U);
}
/* 码间隔:灭 500ms,便于快速识别状态 */
RUN_LED_OFF();
delay_ms(1000U);
}
}
void delay_ms(uint32_t ms)
{
uint32_t start;
uint32_t ticks;
/* 基于 DWT CYCCNT 的精确延时:按 SystemCoreClock 计时 */
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
start = DWT->CYCCNT;
ticks = (SystemCoreClock / 1000U) * ms;
while ((DWT->CYCCNT - start) < ticks) {
__NOP();
}
}
/*
### CMSIS-RTOS2 优先级与任务周期匹配表
| 优先级范围 | 适用任务类型 | 典型执行周期 | 说明 |
| **osPriorityRealtime**
(48~55) | 硬件中断延迟处理、安全关键任务 | **<1ms** | 最高优先级,用于不能容忍任何延迟的任务(如电机紧急停止) |
| **osPriorityHigh**
(40~47) | 实时控制、高频传感器处理 | **1~10ms** | 要求严格定时执行的任务(如PID控制、IMU数据融合) |
| **osPriorityAboveNormal**
(32~39) | 通信协议栈、用户输入响应 | **10~50ms** | 需要快速响应但允许轻微抖动的任务(如UART命令解析、触摸屏响应) |
| **osPriorityNormal**
(24~31) | 主要业务逻辑、中等频率任务 | **50~200ms** | 常规任务(如状态机更新、中等频率数据采集) |
| **osPriorityBelowNormal**
(16~23) | 后台处理、低优先级服务 | **200ms~1s** | 允许延迟的任务(如日志写入、非实时数据分析) |
| **osPriorityLow**
(8~15) | 维护性任务 | **1s~10s** | 对时间不敏感的任务(如LED心跳灯、内存碎片整理) |
| **osPriorityIdle**
(1) | 空闲任务 | **无固定周期** | 仅当系统空闲时运行(如低功耗模式准备) |
#### 配置原则
1. **周期越短 → 优先级越高**
- 例:100us级电机控制 → `osPriorityRealtime7` (55)
2. **关键性补偿**
- 重要但低频的任务(如看门狗)可提高1-2级优先级
3. **避免优先级反转**
- 共享资源的任务间优先级差建议≤8级
*/
const MY_TASK_DATA my_task_data[MY_TASK_NUM] =
{
/* 格式:{名称, 优先级, 栈大小(字节), 执行周期(ms), 任务入口, 任务参数} */
/* FreeRTOS 优先级规则(重要):
* - 数值越大,优先级越高;0 为最低优先级(通常是 IDLE)。
* - 当前工程 configMAX_PRIORITIES=32,可用范围 0~31。
* - 现场要求任务优先级不重复,以下按周期和关键性分配唯一优先级。 */
{"EthIf", (UBaseType_t)(tskIDLE_PRIORITY + 30U), TASK_SIZE_SIZE_2048, TASK_SLEEP_MS_1, NULL, NULL},
{"TCP/IP", (UBaseType_t)(tskIDLE_PRIORITY + 29U), TASK_SIZE_SIZE_8k, TASK_SLEEP_MS_1, NULL, NULL},
{"BmsComm", (UBaseType_t)(tskIDLE_PRIORITY + 27U), TASK_SIZE_SIZE_4k, TASK_SLEEP_MS_5, v_bms_task, NULL},
{"DataColl",(UBaseType_t)(tskIDLE_PRIORITY + 26U), TASK_SIZE_SIZE_2048, TASK_SLEEP_MS_10, v_collect_task, NULL},
{"FlowCtrl",(UBaseType_t)(tskIDLE_PRIORITY + 25U), TASK_SIZE_SIZE_4k, TASK_SLEEP_MS_20, v_flowctrl_task, NULL},
{"FaultCheck",(UBaseType_t)(tskIDLE_PRIORITY + 24U), TASK_SIZE_SIZE_6k, TASK_SLEEP_MS_50, v_fault_task, NULL},
{"MduComm", (UBaseType_t)(tskIDLE_PRIORITY + 23U), TASK_SIZE_SIZE_2048, TASK_SLEEP_MS_50, v_Mdu_Comm_task, NULL},
{"SubComm", (UBaseType_t)(tskIDLE_PRIORITY + 22U), TASK_SIZE_SIZE_2048, TASK_SLEEP_MS_50, v_sub_comm_task, NULL},
{"PlatComm",(UBaseType_t)(tskIDLE_PRIORITY + 21U), TASK_SIZE_SIZE_8k*2, TASK_SLEEP_MS_100, v_plat_comm_task, NULL},
#if (MY_SHELL_EN)
{"MyShell", (UBaseType_t)(tskIDLE_PRIORITY + 20U), TASK_SIZE_SIZE_4k, TASK_SLEEP_MS_100, v_myshell_task, &shell},
#endif
{"UiComm", (UBaseType_t)(tskIDLE_PRIORITY + 19U), TASK_SIZE_SIZE_3k, TASK_SLEEP_MS_100, v_ui_task, NULL},
/* WatchDog 放在 EthIf/TCP-IP 之后,保留较高优先级 */
{"WatchDog",(UBaseType_t)(tskIDLE_PRIORITY + 28U), TASK_SIZE_SIZE_1024, TASK_SLEEP_MS_150, v_wdt_task, NULL},
{"MeterColl",(UBaseType_t)(tskIDLE_PRIORITY + 18U), TASK_SIZE_SIZE_2048, TASK_SLEEP_MS_200, v_Meter_Coll_task, NULL},
{"Meterfee",(UBaseType_t)(tskIDLE_PRIORITY + 17U), TASK_SIZE_SIZE_3k, TASK_SLEEP_MS_200, v_meterfee_task, NULL},
{"MyLog", (UBaseType_t)(tskIDLE_PRIORITY + 16U), TASK_SIZE_SIZE_8k*2, TASK_SLEEP_MS_200, v_mylog_task, NULL},
#if TCP_DEBUG_EN
{"TcpSer", (UBaseType_t)(tskIDLE_PRIORITY + 15U), TASK_SIZE_SIZE_8k*2, TASK_SLEEP_MS_200, v_tcp_ser_task, NULL},
#endif
{"EthLink", (UBaseType_t)(tskIDLE_PRIORITY + 1U), TASK_SIZE_SIZE_1024, TASK_SLEEP_MS_1000, ethernet_link_thread, NETCONF_ETH_NETIF}
};
void app_os_init(void)
{
BaseType_t create_ret;
v_public_cfg_data_init(); //参数初始化
#if (MY_SHELL_EN)
userShellInit();
#endif
#if SYSTEM_TYPE == SYSTEM_TYPE_CCU601E_D
v_adc_data_init();
extern void Netif_Config_init(void);
Netif_Config_init(); //网络及lwip 初始化 内部创建3个线程 分别是EthIf TCP/IP EthLink
CANSPI_Initialize(); //SPI CAN 配置
#elif SYSTEM_TYPE == SYSTEM_TYPE_CCU621_M
create_ret = net_init_task_create();
if (create_ret != pdPASS) {
MYLOG_MSG(0xFFU, "NetInit create failed, ret=%ld", (long)create_ret);
} else {
MYLOG_MSG(0xFFU, "NetInit create ok");
}
#else
#endif
for (uint32_t i = 0U; i < (uint32_t)MY_TASK_NUM; ++i) {
if (my_task_data[i].task_entry == NULL) {
continue;
}
create_ret = xTaskCreate(my_task_data[i].task_entry,
my_task_data[i].task_name,
(uint16_t)(my_task_data[i].task_size / sizeof(StackType_t)),
my_task_data[i].task_arg,
my_task_data[i].task_prio,
NULL);
if (create_ret != pdPASS) {
MYLOG_MSG(0xFFU, "Task[%s] create FAILED! ret=%ld", my_task_data[i].task_name, (long)create_ret);
} else {
MYLOG_MSG(0xFFU, "Task[%s] create ok", my_task_data[i].task_name);
}
}
#if SD_CARD_EN
sdmmc_sd_drv_init();
app_sdmmc_init();
#endif
#if SD_CARD_EN
fatfs_init();
#endif
}