/* 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"
#include "../test/ch395f_test.h"   /* ENABLE_NET_LAYER_TESTS：netTask 条件创建 */
#include "time_sync.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* 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 Variables */
/* 存储测试变量（g_storage_stats / s_perf_buf）已迁至 test/storage_test_task.c */
osThreadId_t timeSyncTaskHandle;
const osThreadAttr_t timeSyncTask_attributes = {
  .name = "timeSyncTask",
  .stack_size = 512 * 4,
  .priority = (osPriority_t) osPriorityNormal,
};
/* 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 */
#ifdef ENABLE_NET_LAYER_TESTS
  /* NET 层测试模式（阶段 6~10）：完整网络栈，netTask 负责轮询与消息处理 */
  netTaskHandle = osThreadNew(StartNetTask, NULL, &netTask_attributes);
#endif

  /* 本地时间同步任务（PC 推送 TCP）：依赖 netTask 处理消息队列 */
  timeSyncTaskHandle = osThreadNew(timeSyncTask, NULL, &timeSyncTask_attributes);
  /* 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 */
  (void)argument;

  /* 系统启动期挂载 NAND 上的 FatFS 卷，供 FTP 及其它模块访问。
   * f_mount(forced=1) 会触发 disk_initialize() → nand_ftl_init()
   * （dhara_map_resume）。此前默认构建从未挂载，导致 FTP 的
   * LIST/STOR/RETR 全部返回 550（f_opendir 失败）。
   * 若卷为空（FR_NO_FILESYSTEM，如恢复/坏块重建后清空），则首次自动
   * 格式化建卷（MKFS_PARM 与存储测试一致：FM_FAT32 / 无分区表）。 */
  static FATFS default_fatfs;
  FRESULT fr = f_mount(&default_fatfs, "", 1);
  if (fr == FR_NO_FILESYSTEM) {
      DBG_INFO("[FS] no FAT volume, formatting NAND...");
      static uint8_t fs_work[FF_MAX_SS];
      MKFS_PARM opts = { FM_FAT32, 0, 0, 0, 0 };
      fr = f_mkfs("", &opts, fs_work, sizeof(fs_work));
      if (fr == FR_OK) {
          fr = f_mount(&default_fatfs, "", 1);
      } else {
          DBG_ERROR("[FS] f_mkfs failed (fr=%d)", (int)fr);
      }
  }
  if (fr == FR_OK) {
      DBG_INFO("[FS] FATFS mounted");
  } else {
      DBG_ERROR("[FS] f_mount failed (fr=%d)", (int)fr);
  }

  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 */

