c_cpp FreeRTOS的基于信号量和委托的任务数据共享与同步

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c_cpp FreeRTOS的基于信号量和委托的任务数据共享与同步相关的知识,希望对你有一定的参考价值。

#include "Sys.h"
typedef struct
{
  TaskHandle_t taskHandle;
  ST_COMMAND* acquireCommand;
  ST_COMMAND* transmitterCommand;
  SemaphoreHandle_t acquireSemaphore;
  SemaphoreHandle_t transmitterSemaphore;
}TaskCmdStrorage;
typedef struct TaskCmdStrorageLinked TaskCmdStrorageLinked;
struct TaskCmdStrorageLinked
{
  TaskCmdStrorage*  stTaskCmdStrorage;
  TaskCmdStrorageLinked*  prev;
  TaskCmdStrorageLinked*  next;
};

static TaskCmdStrorageLinked* taskCmdStrorageLinked = NULL;

static TaskCmdStrorageLinked* InitTaskCmdStrorageLinked()
{
  if (taskCmdStrorageLinked != NULL)
  {
    taskCmdStrorageLinked = (TaskCmdStrorageLinked*)pvPortMalloc(sizeof(TaskCmdStrorageLinked));
    taskCmdStrorageLinked->prev = taskCmdStrorageLinked;
    taskCmdStrorageLinked->next = taskCmdStrorageLinked;
  }
  return taskCmdStrorageLinked;
}
static TaskCmdStrorageLinked const* AddStTaskCmdStrorageToLinked(TaskCmdStrorage* stTaskCmdStrorage)
{
  TaskCmdStrorageLinked *stLinked = NULL;
  stLinked = (TaskCmdStrorageLinked*)pvPortMalloc(sizeof(TaskCmdStrorageLinked));
  if (stLinked != NULL)
  {
    stLinked->stTaskCmdStrorage = stTaskCmdStrorage;
    stLinked->prev = taskCmdStrorageLinked->prev->next;
    taskCmdStrorageLinked->prev->next = stLinked;
    stLinked->next = taskCmdStrorageLinked;
  }
  return stLinked;
}

static void RemoveStTaskCmdStrorageFromLinked(TaskCmdStrorageLinked* stLinked)
{
  stLinked->prev->next = stLinked->next;
  stLinked->next->prev = stLinked->prev;
  vPortFree(stLinked);
}

TaskCmdHandle_t RegisterStTaskCmdStrorage()
{
  TaskCmdStrorage* stTaskCmdStrorage;
  stTaskCmdStrorage = (TaskCmdStrorage*)pvPortMalloc(sizeof(TaskCmdStrorage));
  stTaskCmdStrorage->taskHandle = xTaskGetCurrentTaskHandle();
  
  //stTaskCmdStrorage->acquireCommand = pvPortMalloc(sizeof(ST_COMMAND));
  //stTaskCmdStrorage->transmitterCommand =  pvPortMalloc(sizeof(ST_COMMAND));
  
  stTaskCmdStrorage->transmitterSemaphore = xSemaphoreCreateBinary();
  stTaskCmdStrorage->acquireSemaphore = xSemaphoreCreateBinary();
  xSemaphoreGive(stTaskCmdStrorage->acquireSemaphore);
  xSemaphoreGive(stTaskCmdStrorage->transmitterSemaphore);
  return stTaskCmdStrorage;
}

