1# Niobe407开发板OpenHarmony内核编程开发——事件标志 2本示例将演示如何在Niobe407开发板上使用cmsis 2.0 接口使用事件标志同步线程 3 4 5## EventFlags API分析 6 7 8## osEventFlagsNew() 9 10```c 11 /// Create and Initialize an Event Flags object. 12 /// \param[in] attr event flags attributes; NULL: default values. 13 /// \return event flags ID for reference by other functions or NULL in case of error. 14osEventFlagsId_t osEventFlagsNew(const osEventFlagsAttr_t *attr) 15``` 16**描述:** 17 18osEventFlagsNew函数创建了一个新的事件标志对象,用于跨线程发送事件,并返回事件标志对象标识符的指针,或者在出现错误时返回NULL。可以在RTOS启动(调用 osKernelStart)之前安全地调用该函数,但不能在内核初始化 (调用 osKernelInitialize)之前调用该函数。 19> **注意** :不能在中断服务调用该函数 20 21**参数:** 22 23|名字|描述| 24|:--|:------| 25| attr |事件标志属性;空:默认值. | 26 27## osEventFlagsSet() 28 29```c 30 /// Set the specified Event Flags. 31 /// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. 32 /// \param[in] flags specifies the flags that shall be set. 33 /// \return event flags after setting or error code if highest bit set. 34uint32_t osEventFlagsSet(osEventFlagsId_t ef_id,uint32_t flags) 35``` 36**描述:** 37osEventFlagsSet函数在一个由参数ef_id指定的事件标记对象中设置由参数flags指定的事件标记。 38 39> **注意** :不能在中断服务调用该函数 40 41 42**参数:** 43 44|名字|描述| 45|:--|:------| 46| ef_id | 事件标志由osEventFlagsNew获得的ID. | 47| flags | 指定设置的标志. | 48| return | 返回设置的事件标志,或者如果高位设置值则返回错误码. | 49 50## osEventFlagsWait() 51 52```c 53 /// Wait for one or more Event Flags to become signaled. 54 /// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. 55 /// \param[in] flags specifies the flags to wait for. 56 /// \param[in] options specifies flags options (osFlagsXxxx). 57 /// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. 58 /// \return event flags before clearing or error code if highest bit set. 59uint32_t osEventFlagsWait(osEventFlagsId_t ef_id,uint32_t flags,uint32_t options,uint32_t timeout) 60``` 61**描述:** 62osEventFlagsWait函数挂起当前运行线程,直到设置了由参数ef_id指定的事件对象中的任何或所有由参数flags指定的事件标志。当这些事件标志被设置,函数立即返回。否则,线程将被置于阻塞状态。 63 64> **注意** :如果参数timeout设置为0,可以从中断服务例程调用 65 66 67**参数:** 68 69|名字|描述| 70|:--|:------| 71| ef_id | 事件标志由osEventFlagsNew获得的ID. | 72| flags | 指定要等待的标志. | 73| options | 指定标记选项. | 74| timeout | 超时时间,0表示不超时 | 75| return | 返回设置的事件标志,或者如果高位设置值则返回错误码. | 76 77## 软件设计 78 79## 软件设计 80 81**主要代码分析** 82 83在OS_Event_example函数中,通过osEventFlagsNew()函数创建了事件标记ID g_event_flags_id,OS_Thread_EventReceiver()函数中通过osEventFlagsWait()函数一直将线程置于阻塞状态,等待事件标记。在OS_Thread_EventSender()函数中通过osEventFlagsSet()函数每隔1S设置的标志,实现任务间的同步。 84 85```c 86/** 87 *发送事件 88 *\param[in] argument 发送参数 89 */ 90void OS_Thread_EventSender(void *argument) 91{ 92 osEventFlagsId_t flags; 93 (void)argument; 94 while (1) 95 { 96 /// Set the specified Event Flags. 97 /// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. 98 /// \param[in] flags specifies the flags that shall be set. 99 /// \return event flags after setting or error code if highest bit set. 100 flags = osEventFlagsSet(g_event_flags_id, FLAGS_MSK1); 101 102 printf("Sender Flags is %d\n", flags); 103 //挂起线程,让位其他线程调度 104 osThreadYield(); 105 osDelay(100); 106 } 107} 108 109/** 110 * 接收事件 111 * \param[in] argument 发送参数 112*/ 113void OS_Thread_EventReceiver(void *argument) 114{ 115 (void)argument; 116 uint32_t flags; 117 118 while (1) 119 { 120 /// Wait for one or more Event Flags to become signaled. 121 /// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. 122 /// \param[in] flags specifies the flags to wait for. 123 /// \param[in] options specifies flags options (osFlagsXxxx). 124 /// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. 125 /// \return event flags before clearing or error code if highest bit set. 126 flags = osEventFlagsWait(g_event_flags_id, FLAGS_MSK1, osFlagsWaitAny, osWaitForever); 127 printf("Receive Flags is %d\n", flags); 128 } 129} 130 131/** 132 * 事件测试Example 133*/ 134static void OS_Event_example(void) 135{ 136 // ==== Event Flags Management Functions ==== 137 /// Create and Initialize an Event Flags object. 138 /// \param[in] attr event flags attributes; NULL: default values. 139 /// \return event flags ID for reference by other functions or NULL in case of error. 140 g_event_flags_id = osEventFlagsNew(NULL); 141 if (g_event_flags_id == NULL) 142 { 143 printf("Failed to create EventFlags!\n"); 144 return; 145 } 146 147 osThreadAttr_t attr; 148 149 attr.attr_bits = 0U; 150 attr.cb_mem = NULL; 151 attr.cb_size = 0U; 152 attr.stack_mem = NULL; 153 attr.stack_size = 1024 * 4; 154 attr.priority = 25; 155 156 attr.name = "Thread_EventSender"; 157 /// Create a thread and add it to Active Threads. 158 /// \param[in] func thread function. 159 /// \param[in] argument pointer that is passed to the thread function as start argument. 160 /// \param[in] attr thread attributes; NULL: default values. 161 /// \return thread ID for reference by other functions or NULL in case of error 162 //osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr); 163 if (osThreadNew(OS_Thread_EventSender, NULL, &attr) == NULL) 164 { 165 printf("Failed to create Thread_EventSender!\n"); 166 return; 167 } 168 169 attr.name = "Thread_EventReceiver"; 170 if (osThreadNew(OS_Thread_EventReceiver, NULL, &attr) == NULL) 171 { 172 printf("Failed to create Thread_EventReceiver!\n"); 173 return; 174 } 175} 176 177``` 178 179## 编译调试 180- 进入//kernel/liteos_m目录, 在menuconfig配置中进入如下选项: 181 182 `(Top) → Platform → Board Selection → select board niobe407 → use talkweb niobe407 application → niobe407 application choose` 183 184- 选择 `004_system_event` 185 186- 回到sdk根目录,执行`hb build -f`脚本进行编译。 187 188### 运行结果 189 190示例代码编译烧录代码后,按下开发板的RESET按键,通过串口助手查看日志,会每隔1S输出一次日志。 191``` 192Start OS_Event_example. 193Start OS_Thread_EventSender. 194Send Flags is 1 195Start OS_Thread_EventSender. 196Receive Flags is 1 197Send Flags is 1 198Receive Flags is 1 199Send Flags is 1 200Receive Flags is 1 201Send Flags is 1 202Receive Flags is 1 203Send Flags is 1 204Receive Flags is 1 205Send Flags is 1 206Receive Flags is 1 207``` 208