【STM32&RT-Thread零基础入门】 5. 线程创建应用(线程创建、删除、初始化、脱离、启动、睡眠)

这篇具有很好参考价值的文章主要介绍了【STM32&RT-Thread零基础入门】 5. 线程创建应用(线程创建、删除、初始化、脱离、启动、睡眠)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

硬件:STM32F103ZET6、ST-LINK、usb转串口工具、4个LED灯、1个蜂鸣器、4个1k电阻、2个按键、面包板、杜邦线


前言

本章主要讲线程的工作机制和管理方法,通过实例讲解如何使用多线程完成多任务开发。


一、线程管理接口介绍

RT-Thread用线程控制块来描述和管理一个线程,一个线程对应一个线程控制块。线程控制块由结构体struct rt_thread表示,它用于存放线程的所有一些信息,例如优先级、线程名称、线程状态等,也包含线程与线程之间连接用的链表结构,线程等待事件集合等,详细定义如下:

/* 线程控制块 */
struct rt_thread
{
    /* rt 对象 */
    char        name[RT_NAME_MAX];     /* 线程名称 */
    rt_uint8_t  type;                   /* 对象类型 */
    rt_uint8_t  flags;                  /* 标志位 */

    rt_list_t   list;                   /* 对象列表 */
    rt_list_t   tlist;                  /* 线程列表 */

    /* 栈指针与入口指针 */
    void       *sp;                      /* 栈指针 */
    void       *entry;                   /* 入口函数指针 */
    void       *parameter;              /* 参数 */
    void       *stack_addr;             /* 栈地址指针 */
    rt_uint32_t stack_size;            /* 栈大小 */

    /* 错误代码 */
    rt_err_t    error;                  /* 线程错误代码 */
    rt_uint8_t  stat;                   /* 线程状态 */

    /* 优先级 */
    rt_uint8_t  current_priority;    /* 当前优先级 */
    rt_uint8_t  init_priority;        /* 初始优先级 */
    rt_uint32_t number_mask;

    ......

    rt_ubase_t  init_tick;               /* 线程初始化计数值 */
    rt_ubase_t  remaining_tick;         /* 线程剩余计数值 */

    struct rt_timer thread_timer;      /* 内置线程定时器 */

    void (*cleanup)(struct rt_thread *tid);  /* 线程退出清除函数 */
    rt_uint32_t user_data;                      /* 用户数据 */
};

  • init_priority 是线程创建时指定的线程优先级,在线程运行过程当中是不会被改变的(除非用户执行线程控制函数进行手动调整线程优先级)。
  • cleanup 会在线程退出时,被空闲线程回调一次以执行用户设置的清理现场等工作。
  • user_data 可由用户挂接一些数据信息到线程控制块中,以提供一种类似线程私有数据的实现方式。

线程的创建、启动、删除等操作,都与线程控制块相关,RT-Thread提供线程管理和控制的一些函数,具体如下:

  • rt_thread_create() 创建线程
  • rt_thread_delete() 删除线程
  • rt_thread_init() 初始化线程
  • rt_thread_detach() 脱离线程
  • rt_thread_startup() 启动线程
  • rt_thread_self() 活得当前正在运行的线程,返回值位rt_thread_t类型(线程的句柄)
  • rt_thread_yield() 使线程让出处理器资源
  • rt_thread_sleep() 使线程睡眠指定tick,调用该函数,线程会被挂起
  • rt_thread_delay() 使线程延迟指定tick,调用该函数,线程会被挂起
  • rt_thread_mdelay() 使线程睡眠指定毫秒,调用该函数,线程会被挂起
  • rt_thread_suspend() 挂起线程
  • rt_thread_resume() 恢复线程
  • rt_thread_control() 控制线程

二、任务:使用多线程的方式同时实现led闪烁和按键控制喇叭(扫描法)

