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 :
Options | Description |
---|---|
osFlagsWaitAny | Wait for any flag to be set(default) |
osFlagsWaitAll | Wait for all flags to be set |
osFlagsNoClear | Do 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对象,可以被所有线程使用。
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为指定数量。
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的属性:
Bitmask | Description |
---|---|
osMutexRecursive | The same thread can consume a mutex multiple times without locking itself. |
osMutexPrioInherit | While a thread owns the mutex it cannot be preempted by a higher priority thread. |
osMutexRobust | Notify threads that acquire a mutex that the previous owner was terminated. |
osMutexId_t uart_mutex;
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
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); // 接受消息
也可以使用传递指针方式来传递大块数据。
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
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); // 释放内存