【RT-thread studio 下使用STM32F103-学习sem-信号量-初步使用-线程之间控制-基础样例】

news2024/12/25 9:05:40

1、前言

最近,在使用rt-thread的时候,想要用一个线程控制另一个线程的暂停与运行,
但看资料的时候,发现删除线程和重启线程的时候,好像不太理想,这么弄是容易出现问题的,但通过信号量的方式,比较好,所以这次咱们一起来学习下sem。

自己也从新手的角度,一点点学习。整个rt-thread 还是挺大的,不是深耕多年,很难面面聚到,不过用那学哪里。

2、环境

在这里插入图片描述

3、事项了解

(1)了解sem概念-了解官网消息

大概看了一遍整个资料,还是挺多的,当你想要使用的时候,其实多少还是有些摸不到头脑的。
但既然要使用Rt-thread的,官方的文档还是要读一下。

链接:https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/ipc1/ipc1?id=%e4%bf%a1%e5%8f%b7%e9%87%8f
在这里插入图片描述

(2)根据自己理解,设计几个使用方式

我们使用某种RT-thread带有的功能,是为了解决我们自己出现的问题。

设计实验1:
通过使用sem信号量,当一个线程先运行后,再运行另一个线程。这样其实就是让线程之间形成先后关系,适合一定是某个线程完成后,在运行另一个线程。

设计实验2:
通过使用sem信号量,用一个线程,或者一个变量,控制或者暂停另一个线程。这样其实就是有个主线程,或不一定是主线程,可以控制其他线程运行。

以上都是小的功能模块,但是大的项目,都是小模块一点点搭建起来,这算是其中一个砖块,使用的时候,根据自己情况再调整下。

(3)不建议运行中,反复删除,在运行线程。

在看网上资料是,看到有说到,其实不建议反复挂起或删除创建线程,很容易出现问题。
当时看到了资料忘记去哪里,不过本片将有关sem信号量的。

4、实验过程

实验说明

1、第一部分实验

万事皆有要基础,一步一个脚印,如果环境不能使用的话,后续代码都是无用的,所以第一步是要搭建一个可以运行的程序。自己这块没注意,认为软件装好后,随便创建一个工程,就可以运行,没想到卡了一下。

(1)实验说明-创建工程

在这里插入图片描述

在这里插入图片描述

(2)编写代码

以下内容,RT-Thread Studio工具会自动生成的。

int main(void)
{
    int count = 1;

   
    while (count++)
    {
        LOG_D("Hello RT-Thread!");
        rt_thread_mdelay(1000);
    }

    return RT_EOK;
}
(3)验证结果

这块其实遇到一个内存相关报错,更细节部分可以看细节说明部分。
在这里插入图片描述

上述问题解决后,然后连接硬件代码,进行下载验证。
在这里插入图片描述

2、第二部分实验

(1)实验说明

此部分,主要是让一个线程先运行,运行完毕,再运行了另一个线程。在现实应用中,很多情况下,都是需要的,并且有实际意义的。

举个例子,现实中,有很多测温需求,温度过高过低,都需要做些事情,相当触发异常,这个时候,温度异常,必须先出现,才做后面事情,可以用这样逻辑解决。

(2)编写代码
/*
 * Copyright (c) 2006-2024, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-06-21     RT-Thread    first version
 */

#include <rtthread.h>

#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>


//第一步
//#include <rtthread.h>

static rt_sem_t sem; // 信号量

//第二步
void sem1_init(void)
{
    // 创建一个信号量,初始值为 0
    sem = rt_sem_create("sem", 0, RT_IPC_FLAG_FIFO);
    if (sem == RT_NULL)
    {
        rt_kprintf("create semaphore failed.\n");
    }
}
//第三步
void thread1_entry(void *parameter)
{
    while (1)
    {
        // 尝试获取信号量,如果信号量值为 0,则线程将被阻塞
        rt_sem_take(sem, RT_WAITING_FOREVER);
        rt_kprintf("Thread 1 is running.\n");
        rt_thread_mdelay(1000); // 模拟线程工作
    }
}
//第四步
void thread2_entry(void *parameter)
{
    while (1)
    {
        rt_thread_mdelay(3000); // 等待 3 秒
        rt_kprintf("Thread 2 releases semaphore.\n");
        rt_sem_release(sem); // 释放信号量
    }
}



