/*
 * FreeRTOS Kernel V11.1.0 — Windows 仿真配置文件
 *
 * 本文件为 FreeRTOS 提供了在 Windows (MinGW) 上模拟运行时的全部配置选项。
 * 每个宏都附有详细的中文说明,方便学习和调试。
 *
 * SPDX-License-Identifier: MIT
 */

#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

/*===========================================================================
 *  编译器兼容性
 *===========================================================================*/
#if defined(_MSC_VER)
    /* 消除 MSVC 关于不安全 CRT 函数的编译警告 */
    #define _CRT_SECURE_NO_WARNINGS
#endif

/*===========================================================================
 *  内核调度策略
 *===========================================================================*/

/*
 * configUSE_PREEMPTION —— 是否启用抢占式调度
 *   1 = 抢占式调度(高优先级任务就绪时立即抢占低优先级任务)
 *   0 = 协作式调度(任务必须主动让出 CPU,如调用 vTaskDelay() 或 taskYIELD())
 *   仿真环境通常用 1,更贴近真实嵌入式场景。
 */
#define configUSE_PREEMPTION                    1

/*
 * configUSE_PORT_OPTIMISED_TASK_SELECTION —— 是否使用硬件优化的任务选择算法
 *   1 = 使用位运算(如 BSR 指令)在 O(1) 时间内找到最高优先级就绪任务
 *   0 = 使用通用的链表遍历查找
 *   Windows 仿真下也支持,开启可提高效率。要求 configMAX_PRIORITIES ≤ 32。
 */
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1

/*
 * configUSE_TICKLESS_IDLE —— 低功耗无节拍模式
 *   0 = 关闭。空闲期间定时器中断仍然周期性产生
 *   1 = 开启。空闲期间停止周期性 Tick 中断以省电(用于电池供电设备)
 *   仿真环境不需要省电,始终设为 0。
 */
#define configUSE_TICKLESS_IDLE                 0

/*===========================================================================
 *  钩子函数 (Hook / Callback)
 *===========================================================================*/

/*
 * configUSE_IDLE_HOOK —— 空闲任务钩子
 *   1 = 使能,需要在代码中实现 vApplicationIdleHook()
 *   0 = 关闭
 *   空闲钩子在空闲任务每轮循环中被调用,可用于休眠或背景处理。
 */
#define configUSE_IDLE_HOOK                     0

/*
 * configUSE_TICK_HOOK —— Tick 中断钩子
 *   1 = 使能,需要在代码中实现 vApplicationTickHook()
 *   0 = 关闭
 *   Tick 钩子在每次 SysTick 中断中执行,要求非常短小精悍。
 */
#define configUSE_TICK_HOOK                     0

/*
 * configUSE_MALLOC_FAILED_HOOK —— 内存分配失败钩子
 *   1 = 使能,需要在代码中实现 vApplicationMallocFailedHook()
 *   0 = 关闭
 *   当 pvPortMalloc() 返回 NULL 时触发。
 */
#define configUSE_MALLOC_FAILED_HOOK            0

/*
 * configUSE_DAEMON_TASK_STARTUP_HOOK —— 守护任务启动钩子
 *   1 = 使能,定时器服务任务启动时会调用 vApplicationDaemonTaskStartupHook()
 *   0 = 关闭
 */
#define configUSE_DAEMON_TASK_STARTUP_HOOK      0

/*===========================================================================
 *  协程 (Co-routines,已过时)
 *===========================================================================*/

/*
 * configUSE_CO_ROUTINES —— 是否启用协程(旧版轻量级任务替代方案)
 *   1 = 启用,需要同时定义 configMAX_CO_ROUTINE_PRIORITIES
 *   0 = 关闭,协程是 v8.0 之前的特性,新项目建议直接用任务
 */
#define configUSE_CO_ROUTINES                   0

/*===========================================================================
 *  时钟与 Tick 配置
 *===========================================================================*/

/*
 * configCPU_CLOCK_HZ —— CPU 时钟频率 (Hz)
 *   在真实 MCU 上写入实际的主频,用于计算 tick 周期。
 *   在 Windows 仿真中只是一个参考值,实际定时精度取决于 Sleep()。
 */
#define configCPU_CLOCK_HZ                      ( ( unsigned long ) 12000000 )

/*
 * configTICK_RATE_HZ —— 系统 Tick 频率 (Hz)
 *   即每秒产生多少次 Tick 中断。1000 表示每 1ms 一次 Tick。
 *   vTaskDelay(1000) 会阻塞 1000 个 Tick = 1 秒。
 *   注意:Windows 仿真受 Sleep() 精度限制,实际节拍不会精确到毫秒级。
 */
#define configTICK_RATE_HZ                      ( ( TickType_t ) 1000 )

