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

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、总结

一个砖一个砖,垒起来。

相关推荐

  1. STM32F103RC使用HAL库配置USART进行数据收发

    2024-07-11 18:02:05       27 阅读
  2. <span style='color:red;'>STM</span><span style='color:red;'>32</span><span style='color:red;'>F</span><span style='color:red;'>103</span>

    STM32F103

    2024-07-11 18:02:05      67 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-11 18:02:05       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-11 18:02:05       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-11 18:02:05       58 阅读
  4. Python语言-面向对象

    2024-07-11 18:02:05       69 阅读

热门阅读

  1. 7.10飞书一面面经

    2024-07-11 18:02:05       24 阅读
  2. mysql bit 对gorm使用何种类型?

    2024-07-11 18:02:05       26 阅读
  3. python爬虫学习(三十三天)---多线程上篇

    2024-07-11 18:02:05       23 阅读
  4. 一、Python 日志系统设计之不同级别的系统日志

    2024-07-11 18:02:05       20 阅读
  5. SpringAMQP收发消息demo

    2024-07-11 18:02:05       20 阅读
  6. SpringSecurity中文文档(Servlet OAuth 2.0 Login)

    2024-07-11 18:02:05       19 阅读
  7. ant-design-vue表格设置某列标题部分文字颜色

    2024-07-11 18:02:05       24 阅读