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

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

文章目录

  • 前言
  • 一、cubemx配置
  • 二、board.c文件修改
    • 2.rtconfig.h文件修改
  • 三、主程序
    • 1. main函数
    • 2. task函数
  • 总结


前言

利用RT_Thread操作系统实现三种不同的LED等闪烁


提示:以下是本篇文章正文内容,下面案例可供参考

一、cubemx配置

cubemx配置参考教程:
基于 CubeMX 移植 RT-Thread Nano
后面程序所需的引脚
在这里插入图片描述

二、board.c文件修改

/** Copyright (c) 2006-2019, RT-Thread Development Team** SPDX-License-Identifier: Apache-2.0** Change Logs:* Date           Author       Notes* 2021-05-24                  the first version*/#include <rthw.h>
#include <rtthread.h>#include "main.h"
#include "usart.h"// 使用cubemx产生的MX_USART1_UART_Init()
#include "gpio.h" // 使用cubemx产生的MX_GPIO_Init()#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
/** Please modify RT_HEAP_SIZE if you enable RT_USING_HEAP* the RT_HEAP_SIZE max value = (sram size - ZI size), 1024 means 1024 bytes*/
#define RT_HEAP_SIZE (15*1024)
static rt_uint8_t rt_heap[RT_HEAP_SIZE];RT_WEAK void *rt_heap_begin_get(void)
{return rt_heap;
}RT_WEAK void *rt_heap_end_get(void)
{return rt_heap + RT_HEAP_SIZE;
}
#endifvoid SysTick_Handler(void)
{rt_interrupt_enter();rt_tick_increase();rt_interrupt_leave();
}/*** This function will initial your board.*/
void rt_hw_board_init(void)
{extern void SystemClock_Config(void);HAL_Init();SystemClock_Config();SystemCoreClockUpdate();/* * 1: OS Tick Configuration* Enable the hardware timer and call the rt_os_tick_callback function* periodically with the frequency RT_TICK_PER_SECOND. */HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/RT_TICK_PER_SECOND);/* Call components board initial (use INIT_BOARD_EXPORT()) */MX_GPIO_Init();//【增加】#ifdef RT_USING_COMPONENTS_INITrt_components_board_init();
#endif#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
#endif
}#ifdef RT_USING_CONSOLEstatic UART_HandleTypeDef UartHandle;
static int uart_init(void)
{/* TODO: Please modify the UART port number according to your needs */UartHandle.Instance = USART1;//【修改为USART1】UartHandle.Init.BaudRate = 115200;UartHandle.Init.WordLength = UART_WORDLENGTH_8B;UartHandle.Init.StopBits = UART_STOPBITS_1;UartHandle.Init.Parity = UART_PARITY_NONE;UartHandle.Init.Mode = UART_MODE_TX_RX;UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;if (HAL_UART_Init(&UartHandle) != HAL_OK){while (1);}return 0;
}
INIT_BOARD_EXPORT(uart_init);void rt_hw_console_output(const char *str)
{rt_size_t i = 0, size = 0;char a = '\r';__HAL_UNLOCK(&UartHandle);size = rt_strlen(str);for (i = 0; i < size; i++){if (*(str + i) == '\n'){HAL_UART_Transmit(&UartHandle, (uint8_t *)&a, 1, 1);}HAL_UART_Transmit(&UartHandle, (uint8_t *)(str + i), 1, 1);}
}
#endif#ifdef RT_USING_FINSH
char rt_hw_console_getchar(void)
{/* Note: the initial value of ch must < 0 */int ch = -1;if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_RXNE) != RESET){ch = UartHandle.Instance->DR & 0xff;}else{rt_thread_mdelay(10);}return ch;
}
#endif

2.rtconfig.h文件修改

RT-Thread Nano 的配置在 rtconfig.h 中进行,通过开关宏定义来使能或关闭某些功能,接下来对该配置文件中的宏定义进行说明。


