Release:5.20灰测
This commit is contained in:
90
Core/User/App/task_air724.c
Normal file
90
Core/User/App/task_air724.c
Normal file
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* @file udp_manager.c
|
||||
* @brief UDP管理模块
|
||||
* @details 处理充电桩与服务器之间的UDP通信,提供数据发送功能。
|
||||
* 支持向指定充电桩发送数据以及向上位机服务器发送数据。
|
||||
* @date 2025-01-09 14:32:15
|
||||
* @version 1.0.0
|
||||
* @copyright Copyright (c) 2026
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "task_air724.h"
|
||||
#include "ykc_router.h"
|
||||
#include "drv_air724.h"
|
||||
|
||||
/* typedef --------------------------------------------------------------------*/
|
||||
|
||||
/* variables ------------------------------------------------------------------*/
|
||||
|
||||
/* code -----------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief tcp_recv_task_function:云快充 TCP 消息解析任务
|
||||
*
|
||||
* @note none
|
||||
*
|
||||
* @param taskID : 任务ID
|
||||
*
|
||||
* @retval runtime : 任务周期
|
||||
*/
|
||||
|
||||
void air724_recv_task_function(void const *argument)
|
||||
{
|
||||
|
||||
uint8_t air724_rx_msg[UART1_RX_BUFFER_SIZE];
|
||||
uint8_t *ykc_downlink_frame = NULL;
|
||||
/* 等待 datalink_conn 初始化完成 */
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
|
||||
/**/
|
||||
while (1)
|
||||
{
|
||||
/*---------------------------------------------------获取任务运行状态---------------------------------------------------*/
|
||||
TaskRunTimeStat.DownLinkTask.threads_runtime = GetTask_RunTime(DownLinkTaskID);
|
||||
TaskRunTimeStat.DownLinkTask.threads_counter = GetTask_Beatcnt(DownLinkTaskID);
|
||||
TaskRunTimeStat.DownLinkTask.threads_freestack = Get_Free_Stack(DownLinkTaskID);
|
||||
|
||||
if (xQueueReceive(Air724_Message_Queue, &air724_rx_msg, 10) == pdPASS)
|
||||
{
|
||||
if (air724_rx_msg[0] == 0x55 && air724_rx_msg[1] == 0xAA)
|
||||
{
|
||||
// 主指令解析
|
||||
switch (air724_rx_msg[2])
|
||||
{
|
||||
// 云快充下行解析
|
||||
case 0x01:
|
||||
{
|
||||
uint8_t charger_index = air724_rx_msg[3];
|
||||
uint8_t ykc_downlink_frame_len = air724_rx_msg[4];
|
||||
memcpy(ykc_downlink_frame, &air724_rx_msg[5], ykc_downlink_frame_len);
|
||||
|
||||
SERVER_PACK frame;
|
||||
frame.start_flag = ykc_downlink_frame[0];
|
||||
frame.len = ykc_downlink_frame[1];
|
||||
frame.serial = (ykc_downlink_frame[2] << 8) | ykc_downlink_frame[3];
|
||||
frame.encrypt_flag = ykc_downlink_frame[4];
|
||||
frame.frame_type = ykc_downlink_frame[5];
|
||||
frame.data = (uint8_t *)pvPortMalloc(frame.len - 4);
|
||||
memcpy(frame.data, ykc_downlink_frame + HEADER_LENGTH, frame.len - 4);
|
||||
frame.crc = (ykc_downlink_frame[HEADER_LENGTH + frame.len] << 8) | ykc_downlink_frame[HEADER_LENGTH + frame.len + 1];
|
||||
|
||||
ykc_route_dispatch(charger_index, &frame); // 云快充路由分发
|
||||
|
||||
vPortFree(frame.data);
|
||||
}
|
||||
break;
|
||||
case 0x83:
|
||||
case 0x84:
|
||||
case 0x85:
|
||||
case 0x86:
|
||||
case 0x87:
|
||||
{
|
||||
drv_air724_parse_response(air724_rx_msg, UART1_RX_BUFFER_SIZE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
16
Core/User/App/task_air724.h
Normal file
16
Core/User/App/task_air724.h
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
#ifndef __AIR724_RECV_TASK_H
|
||||
#define __AIR724_RECV_TASK_H
|
||||
|
||||
/* includes ----------------------------------------------------------------------------------------------*/
|
||||
#include "global.h"
|
||||
|
||||
/* macro ------------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/* struct ------------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* __AIR724_RECV_TASK_H */
|
||||
82
Core/User/App/task_sys.c
Normal file
82
Core/User/App/task_sys.c
Normal file
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file user\task\HeartBeatTask.c
|
||||
* @author luhuaishuai
|
||||
* @version v0.1
|
||||
* @date 2026-1-12
|
||||
* @brief 心跳任务,负责发送心跳包和处理云快充的响应
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "task_sys.h"
|
||||
|
||||
void HeartBeat_Sign(void);
|
||||
|
||||
|
||||
/**
|
||||
* @funNm : HeartbeatTask_Function
|
||||
* @brief : 心跳
|
||||
* @param : argument
|
||||
* @retval: void
|
||||
*/
|
||||
void sys_task_function(void const *argument)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
TaskRunTimeStat.HeartBeatTask.threads_runtime = GetTask_RunTime(HeartBeatTaskID);
|
||||
TaskRunTimeStat.HeartBeatTask.threads_counter = GetTask_Beatcnt(HeartBeatTaskID);
|
||||
TaskRunTimeStat.HeartBeatTask.threads_freestack = Get_Free_Stack(HeartBeatTaskID);
|
||||
|
||||
HeartBeat_Sign(); // 指示灯、蜂鸣器
|
||||
|
||||
// HAL_IWDG_Refresh(&hiwdg); //喂狗
|
||||
|
||||
osDelay(50);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @funNm : HeartBeat_Sign
|
||||
* @brief : 心跳指示灯、蜂鸣器 云快充心跳
|
||||
* @param : none
|
||||
* @retval: void
|
||||
*/
|
||||
static uint32_t last_heartbeat_tick[MAX_CHARGER_COUNT] = {0};
|
||||
|
||||
void HeartBeat_Sign(void)
|
||||
{
|
||||
int i;
|
||||
uint32_t now = HAL_GetTick();
|
||||
bool any_online = false;
|
||||
|
||||
/* 6路桩独立心跳,互不影响 */
|
||||
for (i = 0; i < MAX_CHARGER_COUNT; i++)
|
||||
{
|
||||
if (g_charger_manager.charger_piles[i].is_online)
|
||||
{
|
||||
any_online = true;
|
||||
if ((now - last_heartbeat_tick[i]) >= 8000)
|
||||
{
|
||||
last_heartbeat_tick[i] = now;
|
||||
charger_to_server_0X03(i + 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (any_online)
|
||||
{
|
||||
RUN_EVERY(50, tick_B, {
|
||||
System_Mode_Led_Toggle();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
RUN_EVERY(500, tick_C, {
|
||||
System_Mode_Led_Toggle();
|
||||
});
|
||||
}
|
||||
|
||||
RUN_EVERY(1000, tick_D, {
|
||||
System_Run_Led_Toggle();
|
||||
});
|
||||
}
|
||||
22
Core/User/App/task_sys.h
Normal file
22
Core/User/App/task_sys.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef __TASK_SYS_H
|
||||
#define __TASK_SYS_H
|
||||
|
||||
/* includes ----------------------------------------------------------------------------------------------*/
|
||||
#include "global.h"
|
||||
#include "cmsis_os.h" // 或使用 HAL_GetTick() 等
|
||||
|
||||
// 获取当前系统时间(毫秒)
|
||||
//#define GET_TICK() (osKernelSysTick()) // FreeRTOS/CMSIS-RTOS
|
||||
#define GET_TICK() (HAL_GetTick()) // STM32 HAL 用户可换这行
|
||||
|
||||
// 非阻塞延时宏:每 interval_ms 执行一次 {code}
|
||||
#define RUN_EVERY(interval_ms, static_tick_var, code) \
|
||||
do { \
|
||||
static uint32_t static_tick_var = 0; \
|
||||
if ((GET_TICK() - static_tick_var) >= (interval_ms)) { \
|
||||
static_tick_var = GET_TICK(); \
|
||||
code; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#endif /* __TASK_SYS_H */
|
||||
123
Core/User/App/task_udp.c
Normal file
123
Core/User/App/task_udp.c
Normal file
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* @file task_udp.c
|
||||
* @brief UDP通信任务处理模块
|
||||
* @details 处理充电桩与服务器之间的UDP通信协议,包括UDP数据接收、数据解析和路由分发等功能。
|
||||
* 支持JSON格式的数据交互,通过FreeRTOS任务和队列机制实现异步数据处理。
|
||||
* 包含两个主要任务:UDP数据接收任务(udp_recv_task_function)和UDP数据解析任务(udp_parse_task_function)。
|
||||
* @date 2025-01-09 14:32:15
|
||||
* @version 1.0.0
|
||||
* @copyright Copyright (c) 2026
|
||||
*/
|
||||
|
||||
#include "task_udp.h"
|
||||
|
||||
/**
|
||||
* @brief udp_recv_task:UDP 数据接受任务
|
||||
*
|
||||
* @note none
|
||||
*
|
||||
* @param taskID : 任务ID
|
||||
*
|
||||
* @retval runtime : 任务周期
|
||||
*/
|
||||
|
||||
void udp_recv_task_function(void const *argument)
|
||||
{
|
||||
err_t recv_err;
|
||||
struct netbuf *datalink_buf = NULL;
|
||||
datalink_conn = netconn_new(NETCONN_UDP);
|
||||
netconn_bind(datalink_conn, IP_ADDR_ANY, LINK_SERVER_PORT);
|
||||
UDP_Message_Queue_Init(); // 初始化UDP接收队列
|
||||
/*桩UDP通讯初始化完成 发送云快充任务通知*/
|
||||
xTaskNotifyGive(YkcTaskHandle);
|
||||
xTaskNotifyGive(Air724_ParseTaskHandle);
|
||||
xTaskNotifyGive(UDP_ParseTaskHandle);
|
||||
|
||||
while (1)
|
||||
{
|
||||
/*获取任务运行状态*/
|
||||
TaskRunTimeStat.UPLinkTask.threads_runtime = GetTask_RunTime(UPLinkTaskID);
|
||||
TaskRunTimeStat.UPLinkTask.threads_counter = GetTask_Beatcnt(UPLinkTaskID);
|
||||
TaskRunTimeStat.UPLinkTask.threads_freestack = Get_Free_Stack(UPLinkTaskID);
|
||||
|
||||
recv_err = netconn_recv(datalink_conn, &datalink_buf);
|
||||
|
||||
if (recv_err == ERR_OK && datalink_buf != NULL)
|
||||
{
|
||||
uint8_t *playload;
|
||||
uint16_t playload_len;
|
||||
netbuf_data(datalink_buf, (void *)&playload, &playload_len);
|
||||
if (playload_len > 0)
|
||||
{
|
||||
UdpMsg_t msg;
|
||||
ip_addr_copy(msg.src_ip, *netbuf_fromaddr(datalink_buf)); // 获取UDP源IP
|
||||
msg.src_port = netbuf_fromport(datalink_buf); // 获取UDP源端口
|
||||
msg.len = playload_len;
|
||||
msg.data = (char *)pvPortMalloc(playload_len + 1);
|
||||
if (msg.data != NULL)
|
||||
{
|
||||
memcpy(msg.data, playload, playload_len);
|
||||
msg.data[playload_len] = '\0';
|
||||
// 队列满,释放数据内存
|
||||
if (xQueueSend(UDP_Message_Queue, &msg, 0) != pdPASS)
|
||||
{
|
||||
vPortFree(msg.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
netbuf_delete(datalink_buf); // 释放UDP网络缓冲区
|
||||
}
|
||||
else
|
||||
{
|
||||
if (recv_err != ERR_TIMEOUT && recv_err != ERR_WOULDBLOCK)
|
||||
{
|
||||
printf("datalink netconn_recv err: %d\r\n", recv_err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UDP_ParseTask_Function:UDP 数据解析任务
|
||||
*
|
||||
* @note none
|
||||
*
|
||||
* @param taskID : 任务ID
|
||||
*
|
||||
* @retval runtime : 任务周期
|
||||
*/
|
||||
void udp_parse_task_function(void const *argument)
|
||||
{
|
||||
UdpMsg_t msg;
|
||||
cJSON *root = NULL, *cmd = NULL, *id = NULL;
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY); /* 等待桩通讯协议层完成*/
|
||||
while (1)
|
||||
{
|
||||
if (xQueueReceive(UDP_Message_Queue, &msg, portMAX_DELAY) == pdPASS)
|
||||
{
|
||||
root = cJSON_Parse((const char *)msg.data);
|
||||
if (root == NULL)
|
||||
{
|
||||
printf("JSON Parse Failed: %s\r\n", msg.data);
|
||||
vPortFree(msg.data);
|
||||
continue;
|
||||
}
|
||||
id = cJSON_GetObjectItem(root, "id");
|
||||
cmd = cJSON_GetObjectItem(root, "cmd");
|
||||
|
||||
if (cmd != NULL && id != NULL)
|
||||
{
|
||||
const char *cmd_str = cmd->valuestring;
|
||||
udp_route_dispatch((uint8_t)id->valueint, cmd->valuestring, root); //送入路由处理
|
||||
cJSON_Delete(root);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Missing 'code' field from \r\n");
|
||||
cJSON_Delete(root);
|
||||
}
|
||||
vPortFree(msg.data);
|
||||
msg.data = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
25
Core/User/App/task_udp.h
Normal file
25
Core/User/App/task_udp.h
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
#ifndef __UDP_TASK_H
|
||||
#define __UDP_TASK_H
|
||||
|
||||
/* includes ----------------------------------------------------------------------------------------------*/
|
||||
#include "global.h"
|
||||
#include "board_config.h"
|
||||
#include "udp_router.h"
|
||||
#include "udp_manager.h"
|
||||
#include "lwip/opt.h"
|
||||
#include "lwip/api.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "httpd.h"
|
||||
|
||||
// 定义UDP消息体
|
||||
typedef struct {
|
||||
ip4_addr_t src_ip; // 来源IP
|
||||
uint16_t src_port; // 来源端口
|
||||
uint16_t len; // 数据长度
|
||||
char *data; // 数据指针(动态分配)
|
||||
} UdpMsg_t;
|
||||
|
||||
|
||||
|
||||
#endif /* __UDP_TASK_H */
|
||||
197
Core/User/App/task_ykc.c
Normal file
197
Core/User/App/task_ykc.c
Normal file
@@ -0,0 +1,197 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file user\task\HeartBeatTask.c
|
||||
* @author luhuaishuai
|
||||
* @version v0.1
|
||||
* @date 2026-1-12
|
||||
* @brief Briefly describe the function of your function
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
#include "task_ykc.h"
|
||||
#include "lwip/opt.h"
|
||||
#include "lwip/api.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "usbd_cdc_if.h"
|
||||
|
||||
/**
|
||||
* @funNm : ykc_task_function
|
||||
* @brief : 云快充平台交互主任务
|
||||
* @param : argument
|
||||
* @retval: void
|
||||
*/
|
||||
|
||||
void ykc_task_function(void const *argument)
|
||||
{
|
||||
uint32_t now;
|
||||
|
||||
init_chargers();
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
osDelay(5000);
|
||||
while (1)
|
||||
{
|
||||
TaskRunTimeStat.YkcTask.threads_runtime = GetTask_RunTime(YkcTaskID);
|
||||
TaskRunTimeStat.YkcTask.threads_counter = GetTask_Beatcnt(YkcTaskID);
|
||||
TaskRunTimeStat.YkcTask.threads_freestack = Get_Free_Stack(YkcTaskID);
|
||||
|
||||
now = HAL_GetTick();
|
||||
|
||||
for (int i = 0; i < g_charger_manager.charger_count; i++)
|
||||
{
|
||||
ChargerPile *pile = &g_charger_manager.charger_piles[i];
|
||||
|
||||
/* ========== 桩层初始化(桩0~2通用,只做一次) ========== */
|
||||
if (pile->step < 3)
|
||||
{
|
||||
if (now < pile->step_tick)
|
||||
continue;
|
||||
|
||||
switch (pile->step)
|
||||
{
|
||||
case 0: // 等待桩上电 + 连接本桩4G通道
|
||||
{
|
||||
// if (pile->is_udp_online)
|
||||
if(1)
|
||||
{
|
||||
if (!g_air724_info.socket_connected[i])
|
||||
{
|
||||
drv_air724_connect_channel(i + 1);
|
||||
pile->step_tick = now + 3000;
|
||||
}
|
||||
else
|
||||
{
|
||||
pile->step = 1;
|
||||
pile->step_tick = now;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
USB_Printf("网关:等待桩%d上电指令\r\n", i + 1);
|
||||
drv_air724_query_iccid();
|
||||
pile->step_tick = now + 1000;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: // 云快充登录认证
|
||||
{
|
||||
if (!pile->is_online)
|
||||
{
|
||||
charger_to_server_0X01(i + 1);
|
||||
pile->step_tick = now + 5000;
|
||||
}
|
||||
else
|
||||
{
|
||||
pile->step = 2;
|
||||
charger_to_server_0X05(1, i + 1);
|
||||
pile->step_tick = now;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // 云快充计费模型请求
|
||||
{
|
||||
if (!pile->get_model)
|
||||
{
|
||||
charger_to_server_0X09(i + 1);
|
||||
pile->step_tick = now + 5000;
|
||||
}
|
||||
else
|
||||
{
|
||||
pile->step = 3;
|
||||
pile->step_tick = now;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* ========== 枪层独立运行(每把枪独立状态机) ========== */
|
||||
for (int g = 0; g < MAX_GUN_PER_CHARGER; g++)
|
||||
{
|
||||
ChargerGun *gun = &pile->guns[g];
|
||||
|
||||
if (now < gun->gun_step_tick)
|
||||
continue;
|
||||
|
||||
switch (gun->gun_step)
|
||||
{
|
||||
case 0: // 运行时:周期上传实时数据 + 账单处理
|
||||
{
|
||||
charger_to_server_0X13(i + 1, g + 1);
|
||||
host_computer_report_data(i + 1, g + 1);
|
||||
|
||||
if (gun->is_get_bill)
|
||||
{
|
||||
charger_to_server_0X3B(i + 1, g + 1);
|
||||
charger_to_server_0X3B(i + 1, g + 1);
|
||||
gun->is_get_bill = 0;
|
||||
memset(gun->real_time_data.trade_serial, 0,
|
||||
sizeof(gun->real_time_data.trade_serial));
|
||||
}
|
||||
gun->gun_step_tick = now + 5000;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
osDelay(10);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 云快充平台状态检查回调
|
||||
* @note 每 500ms 触发一次,遍历 1-6 号桩检查状态
|
||||
* @param xTimer 定时器句柄
|
||||
* @retval none
|
||||
*/
|
||||
|
||||
void ykc_timer_callback_function(TimerHandle_t xTimer)
|
||||
{
|
||||
for (int i = 0; i < MAX_CHARGER_COUNT; i++)
|
||||
{
|
||||
for (int g = 0; g < MAX_GUN_PER_CHARGER; g++)
|
||||
{
|
||||
ChargerGun *gun = &g_charger_manager.charger_piles[i].guns[g];
|
||||
if (gun->charger_state == REDAY_CHARGER_START_STATE)
|
||||
{
|
||||
USB_Printf("状态机:[info] 桩%d 枪%d 查询中,等待启动回复.... \r\n", i + 1, g + 1);
|
||||
}
|
||||
else if (gun->charger_state == SUCCESS_CHARGER_STATE)
|
||||
{
|
||||
USB_Printf("状态机:[success] 桩%d 枪%d 启动成功.... \r\n", i + 1, g + 1);
|
||||
gun->charger_state = CHARGER_STATE_CHARGING;
|
||||
}
|
||||
else if (gun->charger_state == FAIL_CHARGER_STATE)
|
||||
{
|
||||
USB_Printf("状态机:[error] 桩%d 枪%d 启动失败.... \r\n", i + 1, g + 1);
|
||||
}
|
||||
else if (gun->charger_state == CHARGER_STATE_CHARGING)
|
||||
{
|
||||
USB_Printf("状态机:[info] 桩%d 枪%d 充电中.... \r\n", i + 1, g + 1);
|
||||
}
|
||||
else if (gun->charger_state == REDAY_CHARGER_STOP_STATE)
|
||||
{
|
||||
USB_Printf("状态机:[info] 桩%d 枪%d 查询中,等待停止回复.... \r\n", i + 1, g + 1);
|
||||
}
|
||||
else if (gun->charger_state == SUCCESS_CHARGER_STOP_STATE)
|
||||
{
|
||||
USB_Printf("状态机:[success] 桩%d 枪%d 停止成功.... \r\n", i + 1, g + 1);
|
||||
}
|
||||
else if (gun->charger_state == FAIL_CHARGER_STOP_STATE)
|
||||
{
|
||||
USB_Printf("状态机:[error] 桩%d 枪%d 停止失败.... \r\n", i + 1, g + 1);
|
||||
}
|
||||
else if (gun->charger_state == CHARGER_STATE_CHARGE_DONE)
|
||||
{
|
||||
printf("状态机:[success] 桩%d 枪%d 计费数据已发送,充电完成.... \r\n", i + 1, g + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Core/User/App/task_ykc.h
Normal file
11
Core/User/App/task_ykc.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef __TASK_YKC_H
|
||||
#define __TASK_YKC_H
|
||||
|
||||
/* includes ----------------------------------------------------------------------------------------------*/
|
||||
#include "global.h"
|
||||
#include "drv_air724.h"
|
||||
|
||||
void ykc_task_function(void const *argument);
|
||||
void ykc_timer_callback_function(TimerHandle_t xTimer);
|
||||
|
||||
#endif /* __TASK_YKC_H */
|
||||
Reference in New Issue
Block a user