first commit

This commit is contained in:
liyp
2025-12-24 15:26:06 +08:00
commit a7eb3fb3d9
756 changed files with 189958 additions and 0 deletions

28
Src/CanReceiveTask.cpp Normal file
View File

@@ -0,0 +1,28 @@
#include "CanReceiveTask.h"
// 一个任务函数C 风格
void Task1(void* param) {
while (true) {
std::cout << "Task1 running\n";
vTaskDelay(1000); // 延时 1000ms
}
}
// 另一个任务函数
void Task2(void* param) {
while (true) {
std::cout << "Task2 running\n";
vTaskDelay(500); // 延时 500ms
}
}
void CanRecive(void)
{
// 创建“任务”,用 std::thread 代替 FreeRTOS 任务
std::thread t1(Task1, nullptr);
std::thread t2(Task2, nullptr);
// 如果想模拟 FreeRTOS通常任务一直运行主函数也可以阻塞
t1.join();
t2.join();
}

214
Src/SocketApiProtocol.cpp Normal file
View File

@@ -0,0 +1,214 @@
#include <time.h>
#include "SocketApiProtocol.h"
#define RECV_BUFFER_SIZE 26 //接收缓冲区大小
#define PKG_CORE_STATUS 0x00 //读取核心状态
#define PKG_CAN_STATUS 0x01 //CAN盒子状态
#define PKG_TRANS_CAN 0x02 //收发CAN包
#define PKG_CTRL_GET 0xFF //取得控制权限
#define LOG_LEN 512 //日志长度
static asio::io_context io_ctx; //udp上下文
static std::unique_ptr<asio::ip::udp::socket> udp_socket; //socket
asio::ip::udp::endpoint remote_endpoint; //socket remote
std::string RemoteIpStr; //socket remote ip str
uint8_t recv_buffer[RECV_BUFFER_SIZE] = {0x00}; //接收缓冲区
uint8_t send_buffer[RECV_BUFFER_SIZE] = {0x00}; //发送缓冲区
char TimeBuff[64] = {0x00}; //时间缓冲区
char StatusLogBuff[LOG_LEN] = {0x00}; //状态日志缓冲区
char SendLogBuff[LOG_LEN] = {0x00}; //发包日志缓冲区
time_t now; //当前时间戳
struct tm* t; //当前时间
void SocketApiProtocolRun(void);
void start_receive(void);
void UdpAnalysis(uint8_t* RxData);
int UdpSendData(const char* ip, uint16_t port, const uint8_t* data, size_t len);
void CallBackCoreStatus(uint8_t* RxData,uint8_t* TxData);
void SocketApiProtocolInit(uint32_t SocketPort)
{
udp_socket = std::make_unique<asio::ip::udp::socket>(
io_ctx,
asio::ip::udp::endpoint(asio::ip::udp::v4(), SocketPort)
);
if(udp_socket && udp_socket->is_open())
{
std::cout << "[UDP] Listening successfully" << std::endl;
}
else
{
std::cerr << "[UDP] Socket not open" << std::endl;
}
std::thread UdpReceiveTask(SocketApiProtocolRun);
UdpReceiveTask.detach();
start_receive(); // 注册第一次接收
std::cout << "[UDP] Listening on port " << SocketPort << std::endl;
}
void start_receive(void)
{
udp_socket->async_receive_from(
asio::buffer(recv_buffer, RECV_BUFFER_SIZE),
remote_endpoint,
[](const asio::error_code& ec, std::size_t bytes_recvd)
{
if(!ec && bytes_recvd == RECV_BUFFER_SIZE && recv_buffer[0] == 0x55 && recv_buffer[RECV_BUFFER_SIZE - 1] == 0xAA)
{
RemoteIpStr = remote_endpoint.address().to_string();
UdpAnalysis(recv_buffer);
}
// 再次注册接收,保持持续监听
start_receive();
}
);
}
void transTimeToData(uint8_t* TxData, struct tm* t)
{
uint8_t data[7] = {0x00};
data[0] = t->tm_year & 0xFF;
data[1] = (t->tm_year >> 8) & 0xFF;
data[2] = t->tm_mon;
data[3] = t->tm_wday;
data[4] = t->tm_hour;
data[5] = t->tm_min;
data[6] = t->tm_sec;
memcpy(TxData,data,7);
}
void UdpAnalysis(uint8_t* RxData)
{
int command = RxData[1];
if (SystemCall.logEn == ENABLE)
{
now = time(NULL); // 获取当前时间戳从1970-01-01秒数
t = localtime(&now); // 转成本地时间
t->tm_year+=1900;
sprintf(TimeBuff,"%d-%d-%d.log",t->tm_year,t->tm_mon,t->tm_wday);
}
memset(send_buffer,0x00,RECV_BUFFER_SIZE);
/* 添加报文头尾 */
send_buffer[0] = 0x55;
send_buffer[RECV_BUFFER_SIZE - 1] = 0xAA;
switch(command)
{
case PKG_CORE_STATUS:
if (SystemCall.logEn == ENABLE)
{
memset(StatusLogBuff,0x00,LOG_LEN);
sprintf(StatusLogBuff,"[%04d-%02d-%02d-%02d-%02d-%02d]:Get Core Status",t->tm_year
,t->tm_mon
,t->tm_wday
,t->tm_hour
,t->tm_min
,t->tm_sec);
logAdd(TimeBuff,StatusLogBuff);
}
CallBackCoreStatus(RxData, send_buffer);
break;
case PKG_CAN_STATUS:
break;
case PKG_TRANS_CAN:
break;
case PKG_CTRL_GET:
//获取控制权限收到哪个ip的包哪个ip就属于主控主控接收所有Core发送的报文
if (SystemCall.logEn == ENABLE)
{
memset(StatusLogBuff,0x00,LOG_LEN);
sprintf(StatusLogBuff,"[%04d-%02d-%02d-%02d-%02d-%02d]:Get Ctrl Access %s",t->tm_year
,t->tm_mon
,t->tm_wday
,t->tm_hour
,t->tm_min
,t->tm_sec
,RemoteIpStr.c_str());
//还需要把ip加上
logAdd(TimeBuff,StatusLogBuff);
}
memcpy(send_buffer,RxData,RECV_BUFFER_SIZE);
break;
}
//如果调试使能,则回包加入时间
if (SystemCall.logEn == ENABLE)
{
transTimeToData(&send_buffer[2],t);
}
//回包
UdpSendData(RemoteIpStr.c_str(), 12346, send_buffer, RECV_BUFFER_SIZE);
//调试使能就记录一下,记录使用队列保证不影响收发
if (SystemCall.logEn == ENABLE)
{
memset(SendLogBuff,0x00,LOG_LEN);
sprintf(SendLogBuff,"[%04d-%02d-%02d-%02d-%02d-%02d]:Send Pkg ",t->tm_year
,t->tm_mon
,t->tm_wday
,t->tm_hour
,t->tm_min
,t->tm_sec);
char *p = &SendLogBuff[31];
for (int i = 0; i < RECV_BUFFER_SIZE; i++) {
p += sprintf(p, "0x%02X ", send_buffer[i]); // ← 关键在这里
}
if (SystemCall.logEn == ENABLE)
{
logAdd(TimeBuff,SendLogBuff);
}
}
}
void CallBackCoreStatus(uint8_t* RxData, uint8_t* TxData)
{
uint8_t data[4] = {0x00};
data[0] = SystemCall.ProductInfo; //产品信息
data[1] = SystemCall.CanOpenStatus[0]; //通道0打开状态
data[2] = SystemCall.CanOpenStatus[1]; //通道1打开状态
data[3] = SystemCall.logEn; //日志启用状态
memcpy(&TxData[9],data,4);
}
int UdpSendData(const char* ip, uint16_t port, const uint8_t* data, size_t len)
{
if(!udp_socket) return 0;
asio::error_code ec;
asio::ip::udp::endpoint remote(asio::ip::make_address(ip), port);
size_t sent = udp_socket->send_to(asio::buffer(data, len), remote, 0, ec);
if(ec)
{
if (SystemCall.logEn == ENABLE)
{
printf("[UDP] Send failed: %s\n", ec.message().c_str());
}
return 0;
}
return 1;
}
// 让你的系统循环运行 ASIO
void SocketApiProtocolRun(void)
{
io_ctx.run();
}

