RT-Thread 2. GD32在 RT-Thread Nano上添加控制台与 FinSH

news2024/11/19 8:40:07

本篇文档分为两部分:

第一部分是添加 UART 控制台(实现打印):用来向控制台对接的终端输出打印信息;该部分只需要实现两个函数,串口初始化和系统输出函数,即可完成 UART 控制台打印功能。
第二部分是移植 FinSH 组件(实现命令输入),用以在控制台输入命令调试系统;该部分的实现基于第一部分,只需要添加 FinSH 组件源码并再对接一个系统输入函数即可实现。

1. 在 Nano 上添加 UART 控制台(实现打印)

1)代码

使用串口1作为控制台输出串口

方法一:默认使用宏 INIT_BOARD_EXPORT() 进行自动初始化,不需要显式调用,如下所示。
方法二:可以使用显式调用:uart_init() 需要在 board.c 中的 rt_hw_board_init() 函数中调用。

//main.c 实现串口初始化、rt_hw_console_output
#include "gd32f3x0.h"
#include "gd32f330c_start.h"
#include "systick.h"
#include <rtthread.h>

#define delay_ms(x)   rt_thread_mdelay(x)

/*!
    \brief      configure the USART0 GPIO ports
    \param[in]  none
    \param[out] none
    \retval     none
*/
void usart1_gpio_config(void)
{
    /* enable COM GPIO clock */
    rcu_periph_clock_enable(RCU_GPIOA);

    /* connect port to USARTx_Tx */
    gpio_af_set(GPIOA, GPIO_AF_4, GPIO_PIN_8);

    /* connect port to USARTx_Rx */
    gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_15);

    /* configure USART Tx as alternate function push-pull */
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_8);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_8);

    /* configure USART Rx as alternate function push-pull */
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_15);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_15);
}

/*!
    \brief      configure the USART0
    \param[in]  none
    \param[out] none
    \retval     none
*/
void usart1_config(void)
{
    /* enable USART clock */
    rcu_periph_clock_enable(RCU_USART1);

    /* USART configure */
    usart_deinit(USART1);
    usart_word_length_set(USART1, USART_WL_8BIT);
    usart_stop_bit_set(USART1, USART_STB_1BIT);
    usart_parity_config(USART1, USART_PM_NONE);
    usart_baudrate_set(USART1, 115200U);
    usart_receive_config(USART1, USART_RECEIVE_ENABLE);
    usart_transmit_config(USART1, USART_TRANSMIT_ENABLE);

    usart_enable(USART1);
}

void uart1_init(void)
{
  usart1_gpio_config();
  usart1_config();
}

void rt_hw_console_output(const char *str)
{
    rt_size_t i = 0, size = 0;
    char a = '\r';

    size = rt_strlen(str);
    for (i = 0; i < size; i++)
    {
        if (*(str + i) == '\n')
        {
            usart_data_transmit(USART1, a);
          while(RESET == usart_flag_get(USART1,USART_FLAG_TBE));
        }
        usart_data_transmit(USART1, *(str + i));
          while(RESET == usart_flag_get(USART1,USART_FLAG_TBE));
    }  
  
}


/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/

int main(void)
{
  
    /* enable the LED GPIO clock */
    rcu_periph_clock_enable(RCU_GPIOB);
    /* configure led GPIO port */ 
    gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_1);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_1);
    
    gpio_bit_set(GPIOB, GPIO_PIN_1);
    
    while(1){
        /* turn on led1 */
        gpio_bit_write(GPIOB, GPIO_PIN_1, RESET);
        rt_kprintf("Hello\n");
        delay_ms(1000);
        
        /* turn off led1 */
        gpio_bit_write(GPIOB, GPIO_PIN_1, SET);
        delay_ms(1000);
    }
}
Note

注:注意:RT-Thread 系统中已有的打印均以 \n 结尾,而并非 \r\n,所以在字符输出时,需要在输出 \n 之前输出 \r,完成回车与换行,否则系统打印出来的信息将只有换行。

//board.c 在 board.c 中的 rt_hw_board_init() 函数中调用
/*
 * Copyright (c) 2006-2019, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2017-07-24     Tanek        the first version
 * 2018-11-12     Ernest Chen  modify copyright
 */
 
#include <stdint.h>
#include <rthw.h>
#include <rtthread.h>

