Browse Source

实现freeRTOS的互斥和信号量

master
Lizongdi 1 day ago
parent
commit
25ecd88796
  1. 128
      bspMCU/My_freeRTOS.c
  2. 33
      library/common/include/rd_thread.h
  3. 24
      library/common/rd_mempool.c

128
bspMCU/My_freeRTOS.c

@ -17,13 +17,14 @@
******************************************************************************/ ******************************************************************************/
#include "common.h" #include "common.h"
#include "rd_thread.h"
#ifdef USE_FREERTOS #ifdef USE_FREERTOS
#include "cmsis_os.h" #include "cmsis_os.h"
#include "cmsis_os2.h"
#include "FreeRTOS.h" #include "FreeRTOS.h"
#include "task.h" #include "task.h"
#include "string.h" #include "string.h"
#include "stdio.h" #include "stdio.h"
#include "common.h"
#include "lua_base.h" #include "lua_base.h"
/*----------------------------------------------* /*----------------------------------------------*
@ -79,81 +80,102 @@ void ShowHeapSize(void)
lua_print("mempool free:\t%d\t%d\n", myMempool, myTotal); lua_print("mempool free:\t%d\t%d\n", myMempool, myTotal);
} }
/*void *pvPortCalloc(size_t xNum, size_t xSize)
{
size_t xTotalSize = xNum * xSize;
// 防止乘法溢出(健壮性检查) int Rd_SemInit(void *_sem, int _iPshared, int _iValue)
if (xNum != 0 && xTotalSize / xNum != xSize) {
{ rd_sem_t *pSem = (rd_sem_t *)_sem;
return NULL; osSemaphoreAttr_t attr = {
.name = NULL,
.attr_bits = 0,
.cb_mem = pSem->cb_buf,
.cb_size = sizeof(pSem->cb_buf)
};
pSem->sem_id = osSemaphoreNew((uint32_t)_iValue + 1, (uint32_t)_iValue, &attr);
if (pSem->sem_id == NULL) {
return RD_FAILURE;
} }
pSem->count = _iValue;
return RD_SUCCESS;
}
void *pvReturn = pvPortMalloc(xTotalSize); void Rd_SemWait(void *_sem, const char *_pcFunc, int *_piCnt)
if (pvReturn != NULL) { {
// 将分配的内存块全部置零 rd_sem_t *pSem = (rd_sem_t *)_sem;
memset(pvReturn, 0, xTotalSize); (void)_pcFunc;
osSemaphoreAcquire(pSem->sem_id, osWaitForever);
if (_piCnt != NULL) {
(*_piCnt)++;
} }
return pvReturn;
} }
typedef struct A_BLOCK_LINK void Rd_SemPost(void *_sem, const char *_pcFunc, int *_piCnt)
{ {
struct A_BLOCK_LINK *pxNextFreeBlock; rd_sem_t *pSem = (rd_sem_t *)_sem;
size_t xBlockSize; (void)_pcFunc;
} BlockLink_t; osSemaphoreRelease(pSem->sem_id);
if (_piCnt != NULL) {
(*_piCnt)++;
}
}
// 假设你使用的是 heap_4,通常 xHeapStructSize 等于 sizeof(BlockLink_t) 并做了对齐 int Rd_SemDestroy(void *_sem)
// 你可以直接通过指针前移来获取旧大小
void *pvPortRealloc(void *pv, size_t xWantedSize)
{ {
if (xWantedSize == 0) { vPortFree(pv); return NULL; } rd_sem_t *pSem = (rd_sem_t *)_sem;
if (pv == NULL) { return pvPortMalloc(xWantedSize); } if (pSem->sem_id != NULL) {
osSemaphoreDelete(pSem->sem_id);
// 强行读取头部信息获取旧大小 pSem->sem_id = NULL;
uint8_t *puc = (uint8_t *)pv;
puc -= sizeof(BlockLink_t); // 减去头部大小(需注意字节对齐,通常 heap_4 默认是 8 字节对齐)
BlockLink_t *pxLink = (BlockLink_t *)puc;
size_t xOldSize = pxLink->xBlockSize & ~((size_t)0x01); // 去掉最低位的已分配标志位
void *pvNew = pvPortMalloc(xWantedSize);
if (pvNew != NULL)
{
memcpy(pvNew, pv, xOldSize);
vPortFree(pv);
} }
return pvNew; return RD_SUCCESS;
} }
SemaphoreHandle_t xCountingSemaphore; int Rd_MutexInit(void *_pMutex)
StaticSemaphore_t xSemaphoreBuffer;
int Rd_SemInit(void *_sem, int _iPshared, int _iValue)
{ {
xCountingSemaphore = xSemaphoreCreateCountingStatic(5, 5, &xSemaphoreBuffer); rd_mutex_t *pMutex = (rd_mutex_t *)_pMutex;
osMutexAttr_t attr = {
.name = NULL,
.attr_bits = osMutexRecursive | osMutexPrioInherit,
.cb_mem = NULL,
.cb_size = 0
};
*pMutex = osMutexNew(&attr);
if (*pMutex == NULL) {
return RD_FAILURE; return RD_FAILURE;
}
return RD_SUCCESS;
} }
void Rd_SemWait(void *_sem, const char *_pcFunc, int *_piCnt) void Rd_MutexLock(void *_pMutex, const char *_pcFunc, int *_piCnt)
{ {
xSemaphoreTake(sem_full, portMAX_DELAY) rd_mutex_t *pMutex = (rd_mutex_t *)_pMutex;
return; (void)_pcFunc;
if (*pMutex != NULL) {
osMutexAcquire(*pMutex, osWaitForever);
}
if (_piCnt != NULL) {
(*_piCnt)++;
}
} }
void Rd_SemPost(void *_sem, const char *_pcFunc, int *_piCnt) void Rd_MutexUnlock(void *_pMutex, const char *_pcFunc, int *_piCnt)
{
xSemaphoreGive(sem_empty);
return;
}*/
void Rd_MutexLock(void *_pMutex, const char *_pcFunc, int *_piCnt)
{ {
vTaskSuspendAll(); rd_mutex_t *pMutex = (rd_mutex_t *)_pMutex;
(void)_pcFunc;
if (*pMutex != NULL) {
osMutexRelease(*pMutex);
}
if (_piCnt != NULL) {
(*_piCnt)++;
}
} }
void Rd_MutexUnlock(void *_pMutex, const char *_pcFunc, int *_piCnt) int Rd_MutexDestroy(void *_pMutex)
{ {
(void)xTaskResumeAll(); rd_mutex_t *pMutex = (rd_mutex_t *)_pMutex;
if (*pMutex != NULL) {
osMutexDelete(*pMutex);
*pMutex = NULL;
}
return RD_SUCCESS;
} }
void Rd_Delay(uint32_t Delay) void Rd_Delay(uint32_t Delay)

