Browse Source

实现freeRTOS的互斥和信号量

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

134
bspMCU/My_freeRTOS.c

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

33
library/common/include/rd_thread.h

@ -60,13 +60,19 @@ extern "C"{
* include header files *
*----------------------------------------------*/
#include "common.h"
#ifndef USE_FREERTOS
#include <pthread.h>
#endif
/*==============================================*
* 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;
#define RD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
#else
@ -84,19 +90,32 @@ typedef enum {
AUTO_MODE_SYSV = 2 // shmget (老式 Linux)
} rd_shm_mode_t;
#ifdef __ANDROID__
#define RD_SHM_DEFAULT_MODE AUTO_MODE_ANDROID
#if defined(USE_FREERTOS)
/* 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
#define RD_SHM_DEFAULT_MODE AUTO_MODE_POSIX
#endif
typedef struct {
pthread_mutex_t mutex;
pthread_cond_t cond;
int count;
} 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;
#elif RD_SHM_DEFAULT_MODE == AUTO_MODE_SYSV
#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;
#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_initialized = 1;
#ifdef USE_FREERTOS
(void)Rd_MutexInit(&g_pool_mutex);
#endif
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;
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);
}
}
Rd_MutexUnlock(NULL, __func__, NULL);
#ifdef USE_FREERTOS
Rd_MutexUnlock(&g_pool_mutex, __func__, NULL);
#endif
return pvReturn;
}
@ -301,7 +313,9 @@ WEAK void Rd_MemPoolFree(void* ptr)
return;
}
Rd_MutexLock(NULL, __func__, NULL);
#ifdef USE_FREERTOS
Rd_MutexLock(&g_pool_mutex, __func__, NULL);
#endif
{
MemBlockHeader_t* block = get_header_ptr(ptr);
@ -318,7 +332,9 @@ WEAK void Rd_MemPoolFree(void* ptr)
// 【关键】尝试与相邻空闲块合并,减少碎片
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)

Loading…
Cancel
Save