#define _SCB_BASE       (0xE000E010UL)
#define _SYSTICK_CTRL   (*(rt_uint32_t *)(_SCB_BASE + 0x0))
#define _SYSTICK_LOAD   (*(rt_uint32_t *)(_SCB_BASE + 0x4))
#define _SYSTICK_VAL    (*(rt_uint32_t *)(_SCB_BASE + 0x8))
#define _SYSTICK_CALIB  (*(rt_uint32_t *)(_SCB_BASE + 0xC))
#define _SYSTICK_PRI    (*(rt_uint8_t  *)(0xE000ED23UL))

void uart1_init(void);

// Updates the variable SystemCoreClock and must be called 
// whenever the core clock is changed during program execution.
extern void SystemCoreClockUpdate(void);

// Holds the system core clock, which is the system clock 
// frequency supplied to the SysTick timer and the processor 
// core clock.
extern uint32_t SystemCoreClock;

static uint32_t _SysTick_Config(rt_uint32_t ticks)
{
    if ((ticks - 1) > 0xFFFFFF)
    {
        return 1;
    }
    
    _SYSTICK_LOAD = ticks - 1; 
    _SYSTICK_PRI = 0xFF;
    _SYSTICK_VAL  = 0;
    _SYSTICK_CTRL = 0x07;  
    
    return 0;
}

#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
#define RT_HEAP_SIZE 1024
static uint32_t rt_heap[RT_HEAP_SIZE];     // heap default size: 4K(1024 * 4)
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;
}
#endif

/**
 * This function will initial your board.
 */
void rt_hw_board_init()
{
    /* System Clock Update */
    SystemCoreClockUpdate();
    
    /* System Tick Configuration */
    _SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
  
  	uart1_init();

    /* Call components board initial (use INIT_BOARD_EXPORT()) */
#ifdef RT_USING_COMPONENTS_INIT
    rt_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
}

void SysTick_Handler(void)
{
    /* enter interrupt */
    rt_interrupt_enter();

    rt_tick_increase();

    /* leave interrupt */
    rt_interrupt_leave();
}
2)编译

在这里插入图片描述

3) 运行

在这里插入图片描述

2. 在 Nano 上添加 FinSH 组件(实现命令输入)

RT-Thread FinSH 是 RT-Thread 的命令行组件(shell),提供一套供用户在命令行调用的操作接口,主要用于调试或查看系统信息。它可以使用串口 / 以太网 / USB 等与 PC 机进行通信,使用 FinSH 组件基本命令的效果图如下所示:
本文以串口 UART 作为 FinSH 的输入输出端口与 PC 进行通信,描述如何在 Nano 上实现 FinSH shell 功能。
在 RT-Thread Nano 上添加 FinSH 组件,实现 FinSH 功能的步骤主要如下:
添加 FinSH 源码到工程。
实现函数对接。

1)复制 FinSH 源码到目标裸机工程:直接复制 Nano 源码中 rtthread-nano/components 文件夹下的 finsh 文件夹到工程中

在这里插入图片描述

2)finsh_port.c

注释掉RT_WEAK char rt_hw_console_getchar(void)

#include <rthw.h>
#include <rtconfig.h>

#ifndef RT_USING_FINSH
#error Please uncomment the line <#include "finsh_config.h"> in the rtconfig.h 
#endif

#ifdef RT_USING_FINSH

//RT_WEAK char rt_hw_console_getchar(void)
//{
//    /* Note: the initial value of ch must < 0 */
//    int ch = -1;

//#error "TODO 4: Read a char from the uart and assign it to 'ch'."

//    return ch;
//}

#endif /* RT_USING_FINSH */
3) rtconfig.h

增加 #define RT_USING_FINSH

4)main.c
#include "gd32f3x0.h"
#include "gd32f330c_start.h"
#include "systick.h"
#include <rtthread.h>

#define delay_ms(x)   rt_thread_mdelay(x)

/*!
    \brief      configure the USART0 GPIO ports
    \param[in]  none
    \param[out] none
    \retval     none
*/
void usart1_gpio_config(void)
{
    /* enable COM GPIO clock */
    rcu_periph_clock_enable(RCU_GPIOA);

    /* connect port to USARTx_Tx */
    gpio_af_set(GPIOA, GPIO_AF_4, GPIO_PIN_8);

    /* connect port to USARTx_Rx */
    gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_15);

    /* configure USART Tx as alternate function push-pull */
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_8);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_8);

    /* configure USART Rx as alternate function push-pull */
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_15);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_15);
}