任务描述:在main线程中实现LED灯闪烁的功能,同时创建一个线程单独实现按键控制喇叭的功能,按键的识别使用扫描法。另外,要求可以通过命令控制灯的闪烁模式。硬件电路如下:
【STM32&RT-Thread零基础入门】 5. 线程创建应用(线程创建、删除、初始化、脱离、启动、睡眠),STM32 RT-Thread操作系统入门,stm32,windows,嵌入式硬件
【STM32&RT-Thread零基础入门】 5. 线程创建应用(线程创建、删除、初始化、脱离、启动、睡眠),STM32 RT-Thread操作系统入门,stm32,windows,嵌入式硬件
【STM32&RT-Thread零基础入门】 5. 线程创建应用(线程创建、删除、初始化、脱离、启动、睡眠),STM32 RT-Thread操作系统入门,stm32,windows,嵌入式硬件

1. RT-Thread相关接口函数

(1)创建和删除线程

一个线程要成为可执行的对象,就必须由操作系统的内核来为它创建一个线程。线程可以动态创建和删除。

① 创建线程

可以通过如下的接口创建一个动态线程:

rt_thread_t rt_thread_create(const char* name,
                            void (*entry)(void* parameter),
                            void* parameter,
                            rt_uint32_t stack_size,
                            rt_uint8_t priority,
                            rt_uint32_t tick);

调用这个函数时,系统会从动态堆内存中分配一个线程句柄以及按照参数中指定的栈大小从动态堆内存中分配相应的空间。分配出来的栈空间是按照 rtconfig.h 中配置的 RT_ALIGN_SIZE 方式对齐。

线程创建rt_thread_create() 的参数和返回值见下表:

参数 描述
name 线程的名称;线程名称的最大长度由 rtconfig.h 中的宏 RT_NAME_MAX 指定,多余部分会被自动截掉
entry 线程入口函数
parameter 线程入口函数参数
stack_size 线程栈大小,单位是字节
priority 线程的优先级。优先级范围根据系统配置情况(rtconfig.h 中的 RT_THREAD_PRIORITY_MAX 宏定义),如果支持的是 256 级优先级,那么范围是从 0~255,数值越小优先级越高,0 代表最高优先级
tick 线程的时间片大小。时间片(tick)的单位是操作系统的时钟节拍。当系统中存在相同优先级线程时,这个参数指定线程一次调度能够运行的最大时间长度。这个时间片运行结束时,调度器自动选择下一个就绪态的同优先级线程进行运行
返回 Thread:线程创建成功,返回线程句柄;RT_NULL:线程创建失败

② 删除线程

对于一些使用 rt_thread_create() 创建出来的线程,当不需要使用,或者运行出错时,我们可以使用下面的函数接口来从系统中把线程完全删除掉:

rt_err_t rt_thread_delete(rt_thread_t thread);

调用该函数后,线程对象将会被移出线程队列并且从内核对象管理器中删除,线程占用的堆栈空间也会被释放,收回的空间将重新用于其他的内存分配。
实际上,用 rt_thread_delete() 函数删除线程接口,仅仅是把相应的线程状态更改为 RT_THREAD_CLOSE 状态,然后放入到 rt_thread_defunct 队列中;
而真正的删除动作(释放线程控制块和释放线程栈)需要到下一次执行空闲线程时,由空闲线程完成最后的线程删除动作。
线程删除 rt_thread_delete() 接口的参数和返回值见下表:

参数 描述
thread 要删除的线程句柄
返回 RT_EOK 删除线程成功,-RT_ERROR 删除线程失败

注:rt_thread_create() 和 rt_thread_delete() 函数仅在使能了系统动态堆时才有效(即 RT_USING_HEAP 宏定义已经定义了)。

(2)初始化和脱离线程

静态方法使用线程

① 初始化线程

线程的初始化可以使用下面的函数接口完成,来初始化静态线程对象:

rt_err_t rt_thread_init(struct rt_thread* thread,
                        const char* name,
                        void (*entry)(void* parameter), void* parameter,
                        void* stack_start, rt_uint32_t stack_size,
                        rt_uint8_t priority, rt_uint32_t tick);

静态线程的线程句柄(或者说线程控制块指针)、线程栈由用户提供。

