【极海APM32F4xx Tiny】学习笔记05-移植 RTT NANO工程

news2024/11/25 21:12:08

5.移植 RTT NANO工程

移植步骤:
1. mdk添加rtt nano 包文件
2. 添加源码
3. 屏蔽2个中断处理函数
4. 修改board.c文件
5. 添加控制台
6. 添加finsh组件
7. 编写测试工程

1. mdk添加rtt nano 包文件

在这里插入图片描述

也可以下载后手动安装
下载链接https://www.rt-thread.org/download/mdk/RealThread.RT-Thread.3.1.5.pack

在这里插入图片描述

rtt nano 安装位置
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kBOttCeQ-1686746659361)(picture/image-20230614200822254.png)]

2. 添加源码到工程

在这里插入图片描述

添加后如下

在这里插入图片描述

3. 屏蔽2个中断处理函数

void HardFault_Handler(void)

在这里插入图片描述

void PendSV_Handler(void)

在这里插入图片描述

修改 systick

 #include <rtthread.h>
void SysTick_Handler(void)
{
	void rt_os_tick_callback(void);
	rt_os_tick_callback();
}

在这里插入图片描述

3.修改board.c文件

合计修改3个地方

3.1 添加头文件

//添加头文件
#include "apm32f4xx.h"
#include "bsp_usart.h"

3.2 修改rt_hw_board_init 函数

SystemInit();// (1)系统初始化
SystemCoreClockUpdate();// (2)初始化系统时钟
SysTick_Config(SystemCoreClock/RT_TICK_PER_SECOND); //(3) 滴答定时器初始化

在这里插入图片描述

3.4 rttconfig.h 文件说明

/* RT-Thread config file */

#ifndef __RTTHREAD_CFG_H__
#define __RTTHREAD_CFG_H__

// <<< Use Configuration Wizard in Context Menu >>>

// RT_THREAD_PRIORITY_MAX 这个宏表示 RT-Thread 支持多少个优先级,取值范围为 8~256,默认为 32。
#define RT_THREAD_PRIORITY_MAX  32

//RT_TICK_PER_SECOND 表示操作系统每秒钟有多少个 tick,tick 即是操作系统的时钟周期,默认为 1000
#define RT_TICK_PER_SECOND  1000

// 表示 CPU 处理的数据需要多少个字节对齐,默认为 4 个字节
#define RT_ALIGN_SIZE   4

// 内核对象名字的最大长度,取值范围为 2~16,默认为 8。
#define RT_NAME_MAX    8

// 使用 RT-Thread 组件初始化,默认使能
#define RT_USING_COMPONENTS_INIT

// 使用用户 main 函数,默认打开
#define RT_USING_USER_MAIN

// main 线程栈大小,取值范围为 1~4086,单位为字节,默认为512。
#define RT_MAIN_THREAD_STACK_SIZE     256

// </h>

// 调试配置
// <c1>enable kernel debug configuration
//  <i>Default: enable kernel debug configuration
//#define RT_DEBUG
// </c>
// <o>enable components initialization debug configuration<0-1>
//  <i>Default: 0
#define RT_DEBUG_INIT 0
// <c1>thread stack over flow detect
//  <i> Diable Thread stack over flow detect
//#define RT_USING_OVERFLOW_CHECK
// </c>
// </h>

// 钩子函数配置,目前全部关闭。
// <c1>using hook
//  <i>using hook
//#define RT_USING_HOOK
// </c>
// <c1>using idle hook
//  <i>using idle hook
//#define RT_USING_IDLE_HOOK
// </c>
// </h>

// 软件定时器配置,目前关闭,不使用软件定时器。
#define RT_USING_TIMER_SOFT         0
#if RT_USING_TIMER_SOFT == 0
    #undef RT_USING_TIMER_SOFT
#endif
// <o>The priority level of timer thread <0-31>
//  <i>Default: 4
#define RT_TIMER_THREAD_PRIO        4
// <o>The stack size of timer thread <0-8192>
//  <i>Default: 512
#define RT_TIMER_THREAD_STACK_SIZE  512
// </e>


