feat: 保存已验证的CH390网络打通基线
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
#include "debug_log.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "FreeRTOS.h"
|
||||
#include "SEGGER_RTT.h"
|
||||
#include "task.h"
|
||||
|
||||
volatile uint32_t g_rtt_log_seq = 0u;
|
||||
volatile uint32_t g_rtt_log_drop_count = 0u;
|
||||
volatile uint32_t g_rtt_log_last_drop_seq = 0u;
|
||||
|
||||
static void debug_backend_write(const char *msg)
|
||||
{
|
||||
unsigned len;
|
||||
unsigned written;
|
||||
|
||||
if ((msg == NULL) || (msg[0] == '\0')) {
|
||||
return;
|
||||
}
|
||||
|
||||
len = (unsigned)strlen(msg);
|
||||
g_rtt_log_seq += 1u;
|
||||
written = SEGGER_RTT_Write(0u, msg, len);
|
||||
if (written < len) {
|
||||
g_rtt_log_drop_count += 1u;
|
||||
g_rtt_log_last_drop_seq = g_rtt_log_seq;
|
||||
}
|
||||
}
|
||||
|
||||
void debug_log_init(void)
|
||||
{
|
||||
SEGGER_RTT_Init();
|
||||
}
|
||||
|
||||
void debug_log_write(const char *msg)
|
||||
{
|
||||
if (msg == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
debug_backend_write(msg);
|
||||
}
|
||||
|
||||
void debug_log_printf(const char *fmt, ...)
|
||||
{
|
||||
char buffer[192];
|
||||
va_list args;
|
||||
int len;
|
||||
|
||||
if (fmt == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
va_start(args, fmt);
|
||||
len = vsnprintf(buffer, sizeof(buffer), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
if (len < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
buffer[sizeof(buffer) - 1u] = '\0';
|
||||
debug_backend_write(buffer);
|
||||
}
|
||||
|
||||
void debug_log_boot(const char *tag)
|
||||
{
|
||||
debug_log_printf("[BOOT] %s\r\n", (tag != NULL) ? tag : "(null)");
|
||||
}
|
||||
|
||||
void debug_log_fault(const char *tag)
|
||||
{
|
||||
debug_log_printf("[FAULT] %s\r\n", (tag != NULL) ? tag : "(null)");
|
||||
}
|
||||
|
||||
void debug_log_runtime_snapshot(void)
|
||||
{
|
||||
UBaseType_t default_hwm;
|
||||
size_t free_heap;
|
||||
size_t min_heap;
|
||||
|
||||
free_heap = xPortGetFreeHeapSize();
|
||||
min_heap = xPortGetMinimumEverFreeHeapSize();
|
||||
default_hwm = uxTaskGetStackHighWaterMark(NULL);
|
||||
|
||||
debug_log_printf("[RTOS] free=%lu min=%lu self_hwm=%lu\r\n",
|
||||
(unsigned long)free_heap,
|
||||
(unsigned long)min_heap,
|
||||
(unsigned long)default_hwm);
|
||||
}
|
||||
|
||||
void lwip_platform_assert(const char *msg, const char *file, int line)
|
||||
{
|
||||
debug_log_printf("[FAULT] lwip-assert msg=%s file=%s line=%d\r\n",
|
||||
(msg != NULL) ? msg : "(null)",
|
||||
(file != NULL) ? file : "(null)",
|
||||
line);
|
||||
|
||||
taskDISABLE_INTERRUPTS();
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
+235
-345
@@ -1,370 +1,260 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* File Name : freertos.c
|
||||
* Description : Code for freertos applications
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2026 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "main.h"
|
||||
#include "cmsis_os.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include "queue.h"
|
||||
#include "semphr.h"
|
||||
#include "stream_buffer.h"
|
||||
#include "main.h"
|
||||
#include "gpio.h"
|
||||
#include "iwdg.h"
|
||||
|
||||
/* Application modules */
|
||||
#include "config.h"
|
||||
#include "debug_log.h"
|
||||
#include "route_msg.h"
|
||||
#include "app_runtime.h"
|
||||
#include "task_net_poll.h"
|
||||
#include "tcp_server.h"
|
||||
#include "tcp_client.h"
|
||||
#include "uart_trans.h"
|
||||
#include "config.h"
|
||||
#include "ethernetif.h"
|
||||
|
||||
/* LwIP includes */
|
||||
#include "lwip/tcpip.h"
|
||||
#include "lwip/ip4_addr.h"
|
||||
#include "lwip/dhcp.h"
|
||||
#include "lwip/timeouts.h"
|
||||
/* USER CODE END Includes */
|
||||
QueueHandle_t xTcpRxQueue = NULL;
|
||||
QueueHandle_t xConfigQueue = NULL;
|
||||
QueueHandle_t xLinkTxQueues[CONFIG_LINK_COUNT] = {0};
|
||||
SemaphoreHandle_t xNetSemaphore = NULL;
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PTD */
|
||||
TaskHandle_t xUartRxTaskHandle = NULL;
|
||||
TaskHandle_t xConfigTaskHandle = NULL;
|
||||
volatile BaseType_t g_netif_ready = pdFALSE;
|
||||
volatile uint32_t g_netif_phase = 0u;
|
||||
volatile int32_t g_netif_add_err = 0x7FFFFFFF;
|
||||
volatile int32_t g_netif_set_default_err = 0x7FFFFFFF;
|
||||
volatile int32_t g_netif_set_link_down_err = 0x7FFFFFFF;
|
||||
volatile int32_t g_netif_set_up_err = 0x7FFFFFFF;
|
||||
volatile int32_t g_netif_init_ok = 0;
|
||||
volatile uint32_t g_eth_poll_count = 0u;
|
||||
volatile uint32_t g_eth_isr_pr_count = 0u;
|
||||
volatile uint32_t g_eth_rx_count = 0u;
|
||||
volatile uint32_t g_eth_rx_drop_count = 0u;
|
||||
volatile uint32_t g_eth_tx_count = 0u;
|
||||
volatile uint32_t g_eth_link_up_count = 0u;
|
||||
volatile uint32_t g_eth_link_down_count = 0u;
|
||||
volatile uint32_t g_eth_last_isr = 0u;
|
||||
volatile uint32_t g_eth_last_nsr = 0u;
|
||||
volatile uint32_t g_eth_last_mrcmdx = 0u;
|
||||
volatile uint32_t g_eth_last_mrcmdx1 = 0u;
|
||||
volatile uint32_t g_eth_last_mrrl = 0u;
|
||||
volatile uint32_t g_eth_last_mrrh = 0u;
|
||||
volatile uint32_t g_eth_last_bcastcr = 0u;
|
||||
volatile uint32_t g_eth_last_mar7 = 0u;
|
||||
volatile uint32_t g_eth_last_nsr_rxrdy = 0u;
|
||||
volatile uint32_t g_eth_last_rx_ready = 0u;
|
||||
volatile uint32_t g_eth_last_rx_status = 0u;
|
||||
volatile uint32_t g_eth_last_rx_len = 0u;
|
||||
volatile uint32_t g_eth_last_rx_head0 = 0u;
|
||||
volatile uint32_t g_eth_last_rx_head1 = 0u;
|
||||
volatile uint32_t g_eth_last_rx_head2 = 0u;
|
||||
volatile uint32_t g_eth_last_rx_head3 = 0u;
|
||||
volatile uint32_t g_eth_last_rx_fail_stage = 0u;
|
||||
volatile uint32_t g_eth_rx_gate_ok_count = 0u;
|
||||
volatile uint32_t g_eth_rx_fallback_ok_count = 0u;
|
||||
volatile uint32_t g_eth_rx_fallback_reject_count = 0u;
|
||||
volatile uint32_t g_eth_probe_attempted = 0u;
|
||||
volatile uint32_t g_eth_probe_head0 = 0u;
|
||||
volatile uint32_t g_eth_probe_head1 = 0u;
|
||||
volatile uint32_t g_eth_probe_head2 = 0u;
|
||||
volatile uint32_t g_eth_probe_head3 = 0u;
|
||||
volatile uint32_t g_eth_probe_rx_status = 0u;
|
||||
volatile uint32_t g_eth_probe_rx_len = 0u;
|
||||
volatile uint8_t g_eth_probe_dump[32] = {0u};
|
||||
volatile uint32_t g_eth_probe_drop_count = 0u;
|
||||
volatile uint32_t g_eth_reprobe_head0 = 0u;
|
||||
volatile uint32_t g_eth_reprobe_head1 = 0u;
|
||||
volatile uint32_t g_eth_reprobe_head2 = 0u;
|
||||
volatile uint32_t g_eth_reprobe_head3 = 0u;
|
||||
volatile uint32_t g_eth_reprobe_rx_status = 0u;
|
||||
volatile uint32_t g_eth_reprobe_rx_len = 0u;
|
||||
volatile uint32_t g_eth_input_ok_count = 0u;
|
||||
volatile uint32_t g_eth_input_err_count = 0u;
|
||||
volatile int32_t g_eth_last_input_err = 0;
|
||||
volatile uint32_t g_eth_last_frame_len = 0u;
|
||||
volatile uint8_t g_eth_last_frame_head[14] = {0u};
|
||||
volatile uint32_t g_eth_tx_probe_count = 0u;
|
||||
volatile uint32_t g_eth_last_tx_len = 0u;
|
||||
volatile uint8_t g_eth_last_tx_head[14] = {0u};
|
||||
volatile uint32_t g_eth_last_tcr_after = 0u;
|
||||
volatile uint32_t g_eth_last_nsr_after = 0u;
|
||||
volatile uint32_t g_eth_last_tsra = 0u;
|
||||
volatile uint32_t g_eth_last_tsrb = 0u;
|
||||
volatile uint32_t g_eth_last_txpll_rb = 0u;
|
||||
volatile uint32_t g_eth_last_txplh_rb = 0u;
|
||||
volatile uint32_t g_eth_arp_rx_count = 0u;
|
||||
volatile uint32_t g_eth_arp_tx_count = 0u;
|
||||
volatile uint32_t g_eth_arp_rx_op = 0u;
|
||||
volatile uint32_t g_eth_arp_tx_op = 0u;
|
||||
volatile uint8_t g_eth_local_ip[4] = {0u};
|
||||
volatile uint8_t g_eth_local_mac[6] = {0u};
|
||||
volatile uint8_t g_eth_arp_rx_sha[6] = {0u};
|
||||
volatile uint8_t g_eth_arp_rx_spa[4] = {0u};
|
||||
volatile uint8_t g_eth_arp_rx_tha[6] = {0u};
|
||||
volatile uint8_t g_eth_arp_rx_tpa[4] = {0u};
|
||||
volatile uint8_t g_eth_arp_tx_sha[6] = {0u};
|
||||
volatile uint8_t g_eth_arp_tx_spa[4] = {0u};
|
||||
volatile uint8_t g_eth_arp_tx_tha[6] = {0u};
|
||||
volatile uint8_t g_eth_arp_tx_tpa[4] = {0u};
|
||||
volatile uint32_t g_eth_lwip_arp_seen_count = 0u;
|
||||
volatile uint32_t g_eth_lwip_arp_opcode = 0u;
|
||||
volatile uint32_t g_eth_lwip_arp_for_us = 0u;
|
||||
volatile uint32_t g_eth_lwip_arp_from_us = 0u;
|
||||
volatile uint8_t g_eth_lwip_arp_sip[4] = {0u};
|
||||
volatile uint8_t g_eth_lwip_arp_dip[4] = {0u};
|
||||
volatile uint32_t g_eth_lwip_eth_seen_count = 0u;
|
||||
volatile uint32_t g_eth_lwip_eth_last_type = 0u;
|
||||
volatile uint32_t g_eth_lwip_eth_last_len = 0u;
|
||||
volatile uint32_t g_eth_lwip_eth_arp_case_count = 0u;
|
||||
|
||||
/* USER CODE END PTD */
|
||||
static TaskHandle_t xNetPollTaskHandle = NULL;
|
||||
static TaskHandle_t xTcpSrvTaskS1Handle = NULL;
|
||||
static TaskHandle_t xTcpSrvTaskS2Handle = NULL;
|
||||
static TaskHandle_t xTcpCliTaskC1Handle = NULL;
|
||||
static TaskHandle_t xTcpCliTaskC2Handle = NULL;
|
||||
static TaskHandle_t xDefaultTaskHandle = NULL;
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PD */
|
||||
/* Task stack sizes (words, not bytes) */
|
||||
#define LWIP_TASK_STACK_SIZE 384
|
||||
#define TCP_SERVER_TASK_STACK_SIZE 320
|
||||
#define TCP_CLIENT_TASK_STACK_SIZE 320
|
||||
#define UART_TRANS_TASK_STACK_SIZE 192
|
||||
#define CONFIG_TASK_STACK_SIZE 256
|
||||
#define DEFAULT_TASK_STACK_SIZE 128
|
||||
|
||||
/* Task priorities */
|
||||
#define LWIP_TASK_PRIORITY (osPriorityAboveNormal)
|
||||
#define TCP_SERVER_TASK_PRIORITY (osPriorityNormal)
|
||||
#define TCP_CLIENT_TASK_PRIORITY (osPriorityNormal)
|
||||
#define UART_TRANS_TASK_PRIORITY (osPriorityNormal)
|
||||
#define CONFIG_TASK_PRIORITY (osPriorityBelowNormal)
|
||||
#define DEFAULT_TASK_PRIORITY (osPriorityLow)
|
||||
/* USER CODE END PD */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PM */
|
||||
|
||||
/* USER CODE END PM */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Variables */
|
||||
/* Task handles */
|
||||
TaskHandle_t lwipTaskHandle = NULL;
|
||||
TaskHandle_t tcpServerTaskHandle = NULL;
|
||||
TaskHandle_t tcpClientTaskHandle = NULL;
|
||||
TaskHandle_t uartServerTransTaskHandle = NULL;
|
||||
TaskHandle_t uartClientTransTaskHandle = NULL;
|
||||
TaskHandle_t configTaskHandle = NULL;
|
||||
|
||||
/* SPI mutex for CH390 access */
|
||||
SemaphoreHandle_t ch390SpiMutex = NULL;
|
||||
|
||||
/* CH390 interrupt notification semaphore */
|
||||
SemaphoreHandle_t ch390IntSemaphore = NULL;
|
||||
/* USER CODE END Variables */
|
||||
|
||||
/* Definitions for defaultTask */
|
||||
osThreadId_t defaultTaskHandle;
|
||||
const osThreadAttr_t defaultTask_attributes = {
|
||||
.name = "defaultTask",
|
||||
.stack_size = DEFAULT_TASK_STACK_SIZE * 4,
|
||||
.priority = (osPriority_t) DEFAULT_TASK_PRIORITY,
|
||||
};
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* USER CODE BEGIN FunctionPrototypes */
|
||||
void LwIPTask(void *argument);
|
||||
/* USER CODE END FunctionPrototypes */
|
||||
|
||||
void StartDefaultTask(void *argument);
|
||||
|
||||
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
|
||||
|
||||
/**
|
||||
* @brief FreeRTOS initialization
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void MX_FREERTOS_Init(void) {
|
||||
/* USER CODE BEGIN Init */
|
||||
|
||||
/* USER CODE END Init */
|
||||
|
||||
/* USER CODE BEGIN RTOS_MUTEX */
|
||||
/* Create SPI mutex for CH390 access */
|
||||
ch390SpiMutex = xSemaphoreCreateMutex();
|
||||
configASSERT(ch390SpiMutex != NULL);
|
||||
/* USER CODE END RTOS_MUTEX */
|
||||
|
||||
/* USER CODE BEGIN RTOS_SEMAPHORES */
|
||||
/* Create CH390 interrupt notification semaphore */
|
||||
ch390IntSemaphore = xSemaphoreCreateBinary();
|
||||
configASSERT(ch390IntSemaphore != NULL);
|
||||
/* USER CODE END RTOS_SEMAPHORES */
|
||||
|
||||
/* USER CODE BEGIN RTOS_TIMERS */
|
||||
/* start timers, add new ones, ... */
|
||||
/* USER CODE END RTOS_TIMERS */
|
||||
|
||||
/* USER CODE BEGIN RTOS_QUEUES */
|
||||
/* add queues, ... */
|
||||
/* USER CODE END RTOS_QUEUES */
|
||||
|
||||
/* Create the thread(s) */
|
||||
/* creation of defaultTask */
|
||||
defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);
|
||||
|
||||
/* USER CODE BEGIN RTOS_THREADS */
|
||||
BaseType_t task_created;
|
||||
|
||||
/* Create LwIP task (handles network stack + TCP server/client) */
|
||||
task_created = xTaskCreate(LwIPTask, "LwIP", LWIP_TASK_STACK_SIZE, NULL,
|
||||
tskIDLE_PRIORITY + 3, &lwipTaskHandle);
|
||||
configASSERT(task_created == pdPASS);
|
||||
|
||||
/* Create TCP Server task */
|
||||
task_created = xTaskCreate(tcp_server_task, "TCPServer", TCP_SERVER_TASK_STACK_SIZE, NULL,
|
||||
tskIDLE_PRIORITY + 2, &tcpServerTaskHandle);
|
||||
configASSERT(task_created == pdPASS);
|
||||
|
||||
/* Create TCP Client task */
|
||||
task_created = xTaskCreate(tcp_client_task, "TCPClient", TCP_CLIENT_TASK_STACK_SIZE, NULL,
|
||||
tskIDLE_PRIORITY + 2, &tcpClientTaskHandle);
|
||||
configASSERT(task_created == pdPASS);
|
||||
|
||||
/* Create UART Server transparent transmission task */
|
||||
task_created = xTaskCreate(uart_server_trans_task, "UartSrvTx", UART_TRANS_TASK_STACK_SIZE, NULL,
|
||||
tskIDLE_PRIORITY + 2, &uartServerTransTaskHandle);
|
||||
configASSERT(task_created == pdPASS);
|
||||
|
||||
/* Create UART Client transparent transmission task */
|
||||
task_created = xTaskCreate(uart_client_trans_task, "UartCliTx", UART_TRANS_TASK_STACK_SIZE, NULL,
|
||||
tskIDLE_PRIORITY + 2, &uartClientTransTaskHandle);
|
||||
configASSERT(task_created == pdPASS);
|
||||
|
||||
/* Create Configuration task (AT commands via UART1) */
|
||||
task_created = xTaskCreate(config_task, "Config", CONFIG_TASK_STACK_SIZE, NULL,
|
||||
tskIDLE_PRIORITY + 1, &configTaskHandle);
|
||||
configASSERT(task_created == pdPASS);
|
||||
/* USER CODE END RTOS_THREADS */
|
||||
|
||||
/* USER CODE BEGIN RTOS_EVENTS */
|
||||
/* add events, ... */
|
||||
/* USER CODE END RTOS_EVENTS */
|
||||
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN Header_StartDefaultTask */
|
||||
/**
|
||||
* @brief Function implementing the defaultTask thread.
|
||||
* LED blinking for system status indication.
|
||||
* @param argument: Not used
|
||||
* @retval None
|
||||
*/
|
||||
/* USER CODE END Header_StartDefaultTask */
|
||||
void StartDefaultTask(void *argument)
|
||||
static void StartDefaultTask(void *argument)
|
||||
{
|
||||
/* USER CODE BEGIN StartDefaultTask */
|
||||
(void)argument;
|
||||
|
||||
/* Infinite loop - LED heartbeat */
|
||||
for(;;)
|
||||
{
|
||||
/* Toggle LED (PC13, active low) */
|
||||
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
|
||||
|
||||
/* 500ms toggle = 1Hz blink rate */
|
||||
osDelay(500);
|
||||
}
|
||||
/* USER CODE END StartDefaultTask */
|
||||
}
|
||||
TickType_t last_snapshot = xTaskGetTickCount();
|
||||
BaseType_t alive_logged = pdFALSE;
|
||||
|
||||
/* Private application code --------------------------------------------------*/
|
||||
/* USER CODE BEGIN Application */
|
||||
|
||||
/**
|
||||
* @brief LwIP task - handles network stack initialization and processing
|
||||
*/
|
||||
void LwIPTask(void *argument)
|
||||
{
|
||||
(void)argument;
|
||||
|
||||
ip4_addr_t ipaddr, netmask, gw;
|
||||
uart_config_t uart_server_cfg;
|
||||
uart_config_t uart_client_cfg;
|
||||
uint8_t use_dhcp = 0;
|
||||
const device_config_t *cfg;
|
||||
|
||||
/* Wait for configuration to be loaded */
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
|
||||
/* Get device configuration */
|
||||
cfg = config_get();
|
||||
|
||||
/* Initialize UART transparent transmission module */
|
||||
uart_trans_init();
|
||||
debug_log_boot("default-task");
|
||||
|
||||
/* Apply UART settings from configuration */
|
||||
uart_server_cfg.baudrate = UART_DEFAULT_BAUDRATE;
|
||||
uart_server_cfg.data_bits = UART_DEFAULT_DATA_BITS;
|
||||
uart_server_cfg.stop_bits = UART_DEFAULT_STOP_BITS;
|
||||
uart_server_cfg.parity = UART_DEFAULT_PARITY;
|
||||
|
||||
uart_client_cfg.baudrate = UART_DEFAULT_BAUDRATE;
|
||||
uart_client_cfg.data_bits = UART_DEFAULT_DATA_BITS;
|
||||
uart_client_cfg.stop_bits = UART_DEFAULT_STOP_BITS;
|
||||
uart_client_cfg.parity = UART_DEFAULT_PARITY;
|
||||
|
||||
if (cfg != NULL)
|
||||
{
|
||||
uart_server_cfg.baudrate = cfg->uart2_baudrate;
|
||||
uart_server_cfg.data_bits = cfg->uart2_databits;
|
||||
uart_server_cfg.stop_bits = cfg->uart2_stopbits;
|
||||
uart_server_cfg.parity = cfg->uart2_parity;
|
||||
|
||||
uart_client_cfg.baudrate = cfg->uart3_baudrate;
|
||||
uart_client_cfg.data_bits = cfg->uart3_databits;
|
||||
uart_client_cfg.stop_bits = cfg->uart3_stopbits;
|
||||
uart_client_cfg.parity = cfg->uart3_parity;
|
||||
}
|
||||
|
||||
(void)uart_trans_config(UART_CHANNEL_SERVER, &uart_server_cfg);
|
||||
(void)uart_trans_config(UART_CHANNEL_CLIENT, &uart_client_cfg);
|
||||
|
||||
/* Wait for TCP tasks to initialize their StreamBuffers */
|
||||
/* TCP Server and TCP Client tasks call tcp_server_init() / tcp_client_init() */
|
||||
/* which create the StreamBuffers. We need to wait until they're ready. */
|
||||
while (tcp_server_get_rx_stream() == NULL ||
|
||||
tcp_server_get_tx_stream() == NULL ||
|
||||
tcp_client_get_rx_stream() == NULL ||
|
||||
tcp_client_get_tx_stream() == NULL)
|
||||
{
|
||||
vTaskDelay(pdMS_TO_TICKS(50));
|
||||
}
|
||||
|
||||
/* Connect StreamBuffers between TCP and UART modules */
|
||||
/* Server: TCP Server RX -> UART2 TX, UART2 RX -> TCP Server TX */
|
||||
uart_trans_set_streams(UART_CHANNEL_SERVER,
|
||||
tcp_server_get_rx_stream(), /* TCP RX -> UART TX */
|
||||
tcp_server_get_tx_stream()); /* UART RX -> TCP TX */
|
||||
|
||||
/* Client: TCP Client RX -> UART3 TX, UART3 RX -> TCP Client TX */
|
||||
uart_trans_set_streams(UART_CHANNEL_CLIENT,
|
||||
tcp_client_get_rx_stream(), /* TCP RX -> UART TX */
|
||||
tcp_client_get_tx_stream()); /* UART RX -> TCP TX */
|
||||
|
||||
/* Initialize LwIP stack (calls tcpip_init internally) */
|
||||
tcpip_init(NULL, NULL);
|
||||
|
||||
/* Wait for tcpip thread to initialize */
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
|
||||
/* Set IP addresses */
|
||||
if (cfg != NULL && cfg->dhcp_enable != 0)
|
||||
{
|
||||
use_dhcp = 1;
|
||||
IP4_ADDR(&ipaddr, 0, 0, 0, 0);
|
||||
IP4_ADDR(&netmask, 0, 0, 0, 0);
|
||||
IP4_ADDR(&gw, 0, 0, 0, 0);
|
||||
}
|
||||
else if (cfg != NULL)
|
||||
{
|
||||
IP4_ADDR(&ipaddr, cfg->ip[0], cfg->ip[1], cfg->ip[2], cfg->ip[3]);
|
||||
IP4_ADDR(&netmask, cfg->mask[0], cfg->mask[1], cfg->mask[2], cfg->mask[3]);
|
||||
IP4_ADDR(&gw, cfg->gw[0], cfg->gw[1], cfg->gw[2], cfg->gw[3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Default IP if no config */
|
||||
IP4_ADDR(&ipaddr, 192, 168, 1, 200);
|
||||
IP4_ADDR(&netmask, 255, 255, 255, 0);
|
||||
IP4_ADDR(&gw, 192, 168, 1, 1);
|
||||
}
|
||||
|
||||
/* Initialize network interface */
|
||||
lwip_netif_init(&ipaddr, &netmask, &gw);
|
||||
|
||||
if (use_dhcp)
|
||||
{
|
||||
dhcp_start(&ch390_netif);
|
||||
}
|
||||
|
||||
/* Main loop - handle network events */
|
||||
for (;;)
|
||||
{
|
||||
/* Wait for CH390 interrupt or timeout */
|
||||
if (xSemaphoreTake(ch390IntSemaphore, pdMS_TO_TICKS(10)) == pdTRUE)
|
||||
{
|
||||
/* Process network input - poll all pending packets */
|
||||
ethernetif_poll();
|
||||
for (;;) {
|
||||
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
|
||||
HAL_IWDG_Refresh(&hiwdg);
|
||||
if (alive_logged == pdFALSE) {
|
||||
debug_log_write("[RTOS] alive\r\n");
|
||||
alive_logged = pdTRUE;
|
||||
}
|
||||
|
||||
/* Check link status periodically */
|
||||
ethernetif_check_link();
|
||||
if ((xTaskGetTickCount() - last_snapshot) >= pdMS_TO_TICKS(5000)) {
|
||||
debug_log_printf("[RTOS] seq=%lu drops=%lu last=%lu free=%lu min=%lu self_hwm=%lu\r\n",
|
||||
(unsigned long)g_rtt_log_seq,
|
||||
(unsigned long)g_rtt_log_drop_count,
|
||||
(unsigned long)g_rtt_log_last_drop_seq,
|
||||
(unsigned long)xPortGetFreeHeapSize(),
|
||||
(unsigned long)xPortGetMinimumEverFreeHeapSize(),
|
||||
(unsigned long)uxTaskGetStackHighWaterMark(NULL));
|
||||
if (xNetPollTaskHandle != NULL) {
|
||||
debug_log_printf("[RTOS] net_phase=%lu net_hwm=%lu\r\n",
|
||||
(unsigned long)g_netif_phase,
|
||||
(unsigned long)uxTaskGetStackHighWaterMark(xNetPollTaskHandle));
|
||||
}
|
||||
debug_log_printf("[ARP] poll=%lu isr=0x%02lX pr=%lu rx=%lu drop=%lu tx=%lu lup=%lu ldn=%lu\r\n",
|
||||
(unsigned long)g_eth_poll_count,
|
||||
(unsigned long)g_eth_last_isr,
|
||||
(unsigned long)g_eth_isr_pr_count,
|
||||
(unsigned long)g_eth_rx_count,
|
||||
(unsigned long)g_eth_rx_drop_count,
|
||||
(unsigned long)g_eth_tx_count,
|
||||
(unsigned long)g_eth_link_up_count,
|
||||
(unsigned long)g_eth_link_down_count);
|
||||
debug_log_printf("[ARP] txp=%lu tlen=%lu\r\n",
|
||||
(unsigned long)g_eth_tx_probe_count,
|
||||
(unsigned long)g_eth_last_tx_len);
|
||||
debug_log_printf("[ARP] txr tcr=0x%02lX nsr=0x%02lX tsra=0x%02lX tsrb=0x%02lX pll=0x%02lX plh=0x%02lX\r\n",
|
||||
(unsigned long)g_eth_last_tcr_after,
|
||||
(unsigned long)g_eth_last_nsr_after,
|
||||
(unsigned long)g_eth_last_tsra,
|
||||
(unsigned long)g_eth_last_tsrb,
|
||||
(unsigned long)g_eth_last_txpll_rb,
|
||||
(unsigned long)g_eth_last_txplh_rb);
|
||||
debug_log_printf("[ARP] local ip=%lu.%lu.%lu.%lu mac=%02lX:%02lX:%02lX:%02lX:%02lX:%02lX\r\n",
|
||||
(unsigned long)g_eth_local_ip[0],
|
||||
(unsigned long)g_eth_local_ip[1],
|
||||
(unsigned long)g_eth_local_ip[2],
|
||||
(unsigned long)g_eth_local_ip[3],
|
||||
(unsigned long)g_eth_local_mac[0],
|
||||
(unsigned long)g_eth_local_mac[1],
|
||||
(unsigned long)g_eth_local_mac[2],
|
||||
(unsigned long)g_eth_local_mac[3],
|
||||
(unsigned long)g_eth_local_mac[4],
|
||||
(unsigned long)g_eth_local_mac[5]);
|
||||
debug_log_printf("[ARP] rxarp c=%lu op=%lu spa=%lu.%lu.%lu.%lu tpa=%lu.%lu.%lu.%lu\r\n",
|
||||
(unsigned long)g_eth_arp_rx_count,
|
||||
(unsigned long)g_eth_arp_rx_op,
|
||||
(unsigned long)g_eth_arp_rx_spa[0],
|
||||
(unsigned long)g_eth_arp_rx_spa[1],
|
||||
(unsigned long)g_eth_arp_rx_spa[2],
|
||||
(unsigned long)g_eth_arp_rx_spa[3],
|
||||
(unsigned long)g_eth_arp_rx_tpa[0],
|
||||
(unsigned long)g_eth_arp_rx_tpa[1],
|
||||
(unsigned long)g_eth_arp_rx_tpa[2],
|
||||
(unsigned long)g_eth_arp_rx_tpa[3]);
|
||||
debug_log_printf("[ARP] txarp c=%lu op=%lu spa=%lu.%lu.%lu.%lu tpa=%lu.%lu.%lu.%lu\r\n",
|
||||
(unsigned long)g_eth_arp_tx_count,
|
||||
(unsigned long)g_eth_arp_tx_op,
|
||||
(unsigned long)g_eth_arp_tx_spa[0],
|
||||
(unsigned long)g_eth_arp_tx_spa[1],
|
||||
(unsigned long)g_eth_arp_tx_spa[2],
|
||||
(unsigned long)g_eth_arp_tx_spa[3],
|
||||
(unsigned long)g_eth_arp_tx_tpa[0],
|
||||
(unsigned long)g_eth_arp_tx_tpa[1],
|
||||
(unsigned long)g_eth_arp_tx_tpa[2],
|
||||
(unsigned long)g_eth_arp_tx_tpa[3]);
|
||||
debug_log_printf("[ARP] lwip c=%lu op=%lu fu=%lu mu=%lu sip=%lu.%lu.%lu.%lu dip=%lu.%lu.%lu.%lu\r\n",
|
||||
(unsigned long)g_eth_lwip_arp_seen_count,
|
||||
(unsigned long)g_eth_lwip_arp_opcode,
|
||||
(unsigned long)g_eth_lwip_arp_for_us,
|
||||
(unsigned long)g_eth_lwip_arp_from_us,
|
||||
(unsigned long)g_eth_lwip_arp_sip[0],
|
||||
(unsigned long)g_eth_lwip_arp_sip[1],
|
||||
(unsigned long)g_eth_lwip_arp_sip[2],
|
||||
(unsigned long)g_eth_lwip_arp_sip[3],
|
||||
(unsigned long)g_eth_lwip_arp_dip[0],
|
||||
(unsigned long)g_eth_lwip_arp_dip[1],
|
||||
(unsigned long)g_eth_lwip_arp_dip[2],
|
||||
(unsigned long)g_eth_lwip_arp_dip[3]);
|
||||
debug_log_printf("[ARP] edmx c=%lu type=0x%04lX len=%lu arpc=%lu\r\n",
|
||||
(unsigned long)g_eth_lwip_eth_seen_count,
|
||||
(unsigned long)g_eth_lwip_eth_last_type,
|
||||
(unsigned long)g_eth_lwip_eth_last_len,
|
||||
(unsigned long)g_eth_lwip_eth_arp_case_count);
|
||||
last_snapshot = xTaskGetTickCount();
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(500));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get SPI mutex handle for CH390 driver
|
||||
*/
|
||||
SemaphoreHandle_t get_ch390_spi_mutex(void)
|
||||
void MX_FREERTOS_Init(void)
|
||||
{
|
||||
return ch390SpiMutex;
|
||||
}
|
||||
uint32_t i;
|
||||
|
||||
/**
|
||||
* @brief Notify LwIP task of CH390 interrupt (call from ISR)
|
||||
*/
|
||||
void notify_ch390_interrupt_from_isr(void)
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
|
||||
if (ch390IntSemaphore != NULL)
|
||||
{
|
||||
xSemaphoreGiveFromISR(ch390IntSemaphore, &xHigherPriorityTaskWoken);
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
route_msg_init();
|
||||
configASSERT(uart_trans_init() == 0);
|
||||
debug_log_boot("uart-trans-init");
|
||||
|
||||
xNetSemaphore = xSemaphoreCreateBinary();
|
||||
xTcpRxQueue = xQueueCreate(8, sizeof(route_msg_t *));
|
||||
xConfigQueue = xQueueCreate(4, sizeof(route_msg_t *));
|
||||
for (i = 0; i < CONFIG_LINK_COUNT; ++i) {
|
||||
xLinkTxQueues[i] = xQueueCreate(4, sizeof(route_msg_t *));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get UART Server transparent task handle
|
||||
*/
|
||||
TaskHandle_t get_uart_server_task_handle(void)
|
||||
{
|
||||
return uartServerTransTaskHandle;
|
||||
}
|
||||
configASSERT(xNetSemaphore != NULL);
|
||||
configASSERT(xTcpRxQueue != NULL);
|
||||
configASSERT(xConfigQueue != NULL);
|
||||
for (i = 0; i < CONFIG_LINK_COUNT; ++i) {
|
||||
configASSERT(xLinkTxQueues[i] != NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get UART Client transparent task handle
|
||||
*/
|
||||
TaskHandle_t get_uart_client_task_handle(void)
|
||||
{
|
||||
return uartClientTransTaskHandle;
|
||||
}
|
||||
configASSERT(xTaskCreate(StartDefaultTask, "defaultTask", TASK_STACK_DEFAULT, NULL, TASK_PRIORITY_DEFAULT, &xDefaultTaskHandle) == pdPASS);
|
||||
|
||||
/* USER CODE END Application */
|
||||
configASSERT(xTaskCreate(NetPollTask, "NetPoll", TASK_STACK_NET_POLL, NULL, TASK_PRIORITY_NET_POLL, &xNetPollTaskHandle) == pdPASS);
|
||||
#if !DIAG_TASK_ISOLATION
|
||||
configASSERT(xTaskCreate(TcpSrvTask_S1, "TcpSrvS1", TASK_STACK_TCP_SERVER, NULL, TASK_PRIORITY_TCP_SERVER, &xTcpSrvTaskS1Handle) == pdPASS);
|
||||
configASSERT(xTaskCreate(TcpSrvTask_S2, "TcpSrvS2", TASK_STACK_TCP_SERVER, NULL, TASK_PRIORITY_TCP_SERVER, &xTcpSrvTaskS2Handle) == pdPASS);
|
||||
configASSERT(xTaskCreate(TcpCliTask_C1, "TcpCliC1", TASK_STACK_TCP_CLIENT, NULL, TASK_PRIORITY_TCP_CLIENT, &xTcpCliTaskC1Handle) == pdPASS);
|
||||
configASSERT(xTaskCreate(TcpCliTask_C2, "TcpCliC2", TASK_STACK_TCP_CLIENT, NULL, TASK_PRIORITY_TCP_CLIENT, &xTcpCliTaskC2Handle) == pdPASS);
|
||||
configASSERT(xTaskCreate(UartRxTask, "UartRx", TASK_STACK_UART_RX, NULL, TASK_PRIORITY_UART_RX, &xUartRxTaskHandle) == pdPASS);
|
||||
configASSERT(xTaskCreate(ConfigTask, "Config", TASK_STACK_CONFIG, NULL, TASK_PRIORITY_CONFIG, &xConfigTaskHandle) == pdPASS);
|
||||
#else
|
||||
debug_log_write("[DIAG] task-isolation enabled\r\n");
|
||||
#endif
|
||||
debug_log_boot("tasks-created");
|
||||
}
|
||||
|
||||
+5
-1
@@ -65,7 +65,7 @@ void MX_GPIO_Init(void)
|
||||
|
||||
/*Configure GPIO pin : PB0 */
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_0;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
@@ -76,6 +76,10 @@ void MX_GPIO_Init(void)
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/* EXTI interrupt init*/
|
||||
HAL_NVIC_SetPriority(EXTI0_IRQn, 6, 0);
|
||||
HAL_NVIC_EnableIRQ(EXTI0_IRQn);
|
||||
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 2 */
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ void MX_IWDG_Init(void)
|
||||
|
||||
/* USER CODE END IWDG_Init 1 */
|
||||
hiwdg.Instance = IWDG;
|
||||
hiwdg.Init.Prescaler = IWDG_PRESCALER_4;
|
||||
hiwdg.Init.Prescaler = IWDG_PRESCALER_64;
|
||||
hiwdg.Init.Reload = 4095;
|
||||
if (HAL_IWDG_Init(&hiwdg) != HAL_OK)
|
||||
{
|
||||
|
||||
+12
-16
@@ -29,10 +29,8 @@
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include <stdio.h>
|
||||
|
||||
#include "CH390.h"
|
||||
#include "config.h"
|
||||
#include "flash_param.h"
|
||||
#include "uart_trans.h"
|
||||
#include "debug_log.h"
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
@@ -70,6 +68,7 @@ void MX_FREERTOS_Init(void);
|
||||
/* USER CODE BEGIN PFP */
|
||||
static void CH390_HardwareReset(void);
|
||||
static void LED_Init(void);
|
||||
void Debug_TrapWithRttHint(const char *tag);
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* Private user code ---------------------------------------------------------*/
|
||||
@@ -129,14 +128,15 @@ int main(void)
|
||||
HAL_Init();
|
||||
|
||||
/* USER CODE BEGIN Init */
|
||||
|
||||
debug_log_init();
|
||||
debug_log_boot("hal-init");
|
||||
/* USER CODE END Init */
|
||||
|
||||
/* Configure the system clock */
|
||||
SystemClock_Config();
|
||||
|
||||
/* USER CODE BEGIN SysInit */
|
||||
|
||||
debug_log_boot("clock-config");
|
||||
/* USER CODE END SysInit */
|
||||
|
||||
/* Initialize all configured peripherals */
|
||||
@@ -148,6 +148,7 @@ int main(void)
|
||||
MX_USART3_UART_Init();
|
||||
MX_SPI1_Init();
|
||||
/* USER CODE BEGIN 2 */
|
||||
debug_log_boot("peripherals-ready");
|
||||
|
||||
/* LED 初始化 */
|
||||
LED_Init();
|
||||
@@ -157,14 +158,17 @@ int main(void)
|
||||
|
||||
/* Initialize configuration from Flash (fallback to defaults on invalid data) */
|
||||
config_init();
|
||||
debug_log_boot("config-ready");
|
||||
|
||||
/* USER CODE END 2 */
|
||||
|
||||
/* Init scheduler */
|
||||
osKernelInitialize(); /* Call init function for freertos objects (in cmsis_os2.c) */
|
||||
MX_FREERTOS_Init();
|
||||
debug_log_boot("freertos-init");
|
||||
|
||||
/* Start scheduler */
|
||||
debug_log_boot("scheduler-start");
|
||||
osKernelStart();
|
||||
|
||||
/* We should never get here as control is now taken by the scheduler */
|
||||
@@ -225,19 +229,10 @@ void SystemClock_Config(void)
|
||||
/**
|
||||
* @brief 重定向 printf 到 UART1(调试输出)
|
||||
*/
|
||||
#ifdef __GNUC__
|
||||
int _write(int file, char *ptr, int len)
|
||||
void Debug_TrapWithRttHint(const char *tag)
|
||||
{
|
||||
HAL_UART_Transmit(&huart1, (uint8_t *)ptr, len, HAL_MAX_DELAY);
|
||||
return len;
|
||||
debug_log_fault(tag);
|
||||
}
|
||||
#else
|
||||
int fputc(int ch, FILE *f)
|
||||
{
|
||||
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
|
||||
return ch;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* USER CODE END 4 */
|
||||
|
||||
@@ -249,6 +244,7 @@ void Error_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN Error_Handler_Debug */
|
||||
/* User can add his own implementation to report the HAL error return state */
|
||||
debug_log_fault("error-handler");
|
||||
__disable_irq();
|
||||
while (1)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
#include <rt_sys.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#pragma import(__use_no_semihosting)
|
||||
|
||||
const char __stdin_name[] = ":tt";
|
||||
const char __stdout_name[] = ":tt";
|
||||
const char __stderr_name[] = ":tt";
|
||||
|
||||
#define NULL_FH_STDIN 0x8001
|
||||
#define NULL_FH_STDOUT 0x8002
|
||||
#define NULL_FH_STDERR 0x8003
|
||||
|
||||
static int rtt_is_terminal_name(const char *name)
|
||||
{
|
||||
return (name != NULL) && (strcmp(name, ":tt") == 0);
|
||||
}
|
||||
|
||||
FILEHANDLE _sys_open(const char *name, int openmode)
|
||||
{
|
||||
if (!rtt_is_terminal_name(name)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((openmode & OPEN_W) == OPEN_W) {
|
||||
return NULL_FH_STDOUT;
|
||||
}
|
||||
|
||||
if ((openmode & OPEN_A) == OPEN_A) {
|
||||
return NULL_FH_STDERR;
|
||||
}
|
||||
|
||||
return NULL_FH_STDIN;
|
||||
}
|
||||
|
||||
int _sys_close(FILEHANDLE fh)
|
||||
{
|
||||
(void)fh;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _sys_write(FILEHANDLE fh, const unsigned char *buf, unsigned len, int mode)
|
||||
{
|
||||
(void)mode;
|
||||
|
||||
if ((fh != NULL_FH_STDOUT) && (fh != NULL_FH_STDERR)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((buf == NULL) || (len == 0u)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
(void)buf;
|
||||
(void)len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _sys_read(FILEHANDLE fh, unsigned char *buf, unsigned len, int mode)
|
||||
{
|
||||
(void)fh;
|
||||
(void)buf;
|
||||
(void)len;
|
||||
(void)mode;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _sys_istty(FILEHANDLE fh)
|
||||
{
|
||||
return (fh == NULL_FH_STDIN) || (fh == NULL_FH_STDOUT) || (fh == NULL_FH_STDERR);
|
||||
}
|
||||
|
||||
int _sys_seek(FILEHANDLE fh, long pos)
|
||||
{
|
||||
(void)fh;
|
||||
(void)pos;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _sys_ensure(FILEHANDLE fh)
|
||||
{
|
||||
(void)fh;
|
||||
return 0;
|
||||
}
|
||||
|
||||
long _sys_flen(FILEHANDLE fh)
|
||||
{
|
||||
(void)fh;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _sys_tmpnam(char *name, int sig, unsigned maxlen)
|
||||
{
|
||||
(void)name;
|
||||
(void)sig;
|
||||
(void)maxlen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *_sys_command_string(char *cmd, int len)
|
||||
{
|
||||
(void)cmd;
|
||||
(void)len;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void _ttywrch(int ch)
|
||||
{
|
||||
(void)ch;
|
||||
}
|
||||
|
||||
void _sys_exit(int returncode)
|
||||
{
|
||||
(void)returncode;
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
#include "stm32f1xx_hal.h"
|
||||
|
||||
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
|
||||
{
|
||||
RCC_ClkInitTypeDef clkconfig;
|
||||
uint32_t pFLatency;
|
||||
uint32_t uwTimclock;
|
||||
uint32_t uwPrescalerValue;
|
||||
|
||||
__HAL_RCC_TIM4_CLK_ENABLE();
|
||||
|
||||
HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);
|
||||
uwTimclock = HAL_RCC_GetPCLK1Freq();
|
||||
if (clkconfig.APB1CLKDivider != RCC_HCLK_DIV1) {
|
||||
uwTimclock *= 2u;
|
||||
}
|
||||
|
||||
uwPrescalerValue = (uwTimclock / 1000000u) - 1u;
|
||||
|
||||
TIM4->PSC = uwPrescalerValue;
|
||||
TIM4->ARR = 1000u - 1u;
|
||||
TIM4->EGR = TIM_EGR_UG;
|
||||
TIM4->DIER |= TIM_DIER_UIE;
|
||||
TIM4->CR1 |= TIM_CR1_CEN;
|
||||
|
||||
HAL_NVIC_SetPriority(TIM4_IRQn, TickPriority, 0u);
|
||||
HAL_NVIC_EnableIRQ(TIM4_IRQn);
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
HAL_StatusTypeDef HAL_DeInitTick(void)
|
||||
{
|
||||
TIM4->CR1 &= ~TIM_CR1_CEN;
|
||||
TIM4->DIER &= ~TIM_DIER_UIE;
|
||||
HAL_NVIC_DisableIRQ(TIM4_IRQn);
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
void HAL_SuspendTick(void)
|
||||
{
|
||||
TIM4->DIER &= ~TIM_DIER_UIE;
|
||||
}
|
||||
|
||||
void HAL_ResumeTick(void)
|
||||
{
|
||||
TIM4->DIER |= TIM_DIER_UIE;
|
||||
}
|
||||
+84
-338
@@ -1,67 +1,14 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f1xx_it.c
|
||||
* @brief Interrupt Service Routines.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2026 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
#include "stm32f1xx_it.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include "uart_trans.h"
|
||||
|
||||
#include "app_runtime.h"
|
||||
#include "config.h"
|
||||
#include "debug_log.h"
|
||||
#include "uart_trans.h"
|
||||
|
||||
/* External functions from freertos.c */
|
||||
extern void notify_ch390_interrupt_from_isr(void);
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN TD */
|
||||
|
||||
/* USER CODE END TD */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PD */
|
||||
|
||||
/* USER CODE END PD */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PM */
|
||||
|
||||
/* USER CODE END PM */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PV */
|
||||
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* USER CODE BEGIN PFP */
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* Private user code ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
/* External variables --------------------------------------------------------*/
|
||||
extern SPI_HandleTypeDef hspi1;
|
||||
extern DMA_HandleTypeDef hdma_usart1_rx;
|
||||
extern DMA_HandleTypeDef hdma_usart1_tx;
|
||||
@@ -72,343 +19,142 @@ extern DMA_HandleTypeDef hdma_usart3_tx;
|
||||
extern UART_HandleTypeDef huart1;
|
||||
extern UART_HandleTypeDef huart2;
|
||||
extern UART_HandleTypeDef huart3;
|
||||
/* USER CODE BEGIN EV */
|
||||
|
||||
/* USER CODE END EV */
|
||||
|
||||
/******************************************************************************/
|
||||
/* Cortex-M3 Processor Interruption and Exception Handlers */
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* @brief This function handles Non maskable interrupt.
|
||||
*/
|
||||
void NMI_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
|
||||
|
||||
/* USER CODE END NonMaskableInt_IRQn 0 */
|
||||
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
/* USER CODE END NonMaskableInt_IRQn 1 */
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Hard fault interrupt.
|
||||
*/
|
||||
void HardFault_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN HardFault_IRQn 0 */
|
||||
|
||||
/* USER CODE END HardFault_IRQn 0 */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
|
||||
/* USER CODE END W1_HardFault_IRQn 0 */
|
||||
}
|
||||
Debug_TrapWithRttHint("hardfault");
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Memory management fault.
|
||||
*/
|
||||
void MemManage_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
|
||||
|
||||
/* USER CODE END MemoryManagement_IRQn 0 */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
|
||||
/* USER CODE END W1_MemoryManagement_IRQn 0 */
|
||||
}
|
||||
Debug_TrapWithRttHint("memmanage");
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Prefetch fault, memory access fault.
|
||||
*/
|
||||
void BusFault_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN BusFault_IRQn 0 */
|
||||
|
||||
/* USER CODE END BusFault_IRQn 0 */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE BEGIN W1_BusFault_IRQn 0 */
|
||||
/* USER CODE END W1_BusFault_IRQn 0 */
|
||||
}
|
||||
Debug_TrapWithRttHint("busfault");
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Undefined instruction or illegal state.
|
||||
*/
|
||||
void UsageFault_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN UsageFault_IRQn 0 */
|
||||
|
||||
/* USER CODE END UsageFault_IRQn 0 */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE BEGIN W1_UsageFault_IRQn 0 */
|
||||
/* USER CODE END W1_UsageFault_IRQn 0 */
|
||||
}
|
||||
Debug_TrapWithRttHint("usagefault");
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Debug monitor.
|
||||
*/
|
||||
void DebugMon_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
|
||||
|
||||
/* USER CODE END DebugMonitor_IRQn 0 */
|
||||
/* USER CODE BEGIN DebugMonitor_IRQn 1 */
|
||||
|
||||
/* USER CODE END DebugMonitor_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles System tick timer.
|
||||
*/
|
||||
void SysTick_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN SysTick_IRQn 0 */
|
||||
|
||||
/* USER CODE END SysTick_IRQn 0 */
|
||||
HAL_IncTick();
|
||||
#if (INCLUDE_xTaskGetSchedulerState == 1 )
|
||||
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
|
||||
{
|
||||
#endif /* INCLUDE_xTaskGetSchedulerState */
|
||||
xPortSysTickHandler();
|
||||
#if (INCLUDE_xTaskGetSchedulerState == 1 )
|
||||
}
|
||||
#endif /* INCLUDE_xTaskGetSchedulerState */
|
||||
/* USER CODE BEGIN SysTick_IRQn 1 */
|
||||
|
||||
/* USER CODE END SysTick_IRQn 1 */
|
||||
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||
xPortSysTickHandler();
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* STM32F1xx Peripheral Interrupt Handlers */
|
||||
/* Add here the Interrupt Handlers for the used peripherals. */
|
||||
/* For the available peripheral interrupt handler names, */
|
||||
/* please refer to the startup file (startup_stm32f1xx.s). */
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief This function handles DMA1 channel2 global interrupt.
|
||||
*/
|
||||
void DMA1_Channel2_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN DMA1_Channel2_IRQn 0 */
|
||||
|
||||
/* USER CODE END DMA1_Channel2_IRQn 0 */
|
||||
HAL_DMA_IRQHandler(&hdma_usart3_tx);
|
||||
/* USER CODE BEGIN DMA1_Channel2_IRQn 1 */
|
||||
|
||||
/* USER CODE END DMA1_Channel2_IRQn 1 */
|
||||
HAL_DMA_IRQHandler(&hdma_usart3_tx);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles DMA1 channel3 global interrupt.
|
||||
*/
|
||||
void DMA1_Channel3_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN DMA1_Channel3_IRQn 0 */
|
||||
|
||||
/* USER CODE END DMA1_Channel3_IRQn 0 */
|
||||
HAL_DMA_IRQHandler(&hdma_usart3_rx);
|
||||
/* USER CODE BEGIN DMA1_Channel3_IRQn 1 */
|
||||
|
||||
/* USER CODE END DMA1_Channel3_IRQn 1 */
|
||||
HAL_DMA_IRQHandler(&hdma_usart3_rx);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles DMA1 channel4 global interrupt.
|
||||
*/
|
||||
void DMA1_Channel4_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN DMA1_Channel4_IRQn 0 */
|
||||
|
||||
/* USER CODE END DMA1_Channel4_IRQn 0 */
|
||||
HAL_DMA_IRQHandler(&hdma_usart1_tx);
|
||||
/* USER CODE BEGIN DMA1_Channel4_IRQn 1 */
|
||||
|
||||
/* USER CODE END DMA1_Channel4_IRQn 1 */
|
||||
HAL_DMA_IRQHandler(&hdma_usart1_tx);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles DMA1 channel5 global interrupt.
|
||||
*/
|
||||
void DMA1_Channel5_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN DMA1_Channel5_IRQn 0 */
|
||||
|
||||
/* USER CODE END DMA1_Channel5_IRQn 0 */
|
||||
HAL_DMA_IRQHandler(&hdma_usart1_rx);
|
||||
/* USER CODE BEGIN DMA1_Channel5_IRQn 1 */
|
||||
|
||||
/* USER CODE END DMA1_Channel5_IRQn 1 */
|
||||
HAL_DMA_IRQHandler(&hdma_usart1_rx);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles DMA1 channel6 global interrupt.
|
||||
*/
|
||||
void DMA1_Channel6_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN DMA1_Channel6_IRQn 0 */
|
||||
|
||||
/* USER CODE END DMA1_Channel6_IRQn 0 */
|
||||
HAL_DMA_IRQHandler(&hdma_usart2_rx);
|
||||
/* USER CODE BEGIN DMA1_Channel6_IRQn 1 */
|
||||
|
||||
/* USER CODE END DMA1_Channel6_IRQn 1 */
|
||||
HAL_DMA_IRQHandler(&hdma_usart2_rx);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles DMA1 channel7 global interrupt.
|
||||
*/
|
||||
void DMA1_Channel7_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN DMA1_Channel7_IRQn 0 */
|
||||
|
||||
/* USER CODE END DMA1_Channel7_IRQn 0 */
|
||||
HAL_DMA_IRQHandler(&hdma_usart2_tx);
|
||||
/* USER CODE BEGIN DMA1_Channel7_IRQn 1 */
|
||||
|
||||
/* USER CODE END DMA1_Channel7_IRQn 1 */
|
||||
HAL_DMA_IRQHandler(&hdma_usart2_tx);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles SPI1 global interrupt.
|
||||
*/
|
||||
void SPI1_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN SPI1_IRQn 0 */
|
||||
|
||||
/* USER CODE END SPI1_IRQn 0 */
|
||||
HAL_SPI_IRQHandler(&hspi1);
|
||||
/* USER CODE BEGIN SPI1_IRQn 1 */
|
||||
|
||||
/* USER CODE END SPI1_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles USART1 global interrupt.
|
||||
*/
|
||||
void USART1_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN USART1_IRQn 0 */
|
||||
/* Handle IDLE interrupt for configuration */
|
||||
if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))
|
||||
{
|
||||
__HAL_UART_CLEAR_IDLEFLAG(&huart1);
|
||||
config_uart_idle_handler();
|
||||
}
|
||||
/* USER CODE END USART1_IRQn 0 */
|
||||
HAL_UART_IRQHandler(&huart1);
|
||||
/* USER CODE BEGIN USART1_IRQn 1 */
|
||||
|
||||
/* USER CODE END USART1_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles USART2 global interrupt.
|
||||
*/
|
||||
void USART2_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN USART2_IRQn 0 */
|
||||
/* Handle IDLE interrupt for Server transparent transmission */
|
||||
if (__HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE))
|
||||
{
|
||||
__HAL_UART_CLEAR_IDLEFLAG(&huart2);
|
||||
uart_trans_idle_handler(UART_CHANNEL_SERVER);
|
||||
}
|
||||
/* USER CODE END USART2_IRQn 0 */
|
||||
HAL_UART_IRQHandler(&huart2);
|
||||
/* USER CODE BEGIN USART2_IRQn 1 */
|
||||
|
||||
/* USER CODE END USART2_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles USART3 global interrupt.
|
||||
*/
|
||||
void USART3_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN USART3_IRQn 0 */
|
||||
/* Handle IDLE interrupt for Client transparent transmission */
|
||||
if (__HAL_UART_GET_FLAG(&huart3, UART_FLAG_IDLE))
|
||||
{
|
||||
__HAL_UART_CLEAR_IDLEFLAG(&huart3);
|
||||
uart_trans_idle_handler(UART_CHANNEL_CLIENT);
|
||||
}
|
||||
/* USER CODE END USART3_IRQn 0 */
|
||||
HAL_UART_IRQHandler(&huart3);
|
||||
/* USER CODE BEGIN USART3_IRQn 1 */
|
||||
|
||||
/* USER CODE END USART3_IRQn 1 */
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
/**
|
||||
* @brief This function handles EXTI0 interrupt (CH390D INT pin).
|
||||
*/
|
||||
void EXTI0_IRQHandler(void)
|
||||
{
|
||||
/* Clear interrupt flag */
|
||||
if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_0))
|
||||
{
|
||||
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_0);
|
||||
|
||||
/* Notify LwIP task */
|
||||
notify_ch390_interrupt_from_isr();
|
||||
}
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
|
||||
if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_0) != RESET) {
|
||||
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_0);
|
||||
xSemaphoreGiveFromISR(xNetSemaphore, &xHigherPriorityTaskWoken);
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
}
|
||||
|
||||
void SPI1_IRQHandler(void)
|
||||
{
|
||||
HAL_SPI_IRQHandler(&hspi1);
|
||||
}
|
||||
|
||||
void USART1_IRQHandler(void)
|
||||
{
|
||||
if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) != RESET) {
|
||||
__HAL_UART_CLEAR_IDLEFLAG(&huart1);
|
||||
config_uart_idle_handler();
|
||||
}
|
||||
HAL_UART_IRQHandler(&huart1);
|
||||
}
|
||||
|
||||
void USART2_IRQHandler(void)
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
if (__HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE) != RESET) {
|
||||
__HAL_UART_CLEAR_IDLEFLAG(&huart2);
|
||||
uart_trans_notify_rx_from_isr(UART_CHANNEL_U0, &xHigherPriorityTaskWoken);
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
HAL_UART_IRQHandler(&huart2);
|
||||
}
|
||||
|
||||
void USART3_IRQHandler(void)
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
if (__HAL_UART_GET_FLAG(&huart3, UART_FLAG_IDLE) != RESET) {
|
||||
__HAL_UART_CLEAR_IDLEFLAG(&huart3);
|
||||
uart_trans_notify_rx_from_isr(UART_CHANNEL_U1, &xHigherPriorityTaskWoken);
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
HAL_UART_IRQHandler(&huart3);
|
||||
}
|
||||
|
||||
void TIM4_IRQHandler(void)
|
||||
{
|
||||
if ((TIM4->SR & TIM_SR_UIF) != 0u) {
|
||||
TIM4->SR &= ~TIM_SR_UIF;
|
||||
}
|
||||
HAL_IncTick();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief HAL UART TX Complete callback
|
||||
*/
|
||||
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
|
||||
{
|
||||
if (huart == &huart2)
|
||||
{
|
||||
uart_trans_tx_cplt_handler(UART_CHANNEL_SERVER);
|
||||
}
|
||||
else if (huart == &huart3)
|
||||
{
|
||||
uart_trans_tx_cplt_handler(UART_CHANNEL_CLIENT);
|
||||
}
|
||||
if (huart == &huart2) {
|
||||
uart_trans_tx_cplt_handler(UART_CHANNEL_U0);
|
||||
} else if (huart == &huart3) {
|
||||
uart_trans_tx_cplt_handler(UART_CHANNEL_U1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief HAL UART RX Complete callback
|
||||
*/
|
||||
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
|
||||
{
|
||||
if (huart == &huart2)
|
||||
{
|
||||
uart_trans_rx_cplt_handler(UART_CHANNEL_SERVER);
|
||||
}
|
||||
else if (huart == &huart3)
|
||||
{
|
||||
uart_trans_rx_cplt_handler(UART_CHANNEL_CLIENT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief HAL UART RX Half Complete callback
|
||||
*/
|
||||
void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart)
|
||||
{
|
||||
if (huart == &huart2)
|
||||
{
|
||||
uart_trans_rx_half_cplt_handler(UART_CHANNEL_SERVER);
|
||||
}
|
||||
else if (huart == &huart3)
|
||||
{
|
||||
uart_trans_rx_half_cplt_handler(UART_CHANNEL_CLIENT);
|
||||
}
|
||||
}
|
||||
/* USER CODE END 1 */
|
||||
|
||||
Reference in New Issue
Block a user