静态线程是指线程控制块、线程运行栈一般都设置为全局变量,在编译时就被确定、被分配处理,内核不负责动态分配内存空间。

需要注意的是,用户提供的栈首地址需做系统对齐(例如 ARM 上需要做 4 字节对齐)。线程初始化接口 rt_thread_init() 的参数和返回值见下表:

参数 描述
thread 线程句柄。线程句柄由用户提供出来,并指向对应的线程控制块内存地址
name 线程的名称;线程名称的最大长度由 rtconfig.h 中定义的 RT_NAME_MAX 宏指定,多余部分会被自动截掉
entry 线程入口函数
parameter 线程入口函数参数
stack_start 线程栈起始地址
stack_size 线程栈大小,单位是字节。在大多数系统中需要做栈空间地址对齐(例如 ARM 体系结构中需要向 4 字节地址对齐)
priority 线程的优先级。优先级范围根据系统配置情况(rtconfig.h 中的 RT_THREAD_PRIORITY_MAX 宏定义),如果支持的是 256 级优先级,那么范围是从 0 ~ 255,数值越小优先级越高,0 代表最高优先级
tick 线程的时间片大小。时间片(tick)的单位是操作系统的时钟节拍。当系统中存在相同优先级线程时,这个参数指定线程一次调度能够运行的最大时间长度。这个时间片运行结束时,调度器自动选择下一个就绪态的同优先级线程进行运行
返回 RT_EOK 线程创建成功,-RT_ERROR 线程创建失败

② 脱离线程

对于用 rt_thread_init() 初始化的线程,使用 rt_thread_detach() 将使线程对象在线程队列和内核对象管理器中被脱离。线程脱离函数如下:

rt_err_t rt_thread_detach (rt_thread_t thread);

线程脱离接口 rt_thread_detach() 的参数和返回值见下表:

参数 描述
thread 线程句柄,它应该是由rt_thread_init进行初始化的线程句柄
返回 RT_EOK: 线程脱离成功,-RT_ERROR: 线程脱离失败

**这个接口函数与 rt_thread_delete() 函数相对应, rt_thread_delete() 函数操作的对象是 rt_thread_create()创建的句柄,而 rt_thread_detach()函数操作的对象是 rt_thread_init()初始化的线程控制块。**同样线程本身不应调用这个接口脱离线程本身。

(3)启动线程

创建(初始化)的线程状态处于初始状态,并未进入就绪线程的调度队列,我们可以在线程初始化 / 创建成功后调用下面的函数接口让该线程进入就绪态:

rt_err_t rt_thread_startup(rt_thread_t thread);

当调用这个函数时,将把线程的状态更改为就绪状态,并放到相应优先级队列中等待调度。如果新启动的线程优先级比当前线程优先级高,将立刻切换到这个线程。线程启动接口 rt_thread_startup() 的参数和返回值见下表:

参数 描述
thread 线程句柄
返回 RT_EOK:线程启动成功,-RT_ERROR 线程启动失败

(4)线程睡眠

在实际应用中,我们有时需要让运行的当前线程延迟一段时间,在指定的时间到达后重新运行,这就叫做 “线程睡眠”。线程睡眠可使用以下三个函数接口:

rt_err_t rt_thread_sleep(rt_tick_t tick);
rt_err_t rt_thread_delay(rt_tick_t tick);
rt_err_t rt_thread_mdelay(rt_int32_t ms);

这三个函数接口的作用相同,调用它们可以使当前线程挂起一段指定的时间,当这个时间过后,线程会被唤醒并再次进入就绪状态。
这个函数接受一个参数,该参数指定了线程的休眠时间。线程睡眠接口 rt_thread_sleep/delay/mdelay() 的参数和返回值见下表:

参数 描述
tick/ms 线程睡眠的时间:sleep/delay 的传入参数 tick 以 1 个 OS Tick 为单位 ;mdelay 的传入参数 ms 以 1ms 为单位;
返回 RT_EOK: 操作成功

2. 代码实现