/*!
    \brief      configure the USART0
    \param[in]  none
    \param[out] none
    \retval     none
*/
void usart1_config(void)
{
    /* enable USART clock */
    rcu_periph_clock_enable(RCU_USART1);

    /* USART configure */
    usart_deinit(USART1);
    usart_word_length_set(USART1, USART_WL_8BIT);
    usart_stop_bit_set(USART1, USART_STB_1BIT);
    usart_parity_config(USART1, USART_PM_NONE);
    usart_baudrate_set(USART1, 115200U);
    usart_receive_config(USART1, USART_RECEIVE_ENABLE);
    usart_transmit_config(USART1, USART_TRANSMIT_ENABLE);

    usart_enable(USART1);
}

void uart1_init(void)
{
  usart1_gpio_config();
  usart1_config();
}

void rt_hw_console_output(const char *str)
{
    rt_size_t i = 0, size = 0;
    char a = '\r';

    size = rt_strlen(str);
    for (i = 0; i < size; i++)
    {
        if (*(str + i) == '\n')
        {
            usart_data_transmit(USART1, a);
          while(RESET == usart_flag_get(USART1,USART_FLAG_TBE));
        }
        usart_data_transmit(USART1, *(str + i));
          while(RESET == usart_flag_get(USART1,USART_FLAG_TBE));
    }  
  
}

char rt_hw_console_getchar(void)
{
    int ch = -1;

    if (usart_flag_get(USART1, USART_FLAG_RBNE) != RESET)
    {
        ch = usart_data_receive(USART1);
    }
    else
    {
        if(usart_flag_get(USART1, USART_FLAG_ORERR) != RESET)
        {
            usart_flag_clear(USART1,USART_FLAG_ORERR);
        }
        rt_thread_mdelay(10);
    }
    return ch;
}



/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/

int main(void)
{
  
    /* enable the LED GPIO clock */
    rcu_periph_clock_enable(RCU_GPIOB);
    /* configure led GPIO port */ 
    gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_1);
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_1);
    
    gpio_bit_set(GPIOB, GPIO_PIN_1);
    
    while(1){
        /* turn on led1 */
        gpio_bit_write(GPIOB, GPIO_PIN_1, RESET);
//        rt_kprintf("Hello\n");
        delay_ms(1000);
        
        /* turn off led1 */
        gpio_bit_write(GPIOB, GPIO_PIN_1, SET);
        delay_ms(1000);
    }
}
5)finsh_config.h

屏蔽 #define FINSH_THREAD_PRIORITY 21
屏蔽 //#define FINSH_THREAD_STACK_SIZE 1024

/* FinSH config file */

#ifndef __MSH_CFG_H__
#define __MSH_CFG_H__

// <<< Use Configuration Wizard in Context Menu >>>
#define RT_USING_FINSH
#define FINSH_USING_MSH
#define FINSH_USING_MSH_ONLY
// <h>FinSH Configuration
// <o>the priority of finsh thread <1-30>
//  <i>the priority of finsh thread
//  <i>Default: 21
//#define FINSH_THREAD_PRIORITY       21
// <o>the stack of finsh thread <1-4096>
//  <i>the stack of finsh thread
//  <i>Default: 4096  (4096Byte)
//#define FINSH_THREAD_STACK_SIZE     1024

#define FINSH_USING_SYMTAB
// <c1>Enable command description
//  <i>Enable command description
#define FINSH_USING_DESCRIPTION
//  </c>
// </h>

// <<< end of configuration section >>>
#endif
6)编译

在这里插入图片描述

7) 在超级终端中使用FinSH
 \ | /
- RT -     Thread Operating System
 / | \     3.1.5 build May 17 2023
 2006 - 2020 Copyright by rt-thread team
msh >help
RT-Thread shell commands:
version          - show RT-Thread version information
list_thread      - list thread
list_sem         - list semaphore in system
list_mailbox     - list mail box in system
list_timer       - list timer in system
help             - RT-Thread shell help.
ps               - List threads in the system.

msh >ps
thread   pri  status      sp     stack size max used left tick  error
-------- ---  ------- ---------- ----------  ------  ---------- ---
tshell     6  ready   0x0000008c 0x00000200    98%   0x00000004 000
tidle      7  ready   0x00000040 0x00000080    50%   0x0000001e 000
main       2  suspend 0x00000080 0x00000100    96%   0x00000013 000
msh >

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

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

相关文章

