[CMSIS-RTOS2]线程间通信

1. Thread Flags:

支持多达32个thread flag。 可以挂起线程直到另一个线程将一个或一组thread flags置位。

osEvent osThreadFlagsWait (int32_t flags,int32_t options,uint32_t timeout); 将挂起线程并置于wait_event 状态。也可以定义一个超时时间,之后将这个等待线程置回ready状态。

thread flag options :

OptionsDescription
osFlagsWaitAnyWait for any flag to be set(default)
osFlagsWaitAllWait for all flags to be set
osFlagsNoClearDo not clear flags that have been specified to wait for

int32_t osThredFlagsSet (osThreadId_t thread_id, int32_t flags); 置位id指定的线程的flag。

int32_t osThreadFlagsClear (int32_t signals);   清除当前线程的flag。

2. Event Flags:

类似于thread flags,但是需要创建,且作为global rtos对象,可以被所有线程使用。

osEventFlagsAttr_t {

const char *name; ///< name of the event flags

uint32_t attr_bits; ///< attribute bits (none)

void *cb_mem; ///< memory for control block

uint32_t cb_size; ///< size of provided memory for control block

};

osEventFlagsId_t EventFlag_LED;

EventFlag_LED = osEventFlagsNew(&EventFlagAttr_LED);

Functions

osEventFlagsId_t osEventFlagsNew (const osEventFlagsAttr_t *attr)
 Create and Initialize an Event Flags object. More...
 
uint32_t osEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags)
 Set the specified Event Flags. More...
 
uint32_t osEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags)
 Clear the specified Event Flags. More...
 
uint32_t osEventFlagsGet (osEventFlagsId_t ef_id)
 Get the current Event Flags. More...
 
uint32_t osEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout)
 Wait for one or more Event Flags to become signaled. More...
 
osStatus_t osEventFlagsDelete (osEventFlagsId_t ef_id)
 Delete an Event Flags object. More...
 
const char * osEventFlagsGetName (osEventFlagsId_t ef_id)
 Get name of an Event Flags object. More...

3.Semaphores:

同Event一样,用于同步多个线程。简单讲,semaphore 是一个包含一定数量的token的容器。当线程请求semaphore token, 如果token大于0, 则线程继续运行,token数量减1。 如果token为0 , 则线程阻塞,直到token大于0。

首先创建和初始化sem为指定数量。 

osSemaphoreAttr_t {

const char *name; ///< name of the semaphore

uint32_t attr_bits; ///< attribute bits (none)

void *cb_mem; ///< memory for control block

uint32_t cb_size; ///< size of provided memory for control block

};

osSemaphoreId_t sem1;

sem1 = osSemaphoreNew(maxTokenCount,initalTokencount,&osSemaphoreAttr_t);

然后多个线程可以请求和释放token:

osStatus osSemaphoreAcquire(osSemaphoreId_t semaphore_id, uint32_t ticks);

osStatus osSemaphoreRelease(osSemaphoreId_t semaphore_id);

uint32_t osSemaphoreGetCount (osSemaphoreId_t semaphore_id)

最终释放资源:

osStatus_t osSemaphoreDelete (osSemaphoreId_t semaphore_id)

4.Mutex:

Semaphore 的特殊版本,同样是token的容器,不同的是mutex只能拥有一个token。

mutex的属性:

BitmaskDescription
osMutexRecursiveThe same thread can consume a mutex multiple times without locking itself.
osMutexPrioInheritWhile a thread owns the mutex it cannot be preempted by a higher priority thread.
osMutexRobustNotify threads that acquire a mutex that the previous owner was terminated.

osMutexId_t uart_mutex;

osMutexAttr_t {

const char *name; ///< name of the mutex

uint32_t attr_bits; ///< attribute bits

void *cb_mem; ///< memory for control block

uint32_t cb_size; ///< size of provided memory for control block

};

uart_mutex = osMutexNew(&MutexAttr);  //Once declared the mutex must be created in a thread.

osMutexAcquire(osMutexId_t mutex_id,uint32_t ticks);

osMutexRelease(osMutexId_t mutex_id);

注意:

需小心的对持有mutex token的线程使用osThreadTerminate() ,如果否则一旦删除持有token的线程,则相应的受保护资源就不再可用。

5.Data Exchange:

线程间异步数据交换

osMessageQId_t Q_LED;   //定义Q ID

osMessageQueueAttr_t {

const char *name; ///< name of the message queue

uint32_t attr_bits; ///< attribute bits

void *cb_mem; ///< memory for control block

uint32_t cb_size; ///< size of provided memory for control block

void *mq_mem; ///< memory for data storage

uint32_t mq_size; ///< size of provided memory for data storage

};

typedef struct {

uint32_t duration;

uint32_t ledNumber;

uint8_t priority;

} message_t;

Q_LED = osMessageNew(DepthOfMesageQueue,sizeof(message_t),&osMessageQueueAttr); //创建Q

osMessageQueuePut(Q_LED,&dataIn,messagePrioriy,osWaitForever); //发送消息

result = osMessageQueueGet(Q_LED,&dataOut,messagePriority,osWaitForever); // 接受消息

也可以使用传递指针方式来传递大块数据。

osMemoryPoolAttr_t {

const char *name; ///< name of the memory pool

uint32_t attr_bits; ///< attribute bits

void *cb_mem; ///< memory for control block

uint32_t cb_size; ///< size of provided memory for control block

void *mp_mem; ///< memory for data storage

uint32_t mp_size; ///< size of provided memory for data storage

} osMemoryPoolAttr_t;

osMemoryPoolId_t mpool;

typedef struct {

uint8_t LED0;

uint8_t LED1;

uint8_t LED2;

uint8_t LED3;

} memory_block_t;

mpool = osMemoryPoolNew(16, sizeof(memory_block_t),&memorypoolAttr_mpool);//创建pool

memory_block_t *led_data;

led_data = (memory_block_t *) osMemoryPoolAlloc(mPool,osWaitForever);//申请内存

led_data->LED0 = 0;

led_data->LED1 = 1;

led_data->LED2 = 2;

led_data->LED3 = 3;

osMessagePut(Q_LED,(uint32_t)led_data,osWaitForever); //将地址以uint32类型发送 , osMessagePut?

取数据

osEvent event;

memory_block_t *received;

event = osMessageGet(Q_LED, osWatiForever);

received = (memory_block *)event.value.p;

led_on(received->LED0);

osPoolFree(led_pool,received); // 释放内存

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值