/**************************************************************************************************
* 文件: 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;
}