RT-Thread STM32F407 Robomaster开发板C型BSP说明

RT-Thread STM32F407 Robomaster开发板C型BSP说明

简介

本文档为 STM32F407 Robomaster 开发板C型 的 BSP (板级支持包) 说明。

主要内容如下:

  • 开发板资源介绍
  • BSP 快速上手
  • 进阶使用方法

通过阅读快速上手章节开发者可以快速地上手该 BSP,将 RT-Thread 运行在开发板上。在进阶使用指南章节,将会介绍更多高级功能,帮助开发者利用 RT-Thread 驱动更多板载资源。

开发板介绍

Robomaster 开发板C型 是大疆创新科技有限公司推出的一款基于 ARM Cortex-M4 内核的开发板。开发板主控芯片为 STM32F407IGH6TR,最高主频为 168Mhz,拥有丰富的扩展接口和通信接口。板载IMU传感器,可配合RoboMaster出品的M3508、 M2006直流无刷减速电机、UWB模块以及妙算等产品使用,亦可配合DJI飞控SDK使用。

开发板外观如下图所示:

开发板 C 型具有如下外设:

该开发板常用 板载资源 如下:

  • MCU:STM32F407IGH6TR, 主频 168MHz, 1024KB FLASH, 192KB RAM(含64KB CCM RAM)
  • 常用外设
    • 三色 LED:LED_R(PH12), LED_G(PH11), LED_B(PH11),
    • 按键:KEY(PA0)
    • 电压检测:ADC_BAT(PF10)
  • 常用接口:UART 接口、CAN 总线接口、PWM 接口
  • 调试接口:SWD

开发板的用户手册:RoboMaster 开发板 C 型用户手册.pdf

开发板更多详细信息请参考 RoboMaster官网:RoboMaster开发板 C 型

外设支持

本 BSP 目前对外设的支持情况如下:

板载外设支持情况备注
BMI088暂不支持六轴惯性测量单元(有软件包)
IST8310暂不支持三轴磁力计
片上外设支持情况备注
GPIO支持PA0, PA1… PH1 —> PIN: 0, 1…144
UART支持UART1(FinSH), UART3(DBUS), UART6
CAN支持CAN1, CAN2
PWM支持TIM1(CH1/2/3/4), TIM4(CH3), TIM5(CH1/2/3), TIM8(CH1/2/3)
SPI支持SPI2
IIC支持模拟IIC(SDA–>PF0, SCL–>PF1)

使用说明

使用说明分为如下两个章节:

  • 快速上手

    本章节是为刚接触 RT-Thread 的新手准备的使用说明,遵循简单的步骤即可将 RT-Thread 操作系统运行在该开发板上,看到实验效果 。

  • 进阶使用

    本章节是为需要在 RT-Thread 操作系统上使用更多开发板资源的开发者准备的。通过使用ENV 工具对 BSP 进行配置,可以开启更多板载资源,实现更多高级功能。

快速上手

本 BSP 为开发者提供 MDK5 和 IAR 工程,并且支持 GCC 开发环境。下面以 MDK5 开发环境为例,介绍如何将系统运行起来。

硬件连接

将准备好的 ST-Link/JLink/DapLink 与开发板连接,开发板上的调试接口为 MX1.25 4Pin。C板上没有电源指示灯,供电可以选用:调试接口的 3.3V 输入,micro USB 接口供电,XT30 电源输入。

编译下载

双击 project.uvprojx 文件,打开 MDK5 工程,编译并下载程序到开发板。

工程默认配置使用 ST-LINK 下载程序,点击下载按钮即可下载程序到开发板。

运行结果

下载程序成功之后,系统会自动运行,观察开发板上 LED 的运行效果,LED 会以蓝光进行周期性闪烁。

此 BSP 的 FinSH 默认使用串口 1 ( C 板外壳上标有 UART2 的 4Pin 接口),在终端工具里打开相应的串口(115200-8-1-N),复位设备后,可以看到 RT-Thread 的输出信息:

 \ | /
- RT -     Thread Operating System
 / | \     4.1.1 build Jul 29 2022 23:31:38
 2006 - 2022 Copyright by RT-Thread team
msh >

终端工具推荐使用 MobaXtermXshell,均有免费的个人版本

进阶使用

此 BSP 默认只开启了 GPIO 和 UART1(丝印为 UART2 4pin 接口) 的功能,更多高级功能需要利用 ENV 工具对 BSP 进行配置,步骤如下:

  1. 在 BSP 下打开 env 工具。

  2. 输入 menuconfig 命令配置工程,配置好之后保存退出。

  3. 输入 pkgs --update 命令更新软件包。

  4. 输入 scons --target=mdk4/mdk5/iar 命令重新生成工程。

本章节更多详细的介绍请参考 [STM32 系列 BSP 外设驱动使用教程](…/docs/STM32 系列 BSP 外设驱动使用教程. md)。

注意事项

  • 部分外设需通过 XT30 或 USB 接口供电才能正常使用,包括 CAN、舵机5V供电、IMU恒温电路等
  • 目前 scons 支持生成 cmake 配置文件,可以使用 CLion 进行 C板 的程序开发,推荐同学们尝试。详细步骤可参见:在 Clion 中调试 rt-thread 工程,C板的 openOCD 配置文件推荐选用 stm32f4discovery.cfg ,并将该配置文件的最后一行改为 reset_config none

示例代码

…\components\drivers\ipc\dataqueue.c

/*
 * Copyright (c) 2006-2023, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2012-09-30     Bernard      first version.
 * 2016-10-31     armink       fix some resume push and pop thread bugs
 * 2023-09-15     xqyjlj       perf rt_hw_interrupt_disable/enable
 */