/* RT-Thread config file */#ifndef __RTTHREAD_CFG_H__
#define __RTTHREAD_CFG_H__// <<< Use Configuration Wizard in Context Menu >>>
// <h>Basic Configuration
// <o>Maximal level of thread priority <8-256>
//  <i>Default: 32
#define RT_THREAD_PRIORITY_MAX 32// <o>OS tick per second
//  <i>Default: 1000   (1ms)
#define RT_TICK_PER_SECOND 1000// <o>Alignment size for CPU architecture data access
//  <i>Default: 4
#define RT_ALIGN_SIZE 4// <o>the max length of object name<2-16>
//  <i>Default: 8
#define RT_NAME_MAX 8// <c1>Using RT-Thread components initialization
//  <i>Using RT-Thread components initialization
#define RT_USING_COMPONENTS_INIT
// </c>// <c1>Using user main
//  <i>Using user main
#define RT_USING_USER_MAIN
// </c>// <o>the size of main thread<1-4086>
//  <i>Default: 512
#define RT_MAIN_THREAD_STACK_SIZE 1024
// </h>// <h>Debug Configuration
// <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>// <h>Hook Configuration
// <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>// <h>Software timers Configuration
// <c1> Enables user timers
// <i> Enables user timers
//#define RT_USING_TIMER_SOFT
// </c>// <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
// </h>// <h>IPC(Inter-process communication) Configuration
// <c1>Using Semaphore
//  <i>Using Semaphore
#define RT_USING_SEMAPHORE
// </c>// <c1>Using Mutex
//  <i>Using Mutex
//#define RT_USING_MUTEX
// </c>// <c1>Using Event
//  <i>Using Event
//#define RT_USING_EVENT
// </c>// <c1>Using MailBox
//  <i>Using MailBox
//#define RT_USING_MAILBOX
// </c>// <c1>Using Message Queue
//  <i>Using Message Queue
//#define RT_USING_MESSAGEQUEUE
// </c>
// </h>// <h>Memory Management Configuration
// <c1>Using Mempool Management
//  <i>Using Mempool Management
//#define RT_USING_MEMPOOL
// </c>
// <c1>Dynamic Heap Management
//  <i>Dynamic Heap Management
#define RT_USING_HEAP//是否使用 内存堆
// </c>
// <c1>using small memory
//  <i>using small memory
#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>// <h>Console Configuration
// <c1>Using console
//  <i>Using console
#define RT_USING_CONSOLE
// </c>// <o>the buffer size of console <1-1024>
//  <i>the buffer size of console
//  <i>Default: 128  (128Byte)
#define RT_CONSOLEBUF_SIZE 128
// </h>// <h>Enable FinSH Configuration
// <c1>include shell config
//  <i> Select this choice if you using FinSH
//当系统加入 FinSH 组件源码后,需要在 rtconfig.h 中开启以下项
#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

三、主程序

1. main函数

