FreeRTOS qemu mps2-an385 bsp 移植制作 :串口打印篇

news2024/11/17 7:43:20

相关文章

FreeRTOS qemu mps2-an385 bsp 移植制作 :环境搭建篇

FreeRTOS qemu mps2-an385 bsp 移植制作 :系统启动篇

FreeRTOS qemu mps2-an385 bsp 移植制作 :系统运行篇

开发环境

  • Win10 64位 + VS Code,ssh 远程连接 ubuntu

  • VMware Workstation Pro 16 + Ubuntu 20.04

  • FreeRTOSv202212.01(备注:可以在 github 获取最新版本)

  • qemu qemu-system-arm mps2-an385 开发板,qemu 版本 QEMU emulator version 4.2.1 或更高

  • arm gcc 交叉编译工具链:当前使用 gcc 编译环境, gcc-arm-11.2-2022.02-x86_64-arm-none-eabi, gcc version 11.2.1 20220111

前言

  • 前面的 FreeRTOS qemu mps2-an385 bsp 移植制作 :环境搭建篇 大体讲了一下环境搭建,初步配置了工程目录

  • FreeRTOS qemu mps2-an385 bsp 移植制作 :系统启动篇 配置了 VS Code gdb 调试环境,初步让MCU 启动,进入了启动入口函数

FreeRTOS qemu mps2-an385 bsp 移植制作 :系统运行篇 实现了 FreeRTOS 的运行,创建一个task 并成功运行

  • 本篇继续优化,增加串口驱动,让系统运行时打印串口信息

串口驱动

  • qemu mps2-an385 的串口驱动相对简单,当前串口打印只需要关心串口的输出,串口的中断输入,待后续增加 shell 终端功能时再处理

  • 创建 qemu_mps2/driver/drv_uart.c,内容如下:

#include <stdint.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>

#include "drv_uart.h"
#include "CMSDK_CM3.h"

#define DBG_BUFF_MAX_LEN    256
static char rt_log_buf[DBG_BUFF_MAX_LEN] = { 0 };

/* qemu uart dirver class */
struct uart_instance
{
    const char *name;
    CMSDK_UART_TypeDef *handle;
    IRQn_Type irq_num;
    int uart_index;
};

static struct uart_instance uart0_handle = { 0 };

static void uart_putc(uint8_t c)
{
    uart0_handle.handle->DATA = c;
}

static int serial_put(const char *data, int length)
{
    int size;

    size = length;
    while (length)
    {
        uart_putc(*data);
        ++ data;
        -- length;
    }

    return size - length;
}

/* 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);

    serial_put(rt_log_buf, length);
    return length;
}

void UART0RX_Handler(void)
{
    uint32_t irq_status = 0x00;
    irq_status = uart0_handle.handle->INTCLEAR;
    uart0_handle.handle->INTCLEAR = irq_status;
}

int uart_init(void)
{
    uart0_handle.handle = CMSDK_UART0;
    uart0_handle.uart_index = UART0RX_IRQn;
    uart0_handle.name = "uart0";

    uart0_handle.handle->BAUDDIV = 16; /* 115200bps */
    uart0_handle.handle->CTRL = CMSDK_UART_CTRL_RXIRQEN_Msk | CMSDK_UART_CTRL_RXEN_Msk | CMSDK_UART_CTRL_TXEN_Msk;
    NVIC_EnableIRQ(uart0_handle.irq_num);
    uart0_handle.handle->STATE = 0;

    return 0;
}
  • 这里借助 C 库 函数 vsnprintf,实现格式化输出,实现比较的简单,类似于 printf 功能

  • 创建 qemu_mps2/driver/drv_uart.h 串口头文件

#ifndef __DRV_UART_H__
#define __DRV_UART_H__

#include <stdint.h>

int uart_init(void);
int os_printf(const char *fmt, ...);

#endif //__DRV_UART_H__

修改 main.c 增加串口打印

  • qemu_mps2/application/main.c 中,再创建一个 task,注意 栈空间可以适当的加大,防止栈溢出引发异常
#include "FreeRTOS.h"
#include "task.h"

#include <stdio.h>
#include <string.h>

#include "drv_uart.h"

#define TASK_TEST_PRIORITY      (tskIDLE_PRIORITY + 6)
#define TASK_TEST2_PRIORITY     (tskIDLE_PRIORITY + 8)

static void task_test_entry(void *pvParameters)
{
    uint32_t cnt = 0;

    os_printf("%s : enter\r\n", __func__);
    while (1)
    {
        vTaskDelay(1000);
        os_printf("%s : cnt %d\r\n", __func__, cnt++);
    }
}

