目录
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);// 获取当前线程IDosThreadId_t tid = osThreadGetId();// 打印当前线程IDprintf("[Thread Test] threadTest osThreadGetId, thread id:%p\r\n", tid);// 当count小于THREAD_NUM时,循环执行while (count < THREAD_NUM) {// count加1count++;// 打印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进行烧录。