/**************************************************************************************************

 * 文件: embedded_master_demo.c

 * 功能: 嵌入式全栈Demo(硬件抽象+驱动+内存池+任务调度)

 * 适配: 100%兼容LeetCode GCC C语言环境(无编译/段错误/重定义/函数嵌套错误)

 * 核心修复:1. LinkNode替代ListNode避平台隐式冲突 2. 模拟寄存器替代物理地址解段错误 3. 修复RingBuf函数嵌套语法错误

 * 关键价值:整合嵌入式真实部署与LeetCode模拟版的核心差异,全关键节点标注注释

 *************************************************************************************************/

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <time.h>

#include <stdint.h>

#include <stdbool.h>

#include <stdarg.h>

#include <errno.h>

// ============================== 适配LeetCode:定义__IO宏(嵌入式真实环境由芯片库提供) ==============================

#ifndef __IO

#define __IO volatile  // 【嵌入式真实部署差异】真实STM32/MCU环境中,该宏由厂家标准库(如STM32 HAL/LL库)定义在stdint.h,无需自定义

#endif

// ============================== 全局配置宏 ==============================

#define VERSION_MAIN            1

#define VERSION_SUB             0

#define VERSION_PATCH           0

#define ENABLE_LOG              1

#define ENABLE_MEM_POOL         1

#define ENABLE_RING_BUFFER      1

#define ENABLE_DRIVER           1

#define ENABLE_OSAL             1

#define ENABLE_TASK_SCHED       1

#define ENABLE_WATCHDOG         1

#define ENABLE_POWER_MANAGE     1

#define LOG_FILE_PATH           "/tmp/embedded_master.log"  // 【嵌入式真实部署差异】真实设备无/tmp文件系统,需改为Flash/SD卡分区或禁用文件日志

#define LOG_MAX_SIZE            (1024 * 1024)

#define LOG_BUFFER_SIZE         512

// ============================== 错误码定义(嵌入式真实环境需与芯片/RTOS错误码兼容) ==============================

typedef enum {

    E_OK                = 0,

    E_ERROR             = -1,

    E_NULL_PTR          = -2,

    E_INVALID_PARAM     = -3,

    E_MEM_ALLOC         = -4,

    E_MEM_FREE          = -5,

    E_BUF_FULL          = -6,

    E_BUF_EMPTY         = -7,

    E_DEV_NOT_INIT      = -8,

    E_DEV_BUSY          = -9,

    E_TIMEOUT           = -10,

    E_PERMISSION        = -11,

    E_IO_ERROR          = -12

} ErrorCode;

// 【嵌入式真实部署差异】真实项目中,错误码需兼容芯片厂家库(如STM32 HAL_StatusTypeDef)或使用的RTOS错误码(如FreeRTOS BaseType_t),避免冲突

// ============================== 日志级别定义 ==============================

typedef enum {

    LOG_LEVEL_TRACE      = 0,  // 调试跟踪(真实设备禁用,减少Flash/串口开销)

    LOG_LEVEL_DEBUG      = 1,  // 调试信息(真实设备测试阶段启用,量产禁用)

    LOG_LEVEL_INFO       = 2,  // 运行信息(量产保留核心信息)

    LOG_LEVEL_WARN       = 3,  // 警告(量产保留)

    LOG_LEVEL_ERROR      = 4,  // 错误(量产保留)

    LOG_LEVEL_FATAL      = 5   // 致命错误(量产保留,触发后需复位/报警)

} LogLevel;

#define CURRENT_LOG_LEVEL       LOG_LEVEL_TRACE  // 【嵌入式真实部署差异】真实设备量产时需改为LOG_LEVEL_INFO或更高,减少日志输出开销

// ============================== 核心修复:全新命名LinkNode,规避LeetCode隐式ListNode冲突 ==============================

typedef struct LinkNode {

    int data;

    struct LinkNode* next;  // 自引用类型与标签完全统一,无指针兼容问题

} LinkNode;

#define Stack LinkNode  // 栈复用链表节点,无额外定义,杜绝重定义

// 【嵌入式真实部署差异】真实项目中可直接使用ListNode,无LeetCode平台隐式定义冲突,命名可按项目规范调整

// ============================== 1. 调试日志系统 ==============================

#if ENABLE_LOG

static const char* LogLevelStr[] = {"TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"};

static void Log_CheckFileSize(void) {

    struct stat st;

    if (stat(LOG_FILE_PATH, &st) == 0 && st.st_size >= LOG_MAX_SIZE) {

        remove(LOG_FILE_PATH);

    }

}

static void Log_Write(LogLevel level, const char* func, uint32_t line, const char* fmt, ...) {

    if (level < CURRENT_LOG_LEVEL) return;

    Log_CheckFileSize();

    int fd = open(LOG_FILE_PATH, O_WRONLY | O_CREAT | O_APPEND, 0644);

    if (fd < 0) {

        printf("Log open failed: %s\n", strerror(errno));

        return;

    }

    char timeBuf[64];

    time_t now = time(NULL);

    ctime_r(&now, timeBuf);

    timeBuf[strcspn(timeBuf, "\n")] = '\0';

    char logBuf[LOG_BUFFER_SIZE];

    va_list ap;

    va_start(ap, fmt);

    vsnprintf(logBuf, LOG_BUFFER_SIZE - 1, fmt, ap);

    va_end(ap);

    char outBuf[LOG_BUFFER_SIZE];

    snprintf(outBuf, sizeof(outBuf), "[%s][%s][PID:%d][%s:%u] %s\n",

             timeBuf, LogLevelStr[level], getpid(), func, line, logBuf);

    write(fd, outBuf, strlen(outBuf));

    close(fd);

    printf("%s", outBuf);

}

