Files
STM32F4-Base/Src/freertos.c
2026-08-22 19:53:24 +08:00

345 lines
9.3 KiB
C

/* 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 <string.h>
#include "net_task.h"
#include "ch395f.h"
#include "dbg_log.h"
#include "net_socket.h"
#include "usart.h"
#include "ff.h"
#include "gd5f2gq5ue.h"
#include "lftpd.h"
#include "../test/ch395f_test_task.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* 存储测试统计 */
typedef struct {
uint16_t total;
uint16_t passed;
uint16_t failed;
} storage_test_stats_t;
#define STORAGE_TEST_CHECK(cond, fmt, ...) do { \
g_storage_stats.total++; \
if (cond) { \
g_storage_stats.passed++; \
DBG_INFO(" [PASS] " fmt, ##__VA_ARGS__); \
} else { \
g_storage_stats.failed++; \
DBG_ERROR(" [FAIL] " fmt, ##__VA_ARGS__); \
} \
} while (0)
#define STORAGE_TEST_REPORT(name) do { \
DBG_INFO("=== %s: %d/%d PASSED (failed=%d) ===", \
name, g_storage_stats.passed, g_storage_stats.total, g_storage_stats.failed); \
} while (0)
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */
static storage_test_stats_t g_storage_stats;
static uint8_t s_perf_buf[4096];
/* USER CODE END Variables */
/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {
.name = "defaultTask",
.stack_size = 512 * 4,
.priority = (osPriority_t) osPriorityNormal,
};
/* Definitions for netTask */
osThreadId_t netTaskHandle;
const osThreadAttr_t netTask_attributes = {
.name = "netTask",
.stack_size = 1024 * 4,
.priority = (osPriority_t) osPriorityNormal,
};
/* Definitions for ftpTask */
osThreadId_t ftpTaskHandle;
const osThreadAttr_t ftpTask_attributes = {
.name = "ftpTask",
.stack_size = 1024 * 4,
.priority = (osPriority_t) osPriorityNormal,
};
/* Definitions for ch395fTestTask */
osThreadId_t ch395fTestTaskHandle;
const osThreadAttr_t ch395fTestTask_attributes = {
.name = "ch395fTestTask",
.stack_size = 4096 * 4,
.priority = (osPriority_t) osPriorityBelowNormal,
};
/* Definitions for netMsgQueue */
osMessageQueueId_t netMsgQueueHandle;
const osMessageQueueAttr_t netMsgQueue_attributes = {
.name = "netMsgQueue"
};
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
/* USER CODE END FunctionPrototypes */
void StartDefaultTask(void *argument);
void StartNetTask(void *argument);
void StartFtpTask(void *argument);
void StartCh395fTestTask(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 */
/* add mutexes, ... */
/* USER CODE END RTOS_MUTEX */
/* USER CODE BEGIN RTOS_SEMAPHORES */
/* add semaphores, ... */
/* USER CODE END RTOS_SEMAPHORES */
/* USER CODE BEGIN RTOS_TIMERS */
/* start timers, add new ones, ... */
/* USER CODE END RTOS_TIMERS */
/* Create the queue(s) */
/* creation of netMsgQueue */
netMsgQueueHandle = osMessageQueueNew (8, sizeof(net_msg_t), &netMsgQueue_attributes);
/* 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);
/* creation of netTask */
netTaskHandle = osThreadNew(StartNetTask, NULL, &netTask_attributes);
/* creation of ftpTask */
//ftpTaskHandle = osThreadNew(StartFtpTask, NULL, &ftpTask_attributes);
/* creation of ch395fTestTask */
ch395fTestTaskHandle = osThreadNew(StartCh395fTestTask, NULL, &ch395fTestTask_attributes);
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
/* 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.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{
/* USER CODE BEGIN StartDefaultTask */
static FATFS fs;
static FIL fil;
static uint8_t work[FF_MAX_SS];
char read_buf[64];
const char *test_str = "Hello FatFS + dhara FTL!";
memset(&g_storage_stats, 0, sizeof(g_storage_stats));
/* ==================== FTL + FatFS 文件系统测试 ==================== */
FRESULT res = f_mount(&fs, "", 1);
if (res == FR_NO_FILESYSTEM) {
MKFS_PARM opts = {FM_FAT32, 0, 0, 0, 0};
res = f_mkfs("", &opts, work, sizeof(work));
STORAGE_TEST_CHECK(res == FR_OK, "f_mkfs");
res = f_mount(&fs, "", 1);
}
STORAGE_TEST_CHECK(res == FR_OK, "f_mount");
if (res == FR_OK) {
UINT bw, br;
res = f_open(&fil, "test.txt", FA_CREATE_ALWAYS | FA_WRITE);
STORAGE_TEST_CHECK(res == FR_OK, "f_open(write)");
if (res == FR_OK) {
f_write(&fil, test_str, strlen(test_str), &bw);
STORAGE_TEST_CHECK(bw == strlen(test_str), "f_write (%u bytes)", bw);
f_close(&fil);
res = f_open(&fil, "test.txt", FA_READ);
STORAGE_TEST_CHECK(res == FR_OK, "f_open(read)");
if (res == FR_OK) {
f_read(&fil, read_buf, sizeof(read_buf) - 1, &br);
f_close(&fil);
read_buf[br] = '\0';
STORAGE_TEST_CHECK(br == strlen(test_str) && memcmp(test_str, read_buf, br) == 0,
"data verify \"%s\"", read_buf);
}
}
f_unlink("test.txt");
}
/* ==================== FTL + FatFS 性能测试 ==================== */
DBG_INFO("=== Storage Test: Performance ===");
{
FIL pfile;
UINT pw, pr;
uint32_t t0, tw, tr;
uint32_t i;
uint32_t total_kb = 128;
uint32_t chunk = sizeof(s_perf_buf);
uint32_t count = (total_kb * 1024) / chunk;
memset(s_perf_buf, 0xA5, sizeof(s_perf_buf));
/* 写入 */
t0 = HAL_GetTick();
if (f_open(&pfile, "perf.dat", FA_CREATE_ALWAYS | FA_WRITE) == FR_OK) {
for (i = 0; i < count; i++) {
f_write(&pfile, s_perf_buf, chunk, &pw);
}
f_close(&pfile);
}
tw = HAL_GetTick() - t0;
/* 读取 */
t0 = HAL_GetTick();
if (f_open(&pfile, "perf.dat", FA_READ) == FR_OK) {
for (i = 0; i < count; i++) {
f_read(&pfile, s_perf_buf, chunk, &pr);
}
f_close(&pfile);
}
tr = HAL_GetTick() - t0;
f_unlink("perf.dat");
if (tw > 0) {
DBG_INFO(" Write: %lu KB in %lu ms = %lu KB/s",
total_kb, tw, (total_kb * 1000) / tw);
}
if (tr > 0) {
DBG_INFO(" Read: %lu KB in %lu ms = %lu KB/s",
total_kb, tr, (total_kb * 1000) / tr);
}
}
/* ==================== 汇总报告 ==================== */
STORAGE_TEST_REPORT("Storage Tests");
for (;;) {
osDelay(1000);
}
/* USER CODE END StartDefaultTask */
}
/* USER CODE BEGIN Header_StartNetTask */
/**
* @brief Function implementing the netTask thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartNetTask */
void StartNetTask(void *argument)
{
/* USER CODE BEGIN StartNetTask */
net_task_func(argument);
/* USER CODE END StartNetTask */
}
/* USER CODE BEGIN Header_StartFtpTask */
/**
* @brief Function implementing the ftpTask thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartFtpTask */
__weak void StartFtpTask(void *argument)
{
/* USER CODE BEGIN StartFtpTask */
osDelay(7000);
lftpd_t ftp;
lftpd_start("/", 21, &ftp);
/* USER CODE END StartFtpTask */
}
/* USER CODE BEGIN Header_StartCh395fTestTask */
/**
* @brief Function implementing the ch395fTestTask thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartCh395fTestTask */
__weak void StartCh395fTestTask(void *argument)
{
/* USER CODE BEGIN StartCh395fTestTask */
/* Infinite loop */
for(;;)
{
osDelay(1);
}
/* USER CODE END StartCh395fTestTask */
}
/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
/* USER CODE END Application */