目录
Thread API
主要接口说明
测试代码编写
代码分析
hi3861使用的实时系统主要是基于Huawei LiteOS-M,这是华为针对物联网领域推出的轻量级物联网操作系统内核。LiteOS-M是Huawei LiteOS的一个分支,专为IoT领域构建,主要面向没有MMU(内存管理单元)的处理器。它具备轻量级、低功耗、组件丰富、快速开发等关键能力,为开发者提供“一站式”完整软件平台。
技术特点:
轻量级:LiteOS-M内核小巧,适合在资源受限的设备上运行。
低功耗:针对IoT设备的特点,LiteOS-M优化了功耗管理,使设备在运行时更省电。
快速开发:提供丰富的组件和API,降低开发门槛,缩短开发周期。
LiteOS-M通过优化任务调度和中断处理,保证了系统的实时响应能力。
结合hi3861的硬件性能,LiteOS-M能够确保在IoT设备中快速响应各种事件和数据变化。
Thread API
API名称 | 说明 |
osThreadNew | 创建一个线程并将其加入活跃线程组中 |
osThreadGetName | 返回指定线程的名字 |
osThreadGetId | 返回当前运行线程的线程ID |
osThreadGetState | 返回当前线程的状态 |
osThreadSetPriority | 设置指定线程的优先级 |
osThreadGetPriority | 获取当前线程的优先级 |
osThreadYield | 将运行控制转交给下一个处于READY状态的线程 |
osThreadSuspend | 挂起指定线程的运行 |
osThreadResume | 恢复指定线程的运行 |
osThreadDetach | 分离指定的线程(当线程终止运行时,线程存储可以被回收) |
osThreadJoin | 等待指定线程终止运行 |
osThreadExit | 终止当前线程的运行 |
osThreadTerminate | 终止指定线程的运行 |
osThreadGetStackSize | 获取指定线程的栈空间大小 |
osThreadGetStackSpace | 获取指定线程的未使用的栈空间大小 |
osThreadGetCount | 获取活跃线程数 |
osThreadEnumerate | 获取线程组中的活跃线程数 |
主要接口说明
osThreadId_t osThreadNew(osThreadFunc_t func, void *argument,const osThreadAttr_t *attr )
注意 :不能在中断服务调用该函数
参数:
名字 | 描述 |
func | 线程函数. |
argument | 作为启动参数传递给线程函数的指针 |
attr | 线程属性 |
osStatus_t osThreadTerminate (osThreadId_t thread_id)
名字 | 描述 |
thread_id | 指定线程id,该id是由osThreadNew或者osThreadGetId获得 |
测试代码编写
修改D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\BUILD.gn文件
# Copyright (c) 2023 Beijing HuaQing YuanJian Education Technology 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("//build/lite/config/component/lite_component.gni")
lite_component("demo") {
features = [
#"base_00_helloworld:base_helloworld_example",
#"base_01_led:base_led_example",
#"base_02_loopkey:base_loopkey_example",
#"base_03_irqkey:base_irqkey_example",
#"base_04_adc:base_adc_example",
#"base_05_pwm:base_pwm_example",
#"base_06_ssd1306:base_ssd1306_example",
"kernel_01_task:kernel_task_example",
]
}
创建D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\kernel_01_task文件夹
文件夹中创建D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\kernel_01_task\kernel_task_example.c文件D:\DevEcoProjects\test\src\vendor\rtplay\rt_hi3861\demo\kernel_01_task\BUILD.gn文件
# Copyright (c) 2023 Beijing HuaQing YuanJian Education Technology 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.
static_library("kernel_task_example") {
sources = [
"kernel_task_example.c",
]
include_dirs = [
"//utils/native/lite/include",
"//kernel/liteos_m/kal/cmsis",
"//base/iot_hardware/peripheral/interfaces/kits",
"//vendor/hqyj/fs_hi3861/common/bsp/include"
]
}
/*
* Copyright (C) 2023 HiHope Open Source Organization .
* 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 <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#define THREAD_NUM (1000)
#define STACK_SIZE (1024)
#define DELAY_TICKS_20 (20)
#define DELAY_TICKS_100 (100)
osThreadId_t newThread(char *name, osThreadFunc_t func, char *arg)
{
osThreadAttr_t attr = {
name, 0, NULL, 0, NULL, STACK_SIZE*2, osPriorityNormal, 0, 0
};
osThreadId_t tid = osThreadNew(func, (void *)arg, &attr);
if (tid == NULL) {
printf("[Thread Test] osThreadNew(%s) failed.\r\n", name);
} else {
printf("[Thread Test] osThreadNew(%s) success, thread id: %d.\r\n", name, tid);
}
return tid;
}
void threadTest(char *arg)
{
static int count = 0;
printf("%s\r\n", arg);
osThreadId_t tid = osThreadGetId();
printf("[Thread Test] threadTest osThreadGetId, thread id:%p\r\n", tid);
while (count < THREAD_NUM) {
count++;
printf("[Thread Test] threadTest, count: %d.\r\n", count);
osDelay(DELAY_TICKS_20);
}
}
void rtosv2_thread_main(void)
{
osThreadId_t tid = newThread("test_thread", threadTest, "This is a test thread.");
const char *t_name = osThreadGetName(tid);
printf("[Thread Test] osThreadGetName, thread name: %s.\r\n", t_name);
osThreadState_t state = osThreadGetState(tid);
printf("[Thread Test] osThreadGetState, state :%d.\r\n", state);
osStatus_t status = osThreadSetPriority(tid, osPriorityNormal4);
printf("[Thread Test] osThreadSetPriority, status: %d.\r\n", status);
osPriority_t pri = osThreadGetPriority(tid);
printf("[Thread Test] osThreadGetPriority, priority: %d.\r\n", pri);
status = osThreadSuspend(tid);
printf("[Thread Test] osThreadSuspend, status: %d.\r\n", status);
status = osThreadResume(tid);
printf("[Thread Test] osThreadResume, status: %d.\r\n", status);
uint32_t stacksize = osThreadGetStackSize(tid);
printf("[Thread Test] osThreadGetStackSize, stacksize: %u.\r\n", stacksize);
uint32_t stackspace = osThreadGetStackSpace(tid);
printf("[Thread Test] osThreadGetStackSpace, stackspace: %u.\r\n", stackspace);
uint32_t t_count = osThreadGetCount();
printf("[Thread Test] osThreadGetCount, count: %u.\r\n", t_count);
osDelay(DELAY_TICKS_100);
status = osThreadTerminate(tid);
printf("[Thread Test] osThreadTerminate, status: %d.\r\n", status);
}
static void ThreadTestTask(void)
{
osThreadAttr_t attr;
attr.name = "rtosv2_thread_main";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = STACK_SIZE;
attr.priority = osPriorityNormal;
if (osThreadNew((osThreadFunc_t)rtosv2_thread_main, NULL, &attr) == NULL) {
printf("[ThreadTestTask] Falied to create rtosv2_thread_main!\n");
}
}
APP_FEATURE_INIT(ThreadTestTask);
代码分析
创建线程,创建成功则打印线程名字和线程ID
osThreadId_t newThread(char *name, osThreadFunc_t func, char *arg)
{
// 定义线程属性结构体
osThreadAttr_t attr = {
name, 0, NULL, 0, NULL, STACK_SIZE*2, osPriorityNormal, 0, 0
};
// 创建线程,并传入参数
osThreadId_t tid = osThreadNew(func, (void *)arg, &attr);
if (tid == NULL) {
// 如果创建失败,输出提示信息
printf("[Thread Test] osThreadNew(%s) failed.\r\n", name);
} else {
// 如果创建成功,输出提示信息
printf("[Thread Test] osThreadNew(%s) success, thread id: %d.\r\n", name, tid);
}
return tid;
}
该函数首先会打印自己的参数,然后对全局变量count进行循环+1操作,之后会打印count的值
void threadTest(char *arg)
{
// 定义静态变量count,用于记录线程执行次数
static int count = 0;
// 打印传入参数
printf("%s\r\n", arg);
// 获取当前线程ID
osThreadId_t tid = osThreadGetId();
// 打印当前线程ID
printf("[Thread Test] threadTest osThreadGetId, thread id:%p\r\n", tid);
// 当count小于THREAD_NUM时,循环执行
while (count < THREAD_NUM) {
// count加1
count++;
// 打印count值
printf("[Thread Test] threadTest, count: %d.\r\n", count);
// 延时20个节拍
osDelay(DELAY_TICKS_20);
}
}
主程序rtosv2_thread_main创建线程并运行,并使用上述API进行相关操作,最后终止所创建的线程。
void rtosv2_thread_main(void)
{
// 创建一个新的线程
osThreadId_t tid = newThread("test_thread", threadTest, "This is a test thread.");
// 获取线程名称
const char *t_name = osThreadGetName(tid);
printf("[Thread Test] osThreadGetName, thread name: %s.\r\n", t_name);
// 获取线程状态
osThreadState_t state = osThreadGetState(tid);
printf("[Thread Test] osThreadGetState, state :%d.\r\n", state);
// 设置线程优先级
osStatus_t status = osThreadSetPriority(tid, osPriorityNormal4);
printf("[Thread Test] osThreadSetPriority, status: %d.\r\n", status);
// 获取线程优先级
osPriority_t pri = osThreadGetPriority(tid);
printf("[Thread Test] osThreadGetPriority, priority: %d.\r\n", pri);
// 暂停线程
status = osThreadSuspend(tid);
printf("[Thread Test] osThreadSuspend, status: %d.\r\n", status);
// 恢复线程
status = osThreadResume(tid);
printf("[Thread Test] osThreadResume, status: %d.\r\n", status);
// 获取线程栈大小
uint32_t stacksize = osThreadGetStackSize(tid);
printf("[Thread Test] osThreadGetStackSize, stacksize: %u.\r\n", stacksize);
// 获取线程栈空间
uint32_t stackspace = osThreadGetStackSpace(tid);
printf("[Thread Test] osThreadGetStackSpace, stackspace: %u.\r\n", stackspace);
// 获取活跃线程数
uint32_t t_count = osThreadGetCount();
printf("[Thread Test] osThreadGetCount, count: %u.\r\n", t_count);
// 延时100个时钟周期
osDelay(DELAY_TICKS_100);
// 终止线程
status = osThreadTerminate(tid);
printf("[Thread Test] osThreadTerminate, status: %d.\r\n", status);
}
使用build,编译成功后,使用upload进行烧录。