uC-OS2 V2.93 STM32L476 移植:串口打印篇
前言
-
前几篇已经 通过
STM32CubeMX搭建了NUCLEO-L476RG的 STM32L476RG 的 裸机工程,下载了 uC-OS2 V2.93 的源码,并把 uC-OS2 的源文件加入 Keil MDK5 工程,通过适配 Systick 系统定时器与 PendSV 实现任务调度,初步让 uC-OS2 运行起来 -
本篇适配 uC-OS2 的 串口驱动,实现 类似于 printf 的打印功能,让 uC-OS2 有串口运行信息
开发环境
-
win10 64位
-
Keil uVision5,MDK V5.36
-
uC-OS2 V2.93
-
开发板:NUCLEO-L476RG ,MCU 为 STM32L476RG
-
STM32CubeMX 6.9.1,用于生成 STM32的裸机工程
串口驱动
-
通过
STM32CubeMX,已经配置了串口的驱动,默认串口的波特率是 115200 bps,不过没有串口输出的接口,需要自己完善一下 -
新建
uart.c,驱动如下
#include "uart2.h"
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include "stm32l4xx_hal.h"static UART_HandleTypeDef huart2;#define DBG_BUFF_MAX_LEN 256
static char rt_log_buf[DBG_BUFF_MAX_LEN] = { 0 };void uart2_put(const char *fmt)
{HAL_UART_Transmit(&huart2, (uint8_t *)fmt, strlen(fmt), 0xFFFF);
}/* debug print */
int os_printf(const char *fmt, ...)
{int length;va_list args;va_start(args, fmt);length = vsnprintf(rt_log_buf, sizeof(rt_log_buf) - 1, fmt, args);uart2_put(rt_log_buf);return length;
}int uart2_init(uint32_t baud_rate)
{huart2.Instance = USART2;huart2.Init.BaudRate = baud_rate;huart2.Init.WordLength = UART_WORDLENGTH_8B;huart2.Init.StopBits = UART_STOPBITS_1;huart2.Init.Parity = UART_PARITY_NONE;huart2.Init.Mode = UART_MODE_TX_RX;huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;huart2.Init.OverSampling = UART_OVERSAMPLING_16;huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;return HAL_UART_Init(&huart2);
}
-
说明: 这里通过 C 标准库
vsnprintf实现格式化打印,定义一个 全局的 buffer。 -
新建
uart2.h头文件
#ifndef __UART2_H__
#define __UART2_H__#include <stdint.h>int uart2_init(uint32_t baud_rate);
int os_printf(const char *fmt, ...);#endif
main 函数调用
-
首先包含
#include "uart2.h",然后 初始化串口:uart2_init(UART2_BAUD_RATE);,然后就可以使用os_printf格式化打印了 -
格式化打印的意思就是可以像 printf 那样,把一个数值 打印输出 十进制、十六进制等工程,也可以
%s输出一个字符串 -
修改后的 main.c 如下
#include "main.h"
#include "led.h"
#include "app_cfg.h"
#include "os.h"
#include "uart2.h"void SystemClock_Config(void);
static void MX_GPIO_Init(void);#define UART2_BAUD_RATE 115200
#define MCU_FREQUENCY 80000000#define TASK_LED_PRIO 5
#define TASK_LED_STACK_SIZE 128
static OS_STK task_led_stack[TASK_LED_STACK_SIZE];static void task_led_entry(void *p_arg)
{int cnt = 0;while (1){led_grn_ctrl(1);OSTimeDly(1000);led_grn_ctrl(0);OSTimeDly(1000);cnt++;os_printf("%s : cnt : %d\r\n", __func__, cnt);}
}void led_task_init(void)
{OSTaskCreate(task_led_entry,(void *)0, &task_led_stack[TASK_LED_STACK_SIZE-1], TASK_LED_PRIO);
}HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{return HAL_OK;
}/*** @brief The application entry point.* @retval int*/
int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();uart2_init(UART2_BAUD_RATE);os_printf("%s : uC-OS2 Starting...\r\n", __func__);OSInit();led_task_init();OS_CPU_SysTickInitFreq(MCU_FREQUENCY);OSStart();return 0;
}
串口信息
-
编译、烧写到开发板,查看 串口的信息,当前配置的串口波特率是 115200 bps
-
当前串口打印信息正常