#include <rthw.h>
#include <rtdevice.h>

#define DATAQUEUE_MAGIC  0xbead0e0e

struct rt_data_item
{
    const void *data_ptr;
    rt_size_t data_size;
};

/**
 * @brief    This function will initialize the data queue. Calling this function will
 *           initialize the data queue control block and set the notification callback function.
 *
 * @param    queue is a pointer to the data queue object.
 *
 * @param    size is the maximum number of data in the data queue.
 *
 * @param    lwm is low water mark.
 *           When the number of data in the data queue is less than this value, this function will
 *           wake up the thread waiting for write data.
 *
 * @param    evt_notify is the notification callback function.
 *
 * @return   Return the operation status. When the return value is RT_EOK, the initialization is successful.
 *           When the return value is -RT_ENOMEM, it means insufficient memory allocation failed.
 */
rt_err_t
rt_data_queue_init(struct rt_data_queue *queue,
                   rt_uint16_t size,
                   rt_uint16_t lwm,
                   void (*evt_notify)(struct rt_data_queue *queue, rt_uint32_t event))
{
    RT_ASSERT(queue != RT_NULL);
    RT_ASSERT(size > 0);

    queue->evt_notify = evt_notify;

    queue->magic = DATAQUEUE_MAGIC;
    queue->size = size;
    queue->lwm = lwm;

    queue->get_index = 0;
    queue->put_index = 0;
    queue->is_empty = 1;
    queue->is_full = 0;

    rt_spin_lock_init(&(queue->spinlock));

    rt_list_init(&(queue->suspended_push_list));
    rt_list_init(&(queue->suspended_pop_list));

    queue->queue = (struct rt_data_item *)rt_malloc(sizeof(struct rt_data_item) * size);
    if (queue->queue == RT_NULL)
    {
        return -RT_ENOMEM;
    }

    return RT_EOK;
}
RTM_EXPORT(rt_data_queue_init);

/**
 * @brief    This function will write data to the data queue. If the data queue is full,
 *           the thread will suspend for the specified amount of time.
 *
 * @param    queue is a pointer to the data queue object.
 * .
 * @param    data_ptr is the buffer pointer of the data to be written.
 *
 * @param    size is the size in bytes of the data to be written.
 *
 * @param    timeout is the waiting time.
 *
 * @return   Return the operation status. When the return value is RT_EOK, the operation is successful.
 *           When the return value is -RT_ETIMEOUT, it means the specified time out.
 */
rt_err_t rt_data_queue_push(struct rt_data_queue *queue,
                            const void *data_ptr,
                            rt_size_t data_size,
                            rt_int32_t timeout)
{
    rt_base_t level;
    rt_thread_t thread;
    rt_err_t    result;

    RT_ASSERT(queue != RT_NULL);
    RT_ASSERT(queue->magic == DATAQUEUE_MAGIC);

    /* current context checking */
    RT_DEBUG_SCHEDULER_AVAILABLE(timeout != 0);

    result = RT_EOK;
    thread = rt_thread_self();

    level = rt_spin_lock_irqsave(&(queue->spinlock));
    while (queue->is_full)
    {
        /* queue is full */
        if (timeout == 0)
        {
            result = -RT_ETIMEOUT;

            goto __exit;
        }

        /* reset thread error number */
        thread->error = RT_EOK;

        /* suspend thread on the push list */
        rt_thread_suspend_with_flag(thread, RT_UNINTERRUPTIBLE);
        rt_list_insert_before(&(queue->suspended_push_list), &(thread->tlist));
        /* start timer */
        if (timeout > 0)
        {
            /* reset the timeout of thread timer and start it */
            rt_timer_control(&(thread->thread_timer),
                             RT_TIMER_CTRL_SET_TIME,
                             &timeout);
            rt_timer_start(&(thread->thread_timer));
        }

        /* enable interrupt */
        rt_spin_unlock_irqrestore(&(queue->spinlock), level);

        /* do schedule */
        rt_schedule();

        /* thread is waked up */
        result = thread->error;
        level = rt_spin_lock_irqsave(&(queue->spinlock));
        if (result != RT_EOK) goto __exit;
    }

    queue->queue[queue->put_index].data_ptr  = data_ptr;
    queue->queue[queue->put_index].data_size = data_size;
    queue->put_index += 1;
    if (queue->put_index == queue->size)
    {
        queue->put_index = 0;
    }
    queue->is_empty = 0;
    if (queue->put_index == queue->get_index)
    {
        queue->is_full = 1;
    }

    /* there is at least one thread in suspended list */
    if (!rt_list_isempty(&(queue->suspended_pop_list)))
    {
        /* get thread entry */
        thread = rt_list_entry(queue->suspended_pop_list.next,
                               struct rt_thread,
                               tlist);

        /* resume it */
        rt_thread_resume(thread);
        rt_spin_unlock_irqrestore(&(queue->spinlock), level);

        /* perform a schedule */
        rt_schedule();

        return result;
    }

__exit:
    rt_spin_unlock_irqrestore(&(queue->spinlock), level);
    if ((result == RT_EOK) && queue->evt_notify != RT_NULL)
    {
        queue->evt_notify(queue, RT_DATAQUEUE_EVENT_PUSH);
    }

    return result;
}
RTM_EXPORT(rt_data_queue_push);

源码下载

…\bsp\stm32\stm32f407-robomaster-c\project.uvproj

在这里插入图片描述


RT-Thread STM32F407 Robomaster开发板C型BSP说明 源码下载


维护人:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

华为奋斗者精神

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值