33
library/common/include/rd_thread.h

@ -60,13 +60,19 @@ extern "C"{
* include header files * * include header files *
*----------------------------------------------*/ *----------------------------------------------*/
#include "common.h" #include "common.h"
#ifndef USE_FREERTOS
#include <pthread.h> #include <pthread.h>
#endif
/*==============================================* /*==============================================*
* constants or macros define * * constants or macros define *
*----------------------------------------------*/ *----------------------------------------------*/
#ifdef BUILD_PLATFORM_LINUX #if defined(USE_FREERTOS)
/* FreeRTOS: opaque handle, 不依赖 FreeRTOS 头文件 */
typedef void* rd_mutex_t;
#define RD_MUTEX_INITIALIZER NULL
#elif defined(BUILD_PLATFORM_LINUX)
typedef pthread_mutex_t rd_mutex_t; typedef pthread_mutex_t rd_mutex_t;
#define RD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER #define RD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
#else #else
@ -84,19 +90,32 @@ typedef enum {
AUTO_MODE_SYSV = 2 // shmget (老式 Linux) AUTO_MODE_SYSV = 2 // shmget (老式 Linux)
} rd_shm_mode_t; } rd_shm_mode_t;
#ifdef __ANDROID__ #if defined(USE_FREERTOS)
#define RD_SHM_DEFAULT_MODE AUTO_MODE_ANDROID /* FreeRTOS: opaque handle + 预留 buffer,不依赖 FreeRTOS 头文件
* RD_SEM_CB_SIZE StaticSemaphore_t ( ~80-100 bytes) */
#define RD_SEM_CB_SIZE 96
typedef struct {
void *sem_id; /* osSemaphoreId_t (opaque) */
uint8_t cb_buf[RD_SEM_CB_SIZE]; /* 预留空间用于静态分配 */
int count;
} rd_sem_t;
#else #else
#define RD_SHM_DEFAULT_MODE AUTO_MODE_POSIX
#endif
typedef struct { typedef struct {
pthread_mutex_t mutex; pthread_mutex_t mutex;
pthread_cond_t cond; pthread_cond_t cond;
int count; int count;
} rd_sem_t; } rd_sem_t;
#endif
#ifdef __ANDROID__
#define RD_SHM_DEFAULT_MODE AUTO_MODE_ANDROID
#else
#define RD_SHM_DEFAULT_MODE AUTO_MODE_POSIX
#endif
#if RD_SHM_DEFAULT_MODE == AUTO_MODE_POSIX || RD_SHM_DEFAULT_MODE == AUTO_MODE_ANDROID #if defined(USE_FREERTOS)
typedef rd_sem_t Rd_sem_t;
#elif RD_SHM_DEFAULT_MODE == AUTO_MODE_POSIX || RD_SHM_DEFAULT_MODE == AUTO_MODE_ANDROID
typedef rd_sem_t Rd_sem_t; typedef rd_sem_t Rd_sem_t;
#elif RD_SHM_DEFAULT_MODE == AUTO_MODE_SYSV #elif RD_SHM_DEFAULT_MODE == AUTO_MODE_SYSV
#include <semaphore.h> #include <semaphore.h>