48
Src/System.cpp Normal file
View File

@@ -0,0 +1,48 @@
#include "System.h"
SystemConfig SystemCall;
// 在线程池中执行文件操作
static asio::thread_pool pool(2); // 线程专门处理文件I/O
void SystemCallInit(void)
{
SystemCall.ProductInfo = 0xFF;
SystemCall.logEn = ENABLE;
SystemCall.CanOpenStatus[0] = DISABLE;
SystemCall.CanOpenStatus[1] = DISABLE;
}
void logAdd(const std::string& filename, const std::string& content) {
asio::post(pool, [filename, content]() {
std::ofstream file;
try {
// 以追加模式打开文件
file.open(filename, std::ios::app | std::ios::out);
if (!file.is_open()) {
throw std::runtime_error("Cannot open file: " + filename);
}
// 写入内容(追加换行符)
file << content << std::endl;
if (file.fail()) {
throw std::runtime_error("Write failed");
}
//std::cout << "Successfully appended to file: " << filename << std::endl;
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
});
// 注意pool会在作用域结束时join
// 如果需要保持运行可以将pool作为成员变量
}
// 模拟 FreeRTOS 的延时
void vTaskDelay(TickType_t ms)
{
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
}

62
Src/main.cpp Normal file
View File

@@ -0,0 +1,62 @@
#include "CanReceiveTask.h" /* CAN接收任务 */
#include "SocketApiProtocol.h"
#define LISTEN_PORT 12345 //监听端口
int SearchPreProcess(void);
void KillPreProcess(void);
int main() {
//此程序必须只有一个进程在运行
while (SearchPreProcess() == ENABLE)
{
//杀死上一个进程
KillPreProcess();
std::cout<< "Kill Pre Process" <<std::endl;
//等待进程里面的socket和内存被释放
Sleep(500);
}
//系统参数和回调初始化
SystemCallInit();
//监听SOCKET端口
SocketApiProtocolInit(LISTEN_PORT);
//打印一下
std::cout << "Program Run Success" << std::endl;
//阻塞一下
getchar();
return 0;
}
//查找是否有本程序的进程在运行
int SearchPreProcess(void)
{
char cmd[512];
DWORD currentPID = GetCurrentProcessId();
// 查找同名进程,但排除自己
snprintf(cmd, sizeof(cmd),
"tasklist | findstr \"UniversalCanCore.exe\" | findstr /v \"%lu\" > nul",
currentPID);
return system(cmd) == 0 ? ENABLE : DISABLE;
}
//杀死同名进程以及上一个进程
void KillPreProcess(void)
{
char cmd[256];
DWORD currentPID = GetCurrentProcessId();
// 查找并杀死除了自己以外的同名进程
snprintf(cmd, sizeof(cmd),
"for /f \"tokens=2\" %%a in ('tasklist ^| findstr \"UniversalCanCore.exe\"') do if not %%a==%lu taskkill /F /PID %%a",
currentPID);
system(cmd);
}