本任务主要实现两个功能:灯闪烁、按键控制喇叭。这个两个功能都可以采用循环结构来设计,但是在第3章的任务中发现,单线程中采用循环结构同时实现这两个功能,在代码实现上比较困难,所以本任务分两个线程来实现:一个线程实现灯闪烁,另一个线程实现按键扫描并控制喇叭开关。
构建两个小功能模块,分别是灯闪烁和按键控制喇叭。

(1)led灯闪烁功能模块实现

car_led.h文件主要用于实现变量类型的定义和函数的声明,代码如下:

#ifndef APPLICATIONS_CAR_LED_H_
#define APPLICATIONS_CAR_LED_H_

/* 枚举方式定义车灯闪烁模式 */
enum led_mode {
    LED_MODE_STOP=0, //停止闪烁
    LED_MODE_Double, //双闪
    LED_MODE_LEFT,   //左灯闪烁
    LED_MODE_RIGHT   //右灯闪烁
};
void led_thread_entry();               //线程入口函数声明
void led_set_mode(enum led_mode m);    //车灯闪烁模式设置声明

#endif /* APPLICATIONS_CAR_LED_H_ */

car_led.c是具体的函数实现,本文件除了实现闪灯线程的入口函数以外,还按任务要求,实现闪灯模式设置接口,并把设置接口导出到msh命令列表中,导出后,用户就可以通过在终端输入命令来改变闪烁的模式,代码如下:

#include <rtthread.h>
#include <rtdevice.h>
#include "drv_common.h"

#define DBG_TAG "LED"    //定义日志打印标签
#define DBG_LVL DBG_LOG  //定义日志打印级别
/* 包含日志打印头文件。注意,以上2个宏定义一定要在这个头文件前定义才有效*/
#include <rtdbg.h> 
#include <stdlib.h>      //atoi()函数需要包含的头文件
#include "car_led.h"
/* 定义左右转向灯的控制引脚 */
#define LedLeft GET_PIN(D, 8)
#define LedRight GET_PIN(D, 9)
/* 定义开灯/关灯接口 */
#define LedOn(pin) rt_pin_write(pin, PIN_LOW)
#define LedOff(pin) rt_pin_write(pin, PIN_HIGH)

enum led_mode LedMod=LED_MODE_STOP; //车灯默认为不闪烁

/* 设置闪灯模式的接口 */
void led_set_mode(enum led_mode m)   
{
    LedMod = m;
}

/* 车灯控制线程入口函数定义 */
void led_thread_entry()
{
    /*设置车灯控制引脚模式为输出模式*/
    rt_pin_mode(LedLeft, PIN_MODE_OUTPUT);
    rt_pin_mode(LedRight, PIN_MODE_OUTPUT);
    while(1){
        switch(LedMod)//判断模式
        {
        case LED_MODE_STOP://停止闪烁
            LedOff(LedLeft);
            LedOff(LedRight);
            break;
        case LED_MODE_Double://双闪
            LedOn(LedLeft);
            LedOn(LedRight);
            rt_thread_mdelay(500);
            LedOff(LedLeft);
            LedOff(LedRight);
            break;
        case LED_MODE_LEFT://左灯闪
            LedOff(LedRight);
            LedOn(LedLeft);
            rt_thread_mdelay(250);
            LedOff(LedLeft);
            break;
        case LED_MODE_RIGHT://右灯闪
            LedOff(LedLeft);
            LedOn(LedRight);
            rt_thread_mdelay(250);
            LedOff(LedRight);
            break;
        default:
            LOG_D("mode error\n");
        }
        rt_thread_mdelay(250);//此处延时主要是为了让出CPU,不能让线程一直占用CPU
    }
}
/*msh命令接口*/
void ledmode(int argn, char *argv[])
{
    if(argn<2){
        LOG_W("ledmode #mode");
        return ;
    }
    led_set_mode(atoi(argv[1]));//通过atoi函数把字符变量转为整型变量
}
/* 导出到 msh 命令列表中,MSH_CMD_EXPORT(command,desc),其中command为函数名字,desc为用于描述命令用法或功能的字符串,可以自定 */
MSH_CMD_EXPORT(ledmode, set led flash mode);

