From c63d3c4d7947e73953cf6a5aefa1bebdf2fddc84 Mon Sep 17 00:00:00 2001 From: Qx <1061669537@qq.com> Date: Mon, 2 Jun 2025 22:49:51 +0800 Subject: [PATCH] =?UTF-8?q?refactor(freertos):=20=E9=87=8D=E6=9E=84=20Free?= =?UTF-8?q?RTOS=20=E4=BB=BB=E5=8A=A1=E5=B9=B6=E6=B7=BB=E5=8A=A0=E6=96=B0?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 合并多个任务为 IO 控制和 DAC 控制任务 - 添加 DMA 测试任务和相关功能 - 优化 TCA6416 扫描周期 - 调整任务优先级和栈大小 - 添加事件组支持 --- Core/Src/freertos.c | 489 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 384 insertions(+), 105 deletions(-) diff --git a/Core/Src/freertos.c b/Core/Src/freertos.c index ca73d4e..8b8f94f 100644 --- a/Core/Src/freertos.c +++ b/Core/Src/freertos.c @@ -22,6 +22,7 @@ #include "task.h" #include "main.h" #include "cmsis_os.h" +#include "event_groups.h" // 添加事件组支持 /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ @@ -69,15 +70,11 @@ extern ad7124_analog_t ad7124_analog[AD7124_CHANNEL_EN_MAX]; /* USER CODE BEGIN Variables */ osThreadId lwip_taskHandle; osThreadId led_taskHandle; -osThreadId dac_taskHandle; osThreadId adc_taskHandle; -osThreadId gpio_di_do_taskHandle; -osThreadId ec11_taskHandle; -osThreadId ad7124_test_taskHandle; -osThreadId usart6_test_taskHandle; // 添加USART6测试任务句柄 -osThreadId tca6416_taskHandle; // 添加TCA6416任务句柄 -osThreadId dac161s997_test_taskHandle; // 添加DAC161S997测试任务句柄 -osThreadId dac8568_test_taskHandle; // 添加DAC8568测试任务句柄 +osThreadId io_control_taskHandle; // 合并后的IO控制任务 +osThreadId dac_control_taskHandle; // 合并后的DAC控制任务 +osThreadId usart6_test_taskHandle; +osThreadId dma_test_taskHandle; // 添加DMA测试任务句柄 // 添加调试变量 static volatile uint32_t uart6_dr_raw = 0; // UART数据寄存器的原始值 @@ -128,6 +125,39 @@ static uint8_t uart6_data_buffer[UART6_BUFFER_SIZE]; static volatile uint16_t uart6_buffer_index = 0; static volatile uint32_t uart6_last_rx_time = 0; +// 添加任务同步对象 +osSemaphoreId adc_semaphoreHandle; +osSemaphoreId uart6_semaphoreHandle; +osSemaphoreId io_semaphoreHandle; // IO控制任务信号量 +osSemaphoreId dac_semaphoreHandle; // DAC控制任务信号量 + +// DMA测试相关变量 +#define DMA_UART_RX_BUFFER_SIZE 256 +#define DMA_UART_TX_BUFFER_SIZE 256 +#define DMA_ADC_BUFFER_SIZE 32 +#define DMA_DAC_BUFFER_SIZE 32 + +static uint8_t dma_uart_rx_buffer[DMA_UART_RX_BUFFER_SIZE]; +static uint8_t dma_uart_tx_buffer[DMA_UART_TX_BUFFER_SIZE]; +static uint16_t dma_adc_buffer[DMA_ADC_BUFFER_SIZE]; +static uint16_t dma_dac_buffer[DMA_DAC_BUFFER_SIZE]; + +// DMA传输状态标志 +volatile uint8_t dma_uart_rx_complete = 0; +volatile uint8_t dma_uart_tx_complete = 0; +volatile uint8_t dma_adc_complete = 0; +volatile uint8_t dma_dac_complete = 0; +volatile uint16_t dma_uart_rx_count = 0; +volatile uint16_t dma_uart_tx_count = 0; +volatile uint16_t dma_adc_count = 0; +volatile uint16_t dma_dac_count = 0; + +// DMA错误计数 +volatile uint32_t dma_uart_rx_errors = 0; +volatile uint32_t dma_uart_tx_errors = 0; +volatile uint32_t dma_adc_errors = 0; +volatile uint32_t dma_dac_errors = 0; + /* USER CODE END Variables */ /* Private function prototypes -----------------------------------------------*/ @@ -144,22 +174,16 @@ extern struct tcp_pcb *server_pcb_control; extern void tcp_abort(struct tcp_pcb *pcb); void start_usart6_test_task(void const *argument); // 添加USART6测试任务函数声明 -void start_tca6416_task(void const *argument); // 添加TCA6416任务函数声明 -void test_tca6416_task(void const *argument); // 添加TCA6416测试任务函数声明 -void start_dac161s997_test_task(void const *argument); // 添加DAC161S997测试任务函数声明 -void start_dac8568_test_task(void const *argument); // 添加DAC8568测试任务函数声明 +void start_io_control_task(void const *argument); // 添加IO控制任务函数声明 +void start_dac_control_task(void const *argument); // 添加DAC控制任务函数声明 +void start_dma_test_task(void const *argument); // 添加DMA测试任务函数声明 /* USER CODE END FunctionPrototypes */ void start_tcp_task(void const *argument); void start_led_toggle_task(void const *argument); -void start_dac_task(void const *argument); void start_adc_task(void const *argument); -void start_gpio_di_do_task(void const *argument); -void start_ec11_task(void const *argument); -void start_ad7124_test_task(void const *argument); -void ad7124_multi_channel_init(uint8_t sample_rate); -void start_adc_task(void const *argument); -void test_cs_pin(void); +void start_io_control_task(void const *argument); +void start_dac_control_task(void const *argument); extern void MX_LWIP_Init(void); void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */ @@ -188,37 +212,45 @@ void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackTyp void MX_FREERTOS_Init(void) { /* USER CODE BEGIN Init */ + + // 创建同步对象 + osSemaphoreDef(adc_semaphore); + adc_semaphoreHandle = osSemaphoreCreate(osSemaphore(adc_semaphore), 1); + + osSemaphoreDef(uart6_semaphore); + uart6_semaphoreHandle = osSemaphoreCreate(osSemaphore(uart6_semaphore), 1); + + osSemaphoreDef(io_semaphore); + io_semaphoreHandle = osSemaphoreCreate(osSemaphore(io_semaphore), 1); + + osSemaphoreDef(dac_semaphore); + dac_semaphoreHandle = osSemaphoreCreate(osSemaphore(dac_semaphore), 1); /* Create the thread(s) */ /* definition and creation of lwip_task */ osThreadDef(lwip_task, start_tcp_task, osPriorityHigh, 0, 512); lwip_taskHandle = osThreadCreate(osThread(lwip_task), NULL); - - osThreadDef(adc_task, start_adc_task, osPriorityBelowNormal, 0, 128); - adc_taskHandle = osThreadCreate(osThread(adc_task), NULL); - - - /* HART测试任务 */ - osThreadDef(usart6_test_task, start_usart6_test_task, osPriorityNormal, 0, 128); + /* HART测试任务 - 提高优先级和栈大小 */ + osThreadDef(usart6_test_task, start_usart6_test_task, osPriorityAboveNormal, 0, 256); usart6_test_taskHandle = osThreadCreate(osThread(usart6_test_task), NULL); - /* TCA6416任务 */ - osThreadDef(tca6416_task, test_tca6416_task, osPriorityNormal, 0, 128); - tca6416_taskHandle = osThreadCreate(osThread(tca6416_task), NULL); + /* ADC任务 - 提高优先级和栈大小 */ + osThreadDef(adc_task, start_adc_task, osPriorityNormal, 0, 256); + adc_taskHandle = osThreadCreate(osThread(adc_task), NULL); + /* IO控制任务 - 合并TCA6416和GPIO控制 */ + osThreadDef(io_control_task, start_io_control_task, osPriorityNormal, 0, 384); + io_control_taskHandle = osThreadCreate(osThread(io_control_task), NULL); + /* DAC控制任务 - 合并DAC161S997和DAC8568控制 */ + osThreadDef(dac_control_task, start_dac_control_task, osPriorityBelowNormal, 0, 384); + dac_control_taskHandle = osThreadCreate(osThread(dac_control_task), NULL); - /* DAC161S997测试任务 */ - osThreadDef(dac161s997_test_task, start_dac161s997_test_task, osPriorityNormal, 0, 128); - dac161s997_test_taskHandle = osThreadCreate(osThread(dac161s997_test_task), NULL); + /* DMA测试任务 - 使用较高优先级以确保及时处理DMA事件 */ + osThreadDef(dma_test_task, start_dma_test_task, osPriorityAboveNormal, 0, 384); + dma_test_taskHandle = osThreadCreate(osThread(dma_test_task), NULL); - /* DAC8568测试任务 */ - osThreadDef(dac8568_test_task, start_dac8568_test_task, osPriorityLow, 0, 256); - dac8568_test_taskHandle = osThreadCreate(osThread(dac8568_test_task), NULL); - - /* USER CODE BEGIN RTOS_THREADS */ - /* add threads, ... */ /* USER CODE END RTOS_THREADS */ } @@ -350,44 +382,158 @@ void start_adc_task(void const *argument) /* USER CODE END start_adc_task */ } -/* USER CODE BEGIN Header_start_gpio_di_do_task */ +/* USER CODE BEGIN Header_start_io_control_task */ /** - * @brief Function implementing the gpio_di_do_task thread. + * @brief Function implementing the io_control_task thread. * @param argument: Not used * @retval None */ -/* USER CODE END Header_start_gpio_di_do_task */ -void start_gpio_di_do_task(void const *argument) +/* USER CODE END Header_start_io_control_task */ +void start_io_control_task(void const *argument) { - /* USER CODE BEGIN start_gpio_di_do_task */ - /* Infinite loop */ - for (;;) - { - user_gpio_trigger(); - vTaskDelay(100); - } - /* USER CODE END start_gpio_di_do_task */ + /* USER CODE BEGIN start_io_control_task */ + uint8_t ret = 0; + uint8_t addr_scan_result[8] = {0}; + + // 等待系统稳定 + osDelay(100); + + // 初始化TCA6416 + tca6416_test_step = 0; + for(uint8_t addr = 0x20; addr <= 0x27; addr++) + { + I2C_Start(); + ret = I2C_SendByte(addr << 1); + I2C_Stop(); + addr_scan_result[addr - 0x20] = ret; + osDelay(10); + } + + // 初始化三个TCA6416芯片 + tca6416_init_result = TCA6416_Init(); + tca6416_init2_result = TCA6416_Init2(); + tca6416_init3_result = TCA6416_Init3(); + + // 配置TCA6416端口方向 + TCA6416_SetPortDirection(0, 0x00); // Port0输出 + TCA6416_SetPortDirection(1, 0x00); // Port1输出 + + if(tca6416_init2_result == 0) + { + TCA6416_SetPortDirection2(0, 0xFF); // Port0输入 + TCA6416_SetPortDirection2(1, 0xFF); // Port1输入 + } + + if(tca6416_init3_result == 0) + { + TCA6416_SetPortDirection3(0, 0xFF); // Port0输入 + TCA6416_SetPortDirection3(1, 0xFF); // Port1输入 + } + + /* Infinite loop */ + for(;;) + { + // 获取信号量 + if(osSemaphoreWait(io_semaphoreHandle, 100) == osOK) + { + // 处理GPIO输入输出 + user_gpio_trigger(); + + // 读取TCA6416状态 + if(TCA6416_ReadPort(0, &tca6416_read_data) == 0) + { + tca6416_port0_status = tca6416_read_data; + } + + if(TCA6416_ReadPort(1, &tca6416_read_data) == 0) + { + tca6416_port1_status = tca6416_read_data; + } + + if(tca6416_init2_result == 0) + { + if(TCA6416_ReadPort2(0, &tca6416_read_data) == 0) + { + tca6416_port2_status = tca6416_read_data; + } + + if(TCA6416_ReadPort2(1, &tca6416_read_data) == 0) + { + tca6416_port3_status = tca6416_read_data; + } + } + + if(tca6416_init3_result == 0) + { + if(TCA6416_ReadPort3(0, &tca6416_read_data) == 0) + { + tca6416_port4_status = tca6416_read_data; + } + + if(TCA6416_ReadPort3(1, &tca6416_read_data) == 0) + { + tca6416_port5_status = tca6416_read_data; + } + } + + // 释放信号量 + osSemaphoreRelease(io_semaphoreHandle); + } + + // 200ms扫描周期 + osDelay(200); + } + /* USER CODE END start_io_control_task */ } -/* USER CODE BEGIN Header_start_ec11_task */ +/* USER CODE BEGIN Header_start_dac_control_task */ /** - * @brief Function implementing the ec11_task thread. + * @brief Function implementing the dac_control_task thread. * @param argument: Not used * @retval None */ -/* USER CODE END Header_start_ec11_task */ -void start_ec11_task(void const *argument) +/* USER CODE END Header_start_dac_control_task */ +void start_dac_control_task(void const *argument) { - /* USER CODE BEGIN start_ec11_task */ - /* Infinite loop */ - for (;;) - { - linear_encoder_get_data(); - uart_lcd_ec11_control_current(); - uart_forwarding_tcp(); - vTaskDelay(10); - } - /* USER CODE END start_ec11_task */ + /* USER CODE BEGIN start_dac_control_task */ + // 等待系统稳定 + osDelay(1000); + + // 初始化DAC161S997 + dac161s997_init(); + uint16_t init_status = dac161s997_read_status(DAC161S997); + if(init_status == 0xFFFF || init_status == 0x0000) { + osDelay(100); + dac161s997_init(); + } + + // 初始化DAC8568 + DAC8568_Init(&hspi3); + HAL_Delay(10); + DAC8568_EnableStaticInternalRef(); + + /* Infinite loop */ + for(;;) + { + // 获取信号量 + if(osSemaphoreWait(dac_semaphoreHandle, 100) == osOK) + { + // 处理DAC161S997输出 + // current_buff[0] = 12.0f; // 示例值 + // dac161s997_output(DAC161S997, current_buff[0]); + + // 处理DAC8568输出 + // uint16_t dac_value = 32768; // 示例值 + // DAC8568_WriteAndUpdate(BROADCAST, dac_value); + + // 释放信号量 + osSemaphoreRelease(dac_semaphoreHandle); + } + + // 500ms更新周期 + osDelay(500); + } + /* USER CODE END start_dac_control_task */ } // 添加UART接收回调函数声明 @@ -547,7 +693,7 @@ void test_tca6416_task(void const *argument) { /* USER CODE BEGIN test_tca6416_task */ uint8_t ret = 0; - uint8_t addr_scan_result[8] = {0}; // 存储地址扫描结果 + uint8_t addr_scan_result[8] = {0}; // 等待系统稳定 osDelay(100); @@ -603,58 +749,59 @@ void test_tca6416_task(void const *argument) osDelay(10); } - // 步骤6: 循环检测所有芯片状态 + // 步骤6: 循环检测所有芯片状态 - 优化扫描周期 tca6416_test_step = 6; for(;;) { - // 读取第一个芯片状态(由tcpecho_recv_control控制输出) - if(TCA6416_ReadPort(0, &tca6416_read_data) == 0) + // 获取信号量 + if(osSemaphoreWait(tca6416_semaphoreHandle, 100) == osOK) { - tca6416_port0_status = tca6416_read_data; - } - osDelay(10); - - if(TCA6416_ReadPort(1, &tca6416_read_data) == 0) - { - tca6416_port1_status = tca6416_read_data; - } - osDelay(10); - - // 读取第二个芯片状态(如果初始化成功) - if(tca6416_init2_result == 0) - { - if(TCA6416_ReadPort2(0, &tca6416_read_data) == 0) + // 读取第一个芯片状态 + if(TCA6416_ReadPort(0, &tca6416_read_data) == 0) { - tca6416_port2_status = tca6416_read_data; + tca6416_port0_status = tca6416_read_data; } - osDelay(10); - if(TCA6416_ReadPort2(1, &tca6416_read_data) == 0) + if(TCA6416_ReadPort(1, &tca6416_read_data) == 0) { - tca6416_port3_status = tca6416_read_data; + tca6416_port1_status = tca6416_read_data; } - osDelay(10); - } - - // 读取第三个芯片状态(如果初始化成功) - if(tca6416_init3_result == 0) - { - if(TCA6416_ReadPort3(0, &tca6416_read_data) == 0) - { - tca6416_port4_status = tca6416_read_data; - } - osDelay(10); - if(TCA6416_ReadPort3(1, &tca6416_read_data) == 0) + // 读取第二个芯片状态 + if(tca6416_init2_result == 0) { - tca6416_port5_status = tca6416_read_data; + if(TCA6416_ReadPort2(0, &tca6416_read_data) == 0) + { + tca6416_port2_status = tca6416_read_data; + } + + if(TCA6416_ReadPort2(1, &tca6416_read_data) == 0) + { + tca6416_port3_status = tca6416_read_data; + } } - osDelay(10); + + // 读取第三个芯片状态 + if(tca6416_init3_result == 0) + { + if(TCA6416_ReadPort3(0, &tca6416_read_data) == 0) + { + tca6416_port4_status = tca6416_read_data; + } + + if(TCA6416_ReadPort3(1, &tca6416_read_data) == 0) + { + tca6416_port5_status = tca6416_read_data; + } + } + + // 释放信号量 + osSemaphoreRelease(tca6416_semaphoreHandle); } - // 总延时1秒后重复 - osDelay(800); + // 缩短扫描周期到200ms + osDelay(200); } /* USER CODE END test_tca6416_task */ } @@ -687,8 +834,8 @@ void start_dac161s997_test_task(void const *argument) for (;;) { // 设置输出电流为10mA - current_buff[0] = 12.0f; - dac161s997_output(DAC161S997, current_buff[0]); + //current_buff[0] = 12.0f; + //dac161s997_output(DAC161S997, current_buff[0]); // // 读取状态确认写入成功 // uint16_t status = dac161s997_read_status(DAC161S997); @@ -721,7 +868,7 @@ void start_dac8568_test_task(void const *argument) while(1) { - uint16_t i = 65535; + //uint16_t i = 65535; //DAC8568_WriteAndUpdate(CHANNEL_A, (uint16_t)i); //DAC8568_WriteAndUpdate(CHANNEL_B, (uint16_t)i); //DAC8568_WriteAndUpdate(CHANNEL_C, (uint16_t)i); @@ -745,4 +892,136 @@ void start_dac8568_test_task(void const *argument) osDelay(1000); //} } +} + +/* USER CODE BEGIN Header_start_dma_test_task */ +/** + * @brief Function implementing the dma_test_task thread. + * @param argument: Not used + * @retval None + */ +/* USER CODE END Header_start_dma_test_task */ +void start_dma_test_task(void const *argument) +{ + /* USER CODE BEGIN start_dma_test_task */ + HAL_StatusTypeDef status; + + // 等待系统稳定 + osDelay(1000); + + // 初始化DMA + // 1. 配置UART6 DMA + __HAL_RCC_DMA2_CLK_ENABLE(); // 使能DMA2时钟 + + // 配置UART6接收DMA + hdma_uart6_rx.Instance = DMA2_Stream1; + hdma_uart6_rx.Init.Channel = DMA_CHANNEL_5; + hdma_uart6_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; + hdma_uart6_rx.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_uart6_rx.Init.MemInc = DMA_MINC_ENABLE; + hdma_uart6_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + hdma_uart6_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_uart6_rx.Init.Mode = DMA_CIRCULAR; // 循环模式 + hdma_uart6_rx.Init.Priority = DMA_PRIORITY_HIGH; + hdma_uart6_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + + status = HAL_DMA_Init(&hdma_uart6_rx); + if (status != HAL_OK) { + dma_uart_rx_errors++; + Error_Handler(); + } + + // 配置UART6发送DMA + hdma_uart6_tx.Instance = DMA2_Stream6; + hdma_uart6_tx.Init.Channel = DMA_CHANNEL_5; + hdma_uart6_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; + hdma_uart6_tx.Init.PeriphInc = DMA_PINC_DISABLE; + hdma_uart6_tx.Init.MemInc = DMA_MINC_ENABLE; + hdma_uart6_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + hdma_uart6_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + hdma_uart6_tx.Init.Mode = DMA_NORMAL; // 正常模式 + hdma_uart6_tx.Init.Priority = DMA_PRIORITY_HIGH; + hdma_uart6_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + + status = HAL_DMA_Init(&hdma_uart6_tx); + if (status != HAL_OK) { + dma_uart_tx_errors++; + Error_Handler(); + } + + // 关联DMA到UART6 + __HAL_LINKDMA(&huart6, hdmarx, hdma_uart6_rx); + __HAL_LINKDMA(&huart6, hdmatx, hdma_uart6_tx); + + // 启动UART6 DMA接收 + status = HAL_UART_Receive_DMA(&huart6, dma_uart_rx_buffer, DMA_UART_RX_BUFFER_SIZE); + if (status != HAL_OK) { + dma_uart_rx_errors++; + Error_Handler(); + } + + /* Infinite loop */ + for(;;) + { + // 检查DMA传输状态 + if (dma_uart_rx_complete) { + // 处理接收到的数据 + dma_uart_rx_count++; + dma_uart_rx_complete = 0; + + // 这里可以添加数据处理逻辑 + // 例如:将接收到的数据通过TCP发送出去 + if (server_pcb_control != NULL && tcp_echo_flags_control == 1) { + err_t err = tcp_write(server_pcb_control, dma_uart_rx_buffer, DMA_UART_RX_BUFFER_SIZE, 1); + if (err == ERR_OK) { + tcp_output(server_pcb_control); + } + } + } + + // 测试DMA发送 + if (dma_uart_tx_complete) { + dma_uart_tx_count++; + dma_uart_tx_complete = 0; + + // 准备新的测试数据 + for (int i = 0; i < DMA_UART_TX_BUFFER_SIZE; i++) { + dma_uart_tx_buffer[i] = 'A' + (i % 26); // 简单的测试数据 + } + + // 启动新的DMA发送 + status = HAL_UART_Transmit_DMA(&huart6, dma_uart_tx_buffer, DMA_UART_TX_BUFFER_SIZE); + if (status != HAL_OK) { + dma_uart_tx_errors++; + } + } + + // 每100ms检查一次状态 + osDelay(100); + } + /* USER CODE END start_dma_test_task */ +} + +// DMA回调函数 +void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) +{ + if (huart->Instance == USART6) { + dma_uart_rx_complete = 1; + } +} + +void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) +{ + if (huart->Instance == USART6) { + dma_uart_tx_complete = 1; + } +} + +void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) +{ + if (huart->Instance == USART6) { + dma_uart_rx_errors++; + // 重新启动DMA接收 + HAL_UART_Receive_DMA(&huart6, dma_uart_rx_buffer, DMA_UART_RX_BUFFER_SIZE); + } } \ No newline at end of file