void CancelStTaskCmdStrorage(TaskCmdHandle_t taskCmdHandle)
{
  TaskCmdStrorage* stTaskCmdStrorage = (TaskCmdStrorage*)taskCmdHandle;
  vSemaphoreDelete(stTaskCmdStrorage->acquireSemaphore);
  vSemaphoreDelete(stTaskCmdStrorage->transmitterSemaphore);
  //vPortFree(stTaskCmdStrorage->acquireCommand);
  //vPortFree(stTaskCmdStrorage->transmitterCommand);
  vPortFree(taskCmdHandle);
}
bool PushAcquireCmdStorage(const TaskCmdHandle_t taskCmdHandle,const ST_COMMAND stCommand)
{
  TaskCmdStrorage* taskCmdStrorage = (TaskCmdStrorage*)taskCmdHandle;
  if (xSemaphoreTake(taskCmdStrorage->acquireSemaphore,0) == pdTRUE)
  {
    taskCmdStrorage->acquireCommand = (ST_COMMAND*)pvPortMalloc(sizeof(ST_COMMAND));
    taskCmdStrorage->acquireCommand->ucCmdNum = stCommand.ucCmdNum;
    taskCmdStrorage->acquireCommand->unFunc = stCommand.unFunc;
    taskCmdStrorage->acquireCommand->ucCmd = stCommand.ucCmd;
    taskCmdStrorage->acquireCommand->ucLen = stCommand.ucLen;
    for (uint16_t i = 0;i < taskCmdStrorage->acquireCommand->ucLen &&  i < sizeof(stCommand.aucData);i++)
      taskCmdStrorage->acquireCommand->aucData[i] = stCommand.aucData[i];
    return true;
  }
  else
  {
    return false;
  }
}
void PullAcquireCmdStorage(const TaskCmdHandle_t taskCmdHandle, ST_COMMAND * const stCommand)
{
  TaskCmdStrorage* taskCmdStrorage = (TaskCmdStrorage*)taskCmdHandle;
  stCommand->unFunc = taskCmdStrorage->acquireCommand->unFunc;
  stCommand->ucCmdNum = taskCmdStrorage->acquireCommand->ucCmdNum;
  stCommand->ucCmd = taskCmdStrorage->acquireCommand->ucCmd;
  stCommand->ucLen = taskCmdStrorage->acquireCommand->ucLen;
  for (uint16_t i = 0;i < stCommand->ucLen && i < sizeof(stCommand->aucData);i++)
    stCommand->aucData[i] = taskCmdStrorage->acquireCommand->aucData[i];
  vPortFree(taskCmdStrorage->acquireCommand);
  xSemaphoreGive(taskCmdStrorage->acquireSemaphore);
}
bool PushTransmitterCmdStorage(const TaskCmdHandle_t taskCmdHandle,const ST_COMMAND stCommand)
{
  TaskCmdStrorage* taskCmdStrorage = (TaskCmdStrorage*)taskCmdHandle;
  if (xSemaphoreTake(taskCmdStrorage->transmitterSemaphore,0) == pdTRUE)
  {
    taskCmdStrorage->transmitterCommand = (ST_COMMAND*)pvPortMalloc(sizeof(ST_COMMAND));
    taskCmdStrorage->transmitterCommand->unFunc = stCommand.unFunc;
    taskCmdStrorage->transmitterCommand->ucCmdNum = stCommand.ucCmdNum;
    taskCmdStrorage->transmitterCommand->ucCmd = stCommand.ucCmd;
    taskCmdStrorage->transmitterCommand->ucLen = stCommand.ucLen;
    for (uint16_t i = 0;i < taskCmdStrorage->transmitterCommand->ucLen && i < sizeof(ST_COMMAND);i++)
      taskCmdStrorage->transmitterCommand->aucData[i] = stCommand.aucData[i];
    return TRUE;
  }
  else
  {
    return FALSE;
  }
  
}
void PullTransmitterCmdStorage(const TaskCmdHandle_t taskCmdHandle, ST_COMMAND * const stCommand)
{
  TaskCmdStrorage* taskCmdStrorage = (TaskCmdStrorage*)taskCmdHandle;
  
}
static SemaphoreHandle_t acquireSemaphore = NULL;
static SemaphoreHandle_t transmitterSemaphore = NULL;

void SysInit(void)
{
  taskENTER_CRITICAL();
  SysEventInit();
  if (acquireSemaphore == NULL)
  {
    acquireSemaphore = xSemaphoreCreateBinary();
    xSemaphoreGive(acquireSemaphore);
  }
  if (transmitterSemaphore == NULL)
  {
    transmitterSemaphore = xSemaphoreCreateBinary();
    xSemaphoreGive(transmitterSemaphore);
  }
  taskEXIT_CRITICAL();
}

static void (*AcquireProc)(ST_COMMAND *stCommand);
static void (*TransmitterProc)(void(*Proc)(ST_COMMAND const* ));

void DelegateAcquireProc(void (*Delegate)(ST_COMMAND*))
{
  xSemaphoreTake(acquireSemaphore,portMAX_DELAY);
  AcquireProc = Delegate;
}

void ExecuteAcquireProc(ST_COMMAND *stCommand)
{
  AcquireProc(stCommand);
  xSemaphoreGive(acquireSemaphore);
}

void DelegateTransmitterProc(void (*Delegate)(void(*Transmitter)(ST_COMMAND const* )))
{
  xSemaphoreTake(transmitterSemaphore,portMAX_DELAY);
  TransmitterProc = Delegate;
}

void ExecuteTransmitterProc(void(*Transmitter)(ST_COMMAND const* ))
{
  TransmitterProc(Transmitter);
  xSemaphoreGive(transmitterSemaphore);
}

以上是关于c_cpp FreeRTOS的基于信号量和委托的任务数据共享与同步的主要内容,如果未能解决你的问题,请参考以下文章

基于STM32和FreeRTOS的二值信号量实现任务同步

基于STM32和FreeRTOS的二值信号量实现任务同步

FreeRTOS 信号量

FreeRTOS 计数信号量

FreeRTOS学习笔记 ——二值信号量

FreeRTOS学习笔记 ——二值信号量