(2)按键控制喇叭功能模块实现

扫描法进行按键扫描。
car_beep.h代码如下:

#ifndef APPLICATIONS_CAR_BEEP_H_
#define APPLICATIONS_CAR_BEEP_H_
void beep_thread_entry();//按键扫描并控制蜂鸣器的接口声明
#endif /* APPLICATIONS_CAR_BEEP_H_ */

car_beep.c

#include <rtthread.h>
#include <rtdevice.h>
#include "drv_common.h"
#define DBG_TAG "BEEP"     //定义日志打印标签
#define DBG_LVL DBG_LOG    //定义日志打印级别
#include <rtdbg.h>         //以上2个宏定义一定要在这个头文件前定义才有效
#define KeyBeep GET_PIN(A, 0)  //按键引脚定义
#define Beep GET_PIN(A, 5)     //蜂鸣器引脚定义
/*按键扫描并控制蜂鸣器的接口实现*/
int beep_thread_entry(void)
{
    /* 把蜂鸣器引脚设置为推拉模式 */
    rt_pin_mode(Beep, PIN_MODE_OUTPUT);
    /* 把按键引脚设置为上拉输入模式 */
    rt_pin_mode(KeyBeep, PIN_MODE_INPUT_PULLUP);

    while (1)
    {
        if(PIN_LOW==rt_pin_read(KeyBeep)){//按键按下
            rt_thread_mdelay(20);//延时去抖
            if(PIN_LOW==rt_pin_read(KeyBeep))
                rt_pin_write(Beep, PIN_LOW);//蜂鸣器响
        }
        else
            rt_pin_write(Beep, PIN_HIGH);//否则,蜂鸣器不响

        rt_thread_mdelay(100);//每0.1秒进行一次按键扫描,线程要有让出CPU的时候
    }

    return RT_EOK;
}

注:本任务,两个线程都采用了无线循环模式,为了不让线程陷入死循环操作,两个线程都在每次循环后通过调用延时函数来让出CPU使用权。但这种让出方式还不是最好的方式,通常可以通过让线程灯带信号量的方式使线程挂起,从而达到在线程空闲时让出CPU的效果,具体参考后面线程同步相关章节。

(3)main()程序设计

main()程序主要实现线程的创建,在本任务中,我们分别采用动态方法和静态方法来创建线程,主要是方便了解两种方法的使用,具体代码如下:

#include <rtthread.h>
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
#include "car_led.h"    //包含LED控制模块头文件
#include "car_beep.h"   //包含蜂鸣器控制模块头文件

#define THREAD_STACK_SIZE   1024   //定义线程栈大小
#define THREAD_PRIORITY     20     //定义线程优先级
#define THREAD_TIMESLICE    10     //定义线程时间片

/* 栈首地址必须系统对齐 */
ALIGN(RT_ALIGN_SIZE)
static char beep_stack[THREAD_STACK_SIZE];  //定义栈空间
static struct rt_thread beepThread;    //静态方式定义beep线程控制块
rt_thread_t TidLed = RT_NULL;  //动态方式定义LED线程句柄

int main(void)
{
    int ret;

    /* 动态方式创建线程 */
    TidLed = rt_thread_create("LED", 
								led_thread_entry, 
								RT_NULL,
								THREAD_STACK_SIZE, 
								THREAD_PRIORITY, 
								THREAD_TIMESLICE);
    if (TidLed != RT_NULL)//判断线程是否成功创建
        rt_thread_startup(TidLed);//成功则启动线程
    else {//否则打印日志并即出
        LOG_D("can not create LED thread!");
        return -1;
    }

    /* 采用静态方式初始化线程 */
    ret = rt_thread_init(&beepThread,
                            "BEEP",
                            beep_thread_entry,
                            RT_NULL,
                            &beep_stack[0],
                            sizeof(beep_stack),
                            THREAD_PRIORITY,
                            THREAD_TIMESLICE);
    if (ret == RT_EOK) //判断线程是否成功创建
        rt_thread_startup(&beepThread); //成功则启动线程
    else { //否则打印日志并即出
        LOG_D("can not init beep thread!");
        return -1;
    }

    return RT_EOK;
}
void stop_led_thread(void)//删除led线程命令
{
    rt_thread_delete(TidLed);//动态创建的线程用delete删除
}
void stop_beep_thread(void) //删除beep线程命令
{
    rt_thread_detach(&beepThread);//静态初始化的线程用detach删除
}