// 内部通信配置,包括信号量、互斥量、事件、邮箱和消息队列,根据需要配置
#define RT_USING_SEMAPHORE
// 互斥量
//#define RT_USING_MUTEX
// 事件
//#define RT_USING_EVENT
// 邮箱
#define RT_USING_MAILBOX
// 消息队列
//#define RT_USING_MESSAGEQUEUE
// </c>
// </h>

//内存管理配置。
// 这个宏用于表示是否使用内存池,目前关闭,不使用内存池。
//#define RT_USING_MEMPOOL

// 于表示是否堆,目前关闭,不使用堆
/*
	通过使能或者失能 RT_USING_HEAP 这个宏来选择
	使用静态或者动态内存。无论是使用静态还是动态内存方案,使用的都是内部的 SRAM,
	区别是使用的内存是在程序编译的时候分配还是在运行的时候分配。
*/
#define RT_USING_HEAP
#define RT_USING_SMALL_MEM
// </c>
// <c1>using tiny size of memory
//  <i>using tiny size of memory
//#define RT_USING_TINY_SIZE
// </c>
// </h>

// 控制台配置。控制台即是 rt_kprintf()函数调试输出的设备,通常使用串口
#define RT_USING_CONSOLE
//控制台缓存大小
#define RT_CONSOLEBUF_SIZE          256
// </h>

//FINSH  shell 配置
#include "finsh_config.h"
// </c>
// </h>

// <h>Device Configuration
// <c1>using device framework
//  <i>using device framework
//#define RT_USING_DEVICE
// </c>
// </h>

// <<< end of configuration section >>>

#endif

4. 添加控制台

4.1在uart_init中添加串口初始化函数

static int uart_init(void)
{
		bsp_uart1_init(115200);
	
    return 0;
}

4.2.添加控制台输出函数

//(4)添加控制台输出函数
void rt_hw_console_output(const char *str)
{
	rt_size_t size =0;
	size = rt_strlen(str);
	for(int i=0;i<size;i++)
	{
		if(str[i]=='\n')
		{
						/* send a byte of data to the serial port */
			USART_TxData(DEBUG_USART, (uint8_t)'\r');
			/* wait for the data to be send */
			while (USART_ReadStatusFlag(DEBUG_USART, USART_FLAG_TXBE) == RESET);
		}
		  /* send a byte of data to the serial port */
    USART_TxData(DEBUG_USART, (uint8_t)str[i]);
    /* wait for the data to be send */
    while (USART_ReadStatusFlag(DEBUG_USART, USART_FLAG_TXBE) == RESET);
	}
}

5. 添加finsh组件

在finsh_port.h 中完善串口获取数据的功能

RT_WEAK char rt_hw_console_getchar(void)
{
    /* Note: the initial value of ch must < 0 */
    int ch = -1;
    if(USART_ReadStatusFlag(DEBUG_USART, USART_FLAG_RXBNE) != RESET)
    {
        ch = USART_RxData(DEBUG_USART);
    }
    else {

        if(USART_ReadStatusFlag(DEBUG_USART, USART_FLAG_OVRE) != RESET)
        {
            USART_ClearStatusFlag(DEBUG_USART,USART_FLAG_OVRE);
        }
        rt_thread_mdelay(10);
    }

    return ch;
}

在这里插入图片描述

6.编写测试工程

static rt_thread_t tid1 = RT_NULL;

/* 线程 1 的入口函数 */
static void thread1_entry(void *parameter)
{
    rt_uint32_t count = 0;

    while (1)
    {
        /* 线程 1 采用低优先级运行,一直打印计数值 */
        //  rt_kprintf("thread1 count: %d\n", count ++);
        led_toggle(LED1);
        rt_thread_delay(1000);
        // led_toggle(LED0);
    }
}

#define THREAD_PRIORITY         25
#define THREAD_STACK_SIZE       512
#define THREAD_TIMESLICE        5

int main(void)
{
    led_init(LED0);
    led_init(LED1);

    /* 创建线程 1,名称是 thread1,入口是 thread1_entry*/
    tid1 = rt_thread_create("thread1",
                            thread1_entry, RT_NULL,
                            THREAD_STACK_SIZE,
                            THREAD_PRIORITY, THREAD_TIMESLICE);

    /* 如果获得线程控制块,启动这个线程 */
    if (tid1 != RT_NULL)
        rt_thread_startup(tid1);

    init_key_btn();
    while (1)
    {
        rt_thread_mdelay(500);
        led_toggle(LED0);
        //  rt_kprintf("hello\n") ;
        key_lib_buttons_process();

    }
}

