这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » 【转载】RTT简介及其简单应用--from毅

共1条 1/1 1 跳转至

【转载】RTT简介及其简单应用--from毅

工程师
2025-07-19 17:56:51     打赏

一、 裸机系统和多任务系统

裸机系统通常分为轮询系统和前后台系统。

轮询系统不难理解就是按照顺序从上往下反复来执行,伪代码如下:

int main()

{

Init();

while(1)

{

/*事件1*/

event1();

/*事件2*/

event2();

/*事件3*/

event3();

}

}

AI写代码

c

运行

前后台系统就是在轮询系统的基础上多个一个中断,伪代码为:


int main(void)

{

Init();

while(1)

{

/*事件1*/

event1();

/*事件2*/

event2();

/事件3*/

event3();

}

}


void interrupt(void)

{

dosoemthing();

}


AI写代码

c

运行


多任务系统则是一个个单独的任务之间相互协调,且这些任务都是无限循环且不返回的,伪代码为:


int main(void)

{

Init();

RTOS_Init();

RTOS_Start();

}


void thread1_entry(void *arg)

{

while(1)

{

event1();

}

}


void thread2_entry(void *arg)

{

while(1)

{

event2();

}

}


AI写代码

c

运行

二、RTT操作系统

RTT就是一个多任务抢占式操作系统,和裸机系统相比,RTT的优势在于当工程庞大时,我们可以将其分解成一个个小任务,这些任务都有优先级,操作系统的调度机制来决定任务的运行顺序,不用担心每个模块之间的相互干扰,同时,抢占的机制可以迅速的来处理紧急任务。


三,RTT相关函数


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)

AI写代码

c

运行


函数功能:创建一个线程

参数讲解:

const char *name:线程名称

void (*entry)(void *parameter):线程入口

void *parameter:线程参数

rt_uint32_t stack_size:线程栈大小

rt_uint8_t priority:线程优先级

rt_uint32_t tick:时间片

函数返回值:该线程的句柄


rt_err_t rt_thread_startup(rt_thread_t thread)

AI写代码

c

运行

1

函数功能:启动线程

参数讲解:

rt_thread_t thread:线程的句柄


信号量机制:

信号量是一种实现线程间通信的机制,实现线程之间同步或临界资源的互斥访问, 常用于协助一组相互竞争的线程来访问临界资源。在多线程系统中,各线程之间需要同步或互斥实现临界资源的保护。


rt_sem_t rt_sem_create(const char *name, rt_uint32_t value, rt_uint8_t flag);

AI写代码

c

运行

1

函数功能:创建一个信号量

参数讲解:

const char *name:信号量的名字

rt_uint32_t value:持有信号量的个数

rt_uint8_t flag:RT_IPC_FLAG_FIFO(按先后顺序), RT_IPC_FLAG_PRIO(按优先级)。

函数返回值:信号量句柄


rt_err_t rt_sem_release(rt_sem_t sem)

AI写代码

c

运行

1

函数功能:释放一个信号量


rt_err_t rt_sem_take(rt_sem_t sem, rt_int32_t time)

AI写代码

c

运行

1

函数功能:获取一个信号量

说明:如果欲获取的信号量为0,则调用该函数的线程会被挂起,挂起的时间由第二个参数设置


四、小demo

生产者、消费者模型:生产者不停的生产数据,但是当队列满了,就停止生产,消费者不停消费数据,当队列空了停止消费。

3.png

#include "board.h"

#include "rtthread.h"


rt_thread_t producer_thread = RT_NULL;

rt_thread_t consumer_thread = RT_NULL;


rt_sem_t notfull_sem = RT_NULL;

rt_sem_t notempty_sem = RT_NULL;



#define BUF_SIZE 5

typedef struct

{

uint32_t buf[BUF_SIZE];

uint32_t write_p;

uint32_t read_p;

}data;


data data_t;


void producer_thread_entry(void *arg);

void consumer_thread_entry(void *arg);


int main(void)

{

notfull_sem = rt_sem_create("notfull_sem", 0, RT_IPC_FLAG_FIFO);

notempty_sem = rt_sem_create("notempty_sem", 0, RT_IPC_FLAG_FIFO);

producer_thread = rt_thread_create("producer_thread",

    producer_thread_entry,

RT_NULL,

512,

0,

20);

consumer_thread = rt_thread_create("consumer_thread",

    consumer_thread_entry,

RT_NULL,

512,

1,

20);

rt_thread_startup(producer_thread);

rt_thread_startup(consumer_thread);

}


void producer_thread_entry(void *arg)

{

static uint32_t cnt=0;

while(1)

{

if(data_t.write_p - data_t.read_p < BUF_SIZE - 1)

{

data_t.buf[data_t.write_p % BUF_SIZE] = cnt++;

rt_kprintf("生产一个数据: %d\n",data_t.buf[data_t.write_p % BUF_SIZE]);

data_t.write_p++;

rt_sem_release(notempty_sem);

rt_thread_delay(200);

}

else

{

rt_kprintf("生产缓冲区已满\n");

rt_sem_take(notfull_sem,RT_WAITING_FOREVER);

rt_thread_delay(200);

}

}

}


void consumer_thread_entry(void *arg)

{

while(1)

{

if(data_t.read_p != data_t.write_p)

{

rt_kprintf("消费一个数据: %d\n",data_t.buf[data_t.read_p% BUF_SIZE]);

data_t.read_p++;

rt_sem_release(notfull_sem);

rt_thread_delay(400);

}

else

{

rt_sem_take(notempty_sem,RT_WAITING_FOREVER);

rt_kprintf("消费缓冲区已空\n");

}

}

}

可以看到生产者的生产速度大于消费者,出现了缓冲区已满的现象,生产者则停止生产,等待消费者消费一个数据后继续生产

来源: 整理文章为传播相关技术,网络版权归原作者所有,如有侵权,请联系删除。


共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]