RT-Thread STM32L475 潘多拉开发板BSP说明①
RT-Thread STM32L475 潘多拉开发板BSP说明①
简介
本文档为 RT-Thread 开发团队为 STM32L475 潘多拉开发板提供的 BSP (板级支持包) 说明。
主要内容如下:
- 开发板资源介绍
- BSP 快速上手
- 进阶使用方法
通过阅读快速上手章节开发者可以快速地上手该 BSP,将 RT-Thread 运行在开发板上。在进阶使用指南章节,将会介绍更多高级功能,帮助开发者利用 RT-Thread 驱动更多板载资源。
开发板介绍
潘多拉 STM32L475 是正点原子推出的一款基于 ARM Cortex-M4 内核的开发板,最高主频为 80Mhz,该开发板具有丰富的板载资源,可以充分发挥 STM32L475 的芯片性能。
开发板外观如下图所示:
该开发板常用 板载资源 如下:
- MCU:STM32L475VET6,主频 80MHz,512KB FLASH ,128KB RAM
- 外部 FLASH:W25Q128 或 NM25Q128EVB(SPI,16MB)
- 常用外设
- RGB 状态指示灯:1个,(红、绿、蓝三色)
- 按键:4个,KEY_UP(兼具唤醒功能,PC13),K0(PD10),K1(PD9),K2(PD8)
- 红外发射头,红外接收头
- 有源蜂鸣器:1个
- 光环境传感器:1个
- 贴片电机:1个
- 六轴传感器:1个
- 高性能音频解码芯片:1个
- 温湿度传感器(AHT10):1个
- TFTLCD 显示屏:1个
- WIFI 模块(AP6181):1个
- 板载 ST LINK V2.1 功能
- 常用接口:SD 卡接口、USB OTG、Micro USB 接口
- 调试接口,ST-LINK Micro USB 接口
开发板更多详细信息请参考正点原子 STM32 潘多拉开发板介绍。
外设支持
本 BSP 目前对外设的支持情况如下:
板载外设 | 支持情况 | 备注 |
---|---|---|
板载 ST-LINK 转串口 | 支持 | |
QSPI_FLASH | 支持 | |
SD 卡 | 支持 | 使用 SPI1 驱动 |
温湿度传感器 | 支持 | |
六轴传感器 | 支持 | |
音频解码 | 支持 | |
TFTLCD | 支持 | 使用 SPI3 驱动 |
贴片电机 | 暂不支持 | 即将支持 |
光环境传感器 | 暂不支持 | 即将支持 |
AP6181 WIFI 模块 | 支持 | 使用 SDIO 驱动 |
片上外设 | 支持情况 | 备注 |
GPIO | 支持 | |
UART | 支持 | |
SPI | 支持 | |
QSPI | 支持 | |
I2C | 支持 | |
TIM | 支持 | |
ADC | 支持 | |
RTC | 支持 | 支持外部晶振和内部低速时钟 |
WDT | 支持 | |
PWM | 支持 | |
USB Device | 支持 | |
USB Host | 暂不支持 | 即将支持 |
扩展模块 | 支持情况 | 备注 |
NRF24L01 模块 | 支持 | 根据实际板子接线情况修改 NRF24L01 软件包中的 NRF24L01_CE_PIN 和 NRF24_IRQ_PIN 的宏定义,以及 SPI 设备名 |
ATK-ESP8266 模块 | 暂不支持 | 即将支持 |
ENC28J60 模块 | 暂不支持 | 即将支持 |
使用该开发板的更多高级功能请参考 RT-Thread 代码仓库: RT-Thread IoT-Board SDK。 |
使用说明
使用说明分为如下两个章节:
-
快速上手
本章节是为刚接触 RT-Thread 的新手准备的使用说明,遵循简单的步骤即可将 RT-Thread 操作系统运行在该开发板上,看到实验效果 。
-
进阶使用
本章节是为需要在 RT-Thread 操作系统上使用更多开发板资源的开发者准备的。通过使用 ENV 工具对 BSP 进行配置,可以开启更多板载资源,实现更多高级功能。
快速上手
本 BSP 为开发者提供 MDK4、MDK5 和 IAR 工程,并且支持 GCC 开发环境。下面以 MDK5 开发环境为例,介绍如何将系统运行起来。
硬件连接
使用数据线连接开发板到 PC,打开电源开关。
编译下载
双击 project.uvprojx 文件,打开 MDK5 工程,编译并下载程序到开发板。
工程默认配置使用板载 ST-LINK 下载程序,只需一根 USB 线连接开发板,点击下载按钮即可下载程序到开发板
运行结果
下载程序成功之后,系统会自动运行,观察开发板上 LED 灯的运行效果,红色 LED 灯会周期性闪烁。
连接开发板对应串口到 PC , 在终端工具里打开相应的串口(115200-8-1-N),复位设备后,可以看到 RT-Thread 的输出信息:
\ | /
- RT - Thread Operating System
/ | \ 3.1.1 build Nov 19 2018
2006 - 2018 Copyright by rt-thread team
msh >
进阶使用
此 BSP 默认只开启了 GPIO 和 串口1 的功能,如果需使用 SD 卡、Flash 等更多高级功能,需要利用 ENV 工具对 BSP 进行配置,步骤如下:
-
在 bsp 下打开 ENV 工具。
-
输入
menuconfig
命令配置工程,配置好之后保存退出。 -
输入
pkgs --update
命令更新软件包。 -
输入
scons --target=mdk4/mdk5/iar
命令重新生成工程。
本章节更多详细的介绍请参考 STM32 系列 BSP 外设驱动使用教程。
注意事项
关于ST-Link无法升级的问题请参考:…/armink/HackSTLinkUpgrade
示例代码
…\src\components.c
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2012-09-20 Bernard Change the name to components.c
* And all components related header files.
* 2012-12-23 Bernard fix the pthread initialization issue.
* 2013-06-23 Bernard Add the init_call for components initialization.
* 2013-07-05 Bernard Remove initialization feature for MS VC++ compiler
* 2015-02-06 Bernard Remove the MS VC++ support and move to the kernel
* 2015-05-04 Bernard Rename it to components.c because compiling issue
* in some IDEs.
* 2015-07-29 Arda.Fu Add support to use RT_USING_USER_MAIN with IAR
* 2018-11-22 Jesven Add secondary cpu boot up
* 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable
*/
#include <rthw.h>
#include <rtthread.h>
#ifdef RT_USING_USER_MAIN
#ifndef RT_MAIN_THREAD_STACK_SIZE
#define RT_MAIN_THREAD_STACK_SIZE 2048
#endif /* RT_MAIN_THREAD_STACK_SIZE */
#ifndef RT_MAIN_THREAD_PRIORITY
#define RT_MAIN_THREAD_PRIORITY (RT_THREAD_PRIORITY_MAX / 3)
#endif /* RT_MAIN_THREAD_PRIORITY */
#endif /* RT_USING_USER_MAIN */
#ifdef RT_USING_COMPONENTS_INIT
/*
* Components Initialization will initialize some driver and components as following
* order:
* rti_start --> 0
* BOARD_EXPORT --> 1
* rti_board_end --> 1.end
*
* DEVICE_EXPORT --> 2
* COMPONENT_EXPORT --> 3
* FS_EXPORT --> 4
* ENV_EXPORT --> 5
* APP_EXPORT --> 6
*
* rti_end --> 6.end
*
* These automatically initialization, the driver or component initial function must
* be defined with:
* INIT_BOARD_EXPORT(fn);
* INIT_DEVICE_EXPORT(fn);
* ...
* INIT_APP_EXPORT(fn);
* etc.
*/
static int rti_start(void)
{
return 0;
}
INIT_EXPORT(rti_start, "0");
static int rti_board_start(void)
{
return 0;
}
INIT_EXPORT(rti_board_start, "0.end");
static int rti_board_end(void)
{
return 0;
}
INIT_EXPORT(rti_board_end, "1.end");
static int rti_end(void)
{
return 0;
}
INIT_EXPORT(rti_end, "6.end");
/**
* @brief Onboard components initialization. In this function, the board-level
* initialization function will be called to complete the initialization
* of the on-board peripherals.
*/
void rt_components_board_init(void)
{
#ifdef RT_DEBUGING_AUTO_INIT
int result;
const struct rt_init_desc *desc;
for (desc = &__rt_init_desc_rti_board_start; desc < &__rt_init_desc_rti_board_end; desc ++)
{
rt_kprintf("initialize %s", desc->fn_name);
result = desc->fn();
rt_kprintf(":%d done\n", result);
}
#else
volatile const init_fn_t *fn_ptr;
for (fn_ptr = &__rt_init_rti_board_start; fn_ptr < &__rt_init_rti_board_end; fn_ptr++)
{
(*fn_ptr)();
}
#endif /* RT_DEBUGING_AUTO_INIT */
}
/**
* @brief RT-Thread Components Initialization.
*/
void rt_components_init(void)
{
#ifdef RT_DEBUGING_AUTO_INIT
int result;
const struct rt_init_desc *desc;
rt_kprintf("do components initialization.\n");
for (desc = &__rt_init_desc_rti_board_end; desc < &__rt_init_desc_rti_end; desc ++)
{
rt_kprintf("initialize %s", desc->fn_name);
result = desc->fn();
rt_kprintf(":%d done\n", result);
}
#else
volatile const init_fn_t *fn_ptr;
for (fn_ptr = &__rt_init_rti_board_end; fn_ptr < &__rt_init_rti_end; fn_ptr ++)
{
(*fn_ptr)();
}
#endif /* RT_DEBUGING_AUTO_INIT */
}
#endif /* RT_USING_COMPONENTS_INIT */
#ifdef RT_USING_USER_MAIN
void rt_application_init(void);
void rt_hw_board_init(void);
int rtthread_startup(void);
#ifdef __ARMCC_VERSION
extern int $Super$$main(void);
/* re-define main function */
int $Sub$$main(void)
{
rtthread_startup();
return 0;
}
#elif defined(__ICCARM__)
/* __low_level_init will auto called by IAR cstartup */
extern void __iar_data_init3(void);
int __low_level_init(void)
{
// call IAR table copy function.
__iar_data_init3();
rtthread_startup();
return 0;
}
#elif defined(__GNUC__)
/* Add -eentry to arm-none-eabi-gcc argument */
int entry(void)
{
rtthread_startup();
return 0;
}
#endif
#ifndef RT_USING_HEAP
/* if there is not enable heap, we should use static thread and stack. */
rt_align(RT_ALIGN_SIZE)
static rt_uint8_t main_thread_stack[RT_MAIN_THREAD_STACK_SIZE];
struct rt_thread main_thread;
#endif /* RT_USING_HEAP */
/**
* @brief The system main thread. In this thread will call the rt_components_init()
* for initialization of RT-Thread Components and call the user's programming
* entry main().
*
* @param parameter is the arg of the thread.
*/
void main_thread_entry(void *parameter)
{
extern int main(void);
#ifdef RT_USING_COMPONENTS_INIT
/* RT-Thread components initialization */
rt_components_init();
#endif /* RT_USING_COMPONENTS_INIT */
#ifdef RT_USING_SMP
rt_hw_secondary_cpu_up();
#endif /* RT_USING_SMP */
/* invoke system main function */
#ifdef __ARMCC_VERSION
{
extern int $Super$$main(void);
$Super$$main(); /* for ARMCC. */
}
#elif defined(__ICCARM__) || defined(__GNUC__) || defined(__TASKING__) || defined(__TI_COMPILER_VERSION__)
main();
#endif
}
/**
* @brief This function will create and start the main thread, but this thread
* will not run until the scheduler starts.
*/
void rt_application_init(void)
{
rt_thread_t tid;
#ifdef RT_USING_HEAP
tid = rt_thread_create("main", main_thread_entry, RT_NULL,
RT_MAIN_THREAD_STACK_SIZE, RT_MAIN_THREAD_PRIORITY, 20);
RT_ASSERT(tid != RT_NULL);
#else
rt_err_t result;
tid = &main_thread;
result = rt_thread_init(tid, "main", main_thread_entry, RT_NULL,
main_thread_stack, sizeof(main_thread_stack), RT_MAIN_THREAD_PRIORITY, 20);
RT_ASSERT(result == RT_EOK);
/* if not define RT_USING_HEAP, using to eliminate the warning */
(void)result;
#endif /* RT_USING_HEAP */
rt_thread_startup(tid);
}
/**
* @brief This function will call all levels of initialization functions to complete
* the initialization of the system, and finally start the scheduler.
*
* @return Normally never returns. If 0 is returned, the scheduler failed.
*/
int rtthread_startup(void)
{
#ifdef RT_USING_SMP
rt_hw_spin_lock_init(&_cpus_lock);
#endif
rt_hw_local_irq_disable();
/* board level initialization
* NOTE: please initialize heap inside board initialization.
*/
rt_hw_board_init();
/* show RT-Thread version */
rt_show_version();
/* timer system initialization */
rt_system_timer_init();
/* scheduler system initialization */
rt_system_scheduler_init();
#ifdef RT_USING_SIGNALS
/* signal system initialization */
rt_system_signal_init();
#endif /* RT_USING_SIGNALS */
/* create init_thread */
rt_application_init();
/* timer thread initialization */
rt_system_timer_thread_init();
/* idle thread initialization */
rt_thread_idle_init();
#ifdef RT_USING_SMP
rt_hw_spin_lock(&_cpus_lock);
#endif /* RT_USING_SMP */
/* start scheduler */
rt_system_scheduler_start();
/* never reach here */
return 0;
}
#endif /* RT_USING_USER_MAIN */
源码下载
…\bsp\stm32\stm32l475-atk-pandora\project.uvproj
RT-Thread STM32L475 潘多拉开发板BSP说明 源码下载