int main(void)
{
    int count = 1;

    //第五步 应用
    sem1_init();

     // 创建线程 1
     rt_thread_t tid1 = rt_thread_create("thread1",
                                         thread1_entry, RT_NULL,
                                         1024, 10, 10);
     if (tid1 != RT_NULL)
         rt_thread_startup(tid1);

     // 创建线程 2
     rt_thread_t tid2 = rt_thread_create("thread2",
                                         thread2_entry, RT_NULL,
                                         1024, 10, 10);
     if (tid2 != RT_NULL)
         rt_thread_startup(tid2);

    while (count++)
    {
        //LOG_D("Hello RT-Thread!");
        rt_thread_mdelay(1000);
    }

    return RT_EOK;
}
(3)验证结果

如下为具体实验验证,必须是线程2运行完,才会运行线程1,是按照顺序运行。
在这里插入图片描述

3、第三部分实验

(1)实验说明

这种情况,更为复杂些,需要一个线程控制另一个线程,虽然实现方式很多,不一定非要使用这种,但是工具给你准备好了,使不使用看自己,并且是实现比较简单,实际项目,根据自己需求使用。

(2)编写代码

简单讲解下,本实验中,主要是根据a的值,来决定是否运行线程1。

/*
 * Copyright (c) 2006-2024, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-06-21     RT-Thread    first version
 */

#include <rtthread.h>

#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

//第一步
static rt_sem_t sem; // 信号量
volatile int a = 0;  // 控制变量

//第二步
void sem_init(void)
{
    // 创建一个信号量,初始值为 0
    sem = rt_sem_create("sem", 0, RT_IPC_FLAG_FIFO);
    if (sem == RT_NULL)
    {
        rt_kprintf("create semaphore failed.\n");
    }
}
//第三步
void thread1_entry(void *parameter)
{
    while (1)
    {
        // 尝试获取信号量,如果信号量值为 0,则线程将被阻塞
        rt_sem_take(sem, RT_WAITING_FOREVER);
        rt_kprintf("Thread 1 is running.\n");
        rt_thread_mdelay(1000); // 模拟线程工作
    }
}
//第四步
void thread2_entry(void *parameter)
{
    while (1)
    {
        rt_thread_mdelay(1000); // 每秒检查一次变量 a 的值

        if (a == 1)
        {
            // 如果 a == 1,则释放信号量,允许线程 1 运行
            if (rt_sem_release(sem) == RT_EOK)
            {
                rt_kprintf("Thread 2 releases semaphore.\n");
            }
        }
        else
        {
            // 如果 a == 0,则确保信号量不会释放,线程 1 将被暂停
            rt_kprintf("Thread 2: a is 0, thread 1 will pause.\n");
        }
    }
}

void set_a(int value)
{
    a = value;
    rt_kprintf("Variable a set to %d\n", a);
}


int main(void)
{
    int count = 1;

    // 初始化信号量
     sem_init();

     // 创建线程 1
     rt_thread_t tid1 = rt_thread_create("thread1",
                                         thread1_entry, RT_NULL,
                                         1024, 10, 10);
     if (tid1 != RT_NULL)
         rt_thread_startup(tid1);

     // 创建线程 2
     rt_thread_t tid2 = rt_thread_create("thread2",
                                         thread2_entry, RT_NULL,
                                         1024, 10, 10);
     if (tid2 != RT_NULL)
         rt_thread_startup(tid2);

    while (count++)
    {
        set_a(0);
        rt_thread_mdelay(10000);
        set_a(1);
        //LOG_D("Hello RT-Thread!");
        rt_thread_mdelay(10000);
    }

    return RT_EOK;
}
(3)验证结果

在这里插入图片描述

5、代码链接

代码链接:https://download.csdn.net/download/qq_22146161/89466496

6、细节部分

1、dome 文件报错

在这里插入图片描述
在这里插入图片描述

7、总结

一个砖一个砖,垒起来。

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

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

相关文章

