#include "OsSample.h" // --- 1. vTaskDelay --- void vTaskDelay(const TickType_t xTicksToDelay) { #ifdef _WIN32 Sleep(xTicksToDelay); #elif defined(__linux__) struct timespec ts; ts.tv_sec = xTicksToDelay / 1000; ts.tv_nsec = (xTicksToDelay % 1000) * 1000000L; nanosleep(&ts, NULL); #endif } // --- 2. xTaskCreate --- // 内部包装函数:为了适配系统线程接口并防止任务返回导致进程奔溃 #ifdef _WIN32 DWORD WINAPI prvTaskWrapper(LPVOID lpParam) { TaskFunction_t pxTask = (TaskFunction_t)(((void**)lpParam)[0]); void* pvParams = ((void**)lpParam)[1]; free(lpParam); pxTask(pvParams); return 0; } #else void* prvTaskWrapper(void* lpParam) { TaskFunction_t pxTask = (TaskFunction_t)(((void**)lpParam)[0]); void* pvParams = ((void**)lpParam)[1]; free(lpParam); pxTask(pvParams); return NULL; } #endif BaseType_t xTaskCreate(TaskFunction_t pvTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask) { // 准备参数包 void** args = malloc(sizeof(void*) * 2); args[0] = (void*)pvTaskCode; args[1] = pvParameters; #ifdef _WIN32 HANDLE hThread = CreateThread(NULL, usStackDepth, prvTaskWrapper, args, 0, NULL); if (pxCreatedTask) *pxCreatedTask = (TaskHandle_t)hThread; return (hThread != NULL) ? pdPASS : pdFAIL; #elif defined(__linux__) pthread_t threadId; int res = pthread_create(&threadId, NULL, prvTaskWrapper, args); if (pxCreatedTask) *pxCreatedTask = (TaskHandle_t)threadId; return (res == 0) ? pdPASS : pdFAIL; #endif } // --- 3. xQueueCreate (简易内存模拟) --- // 注意:实际生产环境建议使用互斥锁保护。这里仅展示逻辑框架。 typedef struct { uint8_t* storage; uint32_t length; uint32_t item_size; uint32_t write_idx; // 写指针 uint32_t read_idx; // 读指针 uint32_t count; // 当前元素数量 #ifdef _WIN32 HANDLE mutex; // 保护结构体内部数据 HANDLE sem_fill; // 计数信号量:当前有多少数据可读 #else pthread_mutex_t mutex; sem_t sem_fill; #endif } SimulatedQueue; // --- xQueueCreate --- QueueHandle_t xQueueCreate(UBaseType_t uxQueueLength, UBaseType_t uxItemSize) { SimulatedQueue* q = (SimulatedQueue*)malloc(sizeof(SimulatedQueue)); if (!q) return NULL; q->storage = (uint8_t*)malloc(uxQueueLength * uxItemSize); q->length = uxQueueLength; q->item_size = uxItemSize; q->write_idx = 0; q->read_idx = 0; q->count = 0; #ifdef _WIN32 q->mutex = CreateMutex(NULL, FALSE, NULL); q->sem_fill = CreateSemaphore(NULL, 0, uxQueueLength, NULL); #else pthread_mutex_init(&q->mutex, NULL); sem_init(&q->sem_fill, 0, 0); #endif return (QueueHandle_t)q; } // --- xQueueSend --- BaseType_t xQueueSend(QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait) { SimulatedQueue* q = (SimulatedQueue*)xQueue; if (!q) return pdFAIL; // 1. 进入临界区保护数据 #ifdef _WIN32 WaitForSingleObject(q->mutex, INFINITE); #else pthread_mutex_lock(&q->mutex); #endif // 检查队列是否已满 if (q->count >= q->length) { #ifdef _WIN32 ReleaseMutex(q->mutex); #else pthread_mutex_unlock(&q->mutex); #endif return errQUEUE_FULL; } // 2. 拷贝数据到环形缓冲区 memcpy(q->storage + (q->write_idx * q->item_size), pvItemToQueue, q->item_size); q->write_idx = (q->write_idx + 1) % q->length; q->count++; // 3. 释放信号量通知接收方,退出临界区 #ifdef _WIN32 ReleaseSemaphore(q->sem_fill, 1, NULL); ReleaseMutex(q->mutex); #else sem_post(&q->sem_fill); pthread_mutex_unlock(&q->mutex); #endif return pdPASS; } // --- xQueueReceive --- BaseType_t xQueueReceive(QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait) { SimulatedQueue* q = (SimulatedQueue*)xQueue; if (!q) return pdFAIL; // 1. 等待信号量(是否有数据可读) #ifdef _WIN32 DWORD res = WaitForSingleObject(q->sem_fill, (xTicksToWait == portMAX_DELAY) ? INFINITE : xTicksToWait); if (res != WAIT_OBJECT_0) return pdFAIL; WaitForSingleObject(q->mutex, INFINITE); // 进入临界区 #else // Linux 简化处理,直接阻塞等 sem_wait(&q->sem_fill); pthread_mutex_lock(&q->mutex); #endif // 2. 拷贝数据 memcpy(pvBuffer, q->storage + (q->read_idx * q->item_size), q->item_size); q->read_idx = (q->read_idx + 1) % q->length; q->count--; // 3. 退出临界区 #ifdef _WIN32 ReleaseMutex(q->mutex); #else pthread_mutex_unlock(&q->mutex); #endif return pdPASS; } // 在 OsSample.c 中实现 void vTaskStartScheduler(void) { #ifdef _WIN32 // Windows: 挂起主线程,直到进程结束 Sleep(INFINITE); #elif defined(__linux__) // Linux: 使用 pause() 挂起,等待信号,或者用死循环 while(1) { pause(); } #endif }