448 lines
13 KiB
C
448 lines
13 KiB
C
#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, ðernetif_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 API,osal库可能没有提供对应的函数 */
|
||
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;
|
||
}
|
||
|