9ceb218f80
Co-authored-by: Cursor <cursoragent@cursor.com>
196 lines
7.9 KiB
C
196 lines
7.9 KiB
C
#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**<br>(48~55) | 硬件中断延迟处理、安全关键任务 | **<1ms** | 最高优先级,用于不能容忍任何延迟的任务(如电机紧急停止) |
|
|
| **osPriorityHigh**<br>(40~47) | 实时控制、高频传感器处理 | **1~10ms** | 要求严格定时执行的任务(如PID控制、IMU数据融合) |
|
|
| **osPriorityAboveNormal**<br>(32~39) | 通信协议栈、用户输入响应 | **10~50ms** | 需要快速响应但允许轻微抖动的任务(如UART命令解析、触摸屏响应) |
|
|
| **osPriorityNormal**<br>(24~31) | 主要业务逻辑、中等频率任务 | **50~200ms** | 常规任务(如状态机更新、中等频率数据采集) |
|
|
| **osPriorityBelowNormal**<br>(16~23) | 后台处理、低优先级服务 | **200ms~1s** | 允许延迟的任务(如日志写入、非实时数据分析) |
|
|
| **osPriorityLow**<br>(8~15) | 维护性任务 | **1s~10s** | 对时间不敏感的任务(如LED心跳灯、内存碎片整理) |
|
|
| **osPriorityIdle**<br>(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
|
|
|
|
}
|
|
|
|
|