在这里插入图片描述

实例输出结果:

led0 500ms闪烁间隔 LED1 1000ms闪烁间隔

控制台输出RTT版本欢迎信息,可以shell交互
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/647281.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【openeuler】Yocto embedded sig联合例会 (2022-11-03)

Yocto &embedded sig联合例会 (2022-11-03)_哔哩哔哩_bilibili

从浏览器输入url到页面加载(六)前端必须了解的路由器和光纤小知识

前言 上一章我们说到了数据包在网线中的故事&#xff0c;说到了双绞线&#xff0c;还说到了麻花。这一章继续沿着这条线路往下走&#xff0c;说一些和cdn以及路由器相关&#xff0c;运营商以及光纤相关的小知识&#xff0c;前端同学应该了解一下的 目录 前言 1. CDN和路由器…

STM32-I2C通信在AT24C02的应用

AT24C02是一种失去电源供给后依旧能保持数据的储存器&#xff0c;常用来储存一些配置信息&#xff0c;在系统重新上电之后也可以加载。它的容量是2k bit的EEPROM存储器&#xff0c;采用I2C通信方式。 AT24C02支持两种写操作&#xff1a;字节写操作和页写操作。本实验中我们采用…

三十八、动态规划——背包问题( 01 背包 + 完全背包 + 多重背包 + 分组背包 + 优化)

动态规划-背包问题算法主要内容 一、基本思路1、背包问题概述2、动态规划&#xff08;DP&#xff09;问题分析 二、背包问题1、0 1 背包问题2、完全背包问题3、多重背包问题4、分组背包问题 三、例题题解 一、基本思路 1、背包问题概述 0 1 背包问题&#xff1a; 条件&#x…

前端解决按钮重复提交数据问题(节流和防抖)

&#x1f37f;*★,*:.☆(&#xffe3;▽&#xffe3;)/$:*.★* &#x1f37f; &#x1f35f;欢迎来到前端初见的博文&#xff0c;本文主要讲解在工作解决按钮重复提交数据问题&#xff08;节流和防抖&#xff09; &#x1f468;‍&#x1f527; 个人主页 : 前端初见 &#x1f9…

【redis】数据类型,持久化、事务和锁机制、Java和redis交互、使用redis缓存、三大缓存问题

文章目录 Redis数据库NoSQL概论Redis安装和部署基本操作数据操作 数据类型介绍HashListSet和SortedSet 持久化RDBAOF 事务和锁机制锁 使用Java与Redis交互基本操作SpringBoot整合Redis 使用Redis做缓存Mybatis二级缓存Token持久化存储 三大缓存问题缓存穿透缓存击穿缓存雪崩 Re…

kotlin协程Job、CoroutineScope作用域,Android

kotlin协程Job、CoroutineScope作用域&#xff0c;Android import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.util.Log import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines…

(横向刷题)【算法1-6】二分查找与二分答案【算法2-1】前缀和、差分与离散化(上),总结

【算法1-6】二分查找与二分答案 P1024[NOIP2001 提高组] 一元三次方程求解 思路&#xff1a;题目说明根与根之差的绝对值>1,且x1<x2&&f(x1)*f(x2)<0则其中存在解&#xff0c;于是联想到枚举&#xff0c;再用二分答案法控制精度 总结&#xff1a;二分对于精度…

【RabbitMQ教程】第四章 —— RabbitMQ - 交换机

&#x1f4a7; 【 R a b b i t M Q 教程】第四章—— R a b b i t M Q − 交换机 \color{#FF1493}{【RabbitMQ教程】第四章 —— RabbitMQ - 交换机} 【RabbitMQ教程】第四章——RabbitMQ−交换机&#x1f4a7; &#x1f337; 仰望天空&#xff0c;妳我亦是行人.✨ &…

《阿里大数据之路》读书笔记:第一章 总述

阿里巴巴大数据系统体系架构图 阿里数据体系主要分为数据采集、数据计算、数据服务和数据应用四大层次。 一、数据采集层 阿里巴巴建立了一套标准的数据采集体系方案&#xff0c;致力全面、高性能、规范地完成海量数据的采集&#xff0c;并将其传输到大数据平台。 数据来源主…