/*
 * configTICK_TYPE_WIDTH_IN_BITS —— Tick 计数的位宽
 *   可选值:
 *     TICK_TYPE_WIDTH_16_BITS — 16 位,最大计数值 65535
 *     TICK_TYPE_WIDTH_32_BITS — 32 位,最大计数值 ~49 天(@1000Hz)
 *     TICK_TYPE_WIDTH_64_BITS — 64 位(极少使用)
 *   Windows 64 位宿主下建议用 32 位,与 portmacro.h 配合最佳。
 */
#define configTICK_TYPE_WIDTH_IN_BITS           TICK_TYPE_WIDTH_32_BITS

/*===========================================================================
 *  任务参数
 *===========================================================================*/

/*
 * configMAX_PRIORITIES —— 系统支持的最大优先级数
 *   范围为 1~32(使用位运算优化时限制为 32)。
 *   优先级 0 为最低(空闲任务),数值越大优先级越高。
 *   这里设 5 级足够 HelloWorld 测试使用。
 */
#define configMAX_PRIORITIES                    ( 5 )

/*
 * configMINIMAL_STACK_SIZE —— 最小任务堆栈大小(单位:StackType_t 个数)
 *   空闲任务使用此大小。用户创建任务时建议不小于此值。
 *   在 Windows 仿真中,每个任务实际上是一个独立线程,
 *   堆栈只是映射到线程的预留空间,所以设小一点没关系。
 */
#define configMINIMAL_STACK_SIZE                ( ( unsigned short ) 70 )

/*
 * configTOTAL_HEAP_SIZE —— 动态分配的总堆大小(字节)
 *   仅 heap_1/2/4 使用(heap_3 使用 malloc 无此限制)。
 *   此处设置为 65KB,仿真时够用。
 */
#define configTOTAL_HEAP_SIZE                   ( ( size_t ) ( 65 * 1024 ) )

/*
 * configMAX_TASK_NAME_LEN —— 任务名称最大长度(含 '\0')
 *   设置太大会浪费内存,设 12 字节足够描述任务功能。
 */
#define configMAX_TASK_NAME_LEN                 ( 12 )

/*
 * configIDLE_SHOULD_YIELD —— 空闲任务是否主动让出 CPU
 *   1 = 空闲任务在执行一次回调后就让出 CPU,避免低优先级任务饥饿
 *   0 = 空闲任务与同优先级的其他任务共享时间片
 *   建议保持 1。
 */
#define configIDLE_SHOULD_YIELD                 1

/*
 * configUSE_TASK_NOTIFICATIONS —— 是否启用任务通知
 *   1 = 启用。每个任务自带一个 32 位通知值,可用于轻量级信号量/队列
 *   0 = 关闭以节省 RAM(每个任务省 8 字节)
 *   建议开启,任务通知比信号量更快。
 */
#define configUSE_TASK_NOTIFICATIONS            1

/*
 * configUSE_TIME_SLICING —— 是否启用同优先级时间片轮转
 *   1 = 开启,同优先级任务轮流运行(每个 Tick 切换一次)
 *   0 = 关闭,同优先级任务需主动让出 CPU
 */
#define configUSE_TIME_SLICING                  1

/*
 * configNUM_THREAD_LOCAL_STORAGE_POINTERS —— 线程本地存储指针的数量
 *   每个任务可以拥有 N 个 void* 类型的本地存储槽,
 *   用于任务私有的上下文数据,通过 vTaskSetThreadLocalStoragePointer() 访问。
 *   设为 0 可省一点 RAM。
 */
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5

/*===========================================================================
 *  内存分配方式
 *===========================================================================*/

/*
 * configSUPPORT_STATIC_ALLOCATION —— 支持静态分配
 *   1 = 启用,任务/队列/信号量等可以用静态内存(需提供回调函数)
 *   0 = 关闭,仅使用动态分配
 *   设为 0 则无需实现 vApplicationGetIdleTaskMemory 等回调,
 *   代码更简洁,适合 HelloWorld。
 */
#define configSUPPORT_STATIC_ALLOCATION         0

/*
 * configSUPPORT_DYNAMIC_ALLOCATION —— 支持动态分配
 *   1 = 启用,xTaskCreate()/xQueueCreate() 等自动从堆中分配
 *   0 = 关闭,只能用 xTaskCreateStatic() 等静态版本
 *   简单程序用动态分配最方便。
 */
#define configSUPPORT_DYNAMIC_ALLOCATION        1

/*===========================================================================
 *  同步与通信(IPC)
 *===========================================================================*/

/*
 * configUSE_MUTEXES —— 是否启用互斥量
 *   1 = 启用,支持 xSemaphoreCreateMutex() 和优先级继承
 */