static void task_test2_entry(void *pvParameters)
{
    uint32_t cnt = 0;

    os_printf("%s : enter\r\n", __func__);
    while (1)
    {
        vTaskDelay(2000);
        os_printf("%s : cnt %d\r\n", __func__, cnt++);
    }
}

void main( void )
{
    uart_init();
    os_printf("%s : enter\r\n", __func__);
    xTaskCreate(task_test_entry, "task_test", 512, NULL, TASK_TEST_PRIORITY, NULL);
    xTaskCreate(task_test2_entry, "task_test2", 512, NULL, TASK_TEST2_PRIORITY, NULL);
    vTaskStartScheduler();
    for( ;; );
}
  • 串口输出信息

在这里插入图片描述

  • 串口输出正常,两个任务轮流输出

小结

  • 本篇主要实现 qemu mps2-an385 的串口输出打印功能,借助 C 库函数简单实现

  • 后续可以增加串口的 shell 终端功能,到时候会利用起来串口的接收处理

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

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

相关文章

小样本UIE 信息抽取微调快速上手(不含doccona标注)

文章目录 1.安装环境&#xff08;可略过&#xff09;2.模型简介&#xff08;略读&#xff09;抽取任务输入输出示例&#xff1a;1.实体识别2.关系抽取 3.快速上手(主菜)&#xff08;1&#xff09;转换数据标注数据样例 &#xff08;2&#xff09;生成训练数据训练数据样例 &…

【刷题笔记8.17】LeetCode:下一个排列

LeetCode&#xff1a;下一个排列 题目描述 整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。 例如&#xff0c;arr [1,2,3] &#xff0c;以下这些都可以视作 arr 的排列&#xff1a;[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。 整数数组的 下一个排列 是指其整数的…

Java调用https接口添加证书