24
library/common/rd_mempool.c

@ -54,6 +54,10 @@ static int g_initialized = 0;
static uint8_t* g_heap_buf = NULL; static uint8_t* g_heap_buf = NULL;
#endif #endif
#ifdef USE_FREERTOS
static rd_mutex_t g_pool_mutex;
#endif
/*----------------------------------------------* /*----------------------------------------------*
* * * *
*----------------------------------------------*/ *----------------------------------------------*/
@ -209,6 +213,10 @@ WEAK void Rd_MemDoInit(void)
g_free_list_head = initial_block; g_free_list_head = initial_block;
g_initialized = 1; g_initialized = 1;
#ifdef USE_FREERTOS
(void)Rd_MutexInit(&g_pool_mutex);
#endif
log_d("MemPool Init Success: Total %d Bytes", MEM_POOL_TOTAL_SIZE); log_d("MemPool Init Success: Total %d Bytes", MEM_POOL_TOTAL_SIZE);
} }
@ -230,7 +238,9 @@ WEAK void* Rd_MemPoolMalloc(size_t size)
if (!g_initialized || size == 0) return NULL; if (!g_initialized || size == 0) return NULL;
void *pvReturn = NULL; void *pvReturn = NULL;
Rd_MutexLock(NULL, __func__, NULL); #ifdef USE_FREERTOS
Rd_MutexLock(&g_pool_mutex, __func__, NULL);
#endif
{ {
// 对齐大小计算:用户数据 + 头部 // 对齐大小计算:用户数据 + 头部
@ -289,7 +299,9 @@ WEAK void* Rd_MemPoolMalloc(size_t size)
log_d("MemPool Malloc Failed: Request %zu, No Block Found", size); log_d("MemPool Malloc Failed: Request %zu, No Block Found", size);
} }
} }
Rd_MutexUnlock(NULL, __func__, NULL); #ifdef USE_FREERTOS
Rd_MutexUnlock(&g_pool_mutex, __func__, NULL);
#endif
return pvReturn; return pvReturn;
} }
@ -301,7 +313,9 @@ WEAK void Rd_MemPoolFree(void* ptr)
return; return;
} }
Rd_MutexLock(NULL, __func__, NULL); #ifdef USE_FREERTOS
Rd_MutexLock(&g_pool_mutex, __func__, NULL);
#endif
{ {
MemBlockHeader_t* block = get_header_ptr(ptr); MemBlockHeader_t* block = get_header_ptr(ptr);
@ -318,7 +332,9 @@ WEAK void Rd_MemPoolFree(void* ptr)
// 【关键】尝试与相邻空闲块合并,减少碎片 // 【关键】尝试与相邻空闲块合并,减少碎片
merge_free_blocks(block); merge_free_blocks(block);
} }
Rd_MutexUnlock(NULL, __func__, NULL); #ifdef USE_FREERTOS
Rd_MutexUnlock(&g_pool_mutex, __func__, NULL);
#endif
} }
WEAK void* Rd_MemPoolCalloc(size_t n, size_t size) WEAK void* Rd_MemPoolCalloc(size_t n, size_t size)

Loading…
Cancel
Save