mirror of
https://github.com/openharmony/vendor_talkweb.git
synced 2026-06-30 22:08:35 -04:00
@@ -0,0 +1,19 @@
|
||||
# Copyright (c) 2022 Talkweb Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//kernel/liteos_m/liteos.gni")
|
||||
|
||||
module_name = get_path_info(rebase_path("."), "name")
|
||||
kernel_module(module_name) {
|
||||
sources = [ "hello_world.c" ]
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
# 调试打印示例
|
||||
|
||||
## Hello World
|
||||
|
||||
沿袭程序界的传统,入门程序都是Hello World。在Niobe407 开发板中,指的是通过开发板串口,在串口日志中输出Hello World字符串。
|
||||
|
||||
在Niobe407开发板系统代码中,Hello World程序位于applications目录下面,具体路径如下:
|
||||
|
||||
```text
|
||||
device/board/talkweb/niobe407/applications/001_system_helloworld/hello_world.c
|
||||
```
|
||||
## 编译调试
|
||||
- 进入//kernel/liteos_m目录, 在menuconfig配置中进入如下选项:
|
||||
|
||||
`(Top) → Platform → Board Selection → select board niobe407 → use talkweb niobe407 application → niobe407 application choose`
|
||||
|
||||
- 选择 `001_system_helloworld`
|
||||
|
||||
- 回到sdk根目录,执行`hb build -f`脚本进行编译。
|
||||
|
||||
## 运行结果
|
||||
|
||||
示例代码编译烧录代码后,按下开发板的RESET按键,通过串口助手查看日志,显示内容如下则表示执行成功:
|
||||
```
|
||||
**********************
|
||||
[Talkweb] Hello world.
|
||||
**********************
|
||||
```
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Talkweb Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "ohos_run.h"
|
||||
#include <stdio.h>
|
||||
|
||||
static void HelloWorld(void)
|
||||
{
|
||||
printf("**********************\n");
|
||||
printf("[Talkweb] Hello world.\n");
|
||||
printf("**********************\n");
|
||||
return;
|
||||
}
|
||||
|
||||
OHOS_APP_RUN(HelloWorld);
|
||||
@@ -0,0 +1,20 @@
|
||||
# Copyright (c) 2022 Talkweb Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
import("//kernel/liteos_m/liteos.gni")
|
||||
|
||||
module_name = get_path_info(rebase_path("."), "name")
|
||||
kernel_module(module_name) {
|
||||
sources = [ "os_thread_example.c" ]
|
||||
|
||||
include_dirs = [ "//third_party/cmsis/CMSIS/RTOS2/Include" ]
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
# Niobe407开发板OpenHarmony内核编程开发——Thread多线程
|
||||
本示例将演示如何在Niobe407开发板上使用cmsis 2.0 接口进行多线程开发
|
||||
|
||||
## Thread API分析
|
||||
|
||||
## osThreadNew()
|
||||
|
||||
```c
|
||||
osThreadId_t osThreadNew(osThreadFunc_t func, void *argument,const osThreadAttr_t *attr )
|
||||
```
|
||||
**描述:**
|
||||
|
||||
函数osThreadNew通过将线程添加到活动线程列表并将其设置为就绪状态来启动线程函数。线程函数的参数使用参数指针*argument传递。当创建的thread函数的优先级高于当前运行的线程时,创建的thread函数立即启动并成为新的运行线程。线程属性是用参数指针attr定义的。属性包括线程优先级、堆栈大小或内存分配的设置。可以在RTOS启动(调用 osKernelStart)之前安全地调用该函数,但不能在内核初始化 (调用 osKernelInitialize)之前调用该函数。
|
||||
> **注意** :不能在中断服务调用该函数
|
||||
|
||||
|
||||
**参数:**
|
||||
|
||||
|名字|描述|
|
||||
|:--|:------|
|
||||
| func | 线程函数. |
|
||||
| argument |作为启动参数传递给线程函数的指针|
|
||||
| attr |线程属性|
|
||||
|
||||
## 软件设计
|
||||
|
||||
**主要代码分析**
|
||||
|
||||
在OS_Thread_example函数中,通过osThreadNew()函数创建了thread1和thread2两个进程,thread1和thread2启动后会输出打印日志。
|
||||
|
||||
```c
|
||||
void thread_entry1(void)
|
||||
{
|
||||
int sum=0;
|
||||
while (1)
|
||||
{
|
||||
/* 示例代码 */
|
||||
printf("This is Niobe407 Thread1----%d\r\n",sum++);
|
||||
usleep(500000);
|
||||
}
|
||||
}
|
||||
|
||||
void thread_entry2(void)
|
||||
{
|
||||
int sum=0;
|
||||
while (1)
|
||||
{
|
||||
/* 示例代码 */
|
||||
printf("This is Niobe407 Thread2----%d\r\n",sum++);
|
||||
usleep(500000);
|
||||
}
|
||||
}
|
||||
|
||||
static void OS_Thread_example(void)
|
||||
{
|
||||
osThreadAttr_t attr;
|
||||
|
||||
attr.name = "thread1";
|
||||
attr.attr_bits = 0U;
|
||||
attr.cb_mem = NULL;
|
||||
attr.cb_size = 0U;
|
||||
attr.stack_mem = NULL;
|
||||
attr.stack_size = 1024*4;
|
||||
attr.priority = 25;
|
||||
|
||||
if (osThreadNew((osThreadFunc_t)thread_entry1, NULL, &attr) == NULL) {
|
||||
printf("Failed to create thread1!\n");
|
||||
}
|
||||
|
||||
attr.name = "thread2";
|
||||
|
||||
if (osThreadNew((osThreadFunc_t)thread_entry2, NULL, &attr) == NULL) {
|
||||
printf("Failed to create thread2!\n");
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## 编译调试
|
||||
- 进入//kernel/liteos_m目录, 在menuconfig配置中进入如下选项:
|
||||
|
||||
`(Top) → Platform → Board Selection → select board niobe407 → use talkweb niobe407 application → niobe407 application choose`
|
||||
|
||||
- 选择 `002_system_thread`
|
||||
|
||||
- 回到sdk根目录,执行`hb build -f`脚本进行编译。
|
||||
|
||||
### 运行结果
|
||||
|
||||
示例代码编译烧录代码后,按下开发板的RESET按键,通过串口助手查看日志,Thread1和Thread2会交替打印信息
|
||||
```
|
||||
This is Niobe407 Thread1----0
|
||||
This is Niobe407 Thread2----0
|
||||
This is Niobe407 Thread1----1
|
||||
This is Niobe407 Thread2----1
|
||||
This is Niobe407 Thread1----2
|
||||
This is Niobe407 Thread2----2
|
||||
This is Niobe407 Thread1----3
|
||||
This is Niobe407 Thread2----3
|
||||
This is Niobe407 Thread1----4
|
||||
This is Niobe407 Thread2----4
|
||||
This is Niobe407 Thread1----5
|
||||
This is Niobe407 Thread2----5
|
||||
```
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Talkweb Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "ohos_run.h"
|
||||
#include "cmsis_os2.h"
|
||||
|
||||
#define SLEEP_TIME 500000
|
||||
#define THREAD_STACK_SIZE (1024 * 4)
|
||||
#define THREAD1_NAME "thread1"
|
||||
#define THREAD2_NAME "thread2"
|
||||
#define THREAD1_PRIORITY 25
|
||||
|
||||
static void ThreadEntry1(void)
|
||||
{
|
||||
int sum = 0;
|
||||
while (1) {
|
||||
printf("This is Niobe407 Thread1----%d\r\n", sum++);
|
||||
usleep(SLEEP_TIME);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void ThreadEntry2(void)
|
||||
{
|
||||
int sum = 0;
|
||||
while (1) {
|
||||
printf("This is Niobe407 Thread2----%d\r\n", sum++);
|
||||
usleep(SLEEP_TIME);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void OsThreadExample(void)
|
||||
{
|
||||
osThreadAttr_t attr;
|
||||
|
||||
attr.name = THREAD1_NAME;
|
||||
attr.attr_bits = 0U;
|
||||
attr.cb_mem = NULL;
|
||||
attr.cb_size = 0U;
|
||||
attr.stack_mem = NULL;
|
||||
attr.stack_size = THREAD_STACK_SIZE;
|
||||
attr.priority = THREAD1_PRIORITY;
|
||||
|
||||
if (osThreadNew((osThreadFunc_t)ThreadEntry1, NULL, &attr) == NULL) {
|
||||
printf("Failed to create thread1!\n");
|
||||
}
|
||||
|
||||
attr.name = THREAD2_NAME;
|
||||
|
||||
if (osThreadNew((osThreadFunc_t)ThreadEntry2, NULL, &attr) == NULL) {
|
||||
printf("Failed to create thread2!\n");
|
||||
}
|
||||
}
|
||||
|
||||
OHOS_APP_RUN(OsThreadExample);
|
||||
@@ -0,0 +1,21 @@
|
||||
# Copyright (c) 2022 Talkweb Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//kernel/liteos_m/liteos.gni")
|
||||
|
||||
module_name = get_path_info(rebase_path("."), "name")
|
||||
kernel_module(module_name) {
|
||||
sources = [ "os_timer_example.c" ]
|
||||
|
||||
include_dirs = [ "//third_party/cmsis/CMSIS/RTOS2/Include" ]
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
# Niobe407开发板OpenHarmony内核编程开发——定时器
|
||||
本示例将演示如何在Niobe407开发板上使用cmsis 2.0 接口进行定时器开发
|
||||
|
||||
## Timer API分析
|
||||
|
||||
## osTimerNew()
|
||||
|
||||
```c
|
||||
/// Create and Initialize a timer.
|
||||
/// \param[in] func function pointer to callback function.
|
||||
/// \param[in] type \ref osTimerOnce for one-shot or \ref osTimerPeriodic for periodic behavior.
|
||||
/// \param[in] argument argument to the timer callback function.
|
||||
/// \param[in] attr timer attributes; NULL: default values.
|
||||
/// \return timer ID for reference by other functions or NULL in case of error.
|
||||
osTimerId_t osTimerNew (osTimerFunc_t func,osTimerType_t type,void *argument,const osTimerAttr_t *attr)
|
||||
```
|
||||
**描述:**
|
||||
|
||||
函数osTimerNew创建一个一次性或周期性计时器,并将其与一个带参数的回调函数相关联。计时器在osTimerStart启动之前一直处于停止状态。可以在RTOS启动(调用 osKernelStart)之前安全地调用该函数,但不能在内核初始化 (调用 osKernelInitialize)之前调用该函数。
|
||||
> **注意** :不能在中断服务调用该函数
|
||||
**参数:**
|
||||
|名字|描述|
|
||||
|:--|:------|
|
||||
| func | 函数指针指向回调函数. |
|
||||
| type | 定时器类型,osTimerOnce表示单次定时器,ostimer周期表示周期性定时器. |
|
||||
| argument |定时器回调函数的参数|
|
||||
| attr |计时器属性|
|
||||
|
||||
## osTimerStart()
|
||||
|
||||
```c
|
||||
/// Start or restart a timer.
|
||||
/// \param[in] timer_id timer ID obtained by \ref osTimerNew.
|
||||
/// \param[in] ticks \ref CMSIS_RTOS_TimeOutValue "time ticks" value of the timer.
|
||||
/// \return status code that indicates the execution status of the function.
|
||||
osStatus_t osTimerStart(osTimerId_t timer_id, uint32_t ticks);
|
||||
|
||||
```
|
||||
**描述:**
|
||||
|
||||
函数osTimerStart启动或重新启动指定参数timer_id的计时器。参数ticks指定计时器的计数值。
|
||||
|
||||
> **注意** :不能在中断服务调用该函数
|
||||
|
||||
|
||||
**参数:**
|
||||
|
||||
|名字|描述|
|
||||
|:--|:------|
|
||||
| timer_id | 由osTimerNew获得的计时器ID. |
|
||||
| ticks | 时间滴答计时器的值. |
|
||||
|
||||
## 软件设计
|
||||
|
||||
## 软件设计
|
||||
|
||||
**主要代码分析**
|
||||
|
||||
在OS_Timer_example函数中,通过osTimerNew()函数创建了回调函数为OS_Timer1_Callback的定时器1,并通过osTimerStart()函数将该定时器设置为100个tick,因为hi3861默认10ms为一个tick,所以100个tick正好为1S钟,1S计时到后会触发OS_Timer1_Callback()函数并打印日志。定时器2也同理为3S触发OS_Timer2_Callback()函数并打印日志.
|
||||
|
||||
```c
|
||||
static void OS_Timer_example(void)
|
||||
{
|
||||
osTimerId_t timerId1, timerId2;
|
||||
uint32_t delay;
|
||||
osStatus_t status;
|
||||
|
||||
timer1Exec = 1U;
|
||||
/// Create and Initialize a timer.
|
||||
/// \param[in] func function pointer to callback function.
|
||||
/// \param[in] type \ref osTimerOnce for one-shot or \ref osTimerPeriodic for periodic behavior.
|
||||
/// \param[in] argument argument to the timer callback function.
|
||||
/// \param[in] attr timer attributes; NULL: default values.
|
||||
/// \return timer ID for reference by other functions or NULL in case of error.
|
||||
timerId1 = osTimerNew((osTimerFunc_t)OS_Timer1_Callback, osTimerPeriodic, &timer1Exec, NULL);
|
||||
if (timerId1 != NULL)
|
||||
{
|
||||
delay = 100U;
|
||||
/// Start or restart a timer.
|
||||
/// \param[in] timer_id timer ID obtained by \ref osTimerNew.
|
||||
/// \param[in] ticks \ref CMSIS_RTOS_TimeOutValue "time ticks" value of the timer.
|
||||
/// \return status code that indicates the execution status of the function.
|
||||
//osStatus_t osTimerStart(osTimerId_t timer_id, uint32_t ticks);
|
||||
status = osTimerStart(timerId1, delay);
|
||||
if (status != osOK)
|
||||
{
|
||||
printf("Failed to start timer1!\n");
|
||||
}
|
||||
}
|
||||
|
||||
timer2Exec = 100U;
|
||||
timerId2 = osTimerNew((osTimerFunc_t)OS_Timer2_Callback, osTimerPeriodic, &timer2Exec, NULL);
|
||||
if (timerId2 != NULL)
|
||||
{
|
||||
delay = 300U;
|
||||
status = osTimerStart(timerId2, delay);
|
||||
if (status != osOK)
|
||||
{
|
||||
printf("Failed to start timer2!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## 编译调试
|
||||
- 进入//kernel/liteos_m目录, 在menuconfig配置中进入如下选项:
|
||||
|
||||
`(Top) → Platform → Board Selection → select board niobe407 → use talkweb niobe407 application → niobe407 application choose`
|
||||
|
||||
- 选择 `003_system_timer`
|
||||
|
||||
- 回到sdk根目录,执行`hb build -f`脚本进行编译。
|
||||
|
||||
### 运行结果
|
||||
|
||||
示例代码编译烧录代码后,按下开发板的RESET按键,通过串口助手查看日志,OS_Timer1_Callback会1S打印一次数据,OS_Timer2_Callback会3S打印一次数据。
|
||||
|
||||
```
|
||||
This is Niobe407 Timer1_Callback:1!
|
||||
This is Niobe407 Timer1_Callback:1!
|
||||
This is Niobe407 Timer1_Callback:1!
|
||||
This is Niobe407 Timer2_Callback:100!
|
||||
This is Niobe407 Timer1_Callback:1!
|
||||
This is Niobe407 Timer1_Callback:1!
|
||||
This is Niobe407 Timer1_Callback:1!
|
||||
This is Niobe407 Timer2_Callback:100!
|
||||
This is Niobe407 Timer1_Callback:1!
|
||||
This is Niobe407 Timer1_Callback:1!
|
||||
```
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Talkweb Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "ohos_run.h"
|
||||
#include "cmsis_os2.h"
|
||||
|
||||
unsigned int g_timer1Exec = 1, g_timer2Exec = 100;
|
||||
|
||||
static void OsTimer1Callback(void *arg)
|
||||
{
|
||||
printf("This is Niobe407 Timer1_Callback:%u!\r\n", *(unsigned int*)arg);
|
||||
}
|
||||
|
||||
static void OsTimer2Callback(void *arg)
|
||||
{
|
||||
printf("This is Niobe407 Timer2_Callback:%u!\r\n", *(unsigned int*)arg);
|
||||
}
|
||||
|
||||
static void OsTimerExample(void)
|
||||
{
|
||||
osTimerId_t timerId1;
|
||||
osTimerId_t timerId2;
|
||||
unsigned int delay;
|
||||
osStatus_t status;
|
||||
|
||||
g_timer1Exec = 1U;
|
||||
timerId1 = osTimerNew((osTimerFunc_t)OsTimer1Callback, osTimerPeriodic, &g_timer1Exec, NULL);
|
||||
if (timerId1 != NULL) {
|
||||
delay = 100U;
|
||||
status = osTimerStart(timerId1, delay);
|
||||
if (status != osOK) {
|
||||
printf("Failed to start timer1!\n");
|
||||
}
|
||||
}
|
||||
|
||||
g_timer2Exec = 100U;
|
||||
timerId2 = osTimerNew((osTimerFunc_t)OsTimer2Callback, osTimerPeriodic, &g_timer2Exec, NULL);
|
||||
if (timerId2 != NULL) {
|
||||
delay = 300U;
|
||||
status = osTimerStart(timerId2, delay);
|
||||
if (status != osOK) {
|
||||
printf("Failed to start timer2!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OHOS_APP_RUN(OsTimerExample);
|
||||
@@ -0,0 +1,20 @@
|
||||
# Copyright (c) 2022 Talkweb Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
import("//kernel/liteos_m/liteos.gni")
|
||||
|
||||
module_name = get_path_info(rebase_path("."), "name")
|
||||
kernel_module(module_name) {
|
||||
sources = [ "os_event_example.c" ]
|
||||
|
||||
include_dirs = [ "//third_party/cmsis/CMSIS/RTOS2/Include" ]
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
# Niobe407开发板OpenHarmony内核编程开发——事件标志
|
||||
本示例将演示如何在Niobe407开发板上使用cmsis 2.0 接口使用事件标志同步线程
|
||||
|
||||
|
||||
## EventFlags API分析
|
||||
|
||||
|
||||
## osEventFlagsNew()
|
||||
|
||||
```c
|
||||
/// Create and Initialize an Event Flags object.
|
||||
/// \param[in] attr event flags attributes; NULL: default values.
|
||||
/// \return event flags ID for reference by other functions or NULL in case of error.
|
||||
osEventFlagsId_t osEventFlagsNew(const osEventFlagsAttr_t *attr)
|
||||
```
|
||||
**描述:**
|
||||
|
||||
osEventFlagsNew函数创建了一个新的事件标志对象,用于跨线程发送事件,并返回事件标志对象标识符的指针,或者在出现错误时返回NULL。可以在RTOS启动(调用 osKernelStart)之前安全地调用该函数,但不能在内核初始化 (调用 osKernelInitialize)之前调用该函数。
|
||||
> **注意** :不能在中断服务调用该函数
|
||||
|
||||
**参数:**
|
||||
|
||||
|名字|描述|
|
||||
|:--|:------|
|
||||
| attr |事件标志属性;空:默认值. |
|
||||
|
||||
## osEventFlagsSet()
|
||||
|
||||
```c
|
||||
/// Set the specified Event Flags.
|
||||
/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew.
|
||||
/// \param[in] flags specifies the flags that shall be set.
|
||||
/// \return event flags after setting or error code if highest bit set.
|
||||
uint32_t osEventFlagsSet(osEventFlagsId_t ef_id,uint32_t flags)
|
||||
```
|
||||
**描述:**
|
||||
osEventFlagsSet函数在一个由参数ef_id指定的事件标记对象中设置由参数flags指定的事件标记。
|
||||
|
||||
> **注意** :不能在中断服务调用该函数
|
||||
|
||||
|
||||
**参数:**
|
||||
|
||||
|名字|描述|
|
||||
|:--|:------|
|
||||
| ef_id | 事件标志由osEventFlagsNew获得的ID. |
|
||||
| flags | 指定设置的标志. |
|
||||
| return | 返回设置的事件标志,或者如果高位设置值则返回错误码. |
|
||||
|
||||
## osEventFlagsWait()
|
||||
|
||||
```c
|
||||
/// Wait for one or more Event Flags to become signaled.
|
||||
/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew.
|
||||
/// \param[in] flags specifies the flags to wait for.
|
||||
/// \param[in] options specifies flags options (osFlagsXxxx).
|
||||
/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
|
||||
/// \return event flags before clearing or error code if highest bit set.
|
||||
uint32_t osEventFlagsWait(osEventFlagsId_t ef_id,uint32_t flags,uint32_t options,uint32_t timeout)
|
||||
```
|
||||
**描述:**
|
||||
osEventFlagsWait函数挂起当前运行线程,直到设置了由参数ef_id指定的事件对象中的任何或所有由参数flags指定的事件标志。当这些事件标志被设置,函数立即返回。否则,线程将被置于阻塞状态。
|
||||
|
||||
> **注意** :如果参数timeout设置为0,可以从中断服务例程调用
|
||||
|
||||
|
||||
**参数:**
|
||||
|
||||
|名字|描述|
|
||||
|:--|:------|
|
||||
| ef_id | 事件标志由osEventFlagsNew获得的ID. |
|
||||
| flags | 指定要等待的标志. |
|
||||
| options | 指定标记选项. |
|
||||
| timeout | 超时时间,0表示不超时 |
|
||||
| return | 返回设置的事件标志,或者如果高位设置值则返回错误码. |
|
||||
|
||||
## 软件设计
|
||||
|
||||
## 软件设计
|
||||
|
||||
**主要代码分析**
|
||||
|
||||
在OS_Event_example函数中,通过osEventFlagsNew()函数创建了事件标记ID g_event_flags_id,OS_Thread_EventReceiver()函数中通过osEventFlagsWait()函数一直将线程置于阻塞状态,等待事件标记。在OS_Thread_EventSender()函数中通过osEventFlagsSet()函数每隔1S设置的标志,实现任务间的同步。
|
||||
|
||||
```c
|
||||
/**
|
||||
*发送事件
|
||||
*\param[in] argument 发送参数
|
||||
*/
|
||||
void OS_Thread_EventSender(void *argument)
|
||||
{
|
||||
osEventFlagsId_t flags;
|
||||
(void)argument;
|
||||
while (1)
|
||||
{
|
||||
/// Set the specified Event Flags.
|
||||
/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew.
|
||||
/// \param[in] flags specifies the flags that shall be set.
|
||||
/// \return event flags after setting or error code if highest bit set.
|
||||
flags = osEventFlagsSet(g_event_flags_id, FLAGS_MSK1);
|
||||
|
||||
printf("Sender Flags is %d\n", flags);
|
||||
//挂起线程,让位其他线程调度
|
||||
osThreadYield();
|
||||
osDelay(100);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 接收事件
|
||||
* \param[in] argument 发送参数
|
||||
*/
|
||||
void OS_Thread_EventReceiver(void *argument)
|
||||
{
|
||||
(void)argument;
|
||||
uint32_t flags;
|
||||
|
||||
while (1)
|
||||
{
|
||||
/// Wait for one or more Event Flags to become signaled.
|
||||
/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew.
|
||||
/// \param[in] flags specifies the flags to wait for.
|
||||
/// \param[in] options specifies flags options (osFlagsXxxx).
|
||||
/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
|
||||
/// \return event flags before clearing or error code if highest bit set.
|
||||
flags = osEventFlagsWait(g_event_flags_id, FLAGS_MSK1, osFlagsWaitAny, osWaitForever);
|
||||
printf("Receive Flags is %d\n", flags);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 事件测试Example
|
||||
*/
|
||||
static void OS_Event_example(void)
|
||||
{
|
||||
// ==== Event Flags Management Functions ====
|
||||
/// Create and Initialize an Event Flags object.
|
||||
/// \param[in] attr event flags attributes; NULL: default values.
|
||||
/// \return event flags ID for reference by other functions or NULL in case of error.
|
||||
g_event_flags_id = osEventFlagsNew(NULL);
|
||||
if (g_event_flags_id == NULL)
|
||||
{
|
||||
printf("Failed to create EventFlags!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
osThreadAttr_t attr;
|
||||
|
||||
attr.attr_bits = 0U;
|
||||
attr.cb_mem = NULL;
|
||||
attr.cb_size = 0U;
|
||||
attr.stack_mem = NULL;
|
||||
attr.stack_size = 1024 * 4;
|
||||
attr.priority = 25;
|
||||
|
||||
attr.name = "Thread_EventSender";
|
||||
/// Create a thread and add it to Active Threads.
|
||||
/// \param[in] func thread function.
|
||||
/// \param[in] argument pointer that is passed to the thread function as start argument.
|
||||
/// \param[in] attr thread attributes; NULL: default values.
|
||||
/// \return thread ID for reference by other functions or NULL in case of error
|
||||
//osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr);
|
||||
if (osThreadNew(OS_Thread_EventSender, NULL, &attr) == NULL)
|
||||
{
|
||||
printf("Failed to create Thread_EventSender!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
attr.name = "Thread_EventReceiver";
|
||||
if (osThreadNew(OS_Thread_EventReceiver, NULL, &attr) == NULL)
|
||||
{
|
||||
printf("Failed to create Thread_EventReceiver!\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## 编译调试
|
||||
- 进入//kernel/liteos_m目录, 在menuconfig配置中进入如下选项:
|
||||
|
||||
`(Top) → Platform → Board Selection → select board niobe407 → use talkweb niobe407 application → niobe407 application choose`
|
||||
|
||||
- 选择 `004_system_event`
|
||||
|
||||
- 回到sdk根目录,执行`hb build -f`脚本进行编译。
|
||||
|
||||
### 运行结果
|
||||
|
||||
示例代码编译烧录代码后,按下开发板的RESET按键,通过串口助手查看日志,会每隔1S输出一次日志。
|
||||
```
|
||||
Start OS_Event_example.
|
||||
Start OS_Thread_EventSender.
|
||||
Send Flags is 1
|
||||
Start OS_Thread_EventSender.
|
||||
Receive Flags is 1
|
||||
Send Flags is 1
|
||||
Receive Flags is 1
|
||||
Send Flags is 1
|
||||
Receive Flags is 1
|
||||
Send Flags is 1
|
||||
Receive Flags is 1
|
||||
Send Flags is 1
|
||||
Receive Flags is 1
|
||||
Send Flags is 1
|
||||
Receive Flags is 1
|
||||
```
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Talkweb Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "ohos_run.h"
|
||||
#include "cmsis_os2.h"
|
||||
|
||||
#define FLAGS_MSK1 0x00000001U
|
||||
#define TASK_DELAY 1000
|
||||
#define STACK_SIZE 4096
|
||||
|
||||
osEventFlagsId_t g_event_flags_id; // event flags id
|
||||
|
||||
static void OsThreadEventSender(void *argument)
|
||||
{
|
||||
(void *)argument;
|
||||
osEventFlagsId_t flags;
|
||||
printf("Start OsThreadEventSender.\n");
|
||||
while (1) {
|
||||
flags = osEventFlagsSet(g_event_flags_id, FLAGS_MSK1);
|
||||
printf("Send Flags is %d\n", flags);
|
||||
osThreadYield();
|
||||
osDelay(TASK_DELAY);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void OsThreadEventReceiver(void *argument)
|
||||
{
|
||||
(void *)argument;
|
||||
printf("Start OsThreadEventSender.\n");
|
||||
while (1) {
|
||||
uint32_t flags;
|
||||
flags = osEventFlagsWait(g_event_flags_id, FLAGS_MSK1, osFlagsWaitAny, osWaitForever);
|
||||
printf("Receive Flags is %u\n", flags);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void OsEventExample(void)
|
||||
{
|
||||
printf("Start OsEventExample.\n");
|
||||
g_event_flags_id = osEventFlagsNew(NULL);
|
||||
if (g_event_flags_id == NULL) {
|
||||
printf("Failed to create EventFlags!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
osThreadAttr_t attr;
|
||||
|
||||
attr.attr_bits = 0U;
|
||||
attr.cb_mem = NULL;
|
||||
attr.cb_size = 0U;
|
||||
attr.stack_mem = NULL;
|
||||
attr.stack_size = STACK_SIZE;
|
||||
attr.priority = osPriorityNormal;
|
||||
|
||||
attr.name = "Thread_EventSender";
|
||||
if (osThreadNew(OsThreadEventSender, NULL, &attr) == NULL) {
|
||||
printf("Failed to create Thread_EventSender!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
attr.name = "Thread_EventReceiver";
|
||||
if (osThreadNew(OsThreadEventReceiver, NULL, &attr) == NULL) {
|
||||
printf("Failed to create Thread_EventReceiver!\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
OHOS_APP_RUN(OsEventExample);
|
||||
@@ -0,0 +1,21 @@
|
||||
# Copyright (c) 2022 Talkweb Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("//kernel/liteos_m/liteos.gni")
|
||||
|
||||
module_name = get_path_info(rebase_path("."), "name")
|
||||
kernel_module(module_name) {
|
||||
sources = [ "os_mutex_example.c" ]
|
||||
|
||||
include_dirs = [ "//third_party/cmsis/CMSIS/RTOS2/Include" ]
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
# Niobe407开发板OpenHarmony内核编程开发——mutex
|
||||
本示例将演示如何在Niobe407开发板上使用cmsis 2.0 接口进行互斥锁开发
|
||||
|
||||
## mutex API分析
|
||||
|
||||
## osThreadNew()
|
||||
|
||||
```c
|
||||
osThreadId_t osThreadNew(osThreadFunc_t func, void *argument,const osThreadAttr_t *attr )
|
||||
```
|
||||
**描述:**
|
||||
|
||||
函数osThreadNew通过将线程添加到活动线程列表并将其设置为就绪状态来启动线程函数。线程函数的参数使用参数指针*argument传递。当创建的thread函数的优先级高于当前运行的线程时,创建的thread函数立即启动并成为新的运行线程。线程属性是用参数指针attr定义的。属性包括线程优先级、堆栈大小或内存分配的设置。可以在RTOS启动(调用 osKernelStart)之前安全地调用该函数,但不能在内核初始化 (调用 osKernelInitialize)之前调用该函数。
|
||||
> **注意** :不能在中断服务调用该函数
|
||||
|
||||
|
||||
**参数:**
|
||||
|
||||
|名字|描述|
|
||||
|:--|:------|
|
||||
| func | 线程函数. |
|
||||
| argument |作为启动参数传递给线程函数的指针|
|
||||
| attr |线程属性|
|
||||
|
||||
## osMutexNew()
|
||||
|
||||
```c
|
||||
osMutexNew (const osMutexAttr_t *attr);
|
||||
```
|
||||
**描述:**
|
||||
|
||||
创建互斥锁
|
||||
|
||||
|
||||
**参数:**
|
||||
|
||||
|名字|描述|
|
||||
|:--|:------|
|
||||
| attr |mutex属性|
|
||||
|
||||
## osMutexAcquire()
|
||||
|
||||
```c
|
||||
osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout);
|
||||
```
|
||||
**描述:**
|
||||
|
||||
获取互斥锁
|
||||
|
||||
|
||||
**参数:**
|
||||
|
||||
|名字|描述|
|
||||
|:--|:------|
|
||||
| mutex_id |mutex ID|
|
||||
| timeout |delay时间|
|
||||
|
||||
|
||||
## osMutexRelease()
|
||||
|
||||
```c
|
||||
osMutexRelease (osMutexId_t mutex_id);
|
||||
```
|
||||
**描述:**
|
||||
|
||||
释放互斥锁
|
||||
|
||||
|
||||
**参数:**
|
||||
|
||||
|名字|描述|
|
||||
|:--|:------|
|
||||
| mutex_id |mutex ID|
|
||||
|
||||
|
||||
## 软件设计
|
||||
|
||||
**主要代码分析**
|
||||
|
||||
在os_mutex_example函数中,通过osThreadNew()函数创建了firstThread、twoThread、threeThread三个线程,firstThread、twoThread、threeThread三个线程启动后会输出打印日志。
|
||||
|
||||
```c
|
||||
void firstThread(void)
|
||||
{
|
||||
osDelay(100U);
|
||||
while(1)
|
||||
{
|
||||
osMutexAcquire(mutex_id, osWaitForever);
|
||||
printf("firstThread is Acquire.\r\n");
|
||||
osDelay(100U);
|
||||
osMutexRelease(mutex_id);
|
||||
}
|
||||
}
|
||||
|
||||
void twoThread(void)
|
||||
{
|
||||
osDelay(100U);
|
||||
while(1)
|
||||
{
|
||||
printf("twoThread is Acquire.\r\n");
|
||||
osDelay(100U);
|
||||
}
|
||||
}
|
||||
|
||||
void threeThread(void)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
osMutexAcquire(mutex_id, osWaitForever);
|
||||
printf("threeThread is Acquire.\r\n");
|
||||
osDelay(300U);
|
||||
osMutexRelease(mutex_id);
|
||||
}
|
||||
}
|
||||
|
||||
void os_mutex_example(void)
|
||||
{
|
||||
osThreadAttr_t attr;
|
||||
|
||||
attr.attr_bits = 0U;
|
||||
attr.cb_mem = NULL;
|
||||
attr.cb_size = 0U;
|
||||
attr.stack_mem = NULL;
|
||||
attr.stack_size = 1024 * 4;
|
||||
|
||||
attr.name = "firstThread";
|
||||
attr.priority = 26;
|
||||
if (osThreadNew((osThreadFunc_t)firstThread, NULL, &attr) == NULL)
|
||||
{
|
||||
printf("create firstThread failed!\n");
|
||||
}
|
||||
|
||||
attr.name = "twoThread";
|
||||
attr.priority = 25;
|
||||
if (osThreadNew((osThreadFunc_t)twoThread, NULL, &attr) == NULL)
|
||||
{
|
||||
printf("create twoThread failed!\n");
|
||||
}
|
||||
|
||||
attr.name = "threeThread";
|
||||
attr.priority = 24;
|
||||
if (osThreadNew((osThreadFunc_t)threeThread, NULL, &attr) == NULL)
|
||||
{
|
||||
printf("create threeThread failed!\n");
|
||||
}
|
||||
|
||||
mutex_id = osMutexNew(NULL);
|
||||
if (mutex_id == NULL)
|
||||
{
|
||||
printf("create Mutex failed!\n");
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## 编译调试
|
||||
- 进入//kernel/liteos_m目录, 在menuconfig配置中进入如下选项:
|
||||
|
||||
`(Top) → Platform → Board Selection → select board niobe407 → use talkweb niobe407 application → niobe407 application choose`
|
||||
|
||||
- 选择 `005_system_mutex`
|
||||
|
||||
- 回到sdk根目录,执行`hb build -f`脚本进行编译。
|
||||
|
||||
### 运行结果
|
||||
|
||||
示例代码编译烧录代码后,按下开发板的RESET按键,通过串口助手查看日志
|
||||
```
|
||||
threeThread is Acquire.
|
||||
twoThread is Acquire.
|
||||
twoThread is Acquire.
|
||||
firstThread is Acquire.
|
||||
twoThread is Acquire.
|
||||
threeThread is Acquire.
|
||||
twoThread is Acquire.
|
||||
twoThread is Acquire.
|
||||
twoThread is Acquire.
|
||||
firstThread is Acquire.
|
||||
twoThread is Acquire.
|
||||
threeThread is Acquire.
|
||||
twoThread is Acquire.
|
||||
```
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Talkweb Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "ohos_run.h"
|
||||
#include "cmsis_os2.h"
|
||||
|
||||
#define THREAD_STACK_SIZE (1024 * 4)
|
||||
#define FIRST_THREAD_NAME "firstThread"
|
||||
#define SECOND_THREAD_NAME "secondThread"
|
||||
#define THIRD_THREAD_NAME "thirdThread"
|
||||
#define FIRST_THREAD_PRIORITY 26
|
||||
#define SECOND_THREAD_PRIORITY 25
|
||||
#define THIRD_THREAD_PRIORITY 24
|
||||
|
||||
osMutexId_t mutex_id;
|
||||
|
||||
static void FirstThread(void)
|
||||
{
|
||||
osDelay(100U);
|
||||
while (1) {
|
||||
osMutexAcquire(mutex_id, osWaitForever);
|
||||
printf("FirstThread is Acquire.\r\n");
|
||||
osDelay(1000U);
|
||||
osMutexRelease(mutex_id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void TwoThread(void)
|
||||
{
|
||||
osDelay(1000U);
|
||||
while (1) {
|
||||
printf("TwoThread is Acquire.\r\n");
|
||||
osDelay(1000U);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void ThreeThread(void)
|
||||
{
|
||||
while (1) {
|
||||
osMutexAcquire(mutex_id, osWaitForever);
|
||||
printf("ThreeThread is Acquire.\r\n");
|
||||
osDelay(3000U);
|
||||
osMutexRelease(mutex_id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void OsMutexExample(void)
|
||||
{
|
||||
osThreadAttr_t attr;
|
||||
|
||||
attr.attr_bits = 0U;
|
||||
attr.cb_mem = NULL;
|
||||
attr.cb_size = 0U;
|
||||
attr.stack_mem = NULL;
|
||||
attr.stack_size = THREAD_STACK_SIZE;
|
||||
|
||||
attr.name = FIRST_THREAD_NAME;
|
||||
attr.priority = FIRST_THREAD_PRIORITY;
|
||||
if (osThreadNew((osThreadFunc_t)FirstThread, NULL, &attr) == NULL) {
|
||||
printf("create FirstThread failed!\n");
|
||||
}
|
||||
|
||||
attr.name = SECOND_THREAD_NAME;
|
||||
attr.priority = SECOND_THREAD_PRIORITY;
|
||||
if (osThreadNew((osThreadFunc_t)TwoThread, NULL, &attr) == NULL) {
|
||||
printf("create TwoThread failed!\n");
|
||||
}
|
||||
|
||||
attr.name = THIRD_THREAD_NAME;
|
||||
attr.priority = THIRD_THREAD_PRIORITY;
|
||||
if (osThreadNew((osThreadFunc_t)ThreeThread, NULL, &attr) == NULL) {
|
||||
printf("create ThreeThread failed!\n");
|
||||
}
|
||||
|
||||
mutex_id = osMutexNew(NULL);
|
||||
if (mutex_id == NULL) {
|
||||
printf("create Mutex failed!\n");
|
||||
}
|
||||
}
|
||||
|
||||
OHOS_APP_RUN(OsMutexExample);
|
||||
@@ -0,0 +1,20 @@
|
||||
# Copyright (c) 2022 Talkweb Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
import("//kernel/liteos_m/liteos.gni")
|
||||
|
||||
module_name = get_path_info(rebase_path("."), "name")
|
||||
kernel_module(module_name) {
|
||||
sources = [ "os_semp_example.c" ]
|
||||
|
||||
include_dirs = [ "//third_party/cmsis/CMSIS/RTOS2/Include" ]
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
# Niobe407开发板OpenHarmony内核编程开发——Semaphore
|
||||
本示例将演示如何在Niobe407开发板上使用cmsis 2.0 接口进行信号量开发
|
||||
|
||||
## Semaphore API分析
|
||||
|
||||
## osThreadNew()
|
||||
|
||||
```c
|
||||
osThreadId_t osThreadNew(osThreadFunc_t func, void *argument,const osThreadAttr_t *attr )
|
||||
```
|
||||
**描述:**
|
||||
|
||||
函数osThreadNew通过将线程添加到活动线程列表并将其设置为就绪状态来启动线程函数。线程函数的参数使用参数指针*argument传递。当创建的thread函数的优先级高于当前运行的线程时,创建的thread函数立即启动并成为新的运行线程。线程属性是用参数指针attr定义的。属性包括线程优先级、堆栈大小或内存分配的设置。可以在RTOS启动(调用 osKernelStart)之前安全地调用该函数,但不能在内核初始化 (调用 osKernelInitialize)之前调用该函数。
|
||||
> **注意** :不能在中断服务调用该函数
|
||||
|
||||
|
||||
**参数:**
|
||||
|
||||
|名字|描述|
|
||||
|:--|:------|
|
||||
| func | 线程函数. |
|
||||
| argument |作为启动参数传递给线程函数的指针|
|
||||
| attr |线程属性|
|
||||
|
||||
## osSemaphoreNew()
|
||||
|
||||
```c
|
||||
osSemaphoreId_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr)
|
||||
```
|
||||
**描述:**
|
||||
|
||||
创建信号量
|
||||
> **注意** :不能在中断服务调用该函数
|
||||
|
||||
|
||||
**参数:**
|
||||
|
||||
|名字|描述|
|
||||
|:--|:------|
|
||||
| max_count |信号量计数值的最大值|
|
||||
| initial_count |信号量计数值的初始值|
|
||||
| max_count |信号量计数值的最大值|
|
||||
| attr |信号量属性|
|
||||
返回 信号量ID
|
||||
|
||||
## osSemaphoreRelease()
|
||||
|
||||
```c
|
||||
osStatus_t osSemaphoreRelease (osSemaphoreId_t semaphore_id)
|
||||
```
|
||||
**描述:**
|
||||
|
||||
释放信号量
|
||||
> **注意** :该函数可以在中断服务例程调用
|
||||
|
||||
**参数:**
|
||||
|
||||
|名字|描述|
|
||||
|:--|:------|
|
||||
| semaphore_id |信号量ID|
|
||||
返回 0 - 成功,非0 - 失败
|
||||
|
||||
|
||||
## osSemaphoreAcquire()
|
||||
|
||||
```c
|
||||
osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout)
|
||||
```
|
||||
**描述:**
|
||||
|
||||
获取信号量
|
||||
|
||||
|
||||
**参数:**
|
||||
|
||||
|名字|描述|
|
||||
|:--|:------|
|
||||
| semaphore_id |信号量ID|
|
||||
| timeout |超时值|
|
||||
返回 0 - 成功,非0 - 失败
|
||||
|
||||
|
||||
## 软件设计
|
||||
|
||||
**主要代码分析**
|
||||
|
||||
在semp_example函数中,通过osThreadNew()函数创建了Thread_Semp1、Thread_Semp2两个线程,Thread_Semp1、Thread_Semp2两个线程启动后会输出打印日志。
|
||||
|
||||
```c
|
||||
void Thread_Semp1(void)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
osSemaphoreRelease(sem1);
|
||||
printf("Thread_Semp1 Release Semap \n");
|
||||
osDelay(200U);
|
||||
}
|
||||
}
|
||||
|
||||
void Thread_Semp2(void)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
osSemaphoreAcquire(sem1, osWaitForever);
|
||||
printf("Thread_Semp2 get Semap \n");
|
||||
osDelay(100U);
|
||||
}
|
||||
}
|
||||
|
||||
void semp_example(void)
|
||||
{
|
||||
osThreadAttr_t attr;
|
||||
|
||||
attr.attr_bits = 0U;
|
||||
attr.cb_mem = NULL;
|
||||
attr.cb_size = 0U;
|
||||
attr.stack_mem = NULL;
|
||||
attr.stack_size = 1024 * 4;
|
||||
attr.priority = 10;
|
||||
|
||||
attr.name = "Thread_Semp1";
|
||||
if (osThreadNew((osThreadFunc_t)Thread_Semp1, NULL, &attr) == NULL)
|
||||
{
|
||||
printf("create Thread_Semp1 failed!\n");
|
||||
}
|
||||
|
||||
attr.name = "Thread_Semp2";
|
||||
if (osThreadNew((osThreadFunc_t)Thread_Semp2, NULL, &attr) == NULL)
|
||||
{
|
||||
printf("create Thread_Semp2 failed!\n");
|
||||
}
|
||||
|
||||
sem1 = osSemaphoreNew(3, 0, NULL);
|
||||
if (sem1 == NULL)
|
||||
{
|
||||
printf("Semp1 create failed!\n");
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
## 编译调试
|
||||
- 进入//kernel/liteos_m目录, 在menuconfig配置中进入如下选项:
|
||||
|
||||
`(Top) → Platform → Board Selection → select board niobe407 → use talkweb niobe407 application → niobe407 application choose`
|
||||
|
||||
- 选择 `006_system_semp`
|
||||
|
||||
- 回到sdk根目录,执行`hb build -f`脚本进行编译。
|
||||
|
||||
### 运行结果
|
||||
|
||||
示例代码编译烧录代码后,按下开发板的RESET按键,通过串口助手查看日志
|
||||
```
|
||||
Thread_Semp1 Release Semap
|
||||
Thread_Semp2 get Semap
|
||||
Thread_Semp1 Release Semap
|
||||
Thread_Semp2 get Semap
|
||||
Thread_Semp1 Release Semap
|
||||
Thread_Semp2 get Semap
|
||||
Thread_Semp1 Release Semap
|
||||
Thread_Semp2 get Semap
|
||||
```
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Talkweb Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "ohos_run.h"
|
||||
#include "cmsis_os2.h"
|
||||
|
||||
#define SEM_INITIAL_VALUE 3
|
||||
#define SEM_MAX_VALUE 0
|
||||
#define ATTR_BITS 0U
|
||||
#define CB_SIZE_0U 0U
|
||||
#define STACK_SIZE (1024 * 4)
|
||||
#define PRIORITY_LEVEL 10
|
||||
|
||||
osSemaphoreId_t sem1;
|
||||
|
||||
static void ThreadSemp1(void)
|
||||
{
|
||||
while (1) {
|
||||
osSemaphoreRelease(sem1);
|
||||
printf("ThreadSemp1 Release Semap \n");
|
||||
osDelay(200U);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void ThreadSemp2(void)
|
||||
{
|
||||
while (1) {
|
||||
osSemaphoreAcquire(sem1, osWaitForever);
|
||||
printf("ThreadSemp2 get Semap \n");
|
||||
osDelay(100U);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void SempExample(void)
|
||||
{
|
||||
osThreadAttr_t attr;
|
||||
|
||||
attr.attr_bits = ATTR_BITS;
|
||||
attr.cb_mem = NULL;
|
||||
attr.cb_size = CB_SIZE_0U;
|
||||
attr.stack_mem = NULL;
|
||||
attr.stack_size = STACK_SIZE;
|
||||
attr.priority = PRIORITY_LEVEL;
|
||||
|
||||
attr.name = "ThreadSemp1";
|
||||
if (osThreadNew((osThreadFunc_t)ThreadSemp1, NULL, &attr) == NULL) {
|
||||
printf("create ThreadSemp1 failed!\n");
|
||||
}
|
||||
|
||||
attr.name = "ThreadSemp2";
|
||||
if (osThreadNew((osThreadFunc_t)ThreadSemp2, NULL, &attr) == NULL) {
|
||||
printf("create ThreadSemp2 failed!\n");
|
||||
}
|
||||
|
||||
sem1 = osSemaphoreNew(SEM_INITIAL_VALUE, SEM_MAX_VALUE, NULL);
|
||||
if (sem1 == NULL) {
|
||||
printf("Semp1 create failed!\n");
|
||||
}
|
||||
}
|
||||
|
||||
OHOS_APP_RUN(SempExample);
|
||||
@@ -0,0 +1,20 @@
|
||||
# Copyright (c) 2022 Talkweb Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
import("//kernel/liteos_m/liteos.gni")
|
||||
|
||||
module_name = get_path_info(rebase_path("."), "name")
|
||||
kernel_module(module_name) {
|
||||
sources = [ "os_message_example.c" ]
|
||||
|
||||
include_dirs = [ "//third_party/cmsis/CMSIS/RTOS2/Include" ]
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
# Niobe407开发板OpenHarmony内核编程开发——message
|
||||
本示例将演示如何在Niobe407开发板上使用cmsis 2.0 接口进行消息队列开发
|
||||
|
||||
## message API分析
|
||||
|
||||
## osThreadNew()
|
||||
|
||||
```c
|
||||
osThreadId_t osThreadNew(osThreadFunc_t func, void *argument,const osThreadAttr_t *attr )
|
||||
```
|
||||
**描述:**
|
||||
|
||||
函数osThreadNew通过将线程添加到活动线程列表并将其设置为就绪状态来启动线程函数。线程函数的参数使用参数指针*argument传递。当创建的thread函数的优先级高于当前运行的线程时,创建的thread函数立即启动并成为新的运行线程。线程属性是用参数指针attr定义的。属性包括线程优先级、堆栈大小或内存分配的设置。可以在RTOS启动(调用 osKernelStart)之前安全地调用该函数,但不能在内核初始化 (调用 osKernelInitialize)之前调用该函数。
|
||||
> **注意** :不能在中断服务调用该函数
|
||||
|
||||
|
||||
**参数:**
|
||||
|
||||
|名字|描述|
|
||||
|:--|:------|
|
||||
| func | 线程函数. |
|
||||
| argument |作为启动参数传递给线程函数的指针|
|
||||
| attr |线程属性|
|
||||
|
||||
## osMessageQueueNew()
|
||||
|
||||
```c
|
||||
osMessageQueueId_t osMessageQueueNew (uint32_t msg_count,uint32_t msg_size,const osMessageQueueAttr_t *attr)
|
||||
```
|
||||
**描述:**
|
||||
|
||||
创建消息队列
|
||||
> **注意** :不能在中断服务调用该函数
|
||||
|
||||
|
||||
**参数:**
|
||||
|
||||
|名字|描述|
|
||||
|:--|:------|
|
||||
| msg_count |队列中的最大消息数|
|
||||
| msg_size |最大消息大小(以字节为单位)|
|
||||
| attr |消息队列属性;空:默认值|
|
||||
返回 消息队列ID
|
||||
|
||||
## osMessageQueuePut()
|
||||
|
||||
```c
|
||||
osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id,const void *msg_ptr,uint8_t msg_prio,uint32_t timeout)
|
||||
```
|
||||
**描述:**
|
||||
|
||||
发送消息
|
||||
> **注意** :如果参数timeout设置为0,可以从中断服务例程调用
|
||||
|
||||
**参数:**
|
||||
|
||||
|名字|描述|
|
||||
|:--|:------|
|
||||
| mq_id |由osMessageQueueNew获得的消息队列ID|
|
||||
| msg_ptr |要发送的消息|
|
||||
| msg_prio |指优先级|
|
||||
| timeout |超时值|
|
||||
返回 0 - 成功,非0 - 失败
|
||||
|
||||
|
||||
## osMessageQueueGet()
|
||||
|
||||
```c
|
||||
osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id,void *msg_ptr,uint8_t *msg_prio,uint32_t timeout)
|
||||
```
|
||||
**描述:**
|
||||
|
||||
获取消息
|
||||
> **注意** :如果参数timeout设置为0,可以从中断服务例程调用
|
||||
|
||||
**参数:**
|
||||
|
||||
|名字|描述|
|
||||
|:--|:------|
|
||||
| mq_id |由osMessageQueueNew获得的消息队列ID|
|
||||
| msg_ptr |指针指向队列中获取消息的缓冲区指针|
|
||||
| msg_prio |指优先级|
|
||||
| timeout |超时值|
|
||||
返回 0 - 成功,非0 - 失败
|
||||
|
||||
|
||||
## 软件设计
|
||||
|
||||
**主要代码分析**
|
||||
|
||||
在Msg_example函数中,通过osThreadNew()函数创建了Thread_MsgQ1、Thread_MsgQ2两个线程,Thread_MsgQ1、Thread_MsgQ2两个线程启动后会输出打印日志。
|
||||
|
||||
```c
|
||||
typedef struct
|
||||
{
|
||||
char *buffer;
|
||||
} MSG_BUF;
|
||||
MSG_BUF msg_buf;
|
||||
void Thread_MsgQueue1(void *arg)
|
||||
{
|
||||
msg_buf.buffer = "hello niobe";
|
||||
while (1)
|
||||
{
|
||||
osMessageQueuePut(MsgQueue, &msg_buf.buffer, 0U, 0U);
|
||||
//suspend thread
|
||||
osThreadYield();
|
||||
osDelay(100);
|
||||
}
|
||||
}
|
||||
|
||||
void Thread_MsgQueue2(void *arg)
|
||||
{
|
||||
osStatus_t status;
|
||||
|
||||
while (1)
|
||||
{
|
||||
//wait for message
|
||||
status = osMessageQueueGet(MsgQueue, &msg_buf.buffer, NULL, 0U);
|
||||
if (status == osOK)
|
||||
{
|
||||
printf("Thread_MsgQueue2 Get msg: %s\n", msg_buf.buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
osDelay(100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Msg_example(void)
|
||||
{
|
||||
|
||||
MsgQueue = osMessageQueueNew(10, 50, NULL);
|
||||
if (MsgQueue == NULL)
|
||||
{
|
||||
printf("create Message Queue failed!\n");
|
||||
}
|
||||
|
||||
osThreadAttr_t attr;
|
||||
|
||||
attr.attr_bits = 0U;
|
||||
attr.cb_mem = NULL;
|
||||
attr.cb_size = 0U;
|
||||
attr.stack_mem = NULL;
|
||||
attr.stack_size = 1024 * 10;
|
||||
attr.priority = 10;
|
||||
|
||||
attr.name = "Thread_MsgQueue1";
|
||||
if (osThreadNew(Thread_MsgQueue1, NULL, &attr) == NULL)
|
||||
{
|
||||
printf("create Thread_MsgQueue1 failed!\n");
|
||||
}
|
||||
|
||||
attr.name = "Thread_MsgQueue2";
|
||||
if (osThreadNew(Thread_MsgQueue2, NULL, &attr) == NULL)
|
||||
{
|
||||
printf("create Thread_MsgQueue2 failed!\n");
|
||||
}
|
||||
}
|
||||
|
||||
APP_FEATURE_INIT(Msg_example);
|
||||
|
||||
```
|
||||
|
||||
## 编译调试
|
||||
- 进入//kernel/liteos_m目录, 在menuconfig配置中进入如下选项:
|
||||
|
||||
`(Top) → Platform → Board Selection → select board niobe407 → use talkweb niobe407 application → niobe407 application choose`
|
||||
|
||||
- 选择 `007_system_message`
|
||||
|
||||
- 回到sdk根目录,执行`hb build -f`脚本进行编译。
|
||||
|
||||
### 运行结果
|
||||
|
||||
示例代码编译烧录代码后,按下开发板的RESET按键,通过串口助手查看日志
|
||||
```
|
||||
ThreadMsgQueue2 Get msg: hello niobe407
|
||||
ThreadMsgQueue2 Get msg: hello niobe407
|
||||
ThreadMsgQueue2 Get msg: hello niobe407
|
||||
ThreadMsgQueue2 Get msg: hello niobe407
|
||||
ThreadMsgQueue2 Get msg: hello niobe407
|
||||
ThreadMsgQueue2 Get msg: hello niobe407
|
||||
ThreadMsgQueue2 Get msg: hello niobe407
|
||||
```
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Talkweb Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "ohos_run.h"
|
||||
#include "cmsis_os2.h"
|
||||
|
||||
#define DELAY_TIME 100
|
||||
#define ATTR_BITS 0U
|
||||
#define CB_SIZE_0U 0U
|
||||
#define STACK_SIZE (1024 * 4)
|
||||
#define PRIORITY_LEVEL 10
|
||||
#define QUEUE_SIZE 10
|
||||
#define DATA_SIZE 50
|
||||
|
||||
typedef struct {
|
||||
char *buffer;
|
||||
} MSG_BUF;
|
||||
|
||||
MSG_BUF g_msgBuf;
|
||||
osMessageQueueId_t g_msg_queue;
|
||||
|
||||
static void ThreadMsgQueue1(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
g_msgBuf.buffer = "hello niobe407";
|
||||
while (1) {
|
||||
osMessageQueuePut(g_msg_queue, &g_msgBuf.buffer, 0U, 0U);
|
||||
osThreadYield();
|
||||
osDelay(DELAY_TIME);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void ThreadMsgQueue2(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
osStatus_t status;
|
||||
|
||||
while (1) {
|
||||
// wait for message
|
||||
status = osMessageQueueGet(g_msg_queue, &g_msgBuf.buffer, NULL, 0U);
|
||||
if (status == osOK) {
|
||||
printf("ThreadMsgQueue2 Get msg: %s\n", g_msgBuf.buffer);
|
||||
} else {
|
||||
osDelay(DELAY_TIME);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void MsgExample(void)
|
||||
{
|
||||
g_msg_queue = osMessageQueueNew(QUEUE_SIZE, DATA_SIZE, NULL);
|
||||
if (g_msg_queue == NULL) {
|
||||
printf("create Message Queue failed!\n");
|
||||
}
|
||||
|
||||
osThreadAttr_t attr;
|
||||
|
||||
attr.attr_bits = ATTR_BITS;
|
||||
attr.cb_mem = NULL;
|
||||
attr.cb_size = CB_SIZE_0U;
|
||||
attr.stack_mem = NULL;
|
||||
attr.stack_size = STACK_SIZE;
|
||||
attr.priority = PRIORITY_LEVEL;
|
||||
|
||||
attr.name = "ThreadMsgQueue1";
|
||||
if (osThreadNew(ThreadMsgQueue1, NULL, &attr) == NULL) {
|
||||
printf("create ThreadMsgQueue1 failed!\n");
|
||||
}
|
||||
|
||||
attr.name = "ThreadMsgQueue2";
|
||||
if (osThreadNew(ThreadMsgQueue2, NULL, &attr) == NULL) {
|
||||
printf("create ThreadMsgQueue2 failed!\n");
|
||||
}
|
||||
}
|
||||
|
||||
OHOS_APP_RUN(MsgExample);
|
||||
Reference in New Issue
Block a user