当前位置:   article > 正文

【RT-thread】如何将RT-thread系统移植到stm32_rt-thread stdio stm32l151标准库

rt-thread stdio stm32l151标准库

1.RT-thread简介

T-Thread(Real Time-Thread),是一个嵌入式实时多线程操作系统。在 RT-Thread 系统中,任务调度通过线程实现的。
RT-Thread 主要采用 C 语言编写,浅显易懂,方便移植。针对资源受限的微控制器(MCU)系统,可通过方便易用的工具,裁剪出仅需要 3KB Flash、1.2KB RAM 内存资源的 NANO 版本;而对于资源丰富的物联网设备,RT-Thread 又能使用在线的软件包管理工具,配合系统配置工具实现直观快速的模块化裁剪,无缝地导入丰富的软件功能包,实现类似 Android 的图形界面及触摸滑动效果、智能语音交互效果等复杂功能。
如果之前有过FreeRTOS后UCOS等嵌入式系统经验,那这款国产系统更容易上手咯,同时也为支持国产贡献一份力量吧。

点我查看RT-thread学习文档

2.用stm32CubeMx建一个最简单的工程吧

芯片:stm32l031k6t6(手上就只有这款咯,M0+ 32MHz,32KFlash,8KSRAM)
怎么感觉flash和RAM有点不够用咧,还是先做吧
在这里插入图片描述
在这里插入图片描述
导出到MDK-ARM中,编译0 error,0 warning

3.修改一下工程咯

把串口和spi驱动单独封装成一个文件(可以不做处理,这里纯属个人习惯)
  • 1
  1. 添加RT-thread库到工程文档中
    在这里插入图片描述

  2. 将stm32l0xx_it.c中重定义的函数删除、注释或weak一下

  3. 用rtconfig.h配置一下系统,把不需要的组件去除,鉴于用的芯片内存很小,我就把大部分功能去除了
    在这里插入图片描述
    4.RT-thread系统对外设初始化在board.c的rt_hw_board_init()函数中实现的,我们修改一下
    在这里插入图片描述
    5.实现一下串口咯,RT-thread中的串口打印函数是rt-kprintf

void rt_kprintf(const char *fmt, ...)
{
    va_list args;
    rt_size_t length;
    static char rt_log_buf[RT_CONSOLEBUF_SIZE];

    va_start(args, fmt);
    /* the return value of vsnprintf is the number of bytes that would be
     * written to buffer had if the size of the buffer been sufficiently
     * large excluding the terminating null byte. If the output string
     * would be larger than the rt_log_buf, we have to adjust the output
     * length. */
    length = rt_vsnprintf(rt_log_buf, sizeof(rt_log_buf) - 1, fmt, args);
    if (length > RT_CONSOLEBUF_SIZE - 1)
        length = RT_CONSOLEBUF_SIZE - 1;
#ifdef RT_USING_DEVICE
    if (_console_device == RT_NULL)
    {
        rt_hw_console_output(rt_log_buf);
    }
    else
    {
        rt_uint16_t old_flag = _console_device->open_flag;

        _console_device->open_flag |= RT_DEVICE_FLAG_STREAM;
        rt_device_write(_console_device, 0, rt_log_buf, length);
        _console_device->open_flag = old_flag;
    }
#else
    rt_hw_console_output(rt_log_buf);
#endif
    va_end(args);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

rt_hw_console_output()函数需要用户自己实现,实现函数如下

void rt_hw_console_output(const char *str){
    rt_enter_critical();
    while(*str != '\0'){
        if(*str =='\r'){
            HAL_UART_Transmit(&huart2, (uint8_t *)'\n', 1, 0xfff);
        }
        HAL_UART_Transmit(&huart2, (uint8_t *)(str++), 1, 0xfff);
    }
    rt_exit_critical();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

下载测试一下,如下图,就是串口移植成功咯在这里插入图片描述
6. 测试一下线程、消息队列

#include "main.h"
#include "slim_drv.h"
#include <rtthread.h>
#include <stdio.h>

static rt_thread_t thread1 = RT_NULL;
static rt_thread_t thread2 = RT_NULL;
static rt_thread_t thread3 = RT_NULL;
static rt_mq_t rt_mq = RT_NULL;

//function declaration 
static void Thread1_entry(void *arg);
static void Thread2_entry(void *arg);
static void Thread3_entry(void *arg);

int main(void){
	thread1 = rt_thread_create("thread1", Thread1_entry, RT_NULL, 512, 5, 10);
	if(thread1 != RT_NULL){
		rt_thread_startup(thread1);
		rt_kprintf("thread1 create success\n");
	}else{
		rt_kprintf("thread1 create failed\n");
		return -1;
	}
	
	thread2 = rt_thread_create("thread2", Thread2_entry, RT_NULL, 512, 3, 20);
	if(thread2 != RT_NULL){
		rt_thread_startup(thread2);
		rt_kprintf("thread2 create success\n");
	}else{
		rt_kprintf("thread2 create failed\n");
		return -1;
	}
	
	thread3 = rt_thread_create("thread3", Thread3_entry, RT_NULL, 512, 4, 10);
	if(thread3 != RT_NULL){
		rt_thread_startup(thread3);
		rt_kprintf("thread3 create success\n");
	}else{
		rt_kprintf("thread3 create failed\n");
		return -1;
	}
	
	rt_mq = rt_mq_create("mq", 256, 1, RT_IPC_FLAG_FIFO);
	if(rt_mq != RT_NULL){
		rt_kprintf("create MQ success\n");
	}else{
		rt_kprintf("create MQ failed\n");
	}
	rt_kprintf("\n");
    return RT_EOK;
}


void Thread1_entry(void *arg){
	uint8_t cnt = 0;
	while(1){
		rt_kprintf("Thread1 Cnt:%d\n",cnt++);
		rt_thread_delay(2000);
	}
}
void Thread2_entry(void *arg){
	rt_err_t ret = RT_EOK;
	char tx_buff[128] = {0};
	uint32_t cnt = 1;
	while(1){
		sprintf(tx_buff, "Hello World! %d",cnt);
		ret = rt_mq_send(rt_mq, tx_buff, 20);
		rt_thread_delay(5000);
		cnt *= 2;
		if(cnt>0xffff){
			cnt = 1;
		}
	}
}
static void Thread3_entry(void *arg){
	rt_err_t ret = RT_EOK;
	uint8_t r_queue[128] = {0};
	uint32_t r_int = 0;
	while(1){
		ret = rt_mq_recv(rt_mq, r_queue, sizeof(r_queue), RT_WAITING_FOREVER);
		if(RT_EOK == ret){
			rt_kprintf("Rx OK: %s\n",r_queue);
		}else{
			rt_kprintf("Rx Err: %x\n",ret);
		}
		rt_thread_delay(10);
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  1. 测试能正常运行。其他的消息邮箱、信号量、互斥量、事件、软定时器用法就不演示了,到文章开头的RT-thread文档点进去,自行学习调试

在这里插入图片描述

RT-thread移植是不是很简单的,赶紧学习一下吧

点击下载文中的项目工程文件

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/67467
推荐阅读
相关标签
  

闽ICP备14008679号