Files
1CAR/interface_ethernet.c
2025-10-21 19:13:44 +08:00

708 lines
24 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdbool.h>
#include <stdio.h>
#include "debug.h"
#include <string.h>
#include <udelay/udelay.h>
#include "interface_ethernet.h"
#include "eth_cfg.h"
#include "lwip/timeouts.h"
#include "sdrv_eth.h"
#include "app/app_param_manage.h"
#include "app/app_differential_drive.h"
//参数管理
#define MAX_BUFFER_SIZE (sizeof(((RequestContext *)0)->param_request->arr))
#define MAX_PACKET_SIZE 1024 // 定义最大包大小为1K
Timer ethernet_timer_interface;
Timer ethernet_timer_interface1;
struct udp_pcb *udpcb_1;
struct udp_pcb *udpcb_2;
struct udp_pcb *udpcb_3;
struct udp_pcb *udpcb_4;
struct udp_pcb *udpcb_5;
bool eth_pool_rx = false;
UnEthernetFault ethernet_fault_Info = {
.bit_data.auto_count = 0,
.bit_data.manual_count = 0,
.bit_data.auto_state = 0,
.bit_data.manual_state = 0,
};
StrEthernetParameter ethernet_parameter = {
.local_ip = {192,168,17,20},
.mask = {255,255,255,0},
.computer_ip = {192,168,17,3},
.local_communication_port = 8011,
.Local_upper_port = 8000,
.Local_download_port = 7811,
.upper_ip = {192,168,17,3},
.download_ip = {192,168,17,183},
.target_upper_port = 8000,
.target_download_port = 7811,
.target_communication_port = 8011,
};
static bool g_eth1_rx_pkt;
static void eth_dma_rx_int_cb(struct net_driver_s *dev)
{
if (dev == &g_eth1_dev)
g_eth1_rx_pkt = true;
// printf("eth_dma_rx_int_cb\n");
}
static void lwip_Ethernet(void *signal_id)
{
// uint32_t time_boot = getCurrentTime();//记录当前时间
(void)signal_id; // 标记变量为已使用,避免编译器警告
// 接收ETH帧并传递给LWIP协议栈
// 如果使能接收中断因为ISR里会disable接收中断因此这里对于
// 中断接收标志(g_eth1_rx_pkt)的处理过程中不会有
// 新的接收中断被响应,所以,这里不存在原子性问题。
if ((!eth_pool_rx && g_eth1_rx_pkt) || eth_pool_rx)
{
g_eth1_rx_pkt = false;
dwc_eth_rx(&g_eth1_dev, eth_pool_rx);
}
// LWIP协议栈接口用于做LWIP超时检测
sys_check_timeouts();
timerStart(&ethernet_timer_interface1, 10,1); //10ms调用一次
// printf("lwipInterface spend time:%d\n",getCurrentTime() - time_boot);//检查app用了多长时间
}
//err_t
//udp_bind(struct udp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port)
int8_t UdpSendToData(uint8_t udpcbID, uint8_t *buf, uint16_t len, uint8_t *sip, uint16_t port)
{
struct pbuf *DesPuff = NULL;
ip4_addr_t Desaddr;
int8_t SendState = 0;
//----------------------------------------------------------------------------------------------------
IP4_ADDR(&Desaddr,sip[0],sip[1],sip[2],sip[3]);//地址值转换
DesPuff = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_POOL); /* 申请内存 */
pbuf_take(DesPuff, buf, len); /* 将g_lwip_demo_sendbuf中的数据打包进pbuf结构中 */
if(UDPCB_1 == udpcbID)
{
SendState = udp_sendto(udpcb_1, DesPuff, &Desaddr, port);
}
else if(UDPCB_2 == udpcbID)
{
SendState = udp_sendto(udpcb_2, DesPuff, &Desaddr, port);
}
else if(UDPCB_3 == udpcbID)
{
SendState = udp_sendto(udpcb_3, DesPuff, &Desaddr, port);
}
else if(UDPCB_3 == udpcbID)
{
SendState = udp_sendto(udpcb_3, DesPuff, &Desaddr, port);
}
else if(UDPCB_4 == udpcbID)
{
SendState = udp_sendto(udpcb_4, DesPuff, &Desaddr, port);
}
else if(UDPCB_5 == udpcbID)
{
SendState = udp_sendto(udpcb_5, DesPuff, &Desaddr, port);
}
else
{
}
pbuf_free(DesPuff); /* 释放内存 */
return SendState;
}
// udpcbID UDP索引
//recv 回调函数
//port 绑定端口
void UDP_Echo_Init(uint8_t udpcbID, udp_recv_fn recv, uint16_t port)
{
//------------------------------------------
if(UDPCB_1 == udpcbID)
{
/* 新建一个控制块*/
udpcb_1 = udp_new();
ASSERT(udpcb_1);
/* 绑定端口号 */
udp_bind(udpcb_1, IP_ADDR_ANY, port);
/* 注册接收数据回调函数 */
udp_recv(udpcb_1, recv, (void *)udpcbID);
}
else if(UDPCB_2 == udpcbID)
{
/* 新建一个控制块*/
udpcb_2 = udp_new();
ASSERT(udpcb_2);
/* 绑定端口号 */
udp_bind(udpcb_2, IP_ADDR_ANY, port);
/* 注册接收数据回调函数 */
udp_recv(udpcb_2, recv, (void *)udpcbID);
}
else if(UDPCB_3 == udpcbID)
{
/* 新建一个控制块*/
udpcb_3 = udp_new();
ASSERT(udpcb_3);
/* 绑定端口号 */
udp_bind(udpcb_3, IP_ADDR_ANY, port);
/* 注册接收数据回调函数 */
udp_recv(udpcb_3, recv, (void *)udpcbID);
}
else if(UDPCB_4 == udpcbID)
{
/* 新建一个控制块*/
udpcb_4 = udp_new();
ASSERT(udpcb_4);
/* 绑定端口号 */
udp_bind(udpcb_4, IP_ADDR_ANY, port);
/* 注册接收数据回调函数 */
udp_recv(udpcb_4, recv, (void *)udpcbID);
}
else if(UDPCB_5 == udpcbID)
{
/* 新建一个控制块*/
udpcb_5 = udp_new();
ASSERT(udpcb_5);
/* 绑定端口号 */
udp_bind(udpcb_5, IP_ADDR_ANY, port);
/* 注册接收数据回调函数 */
udp_recv(udpcb_5, recv, (void *)udpcbID);
}
else
{
}
}
void udp_Callback_1(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
{
uint8_t *buf = (uint8_t *)(p->payload);
uint16_t i = 0;
uint16_t len = 0;
uint16_t udp_temp = 0;
//------------------------------------------------------------------------------
// uint8_t ip_addr[4] = {0,0,0,0};
//
// ip_addr[0] = addr->addr & 0xff; /* IADDR4 */
// ip_addr[1] = (addr->addr >> 8) & 0xff; /* IADDR3 */
// ip_addr[2] = (addr->addr >> 16) & 0xff; /* IADDR2 */
// ip_addr[3] = (addr->addr >> 24) & 0xff; /* IADDR1 */
if( (0xFF == buf[0] ) && ( 0xBB == buf[1] ) )//自主计算机手动遥控器或者远程遥控器
{
ethernet_fault_Info.bit_data.manual_count ++;
if( (p->len) >= sizeof(UnManualComputerInput) )//如果读取长度超过,就取最小长度
{
len = sizeof(UnManualComputerInput);
}
else
{
len = p->len;
}
for(i = 0; i < len; i++)
{
un_manual_computer_input.arr[i] = buf[i];
}
publishMessage(&un_manual_computer_input, 1);
// p->len = len;
// printf("Manualrecive len:%d\n",len);
// udp_sendto(upcb, p, addr, port);
}
else if( (0xFF == buf[0] ) && (0xCC == buf[1] ) )//自主计算器 自动
{
ethernet_fault_Info.bit_data.auto_count ++;
if( (p->len) >= sizeof(UnAutoComputerInput) )//如果读取长度超过,就取最小长度
{
len = sizeof(UnAutoComputerInput);
}
else
{
len = p->len;
}
// unsigned int frame_header : 16; // 帧头 固定值0xFFCC
// unsigned int frame_type : 16; // 帧类型 固定值0x0001
// unsigned int frame_length : 8; // 帧长 固定值0x19
// unsigned int heartbeat : 8; // 心跳 按帧累加
// unsigned int set_speed : 16; // 设定速度 系数0.01,正为前进,负为后退 单位m/s
// unsigned int set_curvature : 16; // 设定曲率 系数0.0001,正为左转,负为右转
// unsigned int latitude : 32; // 纬度 系数10^-7431234567表示43.1234567度
// unsigned int longitude : 32; // 经度 系数10^-7431234567表示43.1234567度
// unsigned int altitude : 32; // 高度 单位mm
// unsigned int heading : 16; // 航向 车辆航向35999表示359.99度
// unsigned int crc : 8; // CRC 按字节累加之和溢出取低8位
for(i = 0; i < len; i++)
{
un_auto_computer_input.arr[i] = buf[i];
}
udp_temp = ((un_auto_computer_input.bit_data.set_speed << 8) | (un_auto_computer_input.bit_data.set_speed >> 8));//设定速度 20240928 修改高低位交换
un_auto_computer_input.bit_data.set_speed = udp_temp;
udp_temp = ((un_auto_computer_input.bit_data.set_curvature << 8) | (un_auto_computer_input.bit_data.set_curvature >> 8));//设定曲率
un_auto_computer_input.bit_data.set_curvature = udp_temp;
publishMessage(&un_auto_computer_input, 1);
// p->len = len;
// printf("Autorecive len:%d\n",len);
// udp_sendto(upcb, p, addr, port);
}
else if( (0xFF == buf[0] ) && ( 0x12 == buf[1] ) )
{
if( (p->len) >= sizeof(un_computer_turnable_Input) )//如果读取长度超过,就取最小长度
{
len = sizeof(un_computer_turnable_Input);
}
else
{
len = p->len;
}
for(i = 0; i < len; i++)
{
un_computer_turnable_Input.arr[i] = buf[i];
// printf("%d", un_computer_turnable_Input.arr[i]); // 以16进制打印适合二进制数据
}
publishMessage(&un_computer_turnable_Input, 1);
// // 打印PITCH电机CAN数据
// printf("un_computer_turnable_Input - ID: 0x%08X, Data: ", buf->id);
// for(i = 0; i < 8; i++) {
// printf("%02X ", buf->dataBuffer[i]);
// }
// printf("\n");
}
else{}
pbuf_free(p);
}
void udp_Callback_2(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
{
uint8_t *buf = (uint8_t *)(p->payload);
uint8_t ip_addr[4] = {0,0,0,0};
//------------------------------------------------------------------------------------------------
ip_addr[0] = addr->addr & 0xff; /* IADDR4 */
ip_addr[1] = (addr->addr >> 8) & 0xff; /* IADDR3 */
ip_addr[2] = (addr->addr >> 16) & 0xff; /* IADDR2 */
ip_addr[3] = (addr->addr >> 24) & 0xff; /* IADDR1 */
ethernet_parameter.target_upper_port = port;//保存接收到的端口和IP下次发送对应的IP和端口
ethernet_parameter.upper_ip[0] = ip_addr[0];
ethernet_parameter.upper_ip[1] = ip_addr[1];
ethernet_parameter.upper_ip[2] = ip_addr[2];
ethernet_parameter.upper_ip[3] = ip_addr[3];
if( (0x80 == buf[0]) && (0x00 == buf[1]) )
{
memcpy((uint8_t *)&(un_request_frame.arr[0]),buf, sizeof(UnRequestFrame));
publishMessage(&un_request_frame, 1);
}
pbuf_free(p);
}
void udp_Callback_4(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
{
uint8_t *buf = (uint8_t *)(p->payload);
uint8_t ip_addr[4] = {0,0,0,0};
//------------------------------------------------------------------------------------------------
//20250822 增加保存刷写上位机IP
ip_addr[0] = addr->addr & 0xff; /* IADDR4 */
ip_addr[1] = (addr->addr >> 8) & 0xff; /* IADDR3 */
ip_addr[2] = (addr->addr >> 16) & 0xff; /* IADDR2 */
ip_addr[3] = (addr->addr >> 24) & 0xff; /* IADDR1 */
ethernet_parameter.download_ip[0] = ip_addr[0];
ethernet_parameter.download_ip[1] = ip_addr[1];
ethernet_parameter.download_ip[2] = ip_addr[2];
ethernet_parameter.download_ip[3] = ip_addr[3];
boot_eth_flag = true;
FrameHeader = ( (buf[0] << 8) | (buf[1]) );
printf("FrameHeader %d\n",FrameHeader);
pbuf_free(p);
}
void udp_Callback_5(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
{
uint8_t *buf = (uint8_t *)(p->payload);
//------------------------------------------------------------------------------------------------
if(FEEDDOG_HEADER == ( (buf[0] << 8) | (buf[1]) ))
{
WDTReFresh_flag = true;//更新喂狗标志
printf("Feed dog flag received %d\n",getCurrentTime());
}
pbuf_free(p);
}
//100ms 调用一次
void ethernetTimerProcess(void)
{
static uint8_t ethernet_timer = 0;
static uint8_t ethernet_temp[4] = {0,0,0,0};//中间判断值
uint8_t temp = 0;
ethernet_timer ++;
if(ethernet_timer >= 5)//500ms判断一次
{
ethernet_timer = 0;
//自主计算机故障判断------------------------------------------------------------
if(ethernet_fault_Info.bit_data.auto_count == ethernet_temp[0])//数据一样表示故障
{
ethernet_fault_Info.bit_data.auto_state = FAULT;
}
else
{
ethernet_fault_Info.bit_data.auto_state = NORMAL;
ethernet_temp[0] = ethernet_fault_Info.bit_data.auto_count;//数据更新
}
if(ethernet_fault_Info.bit_data.auto_state != ethernet_temp[1])
{
ethernet_temp[1] = ethernet_fault_Info.bit_data.auto_state;
temp ++;
}
//手动故障判断------------------------------------------------------------
if(ethernet_fault_Info.bit_data.manual_count == ethernet_temp[2])//数据一样表示故障
{
ethernet_fault_Info.bit_data.manual_state = FAULT;
}
else
{
ethernet_fault_Info.bit_data.manual_state = NORMAL;
ethernet_temp[2] = ethernet_fault_Info.bit_data.manual_count;//数据更新
}
if(ethernet_fault_Info.bit_data.manual_state != ethernet_temp[3])
{
ethernet_temp[3] = ethernet_fault_Info.bit_data.manual_state;
temp ++;
}
}
publishMessage(&ethernet_fault_Info, 1);// 状态变化 发送信号
}
static void vehicleInfOoutput(void *signal_id)
{
(void)signal_id; // 标记变量为已使用,避免编译器警告
UdpSendToData(UDPCB_2,(uint8_t *)(&un_vehicle_Info_output), sizeof(un_vehicle_Info_output), (uint8_t *)&ethernet_parameter.upper_ip[0], ethernet_parameter.target_upper_port);
}
static void motorStatusOutput(void *signal_id)
{
(void)signal_id; // 标记变量为已使用,避免编译器警告
UdpSendToData(UDPCB_2,(uint8_t *)(&un_motor_status_output), sizeof(un_motor_status_output), (uint8_t *)&ethernet_parameter.upper_ip[0], ethernet_parameter.target_upper_port);
}
static void pidOutput(void *signal_id)
{
(void)signal_id; // 标记变量为已使用,避免编译器警告
UdpSendToData(UDPCB_2,(uint8_t *)(&un_pid_output), sizeof(un_pid_output), (uint8_t *)&ethernet_parameter.upper_ip[0], ethernet_parameter.target_upper_port);
}
static void remoteControlOutput(void *signal_id)
{
(void)signal_id; // 标记变量为已使用,避免编译器警告
UdpSendToData(UDPCB_2,(uint8_t *)(&un_remote_control_output), sizeof(un_remote_control_output), (uint8_t *)&ethernet_parameter.upper_ip[0], ethernet_parameter.target_upper_port);
}
static void manualControlOutput(void *signal_id)
{
(void)signal_id; // 标记变量为已使用,避免编译器警告
UdpSendToData(UDPCB_2,(uint8_t *)(&un_manual_control_output),sizeof(un_manual_control_output), (uint8_t *)&ethernet_parameter.upper_ip[0], ethernet_parameter.target_upper_port);
}
static void autoControlOutput(void *signal_id)
{
(void)signal_id; // 标记变量为已使用,避免编译器警告
UdpSendToData(UDPCB_2,(uint8_t *)(&un_auto_control_output), sizeof(un_auto_control_output), (uint8_t *)&ethernet_parameter.upper_ip[0], ethernet_parameter.target_upper_port);
}
//以太网 发送
void ethernetSendAll(void *signal_id)
{
static uint8_t computer_output_cnt = 0;
uint32_t crc_temp = 0;
uint8_t i = 0;
uint16_t Rg_Tmp = 0;
float Rg_FloatTmp = 0;
static uint8_t eth_cnt = 0;
static uint8_t app_output_cnt = 0;
uint8_t BOOT_Arr[2] = {0x01,0x02};//上电发送app帧给上位机用
//-------------------------------------------------------------------------
//自主计算机以太网50ms发送 20210811修改为100ms发送
//20210827修改为高位在前低位再后与自主计算机保持一致
computer_output_cnt ++;
if(computer_output_cnt >= 1)
{
computer_output_cnt = 0;
//按字节累加和,注意不是信号 20210826修改按照字节累加
// printf("left_motor_speed = %f\n",diff_data.left_motor_speed);
// printf("right_motor_speed = %f\n",diff_data.right_motor_speed);
un_computer_output.bit_data.frame_header = 0xCCFF;
un_computer_output.bit_data.frame_type = 0x1100;
un_computer_output.bit_data.frame_length = 0x0B;
un_computer_output.bit_data.accumulated = eth_cnt ++;
Rg_FloatTmp = (diff_data.left_motor_speed*(float)getParam("whl_dia") * M_PI*60)/1000.0/(float)getParam("gRatio");// 转/分钟——》km/h 一圈1.8米
Rg_FloatTmp = Rg_FloatTmp*100;//,最后需要扩大100倍 ,系数0.01
Rg_Tmp = (uint16_t)((int16_t)(Rg_FloatTmp));//最后转换为无符号型); //20231012修改轮速发送 20231226-3号车修改方向
un_computer_output.bit_data.speed = ((Rg_Tmp << 8) | (Rg_Tmp >> 8));//高位在前,地位灾后
Rg_FloatTmp = (diff_data.right_motor_speed*(float)getParam("whl_dia") * M_PI*60)/1000.0/(float)getParam("gRatio");// 转/分钟——》km/h 一圈1.8米
Rg_FloatTmp = Rg_FloatTmp*100;//,最后需要扩大100倍 ,系数0.01
Rg_Tmp = (uint16_t)((int16_t)(Rg_FloatTmp));//最后转换为无符号型); //20231012修改轮速发送 20231226-3号车修改方向
un_computer_output.bit_data.curvature = ((Rg_Tmp << 8) | (Rg_Tmp >> 8));//高位在前,地位灾后
crc_temp = 0;
for(i = 0; i<10 ;i++)//长度固定
{
crc_temp = crc_temp + (un_computer_output.arr[i]);
}
un_computer_output.bit_data.crc = (uint8_t)crc_temp;
UdpSendToData(UDPCB_1,(uint8_t *)(&un_computer_output.arr[0]), 11, (uint8_t *)&ethernet_parameter.computer_ip[0], COMMUNICATION_PORT);
UdpSendToData(UDPCB_4,(uint8_t *)(&un_computer_output.arr[0]), 11, (uint8_t *)&ethernet_parameter.computer_ip[0], COMMUNICATION_PORT);
}
if(app_output_cnt < 10)//20250109 100ms 发送10帧app帧。解决以太网没有初始化完成就发送的丢帧问题
{
app_output_cnt ++;
UdpSendToData(UDPCB_4, BOOT_Arr, 2, (uint8_t *)&ethernet_parameter.download_ip[0], BOOT_TX_PORT);
}
}
// 以太网定时器信号处理函数
static void ethernetInterfaceTimerProcess(void *signal_id)
{
uint32_t time_boot = getCurrentTime();//记录当前时间
(void)signal_id; // 标记变量为已使用,避免编译器警告
ethernetSendAll(signal_id);
ethernetTimerProcess();//故障判断
timerStart(&ethernet_timer_interface, 100,1); //100ms调用一次
// printf("ethernetInterface spend time:%d\n",getCurrentTime() - time_boot);//检查app用了多长时间
}
static unsigned char receive_buffer[MAX_BUFFER_SIZE];
//参数管理回调
void udp_Callback_3(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
{
static unsigned int received_size = 0;
uint8_t *buf = (uint8_t *)(p->payload);
// 检查是否是新的帧头
if ((0x80 == buf[1]) && (0xFF == buf[0]))
{
// 重置接收过程
received_size = 0;
printf("检测到新的帧头,重置接收过程\n");
}
// 检查是否有足够的空间来存储新数据
if (received_size + p->len <= MAX_BUFFER_SIZE)
{
printf("p->len %d :\n" , p->len);
memcpy(receive_buffer + received_size, buf, p->len);
received_size += p->len;
// 检查是否接收到完整的数据
if (received_size >= sizeof(request_context.param_request->arr))
{
printf("received_size : %d :\n" , received_size);
for(u16_t i = 0; i< sizeof(request_context.param_request->arr); i++)
{
request_context.param_request->arr[i] = receive_buffer[i];
}
memcpy(request_context.param_request->arr, receive_buffer, sizeof(request_context.param_request->arr));
request_context.sender_ip = (unsigned int)addr->addr;
request_context.sender_port = port;
// 打印 request_context.param_request->arr 的内容
// printf("接收到的 param_request->arr 内容:\n");
// for (size_t i = 0; i < sizeof(request_context.param_request->arr); ++i)
// {
// printf("%02X ", request_context.param_request->arr[i]);
// if ((i + 1) % 1024 == 0 || i == sizeof(request_context.param_request->arr) - 1)
// {
// printf("\n");
// feedWatchdog();
// }
// }
publishMessage(&request_context, 1);
printf("received_size%d \n" , received_size);
// 重置接收缓冲区
received_size = 0;
printf("接收到完整数据,处理完毕\n");
}
}
else
{
// 缓冲区溢出,重置接收
received_size = 0;
printf("接收缓冲区溢出,数据丢弃\n");
}
unsigned int tmp_count = pbuf_free(p);
printf("pbuf_free已经释放tmp_count :%d \n" , tmp_count);
p = NULL;
}
void OnParamSend(void *data)
{
uint8_t ip_addr[4] = {0,0,0,0};
RequestContext *signal = (RequestContext *)(data);
ip_addr[0] = signal->sender_ip & 0xff; /* IADDR4 */
ip_addr[1] = (signal->sender_ip >> 8) & 0xff; /* IADDR3 */
ip_addr[2] = (signal->sender_ip >> 16) & 0xff; /* IADDR2 */
ip_addr[3] = (signal->sender_ip >> 24) & 0xff; /* IADDR1 */
uint32_t total_size = sizeof(signal->param_request->arr);
uint32_t sent_size = 0;
while (sent_size < total_size)
{
uint32_t remaining = total_size - sent_size;
uint32_t packet_size = (remaining > MAX_PACKET_SIZE) ? MAX_PACKET_SIZE : remaining;
UdpSendToData(UDPCB_3,
(uint8_t *)(signal->param_request->arr) + sent_size,
packet_size,
ip_addr,
signal->sender_port);
sent_size += packet_size;
// 添加小延迟,避免包丢失
udelay(1000);
}
printf("数据发送完成!%d \n", sent_size);
}
// APP模块的初始化
void ethernetInterfaceInit(void)
{
//-----------------------------------
if (!eth_pool_rx) {
// 使能DMA Rx中断。Tx未使用中断因为ETH速率很高
// Tx中断处理耗时反而可能拖慢发送速度。
dwc_eth_enable_dma_rx_int(&g_eth1_dev, eth_dma_rx_int_cb);
}
timerInit(&ethernet_timer_interface1);
timerInit(&ethernet_timer_interface);
// 订阅定时器信号,用于定时采集
subscribe(&ethernet_timer_interface, ethernetInterfaceTimerProcess);
subscribe(&ethernet_timer_interface1, lwip_Ethernet);
subscribe(&un_vehicle_Info_output, vehicleInfOoutput);
subscribe(&un_motor_status_output, motorStatusOutput);
subscribe(&un_pid_output, pidOutput);
subscribe(&un_remote_control_output, remoteControlOutput);
subscribe(&un_manual_control_output, manualControlOutput);
subscribe(&un_auto_control_output, autoControlOutput);
// 订阅消息,使用静态成员函数作为回调
subscribe(&request_send, OnParamSend);
timerStart(&ethernet_timer_interface, 100,1); //100ms调用一次
timerStart(&ethernet_timer_interface1, 10,1); //10ms调用一次
printf( "ethernetInterface: initial OK %d\n",getCurrentTime());
}