/* =============================================================================
 * FreeRTOSConfig.h - STM32F407VGT6 (Cortex-M4F @168MHz) 용 FreeRTOS 커널 설정
 *
 * 누수감지/SHT30 노드 펌웨어. 네이티브 FreeRTOS API(task/queue/timers/semphr)
 * 만 사용한다(CMSIS-RTOS 미사용).
 *
 * 핵심 결정 사항:
 *  - configCPU_CLOCK_HZ = 168MHz (bsp.c SystemClock_Config: HSE 8MHz -> PLL).
 *  - Tick = 1kHz (1ms). vTaskDelay/타이머 분해능 1ms.
 *  - heap_4 사용. 힙 64KB. (필요 시 linker 로 CCM/SRAM 배치 가능 — 단, LwIP/HAL
 *    DMA 디스크립터는 CCM 에 두지 말 것. 일반 동적할당은 SRAM heap_4 로 충분.)
 *  - FPU(Cortex-M4F) 사용: 포트가 lazy-stacking 으로 부동소수 컨텍스트 저장.
 *  - NVIC: STM32 는 4 우선순위 비트(configPRIO_BITS=4). HAL/EXTI 등 *FromISR
 *    API 를 호출하는 ISR 은 반드시 MAX_SYSCALL 이하(=수치상 크거나 같은)
 *    우선순위(=논리적으로 낮은 선점도)를 가져야 한다.
 *
 * HAL 타임베이스 주의:
 *  vPortSVCHandler/xPortPendSVHandler/xPortSysTickHandler 를 CMSIS 벡터명
 *  (SVC_Handler/PendSV_Handler/SysTick_Handler)으로 매핑한다(아래 #define).
 *  따라서 SysTick 은 FreeRTOS 전용이 되며, HAL 의 HAL_GetTick() 타임베이스는
 *  SysTick 과 충돌하면 안 된다. -> bsp 가 HAL_InitTick() 을 override 하여 HAL
 *  타임베이스를 TIM6 으로 둔다(stm32f4xx_hal_conf.h 의 TICK 우선순위 참고).
 * ===========================================================================*/
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

/* -----------------------------------------------------------------------------
 * 어셈블러에서 인클루드될 때는 C 전용 선언을 숨긴다.
 * (portasm 등에서 본 헤더를 포함할 수 있음)
 * ---------------------------------------------------------------------------*/
#ifndef __IASMARM__
  #include <stdint.h>
  extern uint32_t SystemCoreClock;   /* CMSIS system_stm32f4xx.c 가 갱신 */
#endif

/* =============================================================================
 * 스케줄러 기본 동작
 * ===========================================================================*/
#define configUSE_PREEMPTION                    1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1   /* Cortex-M CLZ 기반 선택 */
#define configUSE_TICKLESS_IDLE                 0   /* IWDG/주기보고가 있어 미사용 */

/* CPU/틱 클럭. SystemClock_Config 가 168MHz 로 설정. */
#define configCPU_CLOCK_HZ                      ( 168000000UL )
#define configTICK_RATE_HZ                      ( ( TickType_t ) 1000 )

#define configMAX_PRIORITIES                    ( 7 )
#define configMINIMAL_STACK_SIZE                ( ( uint16_t ) 128 )  /* words(=512B) */
#define configMAX_TASK_NAME_LEN                 ( 16 )
#define configUSE_16_BIT_TICKS                  0
#define configIDLE_SHOULD_YIELD                 1
#define configUSE_TASK_NOTIFICATIONS            1
#define configTASK_NOTIFICATION_ARRAY_ENTRIES   3
#define configUSE_MUTEXES                       1
#define configUSE_RECURSIVE_MUTEXES             1
#define configUSE_COUNTING_SEMAPHORES           1
#define configQUEUE_REGISTRY_SIZE               8
#define configUSE_QUEUE_SETS                    0
#define configUSE_TIME_SLICING                  1
#define configUSE_NEWLIB_REENTRANT              0
#define configENABLE_BACKWARD_COMPATIBILITY     0
#define configSTACK_DEPTH_TYPE                  uint16_t
#define configMESSAGE_BUFFER_LENGTH_TYPE        size_t

/* =============================================================================
 * 메모리 할당
 *  - 동적/정적 둘 다 지원. 정적: idle/timer 태스크 메모리는 rtos_hooks.c 제공.
 *  - heap_4(coalescing first-fit) 사용 권장. 빌드 시스템이 heap_4.c 를 링크.
 *  - 64KB. LwIP+mbedTLS TLS 핸드셰이크/세션은 메모리를 많이 쓰므로 여유 확보.
 *    (mbedTLS 자체 버퍼는 보통 calloc/정적으로 잡지만, 태스크 스택/큐/세마포어
 *     등 커널 객체 + 애플리케이션 동적할당을 모두 이 힙에서 충당.)
 * ===========================================================================*/
#define configSUPPORT_STATIC_ALLOCATION         1
#define configSUPPORT_DYNAMIC_ALLOCATION        1
#define configTOTAL_HEAP_SIZE                   ( ( size_t ) ( 64 * 1024 ) )
#define configAPPLICATION_ALLOCATED_HEAP        0   /* heap_4 내부 ucHeap[] 사용 */
#define configKERNEL_PROVIDED_STATIC_MEMORY     1

