如何将RT-thread系统移植到stm32

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有点不够用咧,还是先做吧
如何将RT-thread系统移植到stm32_第1张图片
如何将RT-thread系统移植到stm32_第2张图片
导出到MDK-ARM中,编译0 error,0 warning

3.修改一下工程咯

把串口和spi驱动单独封装成一个文件(可以不做处理,这里纯属个人习惯)
  1. 添加RT-thread库到工程文档中
    如何将RT-thread系统移植到stm32_第3张图片

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

  3. 用rtconfig.h配置一下系统,把不需要的组件去除,鉴于用的芯片内存很小,我就把大部分功能去除了
    如何将RT-thread系统移植到stm32_第4张图片
    4.RT-thread系统对外设初始化在board.c的rt_hw_board_init()函数中实现的,我们修改一下
    如何将RT-thread系统移植到stm32_第5张图片
    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);
}

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();
}

下载测试一下,如下图,就是串口移植成功咯如何将RT-thread系统移植到stm32_第6张图片
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. 测试能正常运行。其他的消息邮箱、信号量、互斥量、事件、软定时器用法就不演示了,到文章开头的RT-thread文档点进去,自行学习调试

如何将RT-thread系统移植到stm32_第7张图片

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

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

你可能感兴趣的:(嵌入式,嵌入式系统,嵌入式,RT-thread系统,stm32系统移植)