/* USER CODE BEGIN Header */
/********************************************************************************* @file           : main.c* @brief          : Main program body******************************************************************************* @attention** Copyright (c) 2023 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usart.h"
#include "gpio.h"
#include <rtthread.h>/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes *//* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV */
/* 栈空间地址对齐 */
ALIGN( RT_ALIGN_SIZE )
/* 定义一个数组,栈的空间大小就是1024*8字节 */
rt_uint8_t rt_led1_thread_stack[1024];
/* 初始化线程栈 */
struct rt_thread rt_led1_thread;rt_uint8_t rt_led2_thread_stack[1024];
/* 定义线程控制块指针 */
rt_thread_t rt_led2_thread = RT_NULL;/* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */void led1_thread_entry(void *parameter)
{while(1){HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);rt_thread_mdelay(1000);}
}void led2_thread_entry(void *parameter)
{while(1){HAL_GPIO_TogglePin(LED2_GPIO_Port,LED2_Pin);rt_thread_mdelay(100);}
} /* USER CODE END 0 *//*** @brief  The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */
//  SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 *//**************************** 静态创建 **************************************/rt_err_t rst_led1;rst_led1 = rt_thread_init(&rt_led1_thread,"led1line",led1_thread_entry,RT_NULL,&rt_led1_thread_stack[0],sizeof(rt_led1_thread_stack),RT_THREAD_PRIORITY_MAX-2,20);if(rst_led1 == RT_EOK){rt_thread_startup(&rt_led1_thread);}/***************************** 动态创建 ******************************************/rt_led2_thread = rt_thread_create( "led2line",led2_thread_entry,RT_NULL,sizeof(rt_led2_thread_stack),RT_THREAD_PRIORITY_MAX-3,20);if( rt_led2_thread != RT_NULL )/* rt_thread_startup() 的形参是一个线程控制块指针,动态创建线程时返回的就是线程控制块指针,所以直接传入即可 */rt_thread_startup( rt_led2_thread );elsereturn -1;							/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */rt_thread_mdelay(1000);}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK){Error_Handler();}
}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//*** @brief  This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef  USE_FULL_ASSERT
/*** @brief  Reports the name of the source file and the source line number*         where the assert_param error has occurred.* @param  file: pointer to the source file name* @param  line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

2. task函数

#include "main.h"
#include "rtthread.h"
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>#define THREAD1_PRIORITY  27    
#define THREAD_STACK_SIZE 512  
#define THREAD_TIMESLICE  5    ALIGN(RT_ALIGN_SIZE)
rt_thread_t result = RT_NULL;static void rt_led1_flash_entry(void *parameter)
{while(1){HAL_GPIO_WritePin(LED3_GPIO_Port,LED3_Pin,GPIO_PIN_SET);rt_thread_mdelay(500);HAL_GPIO_WritePin(LED3_GPIO_Port,LED3_Pin,GPIO_PIN_RESET);rt_thread_mdelay(500);}
}int rt_user_thread_entry(void)
{result = rt_thread_create("led3line", rt_led1_flash_entry,NULL,THREAD_STACK_SIZE,THREAD1_PRIORITY,THREAD_TIMESLICE);if (result != RT_NULL) {rt_thread_startup(result);}else{LOG_D("can not create LED thread!");return -1;}}
INIT_APP_EXPORT(rt_user_thread_entry);

总结

以上便是基于 CubeMX 移植 RT-Thread Nano,然后实现3个不同LED灯的闪烁的程序

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

常见的旅游类软文类型分享

假期将至&#xff0c;越来越多人选择出门旅游度过假期&#xff0c;那么各大旅游品牌应该怎么让自己的旅游软文在众多品牌中脱颖而出呢&#xff1f;接下来媒介盒子就给大家分享几个最能吸引受众的旅游类型软文。 一、攻略类软文 和普通的攻略不一样&#xff0c;普通的攻略以用户…

Python函数的概念以及定义方式

一. 前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 二. 什么是函数&#xff1f; 假设你现在是一个工人&#xff0c;如果你实现就准备好了工具&#xff0c;等你接收到任务的时候&#xff0c; 直接带上工…

LeetCode141:环形链表

给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置&#xff08;…

数学建模:回归分析

&#x1f506; 文章首发于我的个人博客&#xff1a;欢迎大佬们来逛逛 数学建模&#xff1a;回归分析 文章目录 数学建模&#xff1a;回归分析回归分析多元线性回归案例 多项式回归一元多项式回归多元二项式回归 非线性回归逐步回归 回归分析 多元线性回归 案例 首先进行回归分…

无涯教程-Flutter - Dart简介

Dart是一种开源通用编程语言&#xff0c;它最初是由Google开发的&#xff0c; Dart是一种具有C样式语法的面向对象的语言&#xff0c;它支持诸如接口&#xff0c;类之类的编程概念&#xff0c;与其他编程语言不同&#xff0c;Dart不支持数组&#xff0c; Dart集合可用于复制数据…

【Github】git本地仓库建立与远程连接

文章目录 前言一、git简介二、git下载2.1下载地址 三、git安装3.1安装3.2 配置3.3 config设置&#xff08;增删改查&#xff09; 四.github与git连接——本地Git仓库4.1 建本地的版本库4.2 源代码放入本地仓库4.3提交仓库 五、github与git的连接——远程连接5.1 创建SSH Key5.2…

网络地址转换技术NAT(第九课)

一 什么是NAT? NAT是网络地址转换的缩写,是一种在计算机网络中使用的技术,可以将私有地址转换为公共地址,从而实现本地网络与公共网络的互联。NAT工作在网络层,可以隐藏内部网络中的IP地址和端口号,从而增强网络的安全性和灵活性。在家庭网络、企业网络、公共WIFI热点等…

虹科方案|HK-Edgility利用边缘计算和VNF降本增效

一、边缘计算和 VNF 在当今瞬息万变的数字环境中&#xff0c;边缘虚拟化网络功能&#xff08;VNF&#xff09;是一个既能够优化网络基础设施&#xff0c;又能控制成本的创新型解决方案。它使客户能够将多个基于软件的 VNF 整合到一个专用计算设备上。更值得高兴的是&#xff0c…

模型压缩-对模型结构进行优化

模型压缩-对模型结构进行优化 概述 模型压缩通常都是对推断过程而言&#xff0c;训练过程的计算代价通常不考虑&#xff0c;因为GPU可以快速完成任意复杂度模型的训练对于推断过程来说&#xff0c;模型应用才是对于速度敏感的场景多数情况下 希望使用尽可能少的能耗完成京可能…

SpringBoot——整合Mongodb

简单介绍 Mongdb是一个开源&#xff0c;高性能&#xff0c;无模式的文档型数据库&#xff0c;NoSQL数据库产品中的一种&#xff0c;是最像关系型数据库的非关系型数据库。 使用场景 用户数据 存储位置&#xff1a;数据库特征&#xff1a;永久性存储&#xff0c;修改频率极低游…

蠕虫病毒流量分析案例

背景 某供排水集团的网络管理员对其网络的健康状况持认可态度&#xff0c;表示网络运行正常&#xff0c;没有发现异常行为。然而&#xff0c;由于网络环境变得越来越复杂&#xff0c;仅凭借传统的网络经验已经不能全面了解网络情况。因此&#xff0c;我们为供排水集团安装了Ne…

【实训】“宅急送”订餐管理系统(程序设计综合能力实训)

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 前言 大一小学期&#xff0c;我迎来了人生中的第一次实训…

LNMP架构搭建论坛

目录 一、LNMP简介&#xff1a; 二、LNMP搭建&#xff1a; 1.前提准备&#xff1a; 关闭防火墙和安全机制&#xff1a; 2.编译安装nginx&#xff1a; 3.编译安装mysql&#xff1a; 3.1 安装依赖环境&#xff1a; 3.2 创建mysql运行用户&#xff1a; 3.3 编译安装&#xff1a…

神经网络与强化学习:揭示AI的超能力

文章目录 神经网络&#xff1a;模拟人脑的工具强化学习&#xff1a;通过试错学习结合神经网络和强化学习价值网络策略网络结合训练 应用领域游戏机器人控制金融交易 未来趋势自动化和自主系统个性化和自适应系统跨学科研究 结论 &#x1f389;欢迎来到AIGC人工智能专栏~神经网络…

msvcp110.dll是什么意思与msvcp110.dll丢失的解决方法

电脑突然提示msvcp110.dll丢失&#xff0c;无法执行此代码。导致软件无法打开运行&#xff0c;这个怎么办呢&#xff1f;我在网上找了一天的资料&#xff0c;终于把这个问题彻底处理好&#xff0c;也弄清楚了msvcp110.dll丢失的原因及msvcp110.dll丢失修复方法&#xff1f;现在…

LDAP服务器如何重启

1、find / -name ldap 该命令只会从根路径下查看ldap文件夹 find / -name ldap2、该命令会从根路径/查看所有包含ldap路径的文件夹&#xff0c;会查询出所有&#xff0c;相当于全局查询 find / -name *ldap*2、启动OpenLADP 找到LDAP安装目录后&#xff0c;执行以下命令 #直…

pytorch搭建squeezenet网络的整套工程,及其转tensorrt进行cuda加速

本来&#xff0c;前辈们用caffe搭建了一个squeezenet的工程&#xff0c;用起来也还行&#xff0c;但考虑到caffe的停更后续转trt应用在工程上时可能会有版本的问题所以搭建了一个pytorch版本的。 以下的环境搭建不再细说&#xff0c;主要就是pyorch&#xff0c;其余的需要什么p…

ABAP BAPI_ACC_DOCUMENT_POST 中 EXTENSION1的用法

BAPI_ACC_DOCUMENT_POST 在过账会计凭证时候&#xff0c;经常会发现一些标准字段在参数中并没有 可以通过CMOD/SMOD增强出口--》ACBAPI01--》EXIT_SAPLACC4_001--》ZXACCU15 示例代码&#xff1a; DATA: wa_extension TYPE bapiextc,it_extension TYPE STANDARD TABLE OF ba…

OpenCV(二十一):椒盐噪声和高斯噪声的产生

目录 1.图像噪声介绍 2.椒盐噪声的产生 3.高斯噪声的产生 1.图像噪声介绍 噪声介绍 图像噪声是指在图像中存在的不期望的、随机的像素值变化&#xff0c;这些变化来源于多种因素。噪声可能导致图像细节模糊、失真或难以分辨。 以下是几种常见的图像噪声类型&#xff1a; 1…

javascritp如何判断是从刷新(重新加载)、正常打开(或链接打开)、还是从浏览器回退进入页面的

重点先下另外一个知识点&#xff1a; 当我们的Web站点采用主体页面的iframe导航各个子页面&#xff08;浏览器地址保持不变&#xff09;的情况&#xff0c;如果我们希望每次iframe中打开的新的子页面&#xff0c;也都能够像在不采用iframe的情况那样&#xff0c;后续能够在浏览…