小结
-
本篇主要在 uC-OS2 上实现 类似于 printf 的串口格式化打印输出功能,适配串口驱动
-
接下来,继续研究 uC-OS2 上实现串口的 shell 等功能,不断的深入熟悉 uC-OS2 的各个模块
相关文章:
uC-OS2 V2.93 STM32L476 移植:串口打印篇
前言 前几篇已经 通过 STM32CubeMX 搭建了 NUCLEO-L476RG 的 STM32L476RG 的 裸机工程,下载了 uC-OS2 V2.93 的源码,并把 uC-OS2 的源文件加入 Keil MDK5 工程,通过适配 Systick 系统定时器与 PendSV 实现任务调度,初步让 uC-OS2 …...
代码随想录算法训练营第四十六天| 139.单词拆分 背包问题总结
代码随想录算法训练营第四十六天| 139.单词拆分 背包问题总结 一、力扣139.单词拆分 题目链接: 思路:确定dp数组,dp[i]为true表示从0到i切分的字串都在字典中出现过。 确定递推公式,dp[i] 为true要求 s[j, i] 在字典中出现&…...
【机器学习】西瓜书习题3.3Python编程实现对数几率回归
参考代码 结合自己的理解,添加注释。 代码 导入相关的库 import numpy as np import pandas as pd import matplotlib from matplotlib import pyplot as plt from sklearn import linear_model导入数据,进行数据处理和特征工程 # 1.数据处理&#x…...
Blazor前后端框架Known-V1.2.9
V1.2.9 Known是基于C#和Blazor开发的前后端分离快速开发框架,开箱即用,跨平台,一处代码,多处运行。 Gitee: https://gitee.com/known/KnownGithub:https://github.com/known/Known 概述 基于C#和Blazor…...
【3D捏脸功能实现】
文章目录 一、技术方案介绍二、技术核心三、底层技术实现选型进行模型建模编写逻辑代码 四、功能落地五、总结 一、技术方案介绍 3D捏脸功能是一种利用3D技术实现用户自定义头像的功能。通常实现这种功能需要以下技术: 3D建模技术。通过3D建模技术可以创建一个可以…...
Kafka的零拷贝
传统的IO模型 如果要把磁盘中的某个文件发送到远程服务器需要经历以下几个步骤 (1) 从磁盘中读取文件的内容,然后拷贝到内核缓冲区 (2) CPU把内核缓冲区的数据赋值到用户空间的缓冲区 (3) 在用户程序中调用write方法,把用户缓冲区的数据拷贝到内核下面…...
如何使用Python进行数据分析?
Python是一个非常流行的编程语言,也是数据科学家和数据分析师最常用的语言之一。 Python的生态系统非常丰富,有很多强大的库和工具可以用来进行数据分析,如NumPy、Pandas、Matplotlib、SciPy等。 Python教程,8天python从入门到精…...
概率论与数理统计复习总结3
概率论与数理统计复习总结,仅供笔者复习使用,参考教材: 《概率论与数理统计》/ 荣腾中主编. — 第 2 版. 高等教育出版社《2024高途考研数学——概率基础精讲》王喆 概率论与数理统计实际上是两个互补的分支:概率论 在 已知随机…...
PHP正则绕过解析
正则绕过 正则表达式PHP正则回溯PHP中的NULL和false回溯案例案例1案例2 正则表达式 在正则中有许多特殊的字符,不能直接使用,需要使用转义符\。如:$,(,),*,,.,?,[,,^,{。 这里大家会有疑问:为啥小括号(),这个就需要两个来转义&a…...
Hive巡检脚本
Hive巡检脚本的示例: #!/bin/bash# 设置Hive连接信息 HIVE_HOST"your_hive_host" HIVE_PORT"your_hive_port" HIVE_USER"your_hive_username" HIVE_PASSWORD"your_hive_password"# 设置巡检结果输出文件路径 OUTPUT_FILE&…...
【状态估计】基于UKF法、AUKF法的电力系统三相状态估计研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
webpack复习
webpack webpack复习 webpack基本配置 拆分配置 - 公共配置 生产环境配置 开发环境配置 使用merge webpack-dev-server 启动本地服务 在公共中引入babel-loader处理es6 webpack高级配置 多入口文件 enty 入口为一个对象 里面的key为入口名 value为入口文件路径 例如 pa…...
开始学习 Kafka,一文掌握基本概念|Kafka 系列 一
如果你还不了解 Kafka,或者也打算深入探索、系统学习,那么欢迎有同样目标的小伙伴可以加群交流,让学习之路不再孤独。 一个人可能走的很快,但是一群人会走的更远。(后台回复:加群) 点击上方“后…...
Couldn‘t lock the file :/tmp/bbc-filesystem-base_syscache_service
解决方案: 进去带这个目录,然后切换成root用户,将它删除...
vscode 通过mongoose 连接mongodb atlas
了解mongodb 的项目结构 1.代表集群名称 > 2.代表数据库名称>3.代表每个 collection名称 三者范围为从大到小的关系 (一对多)。每个集群有不同的连接地址、用户信息(Database Access)、ip配置信息(Network Acce…...
记录 Vue3 + Ts 类型使用
阅读时长: 10 分钟 本文内容:记录在 Vue3 中使用 ts 时的各种写法. 类型大小写 vue3 ts 项目中,类型一会儿大写一会儿小写。 怎么区分与基础类型使用? String、string、Number、number、Boolean、boolean … 在 js 中, 以 string 与 String…...
主从同步带来的业务问题
目录 一: 目前的业务问题二:如何平衡主从不同步和业务隔离?三:解决方案 一: 目前的业务问题 业务A会跑一些规则, 跑完会把规则结果信息落地(落地到主库), 然后会通过TDM…...
主动带宽控制工具
停机和带宽过度使用是任何组织都无法避免的两个问题。随着企业采用 BYOD 文化,通过网络的流量负载可能很重,导致网络拥塞并使网络容易受到网络攻击。为了解决这个问题,企业需要全面的监控策略来保护网络,当看似大量的流量进入网络…...
数据采集的方法有哪些?
近年来,国家和各大企业都在部署大数据战略。“大数据”这个词也越来越频繁地出现在我们的生活中。当我们在进行网上冲浪时,页面总会跳出我们想要搜索的相关产品或关联事物。大数据,似乎总是能够“算”出我们“心中所想”。那么,大…...
linux重新学习-纪录篇
前言: 正式学习linux的时候,除了那些命令之外,更多的是对于这个系统的重新认知。 linux的身世? 在上世纪90年代,那时候计算机非常的珍贵,配置也很一般般,系统也贵,所以没啥人用,在当…...
Python 如何反向 `enumerate` 遍历枚举
在 Python 中,enumerate() 是一个常用的内置函数,用于在遍历可迭代对象(如列表、元组、字符串等)时同时获取索引和值。但默认情况下,enumerate() 是从前往后遍历的。那么,**如何反向 enumerate 遍历&#x…...
AQS深度探索:以ReentrantLock看Java并发编程的高效实现
在技术领域,我们常常被那些闪耀的、可见的成果所吸引。今天,这个焦点无疑是大语言模型技术。它们的流畅对话、惊人的创造力,让我们得以一窥未来的轮廓。然而,作为在企业一线构建、部署和维护复杂系统的实践者,我们深知…...
何时DCDC预降压+LDO二次线性稳压?
LDO 核心选型分界结论及优化要点核心选型分界结论以LDO输入输出压差ΔV为核心判断指标,结合输出功率、场景约束,通用选型规则如下:通用强制分界点:当ΔV≥2V,且输出功率≥100mW(对应你之前的5V转3V70mA工况…...
CTFshow Misc挑战:从WinRAR到明文攻击的实战解析
1. 初识CTFshow Misc挑战:压缩包破解的奥秘 第一次接触CTFshow的Misc题目时,我被那个看似普通的压缩包难住了整整两天。那是个名为6.zip的文件,用360解压提示需要密码,这种场景在CTF比赛中实在太常见了。很多新手遇到这种情况会直…...
【Python内存管理终极指南】:20年专家实测5大智能策略,90%开发者忽略的GC优化盲区揭晓
第一章:Python智能体内存管理策略对比评测报告全景概览本报告聚焦于当前主流Python智能体(Agent)框架在内存管理层面的设计差异与运行表现,涵盖LangChain、LlamaIndex、AutoGen及自研轻量Agent Runtime四大实现。评测维度包括对象…...
WAN2.2文生视频开源镜像快速上手:ComfyUI界面操作+SDXL Prompt Styler详解
WAN2.2文生视频开源镜像快速上手:ComfyUI界面操作SDXL Prompt Styler详解 想试试用几句话就让AI帮你生成一段视频吗?WAN2.2文生视频开源镜像,结合了强大的ComfyUI界面和SDXL Prompt Styler风格化工具,让这个过程变得直观又简单。…...
ADNS3080光学传感器驱动开发与聚焦校准实战
1. ADNS3080光学运动传感器底层驱动技术解析ADNS3080是Avago(现Broadcom)推出的一款高精度、低功耗CMOS光学运动传感器,专为机械鼠标、轨迹球及工业位移检测等场景设计。其核心优势在于集成化程度高——片内集成了LED驱动电路、图像采集阵列&…...
你在关系里是不是“管太多“?免费控制欲测试,评估你的占有程度
你在关系里是不是"管太多"?免费控制欲测试,评估你的占有程度 引言 你是否总是想知道伴侣在哪里、和谁在一起?是否经常查看对方的手机或社交账号?是否对伴侣和异性接触特别敏感? 还是你常常因为对方的某些…...
RevokeMsgPatcher 2.1终极指南:一键实现微信QQ防撤回的完整教程
RevokeMsgPatcher 2.1终极指南:一键实现微信QQ防撤回的完整教程 【免费下载链接】RevokeMsgPatcher :trollface: A hex editor for WeChat/QQ/TIM - PC版微信/QQ/TIM防撤回补丁(我已经看到了,撤回也没用了) 项目地址: https://g…...
IP被封禁?5招快速恢复访问权限
使用网站或平台时,如果你突然遇到“Your IP has been banned(您的IP已被封禁)”的提示,通常意味着该平台已经限制了你当前网络的访问权限。很多人第一反应是账号出问题,但实际上,IP封禁针对的是网络环境&am…...
