Hi3861 OpenHarmony嵌入式应用入门--LiteOS Thread

news2024/11/24 2:57:31

目录

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进行烧录。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1846442.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

永磁同步电机FOC调试记录(一)

永磁同步电机FOC调试记录&#xff08;一&#xff09; 前言架构硬件架构软件架构 调试过程元器件选型开环控制编码器调试速度采样电流检测中断优先级的确定电流环部分烧坏IPM速度-电流环位置-电流环 结语 前言 这是我个人从零开始尝试永磁同步电机&#xff08;PMSM&#xff09;…

别只看影响因子了!又1本毕业神刊偷偷被On Hold了!请谨慎投递

【SciencePub学术】昨日&#xff0c;2023JCR正式发布&#xff0c;现在影响因子的话题依旧是“热搜第一”。大家可以根据自己的研究方向&#xff0c;参考最新发布的JCR报告进行投稿选刊。若大家对于投稿选刊方面有任何问题&#xff0c;都可联系张老师为您解答&#xff01; 相关…

Qt源码阅读笔记:初步了解QtCore模块目录结构

Qt框架是一个跨平台的C应用程序框架&#xff0c;广泛用于开发图形用户界面程序以及用于无界面后台操作的工具和服务器。它由多个模块组成&#xff0c;其中QtCore模块提供了核心的非GUI功能。 QtCore 提供了元对象系统&#xff0c;扩展了c 在元对象系统的基础上&#xff0c;qt又…

timescaledb:创建real-time aggregate

创建hypertable【chz_a】 create table chz_a (time timestamp,device_id int8, value double precision,primary key (time) ); SELECT create_hypertable(chz_a, by_range(time) );往表里面写入数据 # 当天的数据 insert into chz_a (time, device_id, value) values (now(…

七人拼团:互助共赢,电商新动力

在当前繁荣的电商领域中&#xff0c;七人互助拼团模式以其别具一格的激励机制和互助合作理念&#xff0c;成为了消费者和商家共同瞩目的焦点。接下来&#xff0c;我们将详细解读这一模式中的直推激励、滑落补偿以及团队成就奖&#xff0c;并探讨其如何体现互助合作的精神。 一、…

Android面试题:App性能优化之电量优化和网络优化

本文首发于公众号“AntDream”&#xff0c;欢迎微信搜索“AntDream”或扫描文章底部二维码关注&#xff0c;和我一起每天进步一点点 电量优化 Doze模式 系统的行为进入Doze后看看App有没有奔溃就可以 Standby待机模式 针对某个应用 处于上述模式&#xff0c;App会无法访问…

Spring Boot中的各种事件

spring boot 各种事件贯穿整个启动的生命周期&#xff0c;读懂了这些事件也差不多理解了springboot的启动流程。 SpringApplicationRunListener中的事件 接口org.springframework.boot.SpringApplicationRunListener定义了spring启动过程中各个事件被触发的顶层方法 public …

内容安全复习 1 - 信息内容安全概述

文章目录 信息内容安全简介网络空间信息内容安全大模型 人工智能简介 信息内容安全简介 网络空间 网络空间是融合物理域、信息域、认知域和社会域&#xff0c;控制实体行为的信息活动空间。 上图展示了网络空间安全的结构。可以看到将网络空间划分为了网络域和内容域两个部分。…

图片的格式怎样在线转换?在线改图片格式的操作技巧

图片作为日常生活中常用的内容展示方式&#xff0c;面对不同的用途图片的格式也是不同的&#xff0c;那么怎样快速完成图片格式转换呢&#xff1f;通过软件来修改图片格式比较麻烦&#xff0c;现在可以在网上使用图片格式转换器工具来在线改图片格式&#xff0c;这种方式会更加…

RK3568技术笔记十六 QT5开发

背景知识 在阅读本章前&#xff0c;如果对下面所列举的知识点有一定的了解&#xff0c;将有助于更好的理解本章内容。 C基础知识&#xff0c;了解简单的类&#xff0c;继承&#xff0c;重载等面向对象概念&#xff1b;Linux基础知识&#xff0c;了解基本的Shell命令&#xff…

谷歌Chrome浏览器排查js内存溢出