sonarqube上的webAPI如何调用?-暴躁了一天调通了

首先吐槽一句&#xff0c;官方API文档给了个寂寞&#xff0c;调不通啊&#xff0c;然后查各种搞了一天&#xff0c;竟然没有一篇文章能把这件事写清楚&#xff0c;给我暴躁的。 结论竟然是原来是我不会调用接口。。。我今天非要把这篇文章写好。 web接口入口 通过sonarqube下…

QT开发实战-动态壁纸软件

动态壁纸软件开发 项目源代码在下面链接获取: ----------------------------- 开发者:CodeSharkSJ 希望此项目能加强你对Qt的应用 文章目录 项目图与开发环境核心技术原理自定义窗口程序UI布局背景绘制样式表基本实现QWebEngineQMedia使用系统托盘隐藏记忆功能应用程序打包 …

四年巨亏49亿,第四范式四闯IPO

深陷亏损的AI公司第四范式&#xff0c;四闯IPO&#xff01; 4月24日&#xff0c;决策类AI独角兽北京第四范式智能技术股份有限公司&#xff08;下称“第四范式”&#xff09;再次更新招股书&#xff0c;继续向港交所发起上市冲击。 第四范式是一家专注于提供以平台为中心的人…

(9) 线性回归

文章目录 1 多元线性回归LinearRegression1.1 基本原理1.2 linear_model.LinearRegression 2 回归类的模型评估指标2.1 是否预测了正确的数值2.2 是否拟合了足够的信息 3 岭回归与Lasso回归3.1 多重共线性3.2 岭回归3.2.1 linear_model.Ridge3.2.2 选取最佳的正则化参数 α \al…

车载以太网-FlexRay

摘要&#xff1a; 到底什么是FlexRay&#xff1f; 1. FlexRay是什么&#xff1f; 那么到底什么是FlexRay&#xff1f;往简单了说&#xff0c;就是CAN总线加LIN总线混合起来排个课程表、提个速再加个冗余。像LIN一样基于TDMA&#xff0c;提高了协议的复杂度&#xff0c;拥有静态…

【linux】挖矿病毒nanominer伪装成python占用服务器GPU的查杀记录

病毒表现 gpustat -cpu 可以看到root用户将GPU的核心跑满了每个占用都是100%&#xff0c;显存吃了6G多。 nvidia-smi 不能正常显示GPU被哪些进程占用 ![在这里插入图片描述](https://img-blog.csdnimg.cn/780f90080a084a44ac59227e384f985b.png 病毒文件分析 在/tmp/.x/…

win10 vmware虚拟机蓝屏怎么办 win10 vmware虚拟机蓝屏解决方法【详解】

最近有朋友出现win10 vmware虚拟机蓝屏的情况应该怎么办&#xff1f;小伙伴们在使用vmware虚拟机出现了蓝屏现象的小伙伴们不用担心&#xff0c;小编翻阅各种资料后给大家带来两种虚拟机蓝屏的解决方法&#xff0c;想要解决此问题的小伙伴们快跟着小编往下看吧&#xff01; win…

三分钟看懂JDK、JRE和JVM的区别和联系

节选自JavaGuide(Github 标星 134k star!「Java学习 + 面试指南」一份涵盖大部分 Java 程序员所需要掌握的核心知识) JVM Java 虚拟机(JVM)是运行 Java 字节码的虚拟机。JVM 有针对不同系统的特定实现(Windows,Linux,macOS),目的是使用相同的字节码,它们都会给出相同…

腾讯云轻量应用服务器卡死怎么连接?

腾讯云轻量云服务器卡死怎么解决&#xff1f;使用腾讯云自带的VNC登录连接轻量服务器&#xff0c;或使用腾讯云OrcaTerm一键免密登录轻量实例。如果是确定数据没问题&#xff0c;也可以使用控制台自带的重启实例。 腾讯云轻量应用服务器参考&#xff1a;https://curl.qcloud.co…

5月18号软件资讯更新合集.....

JTopCMS V4 更新&#xff1a;静态发布功能优化 适配版本&#xff1a;V4.6 介绍 &#xff1a; 本次更新对静态发布 HTML 功能进行多个重要优化&#xff0c;支持全站增量模式发布&#xff0c;支持跨站级栏目联动发布&#xff0c;增加定时发布指定栏目范围&#xff0c;增加栏目对…

php对接阿里云API调用企业税号查询的高级实战案例解析(下拉筛选查询、远程调用API、xm-select组件应用)