/* 导出到 msh 命令列表中*/
MSH_CMD_EXPORT(stop_led_thread, delete led thread);
MSH_CMD_EXPORT(stop_beep_thread, delete beep thread);

复制以上代码文件到applicastions目录中,构建并下载程序到开发板。

3. 程序测试

(1)系统启动后,两个LED等常亮无闪烁,终端输入ps命令查看系统线程情况,发现系统中新增了2个线程,分别使BEEP和LED,如图所示
【STM32&RT-Thread零基础入门】 5. 线程创建应用(线程创建、删除、初始化、脱离、启动、睡眠),STM32 RT-Thread操作系统入门,stm32,windows,嵌入式硬件
(2)在终端中输入help命令查看系统命令支持情况,发现系统新增了程序中导出的3个命令ledmode、stop_led_thread、stop_beep_thread,如下图所示:
【STM32&RT-Thread零基础入门】 5. 线程创建应用(线程创建、删除、初始化、脱离、启动、睡眠),STM32 RT-Thread操作系统入门,stm32,windows,嵌入式硬件
(3)终端输入ledmode 1、ledmode 2、ledmode 3等命令后,观察到车灯闪烁分别变为“双闪”“左灯闪”“右灯闪”。
【STM32&RT-Thread零基础入门】 5. 线程创建应用(线程创建、删除、初始化、脱离、启动、睡眠),STM32 RT-Thread操作系统入门,stm32,windows,嵌入式硬件
(4)按下按键后,喇叭发出响声。
(5)松开按键后,喇叭停止发声。
(6)一直按住按键不松开,喇叭发出响声的同时,车灯继续闪烁。
(7)通过终端输入停止车灯闪烁命令stop_led_thread,观察车灯不再闪烁;通过ps命令查看系统线程情况,发现系统中不存在LED线程了

【STM32&RT-Thread零基础入门】 5. 线程创建应用(线程创建、删除、初始化、脱离、启动、睡眠),STM32 RT-Thread操作系统入门,stm32,windows,嵌入式硬件

(8)通过终端输入停止喇叭响声命令stop_beep_thread,按下按键时喇叭不响;通过ps命令查看系统线程情况,发现系统中不存在BEEP线程了

【STM32&RT-Thread零基础入门】 5. 线程创建应用(线程创建、删除、初始化、脱离、启动、睡眠),STM32 RT-Thread操作系统入门,stm32,windows,嵌入式硬件


总结

本文讲了线程创建的应用文章来源地址https://www.toymoban.com/news/detail-652042.html