使用InstallCert.Java生成证书 /** Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.** Redistribution and use in source and binary forms, with or without* modification, are permitted provided that the following conditions* are met:** - Redistri…

Druid 德鲁伊 | 安装、使用指南

Druid安装指南 1. druid简介1.1数据库连接池 2. 安装前的环境准备3. 安装步骤3.1 引入maven依赖3.1 编写配置文件3.3 启动Druid Monitor 4. druid使用指南4.1 数据源4.2 SQL监控4.3 SQL防火墙4.4 web应用4.5 URI监控 1. druid简介 druid是阿里开源的一个数据库连接池的解决方案…

【Unity】按Esc进入操作菜单

本文章是基于如下视频的自我总结 https://www.youtube.com/watch?vJivuXdrIHK0 步骤如下 1、在Canvas 界面添加一个Panel Panel中添加一个按钮&#xff0c;调整按钮的大小为合适大小 调整字体的大小为合适大小 可以为字体添加Shadow组件&#xff0c;产生阴影效果 2、调整按…

【IMX6ULL驱动开发学习】05.字符设备驱动开发模板(包括读写函数、poll机制、异步通知、定时器、中断、自动创建设备节点和环形缓冲区)

一、 字符设备驱动简介 字符设备是Linux驱动中最基本的一类设备驱动&#xff0c;字符设备就是一个一个字节&#xff0c;按照字节流进行读写操作的设备&#xff0c;读写数据是分先后顺序的。比如常见的点灯、按键、IIC、SPI、LCD 等等都是字符设备&#xff0c;这些设备的驱动就叫…

Linux 常见问题解决思路

Linux 常见问题解决思路 CPU 高系统平均负载高&#xff08;load average&#xff09; CPU 高 1&#xff0c;步骤&#xff1a;查找进程-》查找线程-》分析threadDump日志-》找出问题代码 a、查看 cpu 高的 java 进程 topb、生成进程下所有线程的栈日志 jstack 1721 > 1712.…

Python入门【TCP建立连接的三次握手、 TCP断开连接的四次挥手、套接字编程实战、 TCP编程的实现、TCP双向持续通信】(二十七)

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱敲代码的小王&#xff0c;CSDN博客博主,Python小白 &#x1f4d5;系列专栏&#xff1a;python入门到实战、Python爬虫开发、Python办公自动化、Python数据分析、Python前后端开发 &#x1f4e7;如果文章知识点有错误…

ant-design-vue在ios使用AUpload组件唤起了相机,HTML的 `capture` 属性

在使用ant design vue组件的上传组件AUpload的时候有一个问题&#xff0c;直接按照demo写&#xff0c;在ios上会唤起相机&#xff0c;但是实际上我们的需求是弹出选择相册/相机这个弹框。 解决办法是加一个 cupture"null"这个属性即可 <a-upload:capture"nu…

电压放大器的作用有哪些呢

电压放大器是一种基础的电子元件&#xff0c;它能够将输入电压信号转化为更高的输出电压信号&#xff0c;从而实现对信号的放大和处理。电压放大器广泛应用于各个领域&#xff0c;如通讯、控制、测量等。下面我们来详细了解一下电压放大器的作用。 一、信号放大 电压放大器最主…

selenium语法进阶+常用API

目录 浏览器操作 浏览器回退&#xff0c;前进 与刷新 浏览器窗口设置大小 浏览器设置宽高 浏览器窗口最大化 浏览器控制滚动条 信息打印 打印页面的标题和当前页面的URL 定位一组元素 鼠标和键盘事件 键盘 鼠标 下拉框操作 通过索引定位&#xff08;se…

Vue-8.集成(.editorconfig、.eslintrc.js、.prettierrc)

介绍 同时使用 .editorconfig、.prettierrc 和 .eslintrc.js 是很常见的做法&#xff0c;因为它们可以在不同层面上帮助确保代码的格式一致性和质量。这种组合可以在开发过程中提供全面的代码维护和质量保证。然而&#xff0c;这也可能增加一些复杂性&#xff0c;需要谨慎配置…

详细记录在迅为iMX6开发板中运行可执行文件

本文主要为了记录通过在虚拟机Ubuntu系统编译生成的可执行文件canitf如何运行在迅为的iMX6开发板上&#xff0c;中间涉及到的一些操作相对来说比较固定&#xff0c;因此可以整理成参考步骤以便之后使用时来依照执行。 一、生成可执行文件 首先在Ubuntu系统对应目录终端运行如…

7-11 到底是不是太胖了

分数 10 全屏浏览题目 切换布局 作者 陈越 单位 浙江大学 据说一个人的标准体重应该是其身高&#xff08;单位&#xff1a;厘米&#xff09;减去100、再乘以0.9所得到的公斤数。真实体重与标准体重误差在10%以内都是完美身材&#xff08;即 | 真实体重 − 标准体重 | < 标…

【深入了解PyTorch】PyTorch模型解释性和可解释性:探索决策过程与预测结果的奥秘

【深入了解PyTorch】PyTorch模型解释性和可解释性:探索决策过程与预测结果的奥秘 PyTorch模型解释性和可解释性:探索决策过程与预测结果的奥秘1. 引言2. 梯度可视化3. 特征重要性分析4. 结论PyTorch模型解释性和可解释性:探索决策过程与预测结果的奥秘 在机器学习和深度学习…

哈夫曼树(赫夫曼树、最优树)详解

目录 哈夫曼树&#xff08;赫夫曼树、最优树&#xff09;详解 哈夫曼树相关的几个名词 什么是哈夫曼树 构建哈夫曼树的过程 哈弗曼树中结点结构 构建哈弗曼树的算法实现 哈夫曼树&#xff08;赫夫曼树、最优树&#xff09;详解 哈夫曼树相关的几个名词 路径&#xff1a;…

“西游记“中的项目管理:如何驾驭你的“取经之路”

​1.​引言 自古以来&#xff0c;文学作品不仅仅是为了娱乐&#xff0c;它们也为我们提供了生活的智慧和经验。中国的古典文学巨著《西游记》便是其中的佼佼者&#xff0c;其中的故事和角色为我们提供了丰富的人生哲理和管理智慧。但你可能会问&#xff0c;一个古老的神话故事…

Windows11 Docker Desktop 启动 -wsl kernel version too low

系统环境&#xff1a;windows11 1&#xff1a;docker下载 Docker: Accelerated Container Application Development 下载后双击安装即可 安装后启动Docker提示&#xff1a;Docker Desktop -wsl kernel version too low 处理起来也是非常方便 1:管理员身份启动&#xff1a;…

Python 处理 Excel 表格的 14 个常用操作

目录 1. 安装依赖库 2. 导入库 3. 读取Excel文件 4. 写入Excel文件 5. 创建工作表 6. 访问工作表 7. 读取单元格数据 8. 写入单元格数据 9. 获取行数和列数 10. 过滤数据 11. 排序数据 12. 添加新行 13. 删除行或列 14. 计算汇总统计 总结 无论是数据分析师、财…

CoordAtt注意力网络结构

源码&#xff1a; import torch import torch.nn as nn import math import torch.nn.functional as Fclass h_sigmoid(nn.Module):def __init__(self, inplaceTrue):super(h_sigmoid, self).__init__()self.relu nn.ReLU6(inplaceinplace)def forward(self, x):return self.…