RedHat / CentOS安装FTP服务

本章教程,记录在RedHat / CentOS中安装FTP的具体步骤。FTP默认端口:21 1、安装 epel 源 yum install -y epel-release2、安装 pure-ftpd yum -y install pure-ftpd3、修改默认配置 # 默认配置位于 /etc/pure-ftpd/pure-ftpd.conf,在配置文件中找到下面几个参数进行修改:#…

Vmware环境下ESXi主机 配置上行链路、虚拟交换机、端口组、VMkernel网卡

一、适用场景 1、使用专业服务器跑多种不同的业务&#xff0c;每种业务可能所需运行的server环境不同&#xff0c;有的需要Linux server CentOS7/8、kali、unbuntu……有的需要windows server2008、2003、2016、2019、2022…… 2、本例采用的是VMware ESXi6.7 update 3版本&am…

一个项目学习Vue3---Class和Style绑定

看下面一段代码学习此部分内容 <template><button click"stateChang">状态切换</button><div :class"{font-color:classObject.openColor,font-weight:classObject.openWeight}">颜色和粗细变化</div><div :class"…

东芝 TB5128FTG 强大性能的步进电机驱动器

TB5128FTG它以高精度和高效能为设计理念&#xff0c;采用 PWM 斩波方法&#xff0c;并内置时钟解码器。通过先进的 BiCD 工艺制造&#xff0c;这款驱动器提供高达 50V 和 5.0A 的输出额定值&#xff0c;成为广泛应用场景中的强劲解决方案。 主要特性 TB5128FTG 拥有众多确保高…

2024暑假集训第三次考试

3004. Sleepy Cow Sorting 思路分析 这道题是一道思维题。 这个就要结合之前学习过的算法&#xff0c;看这个题目的排序方式&#xff0c;我们就理所当然的想到了插入排序&#xff0c;也是这道题的正解。只需要看看前面有几个数是无序的就是需要排的次数。转换一下&#xff0c;也…

【HarmonyOS4学习笔记】《HarmonyOS4+NEXT星河版入门到企业级实战教程》课程学习笔记(二十二)

课程地址&#xff1a; 黑马程序员HarmonyOS4NEXT星河版入门到企业级实战教程&#xff0c;一套精通鸿蒙应用开发 &#xff08;本篇笔记对应课程第 32 节&#xff09; P32《31.通知-基础通知》 基础文本类型通知&#xff1a;briefText 没有用&#xff0c;写了也白写。 长文本类型…

哪里还可以申请免费一年期的SSL证书?

目前&#xff0c;要申请免费一年期的SSL证书&#xff0c;选项较为有限&#xff0c;因为多数供应商已转向提供短期的免费证书&#xff0c;通常有效期为90天。不过&#xff0c;有一个例外是JoySSL&#xff0c;它仍然提供一年期的免费SSL证书&#xff0c;但是只针对教育版和政务版…

可灭新能源锂电池火灾!自动灭火贴到底多少钱一个?

不需要人工干预&#xff0c;想贴哪里就贴哪里&#xff0c;一旦发生火灾就可以立即自动灭火。你敢相信现代的灭火器已经进化到这个地步了吗&#xff1f; 没错&#xff0c;小编说的就是最近大火的全氟己酮自动灭火贴。跟传统灭火器相比&#xff0c;它拥有体积小巧、高效灭火、安…

2024第二届电子通信与计算机科学技术国际会议(ICECCST 2024)

2024第二届电子通信与计算机科学技术国际会议(ICECCST 2024) 会议简介 2024第二届电子通信与计算机科学技术国际会议&#xff08;ICECCST 2024&#xff09;是一次重要的学术盛会&#xff0c;将在中国厦门举行。会议的主要目的是为全球的电子通信和计算机科学技术领域的专家、…

查找——数据结构与算法 总结7

目录 7.1 查找的相关概念 7.2 线性表的查找 7.2.1 顺序查找&#xff08;Linear Search&#xff09; 7.2.2 折半查找&#xff08;Binary Search&#xff09; 判定树&#xff08;折半查找判定树&#xff09;&#xff1a;描述折半查找判定过程的二叉树 7.3 树表的查找 7.31…