【C++】 STL(下)算法、迭代器、容器适配器 和 仿函数

文章目录 算法迭代器容器适配器栈&#xff08;stack&#xff09;队列&#xff08;queue&#xff09; 仿函数 算法 STL中的算法头文件位于和文件中&#xff08;以为主&#xff09; for_each(InputIterator First,InputIterator Last,Function _Func); 遍历&#xff0c;具体做什…

电影《天空之城》观后感

上周看了电影《天空之城》这部电影&#xff0c;这部电影是六一儿童节时上映的&#xff0c;本周也算是补票吧&#xff0c;童年时&#xff0c;看的都是免费的&#xff0c;早已经忘记是在哪里看到的&#xff0c;但当时对自己触动很大&#xff0c;算是启蒙电影&#xff0c;所以今天…

【RabbitMQ教程】第二章 —— RabbitMQ - 简单案例

&#x1f4a7; 【 R a b b i t M Q 教程】第二章—— R a b b i t M Q − 简单案例 \color{#FF1493}{【RabbitMQ教程】第二章 —— RabbitMQ - 简单案例} 【RabbitMQ教程】第二章——RabbitMQ−简单案例&#x1f4a7; &#x1f337; 仰望天空&#xff0c;妳我亦是行人…

汽车电子Autosar之以太网SOMEIP

前言 首先&#xff0c;请问大家几个小小问题&#xff0c;你清楚&#xff1a; 你知道什么是SOME/IP吗&#xff1f;你知道为什么会产生SOME/IP即相关背景吗&#xff1f;你知道SOME/IP与SOA又有着哪些千丝万缕的联系呢&#xff1f;SOME/IP在实践中到底应该如何使用呢&#xff1f…

QuickList

基本概述 ZipList虽节省内存但是申请内存必须是连续的&#xff0c;如果内存占用很大&#xff0c;申请内存效率就会很低&#xff0c;可以限制ZipList长度和entry大小&#xff1b; 实在要存储大量数据&#xff0c;超出ZipList最佳上限了&#xff0c;此时可以创建多个ZipList来分片…

Autosar诊断实战系列04-基于CAPL语言的通信类诊断测试脚本开发

本文框架 前言1.CAPL编程简单介绍2. CAPL脚本开发实战2.1 添加CAPL Test Module2.2 CAPL脚本实战编写前言 在本系列笔者将结合工作中对诊断实战部分的应用经验进一步介绍常用UDS服务的进一步探讨及开发中注意事项, Dem/Dcm/CanTp/Fim模块配置开发及注意事项,诊断与BswM/NvM关…

OpenAI官方提示词课(五)如何进行文本翻译校正修改

在本篇文章中&#xff0c;我们将探讨如何使用大语言模型进行文本转换任务&#xff0c;例如语言翻译、拼写和语法检查、语气调整和格式转换。 翻译 ChatGPT接受多种语言的训练&#xff0c;使得模型具备翻译能力。以下是如何使用这种能力的一些示例。 prompt f""&q…

利用lambda优化反射功能实现方法调用

最近在思考lambda相关的问题&#xff0c;简单记录下做的相关反射替代和函数映射的尝试。 原理分析 lambda是jdk8才提供的&#xff0c;原理其实就是动态生成内部类来执行函数映射的方法。也就是说一段lambda表达式会对应特定的类方法&#xff0c;之后调用。底层是通过LambdaMe…

《离散数学》:逻辑

〇、前言 离散数学是数学的一个分支&#xff0c;研究离散对象和离散结构的数学理论和方法。这学期学校开了离散数学的课程&#xff0c;我受益颇丰&#xff0c;感觉到了离散数学真正的魅力&#xff0c;也被开创离散数学各个分支的人的聪明与才智深深折服。与连续数学不同&#…

Stopwatch工具类计时器探究

搬砖的我们 特别是Java开发的童鞋们, 经常需要通过记录开始时间和结束时间&#xff0c;然后通过计算差值&#xff0c;得到时间差&#xff0c;如下面的代码&#xff1a; long start System.currentTimeMillis(); long end System.currentTimeMillis(); System.out.println(…