工程提交
This commit is contained in:
30
Core/User/Driver/drv_init.c
Normal file
30
Core/User/Driver/drv_init.c
Normal file
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file user\driver\drv_init.c
|
||||
* @author luhuaishuai
|
||||
* @version v0.1
|
||||
* @date 2026-1-12
|
||||
* @brief Briefly describe the function of your function
|
||||
******************************************************************************
|
||||
*/
|
||||
/* Includes -------------------------------------------------------------------*/
|
||||
#include "drv_init.h"
|
||||
// crc16_modbus.c
|
||||
#include <stdint.h>
|
||||
|
||||
/* code -----------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief drv_all_Init:所有传感器、外设芯片、外部设备初始化
|
||||
*
|
||||
* @note none
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @retval none
|
||||
*/
|
||||
|
||||
void drv_all_Init(void)
|
||||
{
|
||||
AIR724_RESET(); /* AIR724 复位 */
|
||||
}
|
||||
15
Core/User/Driver/drv_init.h
Normal file
15
Core/User/Driver/drv_init.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef __DRVINIT_H
|
||||
#define __DRVINIT_H
|
||||
|
||||
|
||||
/* includes ----------------------------------------------------------------------------------------------*/
|
||||
#include "global.h"
|
||||
|
||||
|
||||
|
||||
/* Exported functions prototypes ------------------------------------------------------------------------*/
|
||||
void drv_all_Init(void);
|
||||
|
||||
|
||||
#endif /* __DRVINIT_H */
|
||||
|
||||
46
Core/User/Global/g_dcpile.c
Normal file
46
Core/User/Global/g_dcpile.c
Normal file
@@ -0,0 +1,46 @@
|
||||
#include "g_dcpile.h"
|
||||
|
||||
/*全局充电桩管理器*/
|
||||
ChargerManager g_charger_manager = {0};
|
||||
|
||||
/*充电桩序列号*/
|
||||
const uint8_t piles_serial[6][7] = {
|
||||
{0x32, 0x01, 0x06, 0x01, 0x11, 0x15, 0x58},
|
||||
{0x32, 0x01, 0x06, 0x01, 0x11, 0x16, 0x54},
|
||||
{0x88, 0x26, 0x01, 0x13, 0x12, 0x00, 0x01},
|
||||
{0x88, 0x26, 0x01, 0x13, 0x12, 0x00, 0x02},
|
||||
{0x88, 0x26, 0x01, 0x13, 0x12, 0x00, 0x03},
|
||||
{0x88, 0x26, 0x01, 0x13, 0x12, 0x00, 0x04},
|
||||
{0x88, 0x26, 0x01, 0x13, 0x12, 0x00, 0x05},
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 初始化充电桩管理器
|
||||
* @note 初始化充电桩管理器,设置充电桩数量和每个充电桩的初始状态
|
||||
*/
|
||||
void init_chargers(void) {
|
||||
g_charger_manager.charger_count = 6;
|
||||
|
||||
for (int i = 0; i < g_charger_manager.charger_count; i++) {
|
||||
ChargerPile *ctx = &g_charger_manager.charger_piles[i];
|
||||
|
||||
memcpy(ctx->login_info.charger_serial, piles_serial[i], 7);
|
||||
ctx->get_model = false;
|
||||
ctx->is_udp_online = false;
|
||||
ctx->login_info.charger_type = CHARGER_TYPE_DC;
|
||||
ctx->login_info.gun_num = 2;
|
||||
ctx->login_info.protocol_ver = 0x10; // V1.6
|
||||
strcpy((char*)ctx->login_info.software_ver, "V4.1.50");
|
||||
ctx->login_info.net_conn_type = 0; // SIM
|
||||
memset(ctx->login_info.sim, 0, 10);
|
||||
ctx->login_info.tele_factory = 0x00; // 移动
|
||||
|
||||
// 初始化枪
|
||||
for (int g = 0; g < ctx->login_info.gun_num && g < MAX_GUN_PER_CHARGER; g++) {
|
||||
ctx->guns[g].gun_index = g + 1;
|
||||
ctx->guns[g].status = 0; // 正常
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
47
Core/User/Global/g_dcpile.h
Normal file
47
Core/User/Global/g_dcpile.h
Normal file
@@ -0,0 +1,47 @@
|
||||
|
||||
#ifndef __DC_PILE_H
|
||||
#define __DC_PILE_H
|
||||
|
||||
/* includes ----------------------------------------------------------------------------------------------*/
|
||||
#include "global.h"
|
||||
|
||||
#define MAX_CHARGER_COUNT 6 // 充电桩数量
|
||||
#define MAX_GUN_PER_CHARGER 2 // 每个充电桩最多枪数
|
||||
|
||||
/* 充电枪结构体*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t gun_index; // 枪索引
|
||||
bool is_changing; // 是否正在充电
|
||||
bool is_plugged; // 是否已插入枪
|
||||
bool is_gun_returned; // 是否已返回枪
|
||||
uint8_t status; // 状态
|
||||
PACK_DATA_0X13 real_time_data; // 实时数据
|
||||
} ChargerGun;
|
||||
|
||||
/* 单个充电桩结构体*/
|
||||
typedef struct
|
||||
{
|
||||
PACK_DATA_0X01 login_info;
|
||||
bool is_online; //云快充是否连接
|
||||
bool is_udp_online; //是否本地在线
|
||||
bool get_model;
|
||||
uint16_t last_heartbeat_time; // 最后一次心跳时间
|
||||
|
||||
ChargerGun guns[MAX_GUN_PER_CHARGER]; // 充电枪数组
|
||||
|
||||
} ChargerPile;
|
||||
|
||||
/*全局充电桩管理结构体*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t charger_count; // 桩索引
|
||||
ChargerPile charger_piles[MAX_CHARGER_COUNT]; // 充电桩数组
|
||||
FEE_MODEL fee_model_global ; //全局计费模型
|
||||
} ChargerManager;
|
||||
|
||||
extern ChargerManager g_charger_manager;
|
||||
|
||||
void init_chargers(void); //初始化全局充电桩
|
||||
|
||||
#endif /* __DC_PILE_H */
|
||||
28
Core/User/Global/g_init.c
Normal file
28
Core/User/Global/g_init.c
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file user\global\g_init.c
|
||||
* @author luhuaishuai
|
||||
* @version v0.1
|
||||
* @date 2026-1-12
|
||||
* @brief Briefly describe the function of your function
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "g_init.h"
|
||||
|
||||
/* Includes -------------------------------------------------------------------*/
|
||||
#include "drv_init.h"
|
||||
#include "_hal_init.h"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief 初始化全局系统
|
||||
* @note 初始化全局系统,包括HAL层和驱动层的初始化
|
||||
*/
|
||||
void g_Init(void)
|
||||
{
|
||||
_hal_all_Init();
|
||||
drv_all_Init();
|
||||
}
|
||||
|
||||
13
Core/User/Global/g_init.h
Normal file
13
Core/User/Global/g_init.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef __GINIT_H
|
||||
#define __GINIT_H
|
||||
|
||||
|
||||
|
||||
|
||||
/* Exported functions prototypes ------------------------------------------------------------------------*/
|
||||
void g_Init(void);
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* __GINIT_H */
|
||||
91
Core/User/Global/g_runtime.c
Normal file
91
Core/User/Global/g_runtime.c
Normal file
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file user\global\g_runtime.c
|
||||
* @author luhuaishuai
|
||||
* @version v0.1
|
||||
* @date 2026-1-12
|
||||
* @brief Briefly describe the function of your function
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes -------------------------------------------------------------------*/
|
||||
#include "g_runtime.h"
|
||||
|
||||
|
||||
|
||||
|
||||
/* variables ------------------------------------------------------------------*/
|
||||
TaskRunTimeTypeDef TaskRunTimeStat;
|
||||
|
||||
|
||||
|
||||
/* code -----------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief GetRunTime:计算线程运行间隔时间
|
||||
*
|
||||
* @note none
|
||||
*
|
||||
* @param taskID : 任务ID
|
||||
*
|
||||
* @retval runtime : 任务周期
|
||||
*/
|
||||
|
||||
uint32_t GetTask_RunTime(uint8_t taskID)
|
||||
{
|
||||
static uint32_t lasttime[Task_combined] = {0};
|
||||
|
||||
uint32_t runtime = 0;
|
||||
uint32_t curtime = HAL_GetTick();
|
||||
|
||||
runtime = curtime - lasttime[taskID]; //计算线程运行间隔时间 runtime运行一次
|
||||
|
||||
lasttime[taskID] = curtime;
|
||||
|
||||
return runtime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief GetTask_Beatcnt:线程运行计数,用于判断线程是否在运行
|
||||
*
|
||||
* @note none
|
||||
*
|
||||
* @param taskID : 任务ID
|
||||
*
|
||||
* @retval beatcnt[taskID] : 线程运行计数
|
||||
*/
|
||||
|
||||
uint32_t GetTask_Beatcnt(uint8_t taskID)
|
||||
{
|
||||
static uint8_t beatcnt[Task_combined] = {0};
|
||||
|
||||
beatcnt[taskID]++;
|
||||
|
||||
if(beatcnt[taskID] >= 10)
|
||||
{
|
||||
beatcnt[taskID] = 0;
|
||||
}
|
||||
|
||||
return beatcnt[taskID];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get_Free_Stack:获取剩余任务栈大小
|
||||
*
|
||||
* @note none
|
||||
*
|
||||
* @param taskID : 任务ID
|
||||
*
|
||||
* @retval free_stack[taskID] : 剩余任务栈大小
|
||||
*/
|
||||
|
||||
uint32_t Get_Free_Stack(uint8_t taskID)
|
||||
{
|
||||
static uint32_t free_stack[Task_combined] = {0};
|
||||
|
||||
free_stack[taskID] = uxTaskGetStackHighWaterMark(NULL);
|
||||
|
||||
return free_stack[taskID];
|
||||
}
|
||||
59
Core/User/Global/g_runtime.h
Normal file
59
Core/User/Global/g_runtime.h
Normal file
@@ -0,0 +1,59 @@
|
||||
|
||||
#ifndef __GRUNTIME_H
|
||||
#define __GRUNTIME_H
|
||||
|
||||
|
||||
/* includes ----------------------------------------------------------------------------------------------*/
|
||||
#include "global.h"
|
||||
|
||||
|
||||
|
||||
/* macro ------------------------------------------------------------------------------------------------*/
|
||||
#define Task_combined 8
|
||||
|
||||
|
||||
|
||||
|
||||
/* struct ------------------------------------------------------------------------------------------------*/
|
||||
typedef struct TaskRunTime
|
||||
{
|
||||
uint32_t threads_runtime; // 运行时间
|
||||
uint32_t threads_counter; // 任务计数
|
||||
uint32_t threads_freestack; // 剩余栈空间
|
||||
|
||||
} TaskRunTime;
|
||||
|
||||
|
||||
|
||||
enum Task_ID
|
||||
{
|
||||
HeartBeatTaskID = 0,
|
||||
DownLinkTaskID,
|
||||
UPLinkTaskID,
|
||||
YkcTaskID,
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
typedef struct TaskRunTimeTypeDef
|
||||
{
|
||||
TaskRunTime HeartBeatTask;
|
||||
TaskRunTime DownLinkTask;
|
||||
TaskRunTime UPLinkTask;
|
||||
TaskRunTime YkcTask;
|
||||
|
||||
} TaskRunTimeTypeDef;
|
||||
|
||||
|
||||
|
||||
/* Exported functions prototypes ------------------------------------------------------------------------*/
|
||||
uint32_t GetTask_RunTime(uint8_t taskID);
|
||||
uint32_t GetTask_Beatcnt(uint8_t taskID);
|
||||
uint32_t Get_Free_Stack(uint8_t taskID);
|
||||
|
||||
/* Exported constants -----------------------------------------------------------------------------------*/
|
||||
extern TaskRunTimeTypeDef TaskRunTimeStat;
|
||||
|
||||
|
||||
#endif /* __GRUNTIME_H */
|
||||
119
Core/User/Global/global.h
Normal file
119
Core/User/Global/global.h
Normal file
@@ -0,0 +1,119 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file user\global\global.h
|
||||
* @author liangky
|
||||
* @version v0.1
|
||||
* @date 2023-10-11
|
||||
* @brief Briefly describe the function of your function
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef __GLOBAL_H
|
||||
#define __GLOBAL_H
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
|
||||
/* C 语言标准库 */
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
|
||||
/* CubeMX生成 */
|
||||
#include "main.h"
|
||||
// #include "iwdg.h"
|
||||
#include "usart.h"
|
||||
#include "gpio.h"
|
||||
|
||||
// #include "tim.h"
|
||||
|
||||
/* freeRTOS 相关 */
|
||||
#include "cmsis_os.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
#include "semphr.h"
|
||||
#include "event_groups.h"
|
||||
#include "stream_buffer.h"
|
||||
|
||||
/* Os */
|
||||
#include "os_task.h"
|
||||
#include "os_queue.h"
|
||||
#include "os_semaphore.h"
|
||||
|
||||
/* GL */
|
||||
#include "g_runtime.h"
|
||||
#include "server_to_charger.h"
|
||||
#include "g_dcpile.h"
|
||||
|
||||
/* _hal */
|
||||
#include "_hal_usart.h"
|
||||
|
||||
/* driver */
|
||||
#include "cJSON.h"
|
||||
#include "server_common.h"
|
||||
#include "charger_to_server.h"
|
||||
|
||||
/* macro ------------------------------------------------------------------------------------------------*/
|
||||
#define ON 1
|
||||
#define OFF 0
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
#define PI 3.1415926f
|
||||
|
||||
#define SOFTWARE_VERSION "JSBRv1.2" // 软件版本
|
||||
#define YKC_VERSION 0x10 // YKC 协议版本 v1.6
|
||||
|
||||
#define NET_CONN_TYPE 0 // 0: 4G, 1: LAN
|
||||
|
||||
#define DEBUG 1 // 调试模式
|
||||
|
||||
/*- I/O 输出-*/
|
||||
|
||||
#define AIR724_RESET() \
|
||||
do \
|
||||
{ \
|
||||
HAL_GPIO_WritePin(AIR724_REWST_GPIO_Port, AIR724_REWST_Pin, GPIO_PIN_SET); \
|
||||
uint32_t i = 60000000; \
|
||||
while (i--) \
|
||||
__nop; \
|
||||
HAL_GPIO_WritePin(AIR724_REWST_GPIO_Port, AIR724_REWST_Pin, GPIO_PIN_RESET); \
|
||||
} while (0) /* System Run Led */
|
||||
|
||||
#define RS485_EN(x) \
|
||||
do \
|
||||
{ \
|
||||
x ? HAL_GPIO_WritePin(RS485_EN_GPIO_Port, RS485_EN_Pin, GPIO_PIN_SET) : HAL_GPIO_WritePin(RS485_EN_GPIO_Port, RS485_EN_Pin, GPIO_PIN_RESET); \
|
||||
} while (0) /* RS485 EN Led */
|
||||
|
||||
#define System_Mode_Led(x) \
|
||||
do \
|
||||
{ \
|
||||
x ? HAL_GPIO_WritePin(System_Mode_Led_GPIO_Port, System_Mode_Led_Pin, GPIO_PIN_SET) : HAL_GPIO_WritePin(System_Mode_Led_GPIO_Port, System_Mode_Led_Pin, GPIO_PIN_RESET); \
|
||||
} while (0) /* System Run Led */
|
||||
#define System_Mode_Led_Toggle() HAL_GPIO_TogglePin(System_Mode_Led_GPIO_Port, System_Mode_Led_Pin)
|
||||
|
||||
#define System_Run_Led(x) \
|
||||
do \
|
||||
{ \
|
||||
x ? HAL_GPIO_WritePin(System_Run_Led_GPIO_Port, System_Run_Led_Pin, GPIO_PIN_SET) : HAL_GPIO_WritePin(System_Run_Led_GPIO_Port, System_Run_Led_Pin, GPIO_PIN_RESET); \
|
||||
} while (0) /* System Run Led */
|
||||
#define System_Run_Led_Toggle() HAL_GPIO_TogglePin(System_Run_Led_GPIO_Port, System_Run_Led_Pin) /* System Run Led */
|
||||
|
||||
#define YT8512_RST(x) \
|
||||
do \
|
||||
{ \
|
||||
x ? HAL_GPIO_WritePin(YT8512_RST_GPIO_Port, YT8512_RST_Pin, GPIO_PIN_SET) : HAL_GPIO_WritePin(YT8512_RST_GPIO_Port, YT8512_RST_Pin, GPIO_PIN_RESET); \
|
||||
} while (0) /* System Run Led */
|
||||
|
||||
/*- I/O 输入-*/
|
||||
|
||||
#define get_sys_time_msec() HAL_GetTick()
|
||||
|
||||
#define CONSTRAIN(x, max, min) (x > max ? max : (x < min ? min : x))
|
||||
|
||||
#endif /* __GLOBAL_H */
|
||||
33
Core/User/Hal/_hal_init.c
Normal file
33
Core/User/Hal/_hal_init.c
Normal file
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file user\hal\_hal_init.c
|
||||
* @author luhuaishuai
|
||||
* @version v0.1
|
||||
* @date 2026-1-12
|
||||
* @brief Briefly describe the function of your function
|
||||
******************************************************************************
|
||||
*/
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "_hal_init.h"
|
||||
|
||||
|
||||
/* code -----------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @funNm
|
||||
* @brief
|
||||
* @param
|
||||
*/
|
||||
/**
|
||||
* @brief _hal_all_Init:所有外设接口初始化
|
||||
*
|
||||
* @note none
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @retval none
|
||||
*/
|
||||
void _hal_all_Init(void)
|
||||
{
|
||||
hal_usart_Init();
|
||||
}
|
||||
13
Core/User/Hal/_hal_init.h
Normal file
13
Core/User/Hal/_hal_init.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef __HALINIT_H
|
||||
#define __HALINIT_H
|
||||
|
||||
/* includes ----------------------------------------------------------------------------------------------*/
|
||||
#include "global.h"
|
||||
|
||||
|
||||
|
||||
/* Exported functions prototypes ------------------------------------------------------------------------*/
|
||||
void _hal_all_Init(void);
|
||||
|
||||
#endif /* __HALINIT_H */
|
||||
|
||||
133
Core/User/Hal/_hal_usart.c
Normal file
133
Core/User/Hal/_hal_usart.c
Normal file
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file user\hal\_hal_usart.c
|
||||
* @author luhuaishuai
|
||||
* @version v0.1
|
||||
* @date 2026-1-12
|
||||
* @brief Briefly describe the function of your function
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes -------------------------------------------------------------------*/
|
||||
#include "_hal_usart.h"
|
||||
|
||||
/* variables ------------------------------------------------------------------*/
|
||||
uint8_t uart1_rx_buffer[UART1_RX_BUFFER_SIZE];
|
||||
uint8_t uart1_tx_buffer[UART1_TX_BUFFER_SIZE];
|
||||
|
||||
uint8_t uart3_rx_buffer[UART3_RX_BUFFER_SIZE];
|
||||
uint8_t uart3_tx_buffer[UART3_TX_BUFFER_SIZE];
|
||||
|
||||
/* code -----------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief fputc:printf映射
|
||||
*
|
||||
* @note none
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @retval none
|
||||
*/
|
||||
|
||||
int fputc(int ch, FILE *f)
|
||||
{
|
||||
HAL_UART_Transmit(&huart6, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
|
||||
return ch;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Air724_Message_Send:4G数据发送
|
||||
*
|
||||
* @note none
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @retval none
|
||||
*/
|
||||
void Air724_Message_Send(uint8_t *data, uint16_t len)
|
||||
{
|
||||
HAL_UART_Transmit(&huart1, data, len, HAL_MAX_DELAY);
|
||||
}
|
||||
|
||||
void Rs485_Message_Send(uint8_t *data, uint16_t len)
|
||||
{
|
||||
RS485_EN(1);
|
||||
HAL_UART_Transmit(&huart3, data, len, HAL_MAX_DELAY);
|
||||
RS485_EN(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief _hal_usart_Init:所有串口初始化
|
||||
*
|
||||
* @note none
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @retval none
|
||||
*/
|
||||
|
||||
void hal_usart_Init(void)
|
||||
{
|
||||
|
||||
/* 初始化串口1 */
|
||||
Air724_Message_Queue_Init(); // 初始化4G数据接收队列
|
||||
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
|
||||
HAL_UART_Receive_DMA(&huart1, uart1_rx_buffer, UART1_RX_BUFFER_SIZE);
|
||||
|
||||
/* 初始化串口3 */
|
||||
RS485_Message_Queue_Init(); // 初始化RS485数据接收队列
|
||||
__HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE);
|
||||
HAL_UART_Receive_DMA(&huart3, uart3_rx_buffer, UART3_RX_BUFFER_SIZE);
|
||||
|
||||
RS485_EN(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief HAL_UARTEx_RxEventCallback:串口接收完成中断处理函数
|
||||
*
|
||||
* @note none
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @retval none
|
||||
*/
|
||||
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
|
||||
{
|
||||
if (huart->Instance == USART1)
|
||||
{
|
||||
SCB_InvalidateDCache_by_Addr((uint32_t *)uart1_rx_buffer, UART1_RX_BUFFER_SIZE);
|
||||
air724_callback_fun();
|
||||
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, (uint8_t *)uart1_rx_buffer, UART1_RX_BUFFER_SIZE);
|
||||
}
|
||||
else if (huart->Instance == USART3)
|
||||
{
|
||||
SCB_InvalidateDCache_by_Addr((uint32_t *)uart3_rx_buffer, UART3_RX_BUFFER_SIZE);
|
||||
rs485_callback_fun();
|
||||
HAL_UARTEx_ReceiveToIdle_DMA(&huart3, (uint8_t *)uart3_rx_buffer, UART3_RX_BUFFER_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief air724_callback_fun:4G数据接收回调函数
|
||||
*
|
||||
* @note none
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @retval none
|
||||
*/
|
||||
void air724_callback_fun()
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
xQueueSendFromISR(Air724_Message_Queue, uart1_rx_buffer, &xHigherPriorityTaskWoken);
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
memset(uart1_rx_buffer, 0, UART1_RX_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
void rs485_callback_fun()
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
xQueueSendFromISR(RS485_Message_Queue, uart3_rx_buffer, &xHigherPriorityTaskWoken);
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
memset(uart3_rx_buffer, 0, UART3_RX_BUFFER_SIZE);
|
||||
}
|
||||
35
Core/User/Hal/_hal_usart.h
Normal file
35
Core/User/Hal/_hal_usart.h
Normal file
@@ -0,0 +1,35 @@
|
||||
|
||||
#ifndef __HALUSART_H
|
||||
#define __HALUSART_H
|
||||
|
||||
/* Suppress warning messages */
|
||||
#if defined(__CC_ARM)
|
||||
// Suppress warning message: extended constant initialiser used
|
||||
#pragma diag_suppress 1296
|
||||
#elif defined(__ICCARM__)
|
||||
#elif defined(__GNUC__)
|
||||
#endif
|
||||
|
||||
/* includes ----------------------------------------------------------------------------------------------*/
|
||||
#include "global.h"
|
||||
|
||||
/* macro ------------------------------------------------------------------------------------------------*/
|
||||
#define UART1_TX_BUFFER_SIZE 512
|
||||
#define UART1_RX_BUFFER_SIZE 512
|
||||
|
||||
#define UART3_TX_BUFFER_SIZE 256
|
||||
#define UART3_RX_BUFFER_SIZE 256
|
||||
|
||||
/* global variable ---------------------------------------------------------------------------------------*/
|
||||
extern uint8_t uart1_rx_buffer[UART1_RX_BUFFER_SIZE];
|
||||
extern uint8_t uart1_tx_buffer[UART1_TX_BUFFER_SIZE];
|
||||
|
||||
extern uint8_t uart3_rx_buffer[UART3_RX_BUFFER_SIZE];
|
||||
extern uint8_t uart3_tx_buffer[UART3_TX_BUFFER_SIZE];
|
||||
/* function prototype ------------------------------------------------------------------------------------*/
|
||||
extern void hal_usart_init(void);
|
||||
extern void air724_callback_fun(void);
|
||||
extern void rs485_callback_fun(void);
|
||||
extern void Air724_Message_Send(uint8_t *data, uint16_t len);
|
||||
extern void Rs485_Message_Send(uint8_t *data, uint16_t len);
|
||||
#endif /* __HALUSART_H */
|
||||
32
Core/User/Os/os_init.c
Normal file
32
Core/User/Os/os_init.c
Normal file
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file user\os\os_init.c
|
||||
* @author luhuaishuai
|
||||
* @version v0.1
|
||||
* @date 2026-1-12
|
||||
* @brief Briefly describe the function of your function
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/* Includes -------------------------------------------------------------------*/
|
||||
#include "os_init.h"
|
||||
|
||||
|
||||
/* code -----------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Os_Init:所有系统相关初始化
|
||||
*
|
||||
* @note none
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @retval none
|
||||
*/
|
||||
void Os_Init(void)
|
||||
{
|
||||
|
||||
Os_Semaphore_Init();
|
||||
Os_Task_Init();
|
||||
}
|
||||
|
||||
16
Core/User/Os/os_init.h
Normal file
16
Core/User/Os/os_init.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef __OSINIT_H
|
||||
#define __OSINIT_H
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
#include "global.h"
|
||||
|
||||
|
||||
|
||||
/* Exported functions prototypes ------------------------------------------------------------------------*/
|
||||
void Os_Init(void);
|
||||
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
#endif
|
||||
|
||||
53
Core/User/Os/os_queue.c
Normal file
53
Core/User/Os/os_queue.c
Normal file
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file user\os\os_queue.c
|
||||
* @author luhuaishuai
|
||||
* @version v0.1
|
||||
* @date 2026-1-12
|
||||
* @brief Briefly describe the function of your function
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes -------------------------------------------------------------------*/
|
||||
#include "os_queue.h"
|
||||
#include "ChargerTask.h"
|
||||
|
||||
/*-内核对象句柄-队列-*/
|
||||
QueueHandle_t Air724_Message_Queue = NULL; /* 4G数据接收队列 */
|
||||
QueueHandle_t RS485_Message_Queue = NULL; /* RS485数据接收队列 */
|
||||
QueueHandle_t UDP_Message_Queue = NULL; /* UDP数据接收队列 */
|
||||
|
||||
/* code --------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
void Air724_Message_Queue_Init(void)
|
||||
{
|
||||
Air724_Message_Queue = xQueueCreate(5, UART1_RX_BUFFER_SIZE);
|
||||
if (Air724_Message_Queue == NULL)
|
||||
{
|
||||
printf("Air724_Message_Queue_Init Failed\r\n");
|
||||
// 创建失败处理
|
||||
Error_Handler();
|
||||
}
|
||||
}
|
||||
|
||||
void RS485_Message_Queue_Init(void)
|
||||
{
|
||||
RS485_Message_Queue = xQueueCreate(5, UART3_RX_BUFFER_SIZE);
|
||||
if (RS485_Message_Queue == NULL)
|
||||
{
|
||||
// 创建失败处理
|
||||
printf("RS485_Message_Queue_Init error\r\n");
|
||||
Error_Handler();
|
||||
}
|
||||
}
|
||||
|
||||
void UDP_Message_Queue_Init(void)
|
||||
{
|
||||
UDP_Message_Queue = xQueueCreate(5, sizeof(UdpMsg_t));
|
||||
if (UDP_Message_Queue == NULL)
|
||||
{
|
||||
// 创建失败处理
|
||||
printf("UDP_Message_Queue_Init Failed\r\n");
|
||||
Error_Handler();
|
||||
}
|
||||
}
|
||||
28
Core/User/Os/os_queue.h
Normal file
28
Core/User/Os/os_queue.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef __OSQUEUE_H
|
||||
#define __OSQUEUE_H
|
||||
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
|
||||
#include "global.h"
|
||||
|
||||
|
||||
|
||||
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
void Air724_Message_Queue_Init(void);
|
||||
void RS485_Message_Queue_Init(void);
|
||||
void UDP_Message_Queue_Init(void);
|
||||
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
extern QueueHandle_t Air724_Message_Queue;
|
||||
extern QueueHandle_t RS485_Message_Queue;
|
||||
extern QueueHandle_t UDP_Message_Queue;
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
54
Core/User/Os/os_semaphore.c
Normal file
54
Core/User/Os/os_semaphore.c
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file user\os\os_queue.c
|
||||
* @author luhuaishuai
|
||||
* @version v0.1
|
||||
* @date 2026-1-12
|
||||
* @brief Briefly describe the function of your function
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes -------------------------------------------------------------------*/
|
||||
#include "os_semaphore.h"
|
||||
|
||||
|
||||
/*-内核对象句柄-信号量-*/
|
||||
|
||||
|
||||
|
||||
/*-函数声明-*/
|
||||
void xMutex_Semaphore_Create(void);
|
||||
|
||||
|
||||
/* code -----------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Os_Semaphore_Init:所有信号量相关初始化
|
||||
*
|
||||
* @note none
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @retval none
|
||||
*/
|
||||
void Os_Semaphore_Init(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief xMutex_Semaphore_Create:互斥信号量初始化
|
||||
*
|
||||
* @note none
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @retval none
|
||||
*/
|
||||
void xMutex_Semaphore_Create(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
22
Core/User/Os/os_semaphore.h
Normal file
22
Core/User/Os/os_semaphore.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef __OSSEMAPHORE_H
|
||||
#define __OSSEMAPHORE_H
|
||||
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
|
||||
#include "global.h"
|
||||
|
||||
|
||||
|
||||
/* Exported functions prototypes ------------------------------------------------------------------------*/
|
||||
void Os_Semaphore_Init(void);
|
||||
|
||||
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
extern SemaphoreHandle_t PC_tx_xMutex_Handle;
|
||||
extern SemaphoreHandle_t Usart6_xMutex_Handle;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
97
Core/User/Os/os_task.c
Normal file
97
Core/User/Os/os_task.c
Normal file
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file user\os\os_task.c
|
||||
* @author luhuaishuai
|
||||
* @version v0.1
|
||||
* @date 2026-1-12
|
||||
* @brief Briefly describe the function of your function
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes -------------------------------------------------------------------*/
|
||||
#include "os_task.h"
|
||||
|
||||
/*-任务句柄-*/
|
||||
osThreadId HeartbeatTaskHandle; /* 心跳任务句柄 */
|
||||
|
||||
osThreadId UDPTaskHandle; /* UDP 消息队列接受任务句柄 */
|
||||
|
||||
osThreadId UDP_ParseTaskHandle; /* UDP 消息队列解析任务句柄 */
|
||||
|
||||
osThreadId DownLinkTaskHandle; /* 4G接收消息任务句柄 */
|
||||
|
||||
osThreadId YkcTaskHandle; /* 云快充平台交互任务句柄 */
|
||||
|
||||
/*-函数声明-*/
|
||||
void HeartbeatTask_Function(void const *argument); // 心跳任务
|
||||
|
||||
void UDPTask_Function(void const *argument); // UDP 接受任务
|
||||
|
||||
void UDP_ParseTask_Function(void const *argument); //UDP消息解析任务
|
||||
|
||||
void YkcTask_Function(void const *argument); // 云快充平台交互任务
|
||||
|
||||
void DownLinkTask_Function(void const *argument); // 4G接收消息任务
|
||||
|
||||
/* code -----------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Os_Task_Init:所有任务的创建
|
||||
*
|
||||
* @note definition and creation of xxxTask
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @retval none
|
||||
*/
|
||||
|
||||
void Os_Task_Init(void) /*任务入口函数、任务名字、任务栈大小、任务入口函数参数、任务优先级、任务控制块指针*/
|
||||
{
|
||||
BaseType_t xReturn = pdPASS;
|
||||
|
||||
/* 心跳任务 */
|
||||
xReturn = xTaskCreate((TaskFunction_t)HeartbeatTask_Function, "HeartbeatTask", 128, NULL, (UBaseType_t)osPriorityLow, &HeartbeatTaskHandle);
|
||||
|
||||
/* 4G消息解析任务 */
|
||||
xReturn = xTaskCreate((TaskFunction_t)DownLinkTask_Function, "DownLinkTask", 1024, NULL, osPriorityAboveNormal, &DownLinkTaskHandle);
|
||||
|
||||
/* UDP 消息队列接受任务 */
|
||||
xReturn = xTaskCreate((TaskFunction_t)UDPTask_Function, "UDPTask", 512, NULL, osPriorityAboveNormal, &UDPTaskHandle);
|
||||
|
||||
/* UDP 消息解析任务 */
|
||||
xReturn = xTaskCreate((TaskFunction_t)UDP_ParseTask_Function, "UDPParseTask", 1024, NULL, osPriorityAboveNormal, &UDP_ParseTaskHandle);
|
||||
|
||||
/* 云快充平台交互任务 */
|
||||
xReturn = xTaskCreate((TaskFunction_t)YkcTask_Function, "YKCTask", 1024, NULL, osPriorityAboveNormal, &YkcTaskHandle);
|
||||
|
||||
if (xReturn == pdPASS)
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------Function implementing the xxxTask thread----------------------------------------*/
|
||||
|
||||
__weak void HeartbeatTask_Function(void const *argument)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
osDelay(1);
|
||||
}
|
||||
}
|
||||
|
||||
__weak void DownLinkTask_Function(void const *argument)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
osDelay(1);
|
||||
}
|
||||
}
|
||||
|
||||
__weak void UPLinkTask_Function(void const *argument)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
osDelay(1);
|
||||
}
|
||||
}
|
||||
22
Core/User/Os/os_task.h
Normal file
22
Core/User/Os/os_task.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef __OSTASK_H
|
||||
#define __OSTASK_H
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
|
||||
#include "global.h"
|
||||
|
||||
/* Exported functions prototypes ------------------------------------------------------------------------*/
|
||||
void Os_Task_Init(void);
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
extern osThreadId HeartbeatTaskHandle; /* 心跳任务句柄 */
|
||||
|
||||
extern osThreadId UDPTaskHandle; /* UDP 消息队列接受任务句柄 */
|
||||
|
||||
extern osThreadId UDP_ParseTaskHandle; /* UDP 消息队列解析任务句柄 */
|
||||
|
||||
extern osThreadId DownLinkTaskHandle; /* 消息任务句柄 */
|
||||
|
||||
extern osThreadId YkcTaskHandle; /* 云快充平台交互任务句柄 */
|
||||
|
||||
#endif
|
||||
235
Core/User/Task/ChargerTask.c
Normal file
235
Core/User/Task/ChargerTask.c
Normal file
@@ -0,0 +1,235 @@
|
||||
#include "ChargerTask.h"
|
||||
|
||||
static struct netconn *datalink_conn; // 数据链路句柄
|
||||
#define LINK_SERVER_PORT 6001 // 网关UDP服务端口
|
||||
#define LINK_STAKE_PORT 6001 // 桩通讯端口
|
||||
|
||||
/**
|
||||
* @brief 桩IP地址
|
||||
* @note 桩IP地址从10.12.19.101开始递增
|
||||
*/
|
||||
ip4_addr_t stake_ip_1 = IPADDR4_INIT_BYTES(10, 12, 19, 101); // 桩1IP地址
|
||||
ip4_addr_t stake_ip_2 = IPADDR4_INIT_BYTES(10, 12, 19, 102); // 桩2IP地址
|
||||
ip4_addr_t stake_ip_3 = IPADDR4_INIT_BYTES(10, 12, 19, 103); // 桩3IP地址
|
||||
ip4_addr_t stake_ip_4 = IPADDR4_INIT_BYTES(10, 12, 19, 104); // 桩4IP地址
|
||||
ip4_addr_t stake_ip_5 = IPADDR4_INIT_BYTES(10, 12, 19, 105); // 桩5IP地址
|
||||
ip4_addr_t stake_ip_6 = IPADDR4_INIT_BYTES(10, 12, 19, 106); // 桩6IP地址
|
||||
|
||||
/**
|
||||
* @brief UDP发送
|
||||
* @note 发送数据到指定桩
|
||||
* @param stake_index 目标桩ID
|
||||
* @param data 数据指针
|
||||
* @param len 数据长度
|
||||
* @return err_t 错误码
|
||||
*/
|
||||
err_t udp_send_response(uint8_t stake_index, uint8_t *data, u16_t len)
|
||||
{
|
||||
struct netbuf *buf = netbuf_new();
|
||||
if (!buf)
|
||||
{
|
||||
printf("[%s] %d\n", __func__, __LINE__);
|
||||
return ERR_MEM;
|
||||
}
|
||||
ip4_addr_t *dst_ip = NULL;
|
||||
switch (stake_index)
|
||||
{
|
||||
case 1:
|
||||
dst_ip = &stake_ip_1;
|
||||
break;
|
||||
case 2:
|
||||
dst_ip = &stake_ip_2;
|
||||
break;
|
||||
case 3:
|
||||
dst_ip = &stake_ip_3;
|
||||
break;
|
||||
case 4:
|
||||
dst_ip = &stake_ip_4;
|
||||
break;
|
||||
case 5:
|
||||
dst_ip = &stake_ip_5;
|
||||
break;
|
||||
case 6:
|
||||
dst_ip = &stake_ip_6;
|
||||
break;
|
||||
default:
|
||||
printf("Invalid stake index\r\n");
|
||||
return;
|
||||
}
|
||||
netbuf_ref(buf, data, len);
|
||||
err_t err = netconn_sendto(datalink_conn, buf, dst_ip, LINK_STAKE_PORT);
|
||||
netbuf_delete(buf);
|
||||
return err;
|
||||
}
|
||||
|
||||
void UDP_ParseTask_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;
|
||||
handle_udp_downlink((uint8_t)id->valueint, cmd_str, root);
|
||||
cJSON_Delete(root);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Missing 'code' field\r\n");
|
||||
cJSON_Delete(root);
|
||||
}
|
||||
vPortFree(msg.data);
|
||||
msg.data = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UPLinkTask_Function:桩通讯任务
|
||||
*
|
||||
* @note none
|
||||
*
|
||||
* @param taskID : 任务ID
|
||||
*
|
||||
* @retval runtime : 任务周期
|
||||
*/
|
||||
|
||||
void UDPTask_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(DownLinkTaskHandle);
|
||||
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 解析充电桩上电指令
|
||||
* @note 设置桩为本地在线状态,发送上电应答
|
||||
* @param stake_index 桩索引
|
||||
* @param json_pack json数据包
|
||||
*/
|
||||
void local_on_cmd_callback_power_on(uint8_t stake_index, cJSON *json_pack)
|
||||
{
|
||||
if (stake_index > 6)
|
||||
{
|
||||
return;
|
||||
}
|
||||
g_charger_manager.charger_piles[stake_index - 1].is_udp_online = true; // 设置桩为本地在线状态
|
||||
|
||||
cJSON *root = NULL;
|
||||
char *str = NULL;
|
||||
|
||||
root = cJSON_CreateObject();
|
||||
if (root == NULL)
|
||||
{
|
||||
printf("Failed to create JSON object for stake %d\r\n", stake_index);
|
||||
return;
|
||||
}
|
||||
|
||||
/* 添加一条字符串类型的JSON数据(添加一个链表节点) */
|
||||
cJSON_AddNumberToObject(root, "id", stake_index);
|
||||
cJSON_AddStringToObject(root, "cmd", "power_on");
|
||||
cJSON_AddNumberToObject(root, "code", 1);
|
||||
|
||||
str = cJSON_Print(root);
|
||||
udp_send_response(stake_index, str, strlen(str));
|
||||
free(str);
|
||||
cJSON_Delete(root);
|
||||
|
||||
printf("电桩 %d 上电报文\r\n", stake_index);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 解析充电桩计费模型请求指令
|
||||
* @note 获取云快充下发的计费模型,回复给充电桩
|
||||
* @param stake_index 桩索引
|
||||
* @param json_pack json数据包
|
||||
*/
|
||||
void local_on_cmd_callback_get_billing_model(uint8_t stake_index, cJSON *json_pack)
|
||||
{
|
||||
if (stake_index > 6)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void handle_udp_downlink(uint8_t id, const char *cmd, cJSON *json_pack)
|
||||
{
|
||||
if (cmd == NULL)
|
||||
return;
|
||||
if (strcmp(cmd, "power_on") == 0)
|
||||
{
|
||||
local_on_cmd_callback_power_on(id, json_pack);
|
||||
}
|
||||
else if (strcmp(cmd, "get_billing_model") == 0)
|
||||
{
|
||||
local_on_cmd_callback_get_billing_model(id, json_pack);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Unknown CMD: '%s' from ID %d\r\n", cmd, id);
|
||||
}
|
||||
}
|
||||
30
Core/User/Task/ChargerTask.h
Normal file
30
Core/User/Task/ChargerTask.h
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
#ifndef __CHARGERTASK_H
|
||||
#define __CHARGERTASK_H
|
||||
|
||||
/* includes ----------------------------------------------------------------------------------------------*/
|
||||
#include "global.h"
|
||||
#include "lwip/opt.h"
|
||||
#include "lwip/api.h"
|
||||
#include "lwip/sys.h"
|
||||
|
||||
/* macro ------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/* struct ------------------------------------------------------------------------------------------------*/
|
||||
// 定义UDP消息体
|
||||
typedef struct {
|
||||
ip4_addr_t src_ip; // 来源IP
|
||||
uint16_t src_port; // 来源端口
|
||||
uint16_t len; // 数据长度
|
||||
char *data; // 数据指针(动态分配)
|
||||
} UdpMsg_t;
|
||||
|
||||
|
||||
//void Charger_Task_Init(void);
|
||||
void handle_udp_downlink(uint8_t id, const char *cmd, cJSON *json_pack);
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* __CHARGERTASK_H */
|
||||
|
||||
104
Core/User/Task/DatalinkTask.c
Normal file
104
Core/User/Task/DatalinkTask.c
Normal file
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file user\task\DatalinkTask.c
|
||||
* @author luhuaishuai
|
||||
* @version v0.1
|
||||
* @date 2026-1-12
|
||||
* @brief 数据链路任务,负责处理与云快充的通信
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "DataLinkTask.h"
|
||||
#include "YkcTask.h"
|
||||
#include "lwip/opt.h"
|
||||
#include "lwip/api.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "httpd.h"
|
||||
|
||||
/* typedef --------------------------------------------------------------------*/
|
||||
|
||||
/* variables ------------------------------------------------------------------*/
|
||||
|
||||
/* code -----------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief DownLinkTask_Function:
|
||||
*
|
||||
* @note none
|
||||
*
|
||||
* @param taskID : 任务ID
|
||||
*
|
||||
* @retval runtime : 任务周期
|
||||
*/
|
||||
|
||||
void DownLinkTask_Function(void const *argument)
|
||||
{
|
||||
|
||||
uint8_t air724_rx_msg[UART1_RX_BUFFER_SIZE];
|
||||
uint8_t rs485_rx_msg[UART3_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];
|
||||
|
||||
printf("Raw Bytes: ");
|
||||
for (int i = 0; i < ykc_downlink_frame_len; i++)
|
||||
{
|
||||
printf("%02X ", ykc_downlink_frame[i]);
|
||||
if ((i + 1) % 16 == 0) // 每16字节换行
|
||||
{
|
||||
printf("\r");
|
||||
}
|
||||
}
|
||||
printf("\r");
|
||||
|
||||
handle_ykc_downlink(charger_index, &frame);
|
||||
|
||||
vPortFree(frame.data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (xQueueReceive(RS485_Message_Queue, &rs485_rx_msg, 10) == pdPASS)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("rs-485_rx_msg: %s", rs485_rx_msg);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
18
Core/User/Task/DatalinkTask.h
Normal file
18
Core/User/Task/DatalinkTask.h
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
#ifndef __DATALINKTASK_H
|
||||
#define __DATALINKTASK_H
|
||||
|
||||
/* includes ----------------------------------------------------------------------------------------------*/
|
||||
#include "global.h"
|
||||
|
||||
/* macro ------------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/* struct ------------------------------------------------------------------------------------------------*/
|
||||
|
||||
void DataLink_Task_Init(void);
|
||||
|
||||
|
||||
|
||||
#endif /* __DATALINKTASK_H */
|
||||
|
||||
96
Core/User/Task/HeartBeatTask.c
Normal file
96
Core/User/Task/HeartBeatTask.c
Normal file
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file user\task\HeartBeatTask.c
|
||||
* @author luhuaishuai
|
||||
* @version v0.1
|
||||
* @date 2026-1-12
|
||||
* @brief 心跳任务,负责发送心跳包和处理云快充的响应
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "HeartBeatTask.h"
|
||||
|
||||
void HeartBeat_Sign(void);
|
||||
|
||||
/**
|
||||
* @brief 发送显示数据
|
||||
* @note 发送显示数据,包括充电桩的连接状态和工作状态
|
||||
*/
|
||||
void Send_Display_Data(void)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
char str[128];
|
||||
sprintf(str, "t1.bco=%s\xff\xff\xfft2.bco=%s\xff\xff\xfft3.bco=%s\xff\xff\xfft4.bco=%s\xff\xff\xfft5.bco=%s\xff\xff\xfft6.bco=%s\xff\xff\xff",
|
||||
g_charger_manager.charger_piles[0].is_udp_online ? "GREEN" : "RED",
|
||||
g_charger_manager.charger_piles[1].is_udp_online ? "GREEN" : "RED",
|
||||
g_charger_manager.charger_piles[2].is_udp_online ? "GREEN" : "RED",
|
||||
g_charger_manager.charger_piles[3].is_udp_online ? "GREEN" : "RED",
|
||||
g_charger_manager.charger_piles[4].is_udp_online ? "GREEN" : "RED",
|
||||
g_charger_manager.charger_piles[5].is_udp_online ? "GREEN" : "RED");
|
||||
Rs485_Message_Send(str, strlen(str));
|
||||
|
||||
sprintf(str, "t7.bco=%s\xff\xff\xfft8.bco=%s\xff\xff\xfft9.bco=%s\xff\xff\xfft10.bco=%s\xff\xff\xfft11.bco=%s\xff\xff\xfft12.bco=%s\xff\xff\xff",
|
||||
g_charger_manager.charger_piles[0].is_online ? "GREEN" : "RED",
|
||||
g_charger_manager.charger_piles[1].is_online ? "GREEN" : "RED",
|
||||
g_charger_manager.charger_piles[2].is_online ? "GREEN" : "RED",
|
||||
g_charger_manager.charger_piles[3].is_online ? "GREEN" : "RED",
|
||||
g_charger_manager.charger_piles[4].is_online ? "GREEN" : "RED",
|
||||
g_charger_manager.charger_piles[5].is_online ? "GREEN" : "RED");
|
||||
Rs485_Message_Send(str, strlen(str));
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @funNm : HeartbeatTask_Function
|
||||
* @brief : 心跳
|
||||
* @param : argument
|
||||
* @retval: void
|
||||
*/
|
||||
void HeartbeatTask_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
|
||||
*/
|
||||
void HeartBeat_Sign(void)
|
||||
{
|
||||
if (g_charger_manager.charger_piles[0].is_online)
|
||||
{
|
||||
RUN_EVERY(8000, tick_A, {
|
||||
charger_to_server_0X03(1, 1, 0);
|
||||
});
|
||||
RUN_EVERY(100, 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();
|
||||
});
|
||||
RUN_EVERY(500, tick_E, {
|
||||
Send_Display_Data();
|
||||
});
|
||||
}
|
||||
22
Core/User/Task/HeartBeatTask.h
Normal file
22
Core/User/Task/HeartBeatTask.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef __HEATBEATTASK_H
|
||||
#define __HEATBEATTASK_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 /* __HEATBEATTASK_H */
|
||||
101
Core/User/Task/YkcTask.c
Normal file
101
Core/User/Task/YkcTask.c
Normal file
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file user\task\HeartBeatTask.c
|
||||
* @author luhuaishuai
|
||||
* @version v0.1
|
||||
* @date 2026-1-12
|
||||
* @brief Briefly describe the function of your function
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
#include "YkcTask.h"
|
||||
#include "lwip/opt.h"
|
||||
#include "lwip/api.h"
|
||||
#include "lwip/sys.h"
|
||||
|
||||
/**
|
||||
* @funNm : YkcTask_Function
|
||||
* @brief : 云快充平台交互任务
|
||||
* @param : argument
|
||||
* @retval: void
|
||||
*/
|
||||
|
||||
uint8_t SETP = 0;
|
||||
|
||||
void YkcTask_Function(void const *argument)
|
||||
{
|
||||
init_chargers(); /* 初始化桩结构体*/
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY); /* 等待桩通讯协议层完成*/
|
||||
while (1)
|
||||
{
|
||||
TaskRunTimeStat.YkcTask.threads_runtime = GetTask_RunTime(YkcTaskID);
|
||||
TaskRunTimeStat.YkcTask.threads_counter = GetTask_Beatcnt(YkcTaskID);
|
||||
TaskRunTimeStat.YkcTask.threads_freestack = Get_Free_Stack(YkcTaskID);
|
||||
|
||||
switch (SETP)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
if (!g_charger_manager.charger_piles[1 - 1].is_online)
|
||||
{
|
||||
charger_to_server_0X01(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
SETP = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
if (!g_charger_manager.charger_piles[1 - 1].get_model)
|
||||
charger_to_server_0X09(1); // 桩1计费模型请求
|
||||
else
|
||||
SETP = 2;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
charger_to_server_0X13(1, 1); // 上传状态
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
osDelay(2000);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 解析云快充平台下行数据
|
||||
* @note 解析云快充平台下行数据,根据不同的帧类型调用相应的处理函数
|
||||
* @param stake_mark 桩编号
|
||||
* @param pack 指向SERVER_PACK结构体的指针,包含下行数据
|
||||
*/
|
||||
void handle_ykc_downlink(uint8_t stake_mark, SERVER_PACK *pack)
|
||||
{
|
||||
switch (pack->frame_type)
|
||||
{
|
||||
case FRAME_TYPE_0X02:
|
||||
on_cmd_frame_type_0X02(stake_mark, pack);
|
||||
break;
|
||||
case FRAME_TYPE_0X04:
|
||||
on_cmd_frame_type_0X04(stake_mark, pack);
|
||||
break;
|
||||
case FRAME_TYPE_0X06:
|
||||
on_cmd_frame_type_0X06(stake_mark, pack);
|
||||
break;
|
||||
case FRAME_TYPE_0X0A:
|
||||
on_cmd_frame_type_0X0A(stake_mark, pack);
|
||||
break;
|
||||
case FRAME_TYPE_0X58:
|
||||
on_cmd_frame_type_0X58(stake_mark, pack);
|
||||
break;
|
||||
case FRAME_TYPE_0X34:
|
||||
on_cmd_frame_type_0X34(stake_mark, pack);
|
||||
break;
|
||||
}
|
||||
}
|
||||
11
Core/User/Task/YkcTask.h
Normal file
11
Core/User/Task/YkcTask.h
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
#ifndef __YKCTASK_H
|
||||
#define __YKCTASK_H
|
||||
|
||||
/* includes ----------------------------------------------------------------------------------------------*/
|
||||
#include "global.h"
|
||||
|
||||
void handle_ykc_downlink(uint8_t stake_mark, SERVER_PACK *pack);
|
||||
|
||||
|
||||
#endif /* __YKCTASK_H */
|
||||
0
Core/User/Task/新建 文本文档 (2).txt
Normal file
0
Core/User/Task/新建 文本文档 (2).txt
Normal file
0
Core/User/Task/新建 文本文档.txt
Normal file
0
Core/User/Task/新建 文本文档.txt
Normal file
Reference in New Issue
Block a user