WBCE CMS v1.5.2 远程命令执行漏洞(CVE-2022-25099)

前言 CVE-2022-25099 是一个影响 WBCE CMS v1.5.2 的严重安全漏洞&#xff0c;具体存在于 /languages/index.php 组件中。该漏洞允许攻击者通过上传精心构造的 PHP 文件在受影响的系统上执行任意代码。 技术细节 受影响组件&#xff1a;/languages/index.php受影响版本&…

伯克利、斯坦福和CMU面向具身智能端到端操作联合发布开源通用机器人Policy,可支持多种机器人执行多种任务

不同于LLM或者MLLM那样用于上百亿甚至上千亿参数量的大模型&#xff0c;具身智能端到端大模型并不追求参数规模上的大&#xff0c;而是指其能吸收大量的数据&#xff0c;执行多种任务&#xff0c;并能具备一定的泛化能力&#xff0c;如笔者前博客里的RT1。目前该领域一个前沿工…

LabVIEW环境下OCR文字识别的实现策略与挑战解析

引言 在自动化测试领域&#xff0c;OCR&#xff08;Optical Character Recognition&#xff0c;光学字符识别&#xff09;技术扮演着重要角色&#xff0c;它能够将图像中的文字转换成机器可编辑的格式。对于使用LabVIEW约5个月&#xff0c;主要进行仪器控制与数据采集的你而言…

蓝牙模块功耗优化技术研究

蓝牙模块作为无线通信技术的重要组成部分&#xff0c;在智能家居、可穿戴设备、医疗健康等领域得到了广泛应用。然而&#xff0c;随着设备功能的不断增加和用户对续航能力的日益关注&#xff0c;蓝牙模块的功耗问题逐渐凸显。因此&#xff0c;对蓝牙模块功耗优化技术的研究具有…

两次叛国投敌,没有祸及子孙反而家族长盛不衰的传奇

这个人就是韩国国王韩王信&#xff0c;汉朝八大异姓王之一。 第一次叛国投敌&#xff0c;发生在楚汉争霸时期。有一次他的军队被项羽包围&#xff0c;于是选择了投降。不过&#xff0c;这是权宜之计&#xff0c;不久就借机回到刘邦阵营。 第二次叛国投敌&#xff0c;发生在西…

Docker Desktop 简易操作指南 (Windows, macOS, Linux)

1. 下载最新版本 Docker Desktop https://www.docker.com/products/docker-desktop/ 2.启动 Docker Desktop 3.常用命令&#xff08;在 cmd 或 Terminal 中执行&#xff09; #列出所有镜像&#xff08;Images&#xff09; docker images #列出所有容器&#xff08;Containers&…

发现CPU占用过高,该如何排查解决?

1.使用top命令 查看cpu占用最多的进程 2.使用 top -H -p pid 发现有两个线程占用比较大 3.将线程id转换为16进制 使用命令 printf 0x%x\n pid 4.使用 jstack pid | grep 线程id(16进制&#xff09; -A 20 &#xff08;显示20行&#xff09; 根据代码显示进行错误排查

android2024 gradle8 Processor和ksp两种编译时注解实现

android编译时注解&#xff0c;老生常谈&#xff0c;外面的例子都是bindView&#xff0c;脑壳看疼了&#xff0c;自己学习和编写下。 而且现在已经进化到kotlin2.0&#xff0c;google也逐渐放弃kapt&#xff0c;进入维护状态。所以要好好看看本贴。 参考我的工程&#xff1a; h…

国信华源全力守护湖南水库安全,汛期坚守岗位

连日来&#xff0c;湖南省遭受持续强降雨侵袭&#xff0c;部分地区暴雨倾盆&#xff0c;山塘河库水位急剧上升&#xff0c;防汛形势极为严峻。面对这场防汛大考&#xff0c;北京国信华源公司迅速响应&#xff0c;技术团队以高度的责任感和使命感&#xff0c;全力投入防汛减灾工…

2007年下半年软件设计师【上午题】试题及答案

文章目录 2007年下半年软件设计师上午题--试题2007年下半年软件设计师上午题--答案2007年下半年软件设计师上午题–试题