first commit

This commit is contained in:
liyp
2026-08-25 22:10:31 -04:00
commit dde12bf30b
41 changed files with 1379 additions and 0 deletions
+174
View File
@@ -0,0 +1,174 @@
#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
}
+79
View File
@@ -0,0 +1,79 @@
#ifndef OS_SAMPLE_H
#define OS_SAMPLE_H
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN // 阻止 windows.h 包含旧版 winsock.h
#endif
#include <semaphore.h>
#include <windows.h>
#elif defined(__linux__)
#include <unistd.h>
#include <time.h>
#include <pthread.h>
#endif
/**
* @brief 状态返回码枚举
*/
typedef enum {
#ifndef ERROR
ERROR = 0,
#endif
#ifndef SUCCESS
SUCCESS = 1
#endif
} Status;
// 常用公共宏定义
#define ENABLE 1
#define DISABLE 0
/* 时间常数定义 */
#define portMAX_DELAY (TickType_t)0xFFFFFFFFUL
/* FreeRTOS 基础类型模拟 */
typedef int32_t BaseType_t;
typedef uint32_t TickType_t;
typedef uint32_t UBaseType_t;
typedef void* TaskHandle_t;
typedef void* QueueHandle_t;
#define pdTRUE 1
#define pdFALSE 0
#define pdPASS 1
#define pdFAIL 0
#define errQUEUE_FULL 0 // 或者根据你现有的定义调整
/* 任务函数指针定义 */
typedef void (*TaskFunction_t)(void *);
/* --- 严格一致的接口声明 --- */
// 延时 (ms)
void vTaskDelay(const TickType_t xTicksToDelay);
// 创建任务
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 vTaskStartScheduler(void);
// 队列操作
QueueHandle_t xQueueCreate(UBaseType_t uxQueueLength, UBaseType_t uxItemSize);
BaseType_t xQueueSend(QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait);
BaseType_t xQueueReceive(QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait);
#endif
+85
View File
@@ -0,0 +1,85 @@
#include "SocketSample.h"
#include <stdio.h>
#include <string.h>
// --- 1. xSocketInitEnvironment ---
int xSocketInitEnvironment(void) {
#ifdef _WIN32
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
return SOCKET_FAIL;
}
#endif
return SOCKET_SUCCESS;
}
// --- 2. xSocketCreateUDP ---
Socket_t xSocketCreateUDP(void) {
Socket_t xSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
return xSocket;
}
// --- 3. xSocketBind ---
int xSocketBind(Socket_t xSocket, uint16_t usPort) {
struct sockaddr_in xLocalAddr;
memset(&xLocalAddr, 0, sizeof(xLocalAddr));
xLocalAddr.sin_family = AF_INET;
xLocalAddr.sin_port = htons(usPort);
xLocalAddr.sin_addr.s_addr = INADDR_ANY; // 监听所有网卡
if (bind(xSocket, (struct sockaddr*)&xLocalAddr, sizeof(xLocalAddr)) == SOCKET_ERROR_HANDLE) {
return SOCKET_FAIL;
}
return SOCKET_SUCCESS;
}
// --- 4. vSocketClose ---
void vSocketClose(Socket_t xSocket) {
if (xSocket == INVALID_SOCKET_HANDLE) return;
#ifdef _WIN32
closesocket(xSocket);
#else
close(xSocket);
#endif
}
// --- 5. xSocketSendTo ---
int32_t xSocketSendTo(Socket_t xSocket, const void* pvBuffer, uint32_t ulLength,
const char* pcIPAddress, uint16_t usPort) {
struct sockaddr_in xDestAddr;
memset(&xDestAddr, 0, sizeof(xDestAddr));
xDestAddr.sin_family = AF_INET;
xDestAddr.sin_port = htons(usPort);
xDestAddr.sin_addr.s_addr = inet_addr(pcIPAddress);
int res = sendto(xSocket, (const char*)pvBuffer, (int)ulLength, 0,
(struct sockaddr*)&xDestAddr, sizeof(xDestAddr));
if (res == SOCKET_ERROR_HANDLE) return SOCKET_FAIL;
return (int32_t)res;
}
// --- 6. xSocketReceiveFrom ---
int32_t xSocketReceiveFrom(Socket_t xSocket, void* pvBuffer, uint32_t ulLength,
char* pcIPAddress, uint16_t* pusPort) {
struct sockaddr_in xSourceAddr;
#ifdef _WIN32
int xAddrLen = sizeof(xSourceAddr);
#else
socklen_t xAddrLen = sizeof(xSourceAddr);
#endif
int res = recvfrom(xSocket, (char*)pvBuffer, (int)ulLength, 0,
(struct sockaddr*)&xSourceAddr, &xAddrLen);
if (res != SOCKET_ERROR_HANDLE) {
if (pcIPAddress) {
char* ip = inet_ntoa(xSourceAddr.sin_addr);
if (ip) strcpy(pcIPAddress, ip);
}
if (pusPort) *pusPort = ntohs(xSourceAddr.sin_port);
} else {
return SOCKET_FAIL;
}
return (int32_t)res;
}
+45
View File
@@ -0,0 +1,45 @@
#ifndef SOCKET_SAMPLE_H
#define SOCKET_SAMPLE_H
#include <stdint.h>
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
typedef SOCKET Socket_t;
#define INVALID_SOCKET_HANDLE INVALID_SOCKET
#define SOCKET_ERROR_HANDLE SOCKET_ERROR
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
typedef int Socket_t;
#define INVALID_SOCKET_HANDLE -1
#define SOCKET_ERROR_HANDLE -1
#endif
#define SOCKET_SUCCESS 0
#define SOCKET_FAIL -1
// 环境初始化(Win必须,Linux为空操作)
int xSocketInitEnvironment(void);
// 创建 UDP Socket
Socket_t xSocketCreateUDP(void);
// 绑定端口(接收端必备)
int xSocketBind(Socket_t xSocket, uint16_t usPort);
// 关闭 Socket
void vSocketClose(Socket_t xSocket);
// UDP 发送数据
int32_t xSocketSendTo(Socket_t xSocket, const void* pvBuffer, uint32_t ulLength,
const char* pcIPAddress, uint16_t usPort);
// UDP 接收数据
int32_t xSocketReceiveFrom(Socket_t xSocket, void* pvBuffer, uint32_t ulLength,
char* pcIPAddress, uint16_t* pusPort);
#endif