/* =============================================================================
 * 후크(Hook) 함수 - 구현은 common/rtos_hooks.c
 * ===========================================================================*/
#define configUSE_IDLE_HOOK                     1   /* IWDG refresh / 저전력 hint */
#define configUSE_TICK_HOOK                     0
#define configUSE_MALLOC_FAILED_HOOK            1   /* vApplicationMallocFailedHook */
#define configCHECK_FOR_STACK_OVERFLOW          2   /* method 2: 스택 패턴 검사 */
#define configUSE_DAEMON_TASK_STARTUP_HOOK      0

/* =============================================================================
 * 소프트웨어 타이머 (누수 입력 디바운스 타이머에 사용)
 * ===========================================================================*/
#define configUSE_TIMERS                        1
#define configTIMER_TASK_PRIORITY               ( configMAX_PRIORITIES - 1 )
#define configTIMER_QUEUE_LENGTH                10
#define configTIMER_TASK_STACK_DEPTH            ( configMINIMAL_STACK_SIZE * 2 )

/* =============================================================================
 * 런타임/디버그 통계 (기본 비활성 — 필요 시 bsp 타이머로 ConfigureForRunTimeStats)
 * ===========================================================================*/
#define configGENERATE_RUN_TIME_STATS           0
#define configUSE_TRACE_FACILITY                1
#define configUSE_STATS_FORMATTING_FUNCTIONS    0
#define configRECORD_STACK_HIGH_ADDRESS         1

/* =============================================================================
 * assert() — 개발 중에는 reason 을 잡고 정지, 운영 중엔 IWDG 가 리셋.
 *  vAssertCalled 는 rtos_hooks.c 에 구현(인터럽트 끄고 디버그 정지).
 * ===========================================================================*/
#ifndef __IASMARM__
  void vAssertCalled( const char *pcFile, unsigned long ulLine );
  #define configASSERT( x ) \
      if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ )
#endif

/* =============================================================================
 * 포함할 API (INCLUDE_*)
 * ===========================================================================*/
#define INCLUDE_vTaskPrioritySet                1
#define INCLUDE_uxTaskPriorityGet               1
#define INCLUDE_vTaskDelete                     1
#define INCLUDE_vTaskSuspend                    1
#define INCLUDE_vTaskDelayUntil                 1
#define INCLUDE_xTaskDelayUntil                 1
#define INCLUDE_vTaskDelay                      1
#define INCLUDE_xTaskGetSchedulerState          1
#define INCLUDE_xTaskGetCurrentTaskHandle       1
#define INCLUDE_uxTaskGetStackHighWaterMark     1
#define INCLUDE_xTaskGetIdleTaskHandle          1
#define INCLUDE_eTaskGetState                   1
#define INCLUDE_xTimerPendFunctionCall          1
#define INCLUDE_xTaskAbortDelay                 1
#define INCLUDE_xQueueGetMutexHolder            1
#define INCLUDE_xSemaphoreGetMutexHolder        1
#define INCLUDE_xTaskGetHandle                  1
#define INCLUDE_xTaskResumeFromISR              1

/* =============================================================================
 * Cortex-M4F 인터럽트 우선순위 설정 (NVIC)
 *
 *  STM32F4 는 우선순위 4비트(16단계). 숫자가 작을수록 높은 선점도.
 *  - LOWEST  : 15 (가장 낮은 선점도)
 *  - MAX_SYSCALL : 5 — 이보다 *높은 선점도(숫자 < 5)* 의 ISR 에서는 FreeRTOS
 *    API 를 호출하면 안 된다. ETH/I2C/EXTI/UART 등 *FromISR 을 부르는 HAL IRQ 는
 *    NVIC 우선순위를 5..15 범위(숫자 ≥ 5)로 설정해야 한다.
 *  - 부팅 직후 NVIC_SetPriorityGrouping(0) (4비트 전부 preempt, sub 0)를 HAL_Init
 *    이 설정함을 전제.
 * ===========================================================================*/
#define configPRIO_BITS                         4

/* 가장 낮은 선점도(= 가장 큰 숫자). */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY         15

/* RTOS-aware ISR(=FromISR 사용 ISR)이 가질 수 있는 최고 선점도(=가장 작은 숫자). */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY    5

/* 커널이 PendSV/SysTick 에 쓰는 raw 우선순위 (LOWEST << (8-PRIO_BITS)). */
#define configKERNEL_INTERRUPT_PRIORITY \
    ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << ( 8 - configPRIO_BITS ) )

/* basepri 마스크 임계값 (MAX_SYSCALL << shift). taskENTER_CRITICAL 등에서 사용. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY \
    ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << ( 8 - configPRIO_BITS ) )

/* =============================================================================
 * Cortex-M 포트 핸들러 -> CMSIS 벡터명 매핑
 *  startup_stm32f407xx.s 의 벡터 테이블은 SVC_Handler/PendSV_Handler/
 *  SysTick_Handler 를 참조한다. FreeRTOS 의 핸들러를 그 이름으로 alias.
 *  SysTick 은 FreeRTOS 전용 — HAL 타임베이스는 TIM6 (bsp 가 HAL_InitTick override).
 * ===========================================================================*/
#define vPortSVCHandler                         SVC_Handler
#define xPortPendSVHandler                      PendSV_Handler
#define xPortSysTickHandler                     SysTick_Handler

#endif /* FREERTOS_CONFIG_H */