阿里云API调用企业税号查询 一、功能描述1.请求参数2.GET请求代码3.返回示例4.错误码 二、核心代码1.引入外部JS库2.构建HTML容器3.xmSelect回调 总结 一、功能描述 企业税号查询-公司税号查询-企业公司开票信息查询-企业营业执照信息查询-工商信息查询-企业基本信息查询&…

【ROS】ROS1编程速览

1、简述 很多项目已经转向ROS2&#xff0c;本人作为ROS小白从ROS1开始学起&#xff0c;但是不会深入学习ROS1&#xff0c;只一带而过。 下面只了解一些ROS1中的概念和基本编程接口。 ROS1中有两种通信模式&#xff1a;话题模式和服务模式&#xff0c;区别如下 2、话题模式 …

分享一份适合练手的软件测试实战项目,涵盖金融,电商,银行,商城,家政项目

现如今&#xff0c;越来越多的人涌入到测试行业来了&#xff0c;有自学的&#xff0c;有通过参加培训转行的&#xff0c;不管通过何种方式&#xff0c;他们面临的最主要的问题就是&#xff1a; 1、简历上的项目经验如何去编造&#xff1f; 2、入职的背调、薪资流水、离职证明等…

涨点神器:CVPR2023 InceptionNeXt当Inception遇见ConvNeXt,在Yolov8即插即用,小目标检测涨点明显

论文地址: https://arxiv.org/pdf/2303.16900.pdf 代码: GitHub - sail-sg/inceptionnext: InceptionNeXt: When Inception Meets ConvNeXt 单位:NUS, Sea AI Lab(颜水成等人) 1. InceptionNeXt介绍 摘要:受ViT的 long-range 建模能力的启发,大核卷积来扩大感受野用于…

Nvivo12 mac code comparison编码比较查询:软件操作步骤

编码比较查询步骤 1.合并项目2.编码比较2.1 选择不同的编码人2.1.1 比较单元 2.2-2.4 选择比较项目2.5 显示比较内容 3.结果kappa的解读4.参考资源 1.合并项目 如果两个编码人是在同一个项目文件中编码的&#xff08;你编一遍&#xff0c;我编一遍&#xff09;&#xff0c;此步…

Oracle 扩展统计信息收集 extension statistics

1.扩展统计信息的收集,可以用select dbms_stats.create_extended_stats(scott,test01,(object_name,object_type))from dual 创建扩展统计列,然后dbms_stats.gather_table_stats(scott,test01)收集统计信息,也可以直接在 dbms_stats.gather_table_stats中的method_opt属性同时…

【黑马笔记】IDEA配置Tomcat

文章目录 1. 配置Tomcat-本地部署1.1 官网下载tomcat压缩包1.2 idea配置tomcat1.2.1 本地tomcat查询1.2.2 部署项目 2. 配置Tomcat-插件部署 1. 配置Tomcat-本地部署 1.1 官网下载tomcat压缩包 https://tomcat.apache.org/ 解压Tomcat 1.2 idea配置tomcat 1.2.1 本地tomc…

DELL戴尔笔记本电脑成就Vostro 5620原装出厂Windows11系统恢复原厂OEM专用系统

DELL戴尔笔记本电脑成就Vostro 5620原装出厂Windows11系统恢复原厂OEM专用系统 系统自带所有驱动、办公软件、MyDell、迈克菲等预装程序 链接&#xff1a;https://pan.baidu.com/s/16AKSsMRTzYXQ_AX_Eti22w?pwdazx8 提取码&#xff1a;azx8

一文熟悉广汽埃安的EV+ICV进展

摘要&#xff1a; 本期带大家走进广汽埃安&#xff0c;了解了解埃安使用的紧密相关的那些技术或产品。 2017年&#xff0c;广汽新能源成立&#xff0c;并在2020年更名为广汽埃安新能源汽车有限公司&#xff1b;2022年&#xff0c;广汽埃安产销量 跃至国内第三&#xff0c;业绩…

C++实现开散列/链地址法

前言 解决哈希冲突的方法有闭散列和开散列&#xff0c;上篇博客C实现闭散列已经讲解完了闭散列的实现方式 本篇博客实现开散列/连地址法的哈希表 文章目录 前言一. 开散列二. 开散列实现(1). 结构(2). 插入(3). 查找(4). 删除(5). 析构函数 三. 完整代码结束语 一. 开散列 开…