到了这里,关于【STM32&RT-Thread零基础入门】 5. 线程创建应用(线程创建、删除、初始化、脱离、启动、睡眠)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【STM32&RT-Thread零基础入门】8. 基于 CubeMX 移植 RT-Thread Nano

    硬件:STM32F103ZET6、ST-LINK、usb转串口工具、4个LED灯、1个蜂鸣器、4个1k电阻、2个按键、面包板、杜邦线 利用RT_Thread操作系统实现三种不同的LED等闪烁 提示:以下是本篇文章正文内容,下面案例可供参考 cubemx配置参考教程: 基于 CubeMX 移植 RT-Thread Nano 后面程序所需的引脚 RT

    2024年02月09日
    浏览(47)
  • 【STM32&RT-Thread零基础入门】 3. PIN设备(GPIO)的使用

    硬件:STM32F103ZET6、ST-LINK、usb转串口工具、4个LED灯、1个蜂鸣器、4个1k电阻、2个按键、面包板、杜邦线 在嵌入式系统中,GPIO是最常用的一种设备,在RT-Thread操作系统中,把GPIO命名为PIN设备。 RT-Thread通过PIN设备对芯片的GPIO引脚进行管理,应用程序可以通过其提供的一组PIN设备

    2024年02月13日
    浏览(48)
  • STM32CubeMX+VSCODE+EIDE+RT-THREAD 工程创建

            Eide环境搭建暂且不表,后续补充。主要记录下Vscode环境下 创建Rt-thread工程的过程。分别介绍STM32CubeMX添加rtt支持包的方式和手动添加rtt kernel方式。STM32CubeMX生成工程的时候有\\\"坑\\\",防止下次忘记,方便渡一下有缘人,特此记录。         此工程以创建stm32f405为例

    2024年02月14日
    浏览(50)
  • RT-Thread:STM32实时时钟 RTC开启及应用

    说明: STM32F103/407系列基于 RT-Thread 系统的 RTC 开启及应用 应用流程介绍。 完成以上系统配置,编译无误情况下RTC 就已经开启了。 官方 API 查询地址:https://www.rt-thread.org/document/api/rtc_sample_8c-example.html#a3 1.设置日期:设置系统日期但不修改时间 2.设置时间:设置系统时间但不

    2024年01月17日
    浏览(62)
  • 使用RT-Thread Studio搭配STM32CubeMX新建RT-Thread项目

    STM32CubeMX下载 RT-Thread Studio下载 安装好RT-Thread Studio后,先打开RT-Thread SDK管理器确认有没有自己MCU需要的SDK包,直接安装好之后里面是有STM32F1系列的SDK包,其他的需要自己安装。 之后点击文件→新建→RT-Thread项目,根据自己需要配置好后点击完成就会生成RT-Thread项目。 新建项

    2024年02月11日
    浏览(51)
  • Rt-Thread 移植5--空闲线程和线程阻塞(KF32)

    src中定义idle.c clock.c 5.3.6 中断函数 irq.c main.c

    2024年02月06日
    浏览(42)
  • [嵌入式系统-32]:RT-Thread -17- 任务、进程、线程的区别

    目录 一、基本概念澄清 1.1 任务 1.2 进程 1.3 线程 1.4 比较 1.5 任务VS进程 1.6 进程 VS 线程 1.7 任务 进程 线程 发展历史 任务(Task): 进程(Process): 线程(Thread): 发展趋势: 二、不同操作系统中任务、进程、线程 2.1 Linux:没人任务,只有进程与线程 进程相关函数: 线程

    2024年02月21日
    浏览(45)
  • STM32 + RT-Thread + LwIp + DM9000

    开发板:STM32F103ZET6(战舰) RT-Thread:5.0.0 LwIp:2.1.2 网卡芯片:DM9000 编译环境:keil 我简单了解了一下,在嵌入式中,网络芯片的使用方式大致有三种,如下: (MCU + MAC + PHY) (MUC + MAC) —— PHY MCU —— (MAC + PHY) 注意: 我用括号里面的表示在同一块芯片中 移植 RT-Thread 不是此文

    2024年02月07日
    浏览(49)
  • RT-Thread入门笔记5-线程的时间片轮询调度

    优先级和时间片是线程的两个重要参数,优先级描述了线程竞争处理器资源的能力。 优先级和时间片 优先级 RT-Thread 最大支持 256 个优先级(数值越小的优先级越高,0 为最高优先级, 最低优先级预留给空闲线程);用户可以通过rt_config.h中的RT_THREAD_PRIORITY_MAX宏来修改最大支持

    2024年02月02日
    浏览(43)
  • RT-Thread STM32 GoKit V2.1 开发板BSP说明

    本文档为刘恒为 GoKit V2.1 开发板提供的 BSP (板级支持包) 说明。 主要内容如下: 开发板资源介绍 BSP 快速上手 进阶使用方法 通过阅读快速上手章节开发者可以快速地上手该 BSP,将 RT-Thread 运行在开发板上。在进阶使用指南章节,将会介绍更多高级功能,帮助开发者利用 RT-

    2024年02月04日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包