#define configUSE_MUTEXES                       1

/*
 * configUSE_RECURSIVE_MUTEXES —— 是否启用递归互斥量
 *   1 = 启用,支持 xSemaphoreCreateRecursiveMutex()
 *   允许同一个任务多次获取同一互斥量而不会死锁。
 */
#define configUSE_RECURSIVE_MUTEXES             1

/*
 * configUSE_COUNTING_SEMAPHORES —— 是否启用计数信号量
 *   1 = 启用,支持 xSemaphoreCreateCounting()
 *   用于管理多个资源的场景(如生产者-消费者)。
 */
#define configUSE_COUNTING_SEMAPHORES           1

/*
 * configQUEUE_REGISTRY_SIZE —— 队列注册表大小
 *   调试辅助功能,用于在调试器中按名称查找队列/信号量。
 *   0 表示不注册。非调试时可设为 0 省 RAM。
 */
#define configQUEUE_REGISTRY_SIZE               8

/*
 * configUSE_QUEUE_SETS —— 是否启用队列集
 *   1 = 启用,支持 xQueueCreateSet() 等,可同时等待多个队列/信号量
 */
#define configUSE_QUEUE_SETS                    1

/*===========================================================================
 *  软件定时器
 *===========================================================================*/

/*
 * configUSE_TIMERS —— 是否启用软件定时器
 *   1 = 启用,需要使用 xTimerCreate()/xTimerStart() 等 API
 *   0 = 关闭,定时器相关的功能不可用
 */
#define configUSE_TIMERS                        1

/*
 * configTIMER_TASK_PRIORITY —— 定时器服务任务优先级
 *   建议设为一个较高的优先级,确保定时器回调及时执行。
 */
#define configTIMER_TASK_PRIORITY               ( configMAX_PRIORITIES - 1 )

/*
 * configTIMER_QUEUE_LENGTH —— 定时器命令队列长度
 *   定时器 API(如 xTimerStart)通过此队列向定时器任务发送命令。
 *   10 条对于测试程序足够。
 */
#define configTIMER_QUEUE_LENGTH                10

/*
 * configTIMER_TASK_STACK_DEPTH —— 定时器服务任务堆栈深度
 *   为定时器回调预留足够的堆栈空间。
 */
#define configTIMER_TASK_STACK_DEPTH            ( configMINIMAL_STACK_SIZE * 2 )

/*===========================================================================
 *  调试与追踪
 *===========================================================================*/

/*
 * configUSE_TRACE_FACILITY —— 是否启用运行时统计追踪功能
 *   1 = 启用,支持 uxTaskGetSystemState() / vTaskGetInfo() 等调试 API
 *   0 = 关闭以减小代码体积
 */
#define configUSE_TRACE_FACILITY                1

/*
 * configCHECK_FOR_STACK_OVERFLOW —— 堆栈溢出检测等级
 *   0 = 关闭检测(最快)
 *   1 = 检测栈指针是否超出范围(较安全)
 *   2 = 方法 1 + 检测栈尾部标记是否被破坏(更可靠,但稍慢)
 *   HelloWorld 中设为 0,省去实现 vApplicationStackOverflowHook() 的麻烦。
 */
#define configCHECK_FOR_STACK_OVERFLOW          0

/*
 * configASSERT —— 断言宏
 *   在 FreeRTOS API 参数校验失败时触发。
 *   调试时建议开启,发布版本可以定义为空。
 *   此处实现为:触发断言时关中断并死循环。
 */
#define configASSERT( x )                       if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }

/*===========================================================================
 *  API 功能裁剪(设为 1 表示此 API 可用)
 *===========================================================================*/

#define INCLUDE_xTaskGetSchedulerState          1   /* 获取调度器状态(运行/挂起/未启动) */
#define INCLUDE_vTaskDelay                      1   /* 任务相对延时 */
#define INCLUDE_vTaskDelayUntil                 1   /* 任务绝对延时(固定周期) */
#define INCLUDE_vTaskDelete                     1   /* 删除任务 */
#define INCLUDE_eTaskGetState                   1   /* 查询任务状态 */
#define INCLUDE_xTaskGetCurrentTaskHandle       1   /* 获取当前任务句柄 */
#define INCLUDE_xTaskGetIdleTaskHandle          1   /* 获取空闲任务句柄 */
#define INCLUDE_xTaskGetHandle                  1   /* 通过名称查找任务句柄 */
#define INCLUDE_xSemaphoreGetMutexHolder        1   /* 查询互斥量持有者 */
#define INCLUDE_xTimerPendFunctionCall          1   /* 在定时器任务上下文中执行函数 */

#endif /* FREERTOS_CONFIG_H */