1. 打开谷歌浏览器检查台 2. 点击memory 3. 点击开始快照录制&#xff0c;时隔一会儿录一次&#xff0c;多录几次 4. 进行快照对比

TMS与WMS海外仓系统:两者分别是什么、区别、结合使用的好处

TMS国际物流系统和WMS海外仓系统都旨在提升海外仓储物流作业的效率&#xff0c;不过他们在供应链中却各自发挥着不同的作用。 今天我们会深入的给大家介绍两者分别是什么&#xff0c;区别在哪&#xff0c;结合使用TMS国际物流系统和WMS海外仓系统的好处是什么。 1、了解WMS海…

AI+前端技术的结合(实现图片识别功能)

随着人工智能技术的不断发展&#xff0c;AI在前端设计页面中的应用变得越来越普遍。比如&#xff1a;在电商平台上&#xff0c;可以利用对象检测技术实现商品的自动识别和分类&#xff1b;人脸识别&#xff1b;车辆检测&#xff1b;图片识别等等......其中一个显著的应用是在图…

爆火的AI姓名头像号篇篇10w+, 流量主赚麻了...

最近二师兄在刷公众号时&#xff0c;看到一个非常有趣的账号。简单又“暴li”。 几乎篇篇10w。点击去一看&#xff0c;内容也是非常极简&#xff0c;利用姓氏生成头像。一个字都不多。 几乎每篇文末都有广告&#xff0c;一篇10w按照800来算&#xff0c; 一个月大概 ~~一七得七、…

【SPIE出版】第六届无线通信与智能电网国际会议(ICWCSG 2024,7月26-28)

随着科技的飞速发展和能源需求的日益增长&#xff0c;智能电网技术逐渐成为电力行业的重要发展方向。与此同时&#xff0c;无线通信技术在近年来也取得了显著的进步&#xff0c;为智能电网的发展提供了强有力的支持。为了进一步推动无线通信与智能电网的结合与发展&#xff0c;…

手机拍照如此强,还有买相机的理由么?

点击文末“阅读原文”即可参与节目互动 剪辑、音频 / 卷圈 运营 / SandLiu 卷圈 监制 / 姝琦 封面 / 姝琦Midjourney 产品统筹 / bobo 场地支持 / 声湃轩北京录音间 我们见证了关于摄影工具的世纪之争。 尽管手机摄影技术飞速发展&#xff0c;但传统相机的忠实拥趸们认为…

Flink入门实战详解

Flink入门实战 Flink项目构建 1)基于MavenIdea创建项目&#xff1a; 使用maven进行项目构建&#xff0c;如图1所示。 图-34 构建maven项目 输入项目中的maven的坐标和存储坐标&#xff0c;如图2所示。 图2 maven坐标和存储位置 2)Maven依赖&#xff1a; <properties>…

BEVM基于OP-Stack发布首个以WBTC为GAS连接以太坊和比特币生态的中继链

为了更好的连接以太坊和比特币生态&#xff0c;BEVM团队正在基于OPtimism的OP Stack来构建一个以WBTC为GAS兼容OP-Rollup的中继链&#xff0c;这条中继链将作为一种完全去中心化的中间层&#xff0c;把以太坊上的主流资产(WBTC/ ETH/USDC/USDT等)引入到BEVM网络。 不仅如此&am…

最新扣子(Coze)实战案例:扣子卡片的制作及使用,完全免费教程

&#x1f9d9;‍♂️ 大家好&#xff0c;我是斜杠君&#xff0c;手把手教你搭建扣子AI应用。 &#x1f4dc; 本教程是《AI应用开发系列教程之扣子(Coze)实战教程》&#xff0c;完全免费学习。 &#x1f440; 关注斜杠君&#xff0c;可获取完整版教程。&#x1f44d;&#x1f3f…

Element-UI实现el-dialog弹框拖拽功能

在实际开发中&#xff0c;会发现有些系统&#xff0c;弹框是可以在浏览器的可见区域自由拖拽的&#xff0c;这极大方便用户的操作。但在查看Element-UI中弹框&#xff08;el-dialog&#xff09;组件的文档时&#xff0c;发现并未实现这一功能。不过也无须担心&#xff0c;vue中…