#define LOG_TRACE(fmt, ...)     Log_Write(LOG_LEVEL_TRACE, __func__, __LINE__, fmt, ##__VA_ARGS__)

#define LOG_DEBUG(fmt, ...)     Log_Write(LOG_LEVEL_DEBUG, __func__, __LINE__, fmt, ##__VA_ARGS__)

#define LOG_INFO(fmt, ...)      Log_Write(LOG_LEVEL_INFO,  __func__, __LINE__, fmt, ##__VA_ARGS__)

#define LOG_WARN(fmt, ...)      Log_Write(LOG_LEVEL_WARN,  __func__, __LINE__, fmt, ##__VA_ARGS__)

#define LOG_ERROR(fmt, ...)     Log_Write(LOG_LEVEL_ERROR, __func__, __LINE__, fmt, ##__VA_ARGS__)

#define LOG_FATAL(fmt, ...)     Log_Write(LOG_LEVEL_FATAL, __func__, __LINE__, fmt, ##__VA_ARGS__)

#define ASSERT(cond)                                                                \

    do {                                                                           \

        if (!(cond)) {                                                             \

            LOG_FATAL("ASSERT FAILED: " #cond);                                     \

            exit(E_ERROR);                                                          \

        }                                                                          \

    } while(0)

#else

#define LOG_TRACE(...)

#define LOG_DEBUG(...)

#define LOG_INFO(...)

#define LOG_WARN(...)

#define LOG_ERROR(...)

#define LOG_FATAL(...)

#define ASSERT(cond)

#endif

// ============================== 2. 静态内存池管理(嵌入式真实环境核心必用,替代动态malloc/free) ==============================

#if ENABLE_MEM_POOL

#define MEM_BLOCK_CNT_SMALL     32

#define MEM_BLOCK_SIZE_SMALL    32

#define MEM_BLOCK_CNT_MID       16

#define MEM_BLOCK_SIZE_MID      128

#define MEM_BLOCK_CNT_LARGE     8

#define MEM_BLOCK_SIZE_LARGE    512

typedef enum {

    MEM_BLOCK_SMALL,

    MEM_BLOCK_MID,

    MEM_BLOCK_LARGE

} MemBlockType;

typedef struct {

    uint8_t* buf;

    bool used;

    uint32_t allocTick;

    MemBlockType type;

} MemBlock;

typedef struct {

    uint8_t bufSmall[MEM_BLOCK_CNT_SMALL][MEM_BLOCK_SIZE_SMALL];

    uint8_t bufMid[MEM_BLOCK_CNT_MID][MEM_BLOCK_SIZE_MID];

    uint8_t bufLarge[MEM_BLOCK_CNT_LARGE][MEM_BLOCK_SIZE_LARGE];

    MemBlock blockSmall[MEM_BLOCK_CNT_SMALL];

    MemBlock blockMid[MEM_BLOCK_CNT_MID];

    MemBlock blockLarge[MEM_BLOCK_CNT_LARGE];

    uint32_t allocCnt;

    uint32_t freeCnt;

    uint32_t failCnt;

} MemPool;

static MemPool g_memPool;

static void MemPool_Init(void) {

    memset(&g_memPool, 0, sizeof(MemPool));

    for (int i = 0; i < MEM_BLOCK_CNT_SMALL; i++) {

        g_memPool.blockSmall[i].buf = g_memPool.bufSmall[i];

        g_memPool.blockSmall[i].used = false;

        g_memPool.blockSmall[i].type = MEM_BLOCK_SMALL;

    }

    for (int i = 0; i < MEM_BLOCK_CNT_MID; i++) {

        g_memPool.blockMid[i].buf = g_memPool.bufMid[i];

        g_memPool.blockMid[i].used = false;

        g_memPool.blockMid[i].type = MEM_BLOCK_MID;

    }

    for (int i = 0; i < MEM_BLOCK_CNT_LARGE; i++) {

        g_memPool.blockLarge[i].buf = g_memPool.bufLarge[i];

        g_memPool.blockLarge[i].used = false;

        g_memPool.blockLarge[i].type = MEM_BLOCK_LARGE;

    }

    LOG_INFO("MemPool Init Success. Small:%u*%u, Mid:%u*%u, Large:%u*%u",

             MEM_BLOCK_CNT_SMALL, MEM_BLOCK_SIZE_SMALL,

             MEM_BLOCK_CNT_MID, MEM_BLOCK_SIZE_MID,

             MEM_BLOCK_CNT_LARGE, MEM_BLOCK_SIZE_LARGE);

}

static void* MemPool_Alloc(size_t size) {

    if (size == 0 || size > MEM_BLOCK_SIZE_LARGE) {

        LOG_ERROR("Invalid alloc size: %u", (uint32_t)size);

        g_memPool.failCnt++;

        return NULL;

    }

    MemBlock* pBlock = NULL;

    if (size <= MEM_BLOCK_SIZE_SMALL) {

        for (int i = 0; i < MEM_BLOCK_CNT_SMALL; i++) {

            if (!g_memPool.blockSmall[i].used) {

                pBlock = &g_memPool.blockSmall[i];

                break;

            }

        }

    } else if (size <= MEM_BLOCK_SIZE_MID) {

        for (int i = 0; i < MEM_BLOCK_CNT_MID; i++) {

            if (!g_memPool.blockMid[i].used) {

                pBlock = &g_memPool.blockMid[i];

                break;

            }

        }

    } else {

        for (int i = 0; i < MEM_BLOCK_CNT_LARGE; i++) {

            if (!g_memPool.blockLarge[i].used) {

                pBlock = &g_memPool.blockLarge[i];

                break;

            }

        }

    }

    if (pBlock == NULL) {

        LOG_ERROR("MemPool is full, alloc failed, size: %u", (uint32_t)size);

        g_memPool.failCnt++;

        return NULL;

    }

    pBlock->used = true;

    pBlock->allocTick = (uint32_t)time(NULL);

    g_memPool.allocCnt++;

    LOG_DEBUG("Alloc success, type: %u, addr: %p", pBlock->type, pBlock->buf);

    return pBlock->buf;

}

static ErrorCode MemPool_Free(void* ptr) {

    if (ptr == NULL) {

        LOG_WARN("Free null pointer");

        return E_NULL_PTR;

    }

    MemBlock* pBlock = NULL;

    for (int i = 0; i < MEM_BLOCK_CNT_SMALL; i++) {

        if (g_memPool.blockSmall[i].buf == ptr) {

            pBlock = &g_memPool.blockSmall[i];

            break;

        }

    }

    if (pBlock == NULL) {

        for (int i = 0; i < MEM_BLOCK_CNT_MID; i++) {

            if (g_memPool.blockMid[i].buf == ptr) {

                pBlock = &g_memPool.blockMid[i];

                break;

            }

        }

    }

    if (pBlock == NULL) {

        for (int i = 0; i < MEM_BLOCK_CNT_LARGE; i++) {

            if (g_memPool.blockLarge[i].buf == ptr) {

                pBlock = &g_memPool.blockLarge[i];

                break;

            }

        }

    }

    if (pBlock == NULL) {

        LOG_ERROR("Free invalid pointer: %p", ptr);

        return E_MEM_FREE;

    }

    if (!pBlock->used) {

        LOG_WARN("Free unused memory: %p", ptr);

        return E_MEM_FREE;

    }

    pBlock->used = false;

    memset(pBlock->buf, 0, MEM_BLOCK_SIZE_SMALL << pBlock->type);

    g_memPool.freeCnt++;

    LOG_DEBUG("Free success, addr: %p", ptr);

    return E_OK;

}

static void MemPool_PrintStat(void) {

    LOG_INFO("MemPool Stat: Alloc:%u, Free:%u, Fail:%u",

             g_memPool.allocCnt, g_memPool.freeCnt, g_memPool.failCnt);

    uint32_t now = (uint32_t)time(NULL);

    uint32_t leakCnt = 0;

    MemBlock* pBlocks[] = {g_memPool.blockSmall, g_memPool.blockMid, g_memPool.blockLarge};

    uint32_t cnts[] = {MEM_BLOCK_CNT_SMALL, MEM_BLOCK_CNT_MID, MEM_BLOCK_CNT_LARGE};

    for (int i = 0; i < 3; i++) {

        for (int j = 0; j < cnts[i]; j++) {

            MemBlock* p = &pBlocks[i][j];

            if (p->used && (now - p->allocTick) > 300) {

                LOG_WARN("Suspected leak: type:%u, addr:%p, alloc time:%u",

                         p->type, p->buf, p->allocTick);

                leakCnt++;

            }

        }

    }

    LOG_INFO("Suspected leak count: %u", leakCnt);

}

#else

static void MemPool_Init(void) {}

static void* MemPool_Alloc(size_t size) { return malloc(size); }

static ErrorCode MemPool_Free(void* ptr) { free(ptr); return E_OK; }

static void MemPool_PrintStat(void) {}

#endif

// ============================== 3. 环形缓冲区(核心修复:无函数嵌套,花括号严格配对) ==============================

#if ENABLE_RING_BUFFER

#define RING_BUF_SIZE           256

typedef struct {

    uint8_t buf[RING_BUF_SIZE];

    volatile uint32_t head;

    volatile uint32_t tail;

    uint32_t capacity;

} RingBuffer;

// 环形缓冲区初始化(全局作用域,独立函数,无嵌套)

static void RingBuf_Init(RingBuffer* rb) {

    ASSERT(rb != NULL);

    memset(rb, 0, sizeof(RingBuffer));

    rb->capacity = RING_BUF_SIZE;

    LOG_INFO("RingBuffer init, capacity: %u", rb->capacity);

}

// 清空环形缓冲区(与Init同级,全局作用域)

static void RingBuf_Clear(RingBuffer* rb) {

    ASSERT(rb != NULL);

    rb->head = rb->tail = 0;

    LOG_DEBUG("RingBuffer cleared");

}

static bool RingBuf_IsEmpty(RingBuffer* rb) {

    ASSERT(rb != NULL);

    return (rb->head == rb->tail);

}

static bool RingBuf_IsFull(RingBuffer* rb) {

    ASSERT(rb != NULL);

    return ((rb->head + 1) % rb->capacity) == rb->tail;

}

static uint32_t RingBuf_GetLen(RingBuffer* rb) {

    ASSERT(rb != NULL);

    return (rb->head - rb->tail + rb->capacity) % rb->capacity;

}

static ErrorCode RingBuf_Push(RingBuffer* rb, uint8_t data) {

    ASSERT(rb != NULL);

    if (RingBuf_IsFull(rb)) {

        LOG_WARN("RingBuffer is full");

        return E_BUF_FULL;

    }

    rb->buf[rb->head] = data;

    rb->head = (rb->head + 1) % rb->capacity;

    return E_OK;

}

static ErrorCode RingBuf_Pop(RingBuffer* rb, uint8_t* data) {

    ASSERT(rb != NULL && data != NULL);

    if (RingBuf_IsEmpty(rb)) {

        return E_BUF_EMPTY;

    }

    *data = rb->buf[rb->tail];

    rb->tail = (rb->tail + 1) % rb->capacity;

    return E_OK;

}

static ErrorCode RingBuf_PushMulti(RingBuffer* rb, const uint8_t* data, uint32_t len) {

    ASSERT(rb != NULL && data != NULL);

    if (len == 0) return E_OK;

    if (RingBuf_GetLen(rb) + len >= rb->capacity) {

        LOG_ERROR("No enough space, len:%u", len);

        return E_BUF_FULL;

    }

    for (uint32_t i = 0; i < len; i++) {

        RingBuf_Push(rb, data[i]);

    }

    return E_OK;

}

static ErrorCode RingBuf_PopMulti(RingBuffer* rb, uint8_t* data, uint32_t len, uint32_t* realLen) {

    ASSERT(rb != NULL && data != NULL && realLen != NULL);

    *realLen = 0;

    if (len == 0 || RingBuf_IsEmpty(rb)) return E_BUF_EMPTY;

    uint32_t avail = RingBuf_GetLen(rb);

    uint32_t readLen = (len > avail) ? avail : len;

    for (uint32_t i = 0; i < readLen; i++) {

        RingBuf_Pop(rb, &data[i]);

    }

    *realLen = readLen;

    return E_OK;

}

#endif

// ============================== 4. 硬件抽象层与驱动 ==============================

#if ENABLE_DRIVER

typedef struct {

    __IO uint32_t CR;

    __IO uint32_t SR;

    __IO uint32_t DR;

    __IO uint32_t BRR;

} UART_RegTypeDef;

typedef struct {

    __IO uint32_t ODR;

    __IO uint32_t IDR;

    __IO uint32_t MODER;

} GPIO_RegTypeDef;

typedef struct {

    __IO uint32_t CR1;

    __IO uint32_t SR;

    __IO uint32_t CNT;

    __IO uint32_t PSC;

    __IO uint32_t ARR;

} TIM_RegTypeDef;

typedef struct {

    __IO uint32_t CR;

    __IO uint32_t DR;

    __IO uint32_t SR;

} ADC_RegTypeDef;

static UART_RegTypeDef g_uart1_reg = {0};

static GPIO_RegTypeDef g_gpioa_reg = {0};

static TIM_RegTypeDef g_tim2_reg = {0};

static ADC_RegTypeDef g_adc1_reg = {0};

#define UART1                   (&g_uart1_reg)

#define GPIOA                   (&g_gpioa_reg)

#define TIM2                    (&g_tim2_reg)

#define ADC1                    (&g_adc1_reg)

typedef struct {

    UART_RegTypeDef* Instance;

    RingBuffer rxRingBuf;

    RingBuffer txRingBuf;

    uint32_t baudRate;

    bool isInit;

} UART_HandleTypeDef;

typedef struct {

    GPIO_RegTypeDef* Instance;

    uint32_t pin;

    bool isInit;

} GPIO_HandleTypeDef;

typedef struct {

    TIM_RegTypeDef* Instance;

    uint32_t period;

    uint32_t prescaler;

    bool isInit;

    void (*callback)(void);

} TIM_HandleTypeDef;

static ErrorCode DRV_UART_Init(UART_HandleTypeDef* huart, UART_RegTypeDef* instance, uint32_t baud) {

    ASSERT(huart != NULL && instance != NULL);

    huart->Instance = instance;

    huart->baudRate = baud;

    huart->isInit = false;

   

    huart->Instance->CR = 0x00;

    huart->Instance->SR = 0x00;

    huart->Instance->DR = 0x00;

    huart->Instance->BRR = 0x271;

   

    RingBuf_Init(&huart->rxRingBuf);

    RingBuf_Init(&huart->txRingBuf);

    huart->Instance->CR |= 0x01;

    huart->isInit = true;

    LOG_INFO("UART Init Success, Baud:%u", baud);

    return E_OK;

}

static ErrorCode DRV_UART_SendByte(UART_HandleTypeDef* huart, uint8_t data) {

    ASSERT(huart != NULL);

    if (!huart->isInit) return E_DEV_NOT_INIT;

    if (RingBuf_IsFull(&huart->txRingBuf)) return E_BUF_FULL;

    RingBuf_Push(&huart->txRingBuf, data);

    huart->Instance->DR = data;

    huart->Instance->SR |= 0x02;

    LOG_TRACE("UART Send: 0x%02X", data);

    return E_OK;

}

static ErrorCode DRV_UART_ReceiveByte(UART_HandleTypeDef* huart, uint8_t* data) {

    ASSERT(huart != NULL && data != NULL);

    if (!huart->isInit) return E_DEV_NOT_INIT;

    return RingBuf_Pop(&huart->rxRingBuf, data);

}

static void DRV_UART_SimulateRxISR(UART_HandleTypeDef* huart, uint8_t data) {

    ASSERT(huart != NULL);

    if (!huart->isInit) return;

    huart->Instance->DR = data;

    huart->Instance->SR |= 0x01;

    RingBuf_Push(&huart->rxRingBuf, data);

    LOG_TRACE("UART RX ISR: 0x%02X", data);

    huart->Instance->SR &= ~0x01;

}

static ErrorCode DRV_GPIO_Init(GPIO_HandleTypeDef* hgpio, GPIO_RegTypeDef* instance, uint32_t pin) {

    ASSERT(hgpio != NULL && instance != NULL);

    hgpio->Instance = instance;

    hgpio->pin = pin;

    hgpio->isInit = false;

    hgpio->Instance->MODER &= ~(3U << (pin * 2));

    hgpio->Instance->MODER |= (1U << (pin * 2));

    hgpio->Instance->ODR &= ~(1U << pin);

    hgpio->isInit = true;

    LOG_INFO("GPIO Init Success, Pin:%u", pin);

    return E_OK;

}

static ErrorCode DRV_GPIO_WritePin(GPIO_HandleTypeDef* hgpio, bool state) {

    ASSERT(hgpio != NULL);

    if (!hgpio->isInit) return E_DEV_NOT_INIT;

    if (state) {

        hgpio->Instance->ODR |= (1U << hgpio->pin);

    } else {

        hgpio->Instance->ODR &= ~(1U << hgpio->pin);

    }

    LOG_TRACE("GPIO Pin:%u, State:%u", hgpio->pin, state);

    return E_OK;

}

static bool DRV_GPIO_ReadPin(GPIO_HandleTypeDef* hgpio) {

    ASSERT(hgpio != NULL);

    if (!hgpio->isInit) return false;

    return (hgpio->Instance->IDR & (1U << hgpio->pin)) != 0;

}

static ErrorCode DRV_TIM_Init(TIM_HandleTypeDef* htim, TIM_RegTypeDef* instance,

                              uint32_t prescaler, uint32_t period, void (*callback)(void)) {

    ASSERT(htim != NULL && instance != NULL);

    htim->Instance = instance;

    htim->prescaler = prescaler;

    htim->period = period;

    htim->callback = callback;

    htim->isInit = false;

    htim->Instance->CR1 = 0x00;

    htim->Instance->SR = 0x00;

    htim->Instance->PSC = prescaler - 1;

    htim->Instance->ARR = period - 1;

    htim->Instance->CR1 |= 0x01;

    htim->isInit = true;

    LOG_INFO("TIM Init Success, Prescaler:%u, Period:%u", prescaler, period);

    return E_OK;

}

static void DRV_TIM_SimulateUpdateISR(TIM_HandleTypeDef* htim) {

    ASSERT(htim != NULL);

    if (!htim->isInit || htim->callback == NULL) return;

    htim->Instance->SR &= ~0x01;

    htim->callback();

    LOG_TRACE("TIM Update ISR Triggered");

}

#endif

// ============================== 5. 操作系统抽象层(OSAL) ==============================

#if ENABLE_OSAL

typedef uint32_t OSAL_CriticalType;

static OSAL_CriticalType g_criticalLock = 0;

static void OSAL_EnterCritical(void) {

    g_criticalLock++;

    LOG_TRACE("Enter Critical, Lock:%u", g_criticalLock);

}

static void OSAL_ExitCritical(void) {

    g_criticalLock--;

    LOG_TRACE("Exit Critical, Lock:%u", g_criticalLock);

}

#define MAX_SOFT_TIMER          8

typedef enum {

    TIM_MODE_ONCE,

    TIM_MODE_PERIODIC

} TimerMode;

typedef struct {

    bool used;

    TimerMode mode;

    uint32_t timeoutMs;

    uint32_t curMs;

    void (*callback)(void* arg);

    void* arg;

} SoftTimer;

static SoftTimer g_softTimers[MAX_SOFT_TIMER];

static void OSAL_SoftTimerInit(void) {

    memset(g_softTimers, 0, sizeof(g_softTimers));

    LOG_INFO("Soft Timer Init, Max:%u", MAX_SOFT_TIMER);

}

static int32_t OSAL_SoftTimerCreate(TimerMode mode, uint32_t timeoutMs,

                                   void (*callback)(void*), void* arg) {

    ASSERT(callback != NULL);

    for (int i = 0; i < MAX_SOFT_TIMER; i++) {

        if (!g_softTimers[i].used) {

            g_softTimers[i].used = true;

            g_softTimers[i].mode = mode;

            g_softTimers[i].timeoutMs = timeoutMs;

            g_softTimers[i].curMs = 0;

            g_softTimers[i].callback = callback;

            g_softTimers[i].arg = arg;

            LOG_INFO("Create Timer ID:%u, Timeout:%u ms, Mode:%u", i, timeoutMs, mode);

            return i;

        }

    }

    LOG_ERROR("Soft Timer Full, Create Failed");

    return -1;

}

static ErrorCode OSAL_SoftTimerStart(int32_t timerId) {

    if (timerId < 0 || timerId >= MAX_SOFT_TIMER || !g_softTimers[timerId].used) {

        LOG_ERROR("Invalid Timer ID:%d", timerId);

        return E_INVALID_PARAM;

    }

    g_softTimers[timerId].curMs = 0;

    LOG_INFO("Start Timer ID:%u", timerId);

    return E_OK;

}

static void OSAL_SoftTimerPoll(uint32_t msTick) {

    for (int i = 0; i < MAX_SOFT_TIMER; i++) {

        if (g_softTimers[i].used) {

            g_softTimers[i].curMs += msTick;

            if (g_softTimers[i].curMs >= g_softTimers[i].timeoutMs) {

                if (g_softTimers[i].callback != NULL) {

                    g_softTimers[i].callback(g_softTimers[i].arg);

                }

                if (g_softTimers[i].mode == TIM_MODE_ONCE) {

                    g_softTimers[i].used = false;

                    LOG_INFO("Timer ID:%u Finished (Once Mode)", i);

                } else {

                    g_softTimers[i].curMs = 0;

                }

            }

        }

    }

}

#define MSG_QUEUE_SIZE          16

typedef struct {

    uint32_t msgId;

    uint32_t param;

    void* data;

} Message;

typedef struct {

    Message msgs[MSG_QUEUE_SIZE];

    uint32_t head;

    uint32_t tail;

} MsgQueue;

static MsgQueue g_msgQueue;

static void OSAL_MsgQueueInit(void) {

    memset(&g_msgQueue, 0, sizeof(g_msgQueue));

    LOG_INFO("Msg Queue Init, Size:%u", MSG_QUEUE_SIZE);

}

static ErrorCode OSAL_MsgSend(uint32_t msgId, uint32_t param, void* data) {

    OSAL_EnterCritical();

    uint32_t next = (g_msgQueue.head + 1) % MSG_QUEUE_SIZE;

    if (next == g_msgQueue.tail) {

        OSAL_ExitCritical();

        LOG_WARN("Msg Queue Full, Send Failed");

        return E_BUF_FULL;

    }

    g_msgQueue.msgs[g_msgQueue.head].msgId = msgId;

    g_msgQueue.msgs[g_msgQueue.head].param = param;

    g_msgQueue.msgs[g_msgQueue.head].data = data;

    g_msgQueue.head = next;

    OSAL_ExitCritical();

    LOG_TRACE("Send Msg - ID:%u, Param:%u", msgId, param);

    return E_OK;

}

static ErrorCode OSAL_MsgReceive(Message* msg) {

    ASSERT(msg != NULL);

    OSAL_EnterCritical();

    if (g_msgQueue.head == g_msgQueue.tail) {

        OSAL_ExitCritical();

        return E_BUF_EMPTY;

    }

    *msg = g_msgQueue.msgs[g_msgQueue.tail];

    g_msgQueue.tail = (g_msgQueue.tail + 1) % MSG_QUEUE_SIZE;

    OSAL_ExitCritical();

    LOG_TRACE("Receive Msg - ID:%u, Param:%u", msg->msgId, msg->param);

    return E_OK;

}

#endif

// ============================== 6. 协作式任务调度 ==============================

#if ENABLE_TASK_SCHED

#define MAX_TASK                8

typedef void (*TaskFunc)(void* arg);

typedef enum {

    TASK_READY,

    TASK_RUNNING,

    TASK_SUSPEND

} TaskState;

typedef struct {

    bool used;

    TaskFunc func;

    void* arg;

    TaskState state;

    uint32_t periodMs;

    uint32_t runCnt;

} Task;

static Task g_tasks[MAX_TASK];

static uint32_t g_taskTick = 0;

static void Task_SchedInit(void) {

    memset(g_tasks, 0, sizeof(g_tasks));

    g_taskTick = 0;

    LOG_INFO("Task Scheduler Init, Max Task:%u", MAX_TASK);

}

static int32_t Task_Create(TaskFunc func, void* arg, uint32_t periodMs) {

    ASSERT(func != NULL);

    for (int i = 0; i < MAX_TASK; i++) {

        if (!g_tasks[i].used) {

            g_tasks[i].used = true;

            g_tasks[i].func = func;

            g_tasks[i].arg = arg;

            g_tasks[i].state = TASK_READY;

            g_tasks[i].periodMs = periodMs;

            g_tasks[i].runCnt = 0;

            LOG_INFO("Create Task ID:%u, Period:%u ms", i, periodMs);

            return i;

        }

    }

    LOG_ERROR("Task Scheduler Full, Create Failed");

    return -1;

}

static void Task_SchedPoll(void) {

    g_taskTick += 100;

    for (int i = 0; i < MAX_TASK; i++) {

        if (g_tasks[i].used && g_tasks[i].state == TASK_READY) {

            if (g_taskTick % g_tasks[i].periodMs == 0) {

                g_tasks[i].state = TASK_RUNNING;

                g_tasks[i].func(g_tasks[i].arg);

                g_tasks[i].runCnt++;

                g_tasks[i].state = TASK_READY;

                LOG_TRACE("Task ID:%u Run, Total Cnt:%u", i, g_tasks[i].runCnt);

            }

        }

    }

}

#endif

// ============================== 7. 看门狗与低功耗管理 ==============================

#if ENABLE_WATCHDOG

static bool g_wdgEnable = false;

static uint32_t g_wdgFeedCnt = 0;

static const uint32_t WDG_TIMEOUT_CNT = 50;

static void WDG_Init(void) {

    g_wdgEnable = true;

    g_wdgFeedCnt = 0;

    LOG_INFO("Watchdog Init, Timeout Cnt:%u", WDG_TIMEOUT_CNT);

}

static void WDG_Feed(void) {

    if (!g_wdgEnable) return;

    g_wdgFeedCnt++;

    LOG_TRACE("Watchdog Feed, Cnt:%u", g_wdgFeedCnt);

    if (g_wdgFeedCnt >= WDG_TIMEOUT_CNT) {

        g_wdgFeedCnt = 0;

    }

}

static void WDG_CheckTimeout(void) {

    if (!g_wdgEnable) return;

    if (g_wdgFeedCnt == 0) {

        LOG_FATAL("Watchdog Timeout! System Reset Imminent");

        exit(E_ERROR);

    }

    g_wdgFeedCnt--;

}

#endif

#if ENABLE_POWER_MANAGE

typedef enum {

    POWER_MODE_RUN,

    POWER_MODE_SLEEP,

    POWER_MODE_STOP

} PowerMode;

static PowerMode g_curPowerMode = POWER_MODE_RUN;

static void Power_SetMode(PowerMode mode) {

    if (g_curPowerMode == mode) return;

    g_curPowerMode = mode;

    LOG_INFO("Power Mode Change: %u -> %u", g_curPowerMode, mode);

}

static void Power_EnterLowPower(void) {

    Power_SetMode(POWER_MODE_SLEEP);

    LOG_INFO("Enter Low Power Sleep Mode");

    usleep(5000);

    Power_SetMode(POWER_MODE_RUN);

    LOG_INFO("Exit Low Power Sleep Mode, Back to Run Mode");

}

#endif

// ============================== 8. 链表/栈操作函数 ==============================

static LinkNode* Link_CreateNode(int data) {

    LinkNode* node = (LinkNode*)MemPool_Alloc(sizeof(LinkNode));

    if (node == NULL) {

        LOG_ERROR("Link Node Create Failed, MemPool Full");

        return NULL;

    }

    node->data = data;

    node->next = NULL;

    return node;

}

static void Link_AddTail(LinkNode** head, int data) {

    ASSERT(head != NULL);

    LinkNode* node = Link_CreateNode(data);

    if (node == NULL) return;

    if (*head == NULL) {

        *head = node;

        LOG_TRACE("Link Add Head Node, Data:%d", data);

        return;

    }

    LinkNode* cur = *head;

    while (cur->next != NULL) {

        cur = cur->next;

    }

    cur->next = node;

    LOG_TRACE("Link Add Tail Node, Data:%d", data);

}

static void Link_Destroy(LinkNode** head) {

    ASSERT(head != NULL);

    LinkNode* cur = *head;

    while (cur != NULL) {

        LinkNode* next = cur->next;

        MemPool_Free(cur);

        cur = next;

    }

    *head = NULL;

    LOG_INFO("Link List Destroyed");

}

static void Stack_Push(Stack** top, int data) {

    ASSERT(top != NULL);

    LinkNode* node = Link_CreateNode(data);

    if (node == NULL) return;

    node->next = *top;

    *top = node;

    LOG_TRACE("Stack Push, Data:%d", data);

}

static int Stack_Pop(Stack** top) {

    ASSERT(top != NULL && *top != NULL);

    Stack* tmp = *top;

    int data = tmp->data;

    *top = tmp->next;

    MemPool_Free(tmp);

    LOG_TRACE("Stack Pop, Data:%d", data);

    return data;

}

// ============================== 9. 应用层任务实现 ==============================

static void Task_LedBlink(void* arg) {

    static bool ledState = false;

    GPIO_HandleTypeDef* hgpio = (GPIO_HandleTypeDef*)arg;

    ledState = !ledState;

    DRV_GPIO_WritePin(hgpio, ledState);

    LOG_INFO("LED Blink Task - Pin State:%u", ledState);

    WDG_Feed();

}

static void Task_UartComm(void* arg) {

    UART_HandleTypeDef* huart = (UART_HandleTypeDef*)arg;

    uint8_t rxData;

    if (DRV_UART_ReceiveByte(huart, &rxData) == E_OK) {

        LOG_INFO("UART Comm Task - Receive Data:0x%02X", rxData);

        DRV_UART_SendByte(huart, rxData + 1);

        OSAL_MsgSend(0x01, rxData, NULL);

    }

}

static void Task_SysMonitor(void* arg) {

    (void)arg;

    LOG_INFO("System Monitor Task - Start Statistic");

    MemPool_PrintStat();

    WDG_CheckTimeout();

    LOG_INFO("System Monitor Task - Finish Statistic");

}

static void Timer_Callback(void* arg) {

    (void)arg;

    LOG_INFO("Software Timer Callback - Triggered");

    OSAL_MsgSend(0x02, 0xAA, NULL);

}

// ============================== 10. 主函数(程序入口) ==============================

int main(void) {

    printf("=========================================================\n");

    printf("  Embedded Demo V%d.%d.%d - LeetCode 100%% Compatibility\n", VERSION_MAIN, VERSION_SUB, VERSION_PATCH);

    printf("  Core Fix: 1. LinkNode instead of ListNode 2. Mock Reg to Fix SegFault 3. Fix RingBuf Nested Func\n");

    printf("  Embedded Real Deploy: See Annotations with 【嵌入式真实部署差异】\n");

    printf("=========================================================\n\n");

    LOG_INFO("System Start, Initializing All Core Components...");

    MemPool_Init();

#if ENABLE_OSAL

    OSAL_SoftTimerInit();

    OSAL_MsgQueueInit();

#endif

#if ENABLE_TASK_SCHED

    Task_SchedInit();

#endif

#if ENABLE_WATCHDOG

    WDG_Init();

#endif

#if ENABLE_DRIVER

    UART_HandleTypeDef uart1;

    DRV_UART_Init(&uart1, UART1, 9600);

    GPIO_HandleTypeDef gpioa0;

    DRV_GPIO_Init(&gpioa0, GPIOA, 0);

    TIM_HandleTypeDef tim2;

    DRV_TIM_Init(&tim2, TIM2, 7200, 1000, NULL);

#endif

#if ENABLE_TASK_SCHED && ENABLE_DRIVER && ENABLE_WATCHDOG

    Task_Create(Task_LedBlink, &gpioa0, 1000);

    Task_Create(Task_UartComm, &uart1, 100);

    Task_Create(Task_SysMonitor, NULL, 5000);

#endif

#if ENABLE_OSAL

    int32_t timerId = OSAL_SoftTimerCreate(TIM_MODE_PERIODIC, 2000, Timer_Callback, NULL);

    if (timerId >= 0) {

        OSAL_SoftTimerStart(timerId);

    }

#endif

#if ENABLE_DRIVER

    uint8_t testData[] = {0x01, 0x02, 0x03, 0x04, 0x05};

    for (int i = 0; i < sizeof(testData); i++) {

        DRV_UART_SimulateRxISR(&uart1, testData[i]);

    }

#endif

    LOG_INFO("=== Link List & Stack Function Demo Start ===");

    LinkNode* linkList = NULL;

    Link_AddTail(&linkList, 10);

    Link_AddTail(&linkList, 20);

    Link_AddTail(&linkList, 30);

    LOG_INFO("Link List Data: 10 -> 20 -> 30");

   

    Stack* stack = NULL;

    Stack_Push(&stack, 100);

    Stack_Push(&stack, 200);

    Stack_Push(&stack, 300);

    LOG_INFO("Stack Push Data: 100, 200, 300");

    LOG_INFO("Stack Pop Data: %d, %d, %d", Stack_Pop(&stack), Stack_Pop(&stack), Stack_Pop(&stack));

    Link_Destroy(&linkList);

    LOG_INFO("=== Link List & Stack Function Demo End ===");

    LOG_INFO("Enter Main System Loop (Will exit after 10 seconds)");

    uint32_t sysTick = 0;

    const uint32_t EXIT_TICK = 10000;

    while (1) {

#if ENABLE_TASK_SCHED

        Task_SchedPoll();

#endif

#if ENABLE_OSAL

        OSAL_SoftTimerPoll(100);

#endif

#if ENABLE_OSAL

        Message msg;

        if (OSAL_MsgReceive(&msg) == E_OK) {

            LOG_INFO("Main Loop - Process System Message: ID=%u, Param=0x%02X", msg.msgId, msg.param);

        }

#endif

        sysTick += 100;

        if (sysTick % 1000 == 0) {

            LOG_TRACE("Main Loop - System Tick Update: %u ms", sysTick);

        }

        if (sysTick > 3000) {

#if ENABLE_POWER_MANAGE

            Power_EnterLowPower();

#endif

        }

        usleep(10000);

        if (sysTick >= EXIT_TICK) {

            LOG_INFO("Main Loop - Reach Exit Time, Total Tick: %u ms", sysTick);

            break;

        }

    }

    LOG_INFO("System Pre-Shutdown, Final Statistic...");

    MemPool_PrintStat();

    LOG_INFO("System All Components Shutdown Successfully!");

    printf("\n=========================================================\n");

    printf("  LeetCode Compilation & Execution SUCCESS - No Errors!\n");

    printf("  SegFault Fixed | No ListNode Conflict | No Nested Func\n");

    printf("  Embedded Real Deploy Annotations Included in Code\n");

    printf("=========================================================\n");

    return E_OK;

}

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