Files
ETH_TCP_Demo/app/main.c
2026-03-09 15:34:18 +08:00

448 lines
13 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 "osal.h"
#include "hal.h"
#include "lwip/init.h"
#include "lwip/netif.h"
#include "lwip/tcpip.h"
#include "lwip/dhcp.h"
#include "lwip/sockets.h"
#include "drv_eth.h"
#include "lwip/icmp.h"
#include "lwip/inet_chksum.h"
#include <string.h>
#include "lwip/prot/ip4.h"
#include "sht40.h"
#include "tcp_server.h"
#include "event_queue.h"
#include "event_handler.h"
#include "event_trigger.h"
#include "transaction.h"
#include "state_manager.h"
#include "error_handler.h"
/* Utility macros */
#define MIN(a, b) ((a) < (b) ? (a) : (b))
/* Network Interface */
struct netif gnetif;
osal_sem_t sem_ip_ready = NULL;
/* Static IP Configuration (Fallback) */
#define STATIC_IP_ADDR0 192
#define STATIC_IP_ADDR1 168
#define STATIC_IP_ADDR2 1
#define STATIC_IP_ADDR3 10
#define STATIC_NETMASK0 255
#define STATIC_NETMASK1 255
#define STATIC_NETMASK2 255
#define STATIC_NETMASK3 0
#define STATIC_GW_ADDR0 192
#define STATIC_GW_ADDR1 168
#define STATIC_GW_ADDR2 1
#define STATIC_GW_ADDR3 1
/* Blink Thread */
/**
* @brief LED闪烁任务入口函数
* @param parameter 任务参数(本函数中未使用)
* @note 该函数初始化PA6引脚为输出模式并在循环中翻转该引脚状态实现LED闪烁效果
*/
static void blink_entry(void *parameter)
{
/* Initialize PA6 */
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* 初始化为关闭状态 */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_SET);
while (1)
{
/* 检查数据上传成功标志 */
if (data_upload_success)
{
/* 亮LED */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_RESET);
osal_thread_mdelay(500); /* 亮500ms */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_SET);
/* 重置标志 */
data_upload_success = 0;
}
osal_thread_mdelay(100);
}
}
/* Ethernet Input Thread */
/**
* @brief 以太网输入任务入口函数
* @param parameter 任务参数(本函数中未使用)
* @note 该函数在循环中调用ethernetif_input处理接收到的以太网数据包
*/
static void ethernet_input_entry(void *parameter)
{
while(1)
{
/* Block until packet received */
ethernetif_input(&gnetif);
}
}
/**
* @brief Ping配置参数
* @note 该结构体定义了Ping操作的相关参数包括ID、数据大小、接收超时时间
*/
#define PING_ID 0xAFAF
#define PING_DATA_SIZE 32
#define PING_RCV_TIMEO 5000 // 5 seconds
/* Network Monitor Thread (DHCP & Fallback) */
static void network_monitor_entry(void *parameter)
{
ip4_addr_t ipaddr, netmask, gw;
int dhcp_timeout = 300; /* 300 * 100ms = 30 seconds */
int link_wait_timeout = 100; /* 10 seconds to wait for link up */
osal_log_i("Starting DHCP...");
/* Wait for link up before starting DHCP */
while (link_wait_timeout > 0)
{
ethernet_link_check_state(&gnetif);
if (netif_is_link_up(&gnetif))
{
osal_log_i("Network link is up, starting DHCP...");
break;
}
osal_thread_mdelay(100);
link_wait_timeout--;
/* Print a dot every second */
if (link_wait_timeout % 10 == 0) osal_kprintf(".");
}
osal_kprintf("\n");
if (!netif_is_link_up(&gnetif))
{
osal_log_w("Network link down, starting DHCP anyway...");
}
dhcp_start(&gnetif);
while (dhcp_timeout > 0)
{
/* Check link status periodically */
if (dhcp_timeout % 10 == 0) /* Every second */
{
ethernet_link_check_state(&gnetif);
}
if (gnetif.ip_addr.addr != 0)
{
osal_log_i("DHCP Success!");
/* 触发网络连接事件 */
event_trigger(EVENT_TYPE_NETWORK_CONNECTED, EVENT_PRIORITY_NORMAL, NULL, 0);
break;
}
osal_thread_mdelay(100);
dhcp_timeout--;
/* Print a dot every second */
if (dhcp_timeout % 10 == 0) osal_kprintf(".");
}
osal_kprintf("\n");
if (gnetif.ip_addr.addr == 0)
{
osal_log_w("DHCP Timeout! Fallback to Static IP.");
dhcp_stop(&gnetif);
IP4_ADDR(&ipaddr, STATIC_IP_ADDR0, STATIC_IP_ADDR1, STATIC_IP_ADDR2, STATIC_IP_ADDR3);
IP4_ADDR(&netmask, STATIC_NETMASK0, STATIC_NETMASK1, STATIC_NETMASK2, STATIC_NETMASK3);
IP4_ADDR(&gw, STATIC_GW_ADDR0, STATIC_GW_ADDR1, STATIC_GW_ADDR2, STATIC_GW_ADDR3);
netif_set_addr(&gnetif, &ipaddr, &netmask, &gw);
netif_set_up(&gnetif);
/* 触发网络连接事件 */
event_trigger(EVENT_TYPE_NETWORK_CONNECTED, EVENT_PRIORITY_NORMAL, NULL, 0);
}
osal_log_i("IP Address: %d.%d.%d.%d", ip4_addr1(&gnetif.ip_addr), ip4_addr2(&gnetif.ip_addr), ip4_addr3(&gnetif.ip_addr), ip4_addr4(&gnetif.ip_addr));
osal_log_i("Netmask: %d.%d.%d.%d", ip4_addr1(&gnetif.netmask), ip4_addr2(&gnetif.netmask), ip4_addr3(&gnetif.netmask), ip4_addr4(&gnetif.netmask));
osal_log_i("Gateway: %d.%d.%d.%d", ip4_addr1(&gnetif.gw), ip4_addr2(&gnetif.gw), ip4_addr3(&gnetif.gw), ip4_addr4(&gnetif.gw));
/* Notify TCP Client */
osal_sem_release(sem_ip_ready);
/* Periodic Link Check */
while(1)
{
ethernet_link_check_state(&gnetif);
osal_thread_mdelay(1000);
}
}
/* 事件处理函数 */
static int sensor_data_handler(event_t *event, void *user_data)
{
osal_log_i("Handling sensor data event");
/* 这里可以添加传感器数据处理逻辑 */
return 0;
}
static int network_connected_handler(event_t *event, void *user_data)
{
osal_log_i("Handling network connected event");
state_manager_set_network_state(NETWORK_STATE_CONNECTED);
return 0;
}
static int network_disconnected_handler(event_t *event, void *user_data)
{
osal_log_i("Handling network disconnected event");
state_manager_set_network_state(NETWORK_STATE_DISCONNECTED);
return 0;
}
static int tcp_client_connected_handler(event_t *event, void *user_data)
{
osal_log_i("Handling TCP client connected event");
state_manager_set_tcp_state(TCP_STATE_CONNECTED);
return 0;
}
static int tcp_client_disconnected_handler(event_t *event, void *user_data)
{
osal_log_i("Handling TCP client disconnected event");
state_manager_set_tcp_state(TCP_STATE_LISTENING);
return 0;
}
static int timer_handler(event_t *event, void *user_data)
{
osal_log_i("Handling timer event");
/* 这里可以添加定时任务逻辑 */
return 0;
}
static int error_handler(event_t *event, void *user_data)
{
osal_log_i("Handling error event");
error_code_t error = ERROR_UNKNOWN;
if (event->data != NULL)
{
error = *(error_code_t *)event->data;
}
error_handler_process(error, user_data);
return 0;
}
int main(void)
{
osal_thread_t tid;
/* 1. 系统初始化 */
osal_log_d("System initialization started...\n");
/* OSAL Initialization */
osal_init();
osal_log_d("OSAL initialized\n");
/* Hardware Abstraction Layer Initialization */
if (hal_init() != HAL_STATUS_OK) {
osal_log_e("Failed to initialize hardware abstraction layer\n");
return -1;
}
osal_log_d("Hardware abstraction layer initialized\n");
osal_log_i("Main: OSAL Log Level = %d\n", OSAL_LOG_LEVEL);
osal_log_i("Test osal_log_i from main");
/* 2. 应用组件初始化 */
osal_log_d("Initializing application components...\n");
/* Initialize event queue */
if (event_queue_init() != 0)
{
osal_log_e("Failed to initialize event queue");
return -1;
}
osal_log_d("Event queue initialized\n");
/* Initialize event handler */
if (event_handler_init() != 0)
{
osal_log_e("Failed to initialize event handler");
return -1;
}
osal_log_d("Event handler initialized\n");
/* Initialize transaction management */
if (transaction_init() != 0)
{
osal_log_e("Failed to initialize transaction management");
return -1;
}
osal_log_d("Transaction management initialized\n");
/* Initialize state manager */
if (state_manager_init() != 0)
{
osal_log_e("Failed to initialize state manager");
return -1;
}
osal_log_d("State manager initialized\n");
/* Initialize error handler */
if (error_handler_init() != 0)
{
osal_log_e("Failed to initialize error handler");
return -1;
}
osal_log_d("Error handler initialized\n");
/* Register event handlers */
event_handler_register(EVENT_TYPE_SENSOR_DATA, sensor_data_handler, NULL);
event_handler_register(EVENT_TYPE_NETWORK_CONNECTED, network_connected_handler, NULL);
event_handler_register(EVENT_TYPE_NETWORK_DISCONNECTED, network_disconnected_handler, NULL);
event_handler_register(EVENT_TYPE_TCP_CLIENT_CONNECTED, tcp_client_connected_handler, NULL);
event_handler_register(EVENT_TYPE_TCP_CLIENT_DISCONNECTED, tcp_client_disconnected_handler, NULL);
event_handler_register(EVENT_TYPE_TIMER, timer_handler, NULL);
event_handler_register(EVENT_TYPE_ERROR, error_handler, NULL);
osal_log_d("Event handlers registered\n");
/* 3. 网络初始化 */
osal_log_d("Initializing network components...\n");
/* Initialize TCP/IP stack */
osal_log_d("Initializing TCP/IP stack...\n");
tcpip_init(NULL, NULL);
osal_log_d("TCP/IP stack initialized.\n");
/* Initialize Network Interface */
ip4_addr_t ipaddr, netmask, gw;
/* Initialize with 0.0.0.0 */
IP4_ADDR(&ipaddr, 0, 0, 0, 0);
IP4_ADDR(&netmask, 0, 0, 0, 0);
IP4_ADDR(&gw, 0, 0, 0, 0);
/* Add Network Interface */
netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, &ethernetif_init, &tcpip_input);
netif_set_default(&gnetif);
netif_set_up(&gnetif);
osal_log_d("Network interface added\n");
sem_ip_ready = osal_sem_create("sem_ip", 0);
/* 4. 传感器初始化 */
osal_log_d("Initializing sensors...\n");
/* Initialize SHT40 sensor */
if (sht40_init() != 0)
{
osal_log_e("SHT40 sensor initialization failed");
error_code_t error = ERROR_SENSOR;
event_trigger(EVENT_TYPE_ERROR, EVENT_PRIORITY_HIGH, &error, sizeof(error));
}
else
{
osal_log_i("SHT40 sensor initialized successfully");
state_manager_set_sensor_state(SENSOR_STATE_READY);
/* Use heater once during initialization for self-calibration */
osal_log_i("Performing SHT40 self-calibration using heater...");
if (sht40_heater_enable(1) == 0) // Use medium power (110mW)
{
osal_log_i("SHT40 self-calibration completed successfully");
}
else
{
osal_log_e("SHT40 self-calibration failed");
error_code_t error = ERROR_SENSOR;
event_trigger(EVENT_TYPE_ERROR, EVENT_PRIORITY_HIGH, &error, sizeof(error));
}
}
/* 5. 线程创建 */
osal_log_d("Creating threads...\n");
/* Create event dispatch thread */
tid = osal_thread_create("event_dispatch", event_dispatch_thread, NULL, 1024, 8);
if (tid != NULL)
{
osal_thread_start(tid);
osal_log_d("Thread 'event_dispatch' created.\n");
}
else
{
osal_log_e("Failed to create thread 'event_dispatch'\n");
}
/* Create Network Monitor Thread (DHCP) */
tid = osal_thread_create("net_mon", network_monitor_entry, NULL, 1024, 12);
if (tid != NULL)
{
osal_thread_start(tid);
osal_log_d("Thread 'net_mon' created.\n");
}
else
{
osal_log_e("Failed to create thread 'net_mon'\n");
}
/* Create Ethernet Input Thread */
/* Increased priority to 6 (Higher than TCPIP thread which is 10) for better responsiveness */
tid = osal_thread_create("eth_input", ethernet_input_entry, NULL, 1536, 6);
if (tid != NULL)
{
osal_thread_start(tid);
osal_log_d("Thread 'eth_input' created.\n");
}
else
{
osal_log_e("Failed to create thread 'eth_input'\n");
}
/* Create TCP Server Thread */
tid = osal_thread_create("tcp_server", tcp_server_entry, NULL, 2048, 15);
if (tid != NULL)
{
osal_thread_start(tid);
osal_log_d("Thread 'tcp_server' created.\n");
}
else
{
osal_log_e("Failed to create thread 'tcp_server'\n");
}
/* Create Blink/Status Thread */
tid = osal_thread_create("blink", blink_entry, NULL, 1024, 20);
if (tid != NULL)
{
osal_thread_start(tid);
osal_log_d("Thread 'blink' created.\n");
}
else
{
osal_log_e("Failed to create thread 'blink'\n");
}
/* 6. 系统信息 */
/* 内存信息暂时使用rt-thread APIosal库可能没有提供对应的函数 */
rt_size_t total, used, max_used;
rt_memory_info(&total, &used, &max_used);
osal_log_d("Memory Info: Total=%d, Used=%d, MaxUsed=%d\n", total, used, max_used);
/* 7. 启动系统 */
osal_log_d("System initialization completed. Starting OSAL...\n");
osal_start();
return 0;
}