RT-Thread快速上手-Keil野火霸道STM32F103上手指南

华为奋斗者精神 2023-12-04 15:22:53

@

RT-Thread快速上手-Keil野火霸道STM32F103上手指南

  • RT-Thread快速上手-Keil野火霸道STM32F103上手指南
  • 野火霸道 STM32F103 上手指南
  • 简介
  • 准备工作
  • 1.MDK 开发环境
  • 2.源码获取
  • 源码目录说明
  • rt-thread 源码的目录文件说明
  • rt-thread 目录
  • bsp目录
  • 打开一个 bsp
  • 3.使用 USB 线连接开发板的 USB 转串口 到 PC 机。
  • 运行第一个示例程序
  • 编译下载
  • 运行
  • 继续学习
  • src/scheduler_up.c源代码
  • 维护人:

RT-Thread快速上手-Keil野火霸道STM32F103上手指南

野火霸道 STM32F103 上手指南

简介

霸道 STM32F103 是野火推出的一款基于 ARM Cortex-M3 内核的开发板,最高主频为 72Mhz,该开发板具有丰富的板载资源,可以充分发挥 STM32F103 的芯片性能。

开发板外观如下图所示:

在这里插入图片描述


board

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

MCU:STM32F103ZET6,主频 72MHz,512KB FLASH ,64KB RAM
外部 RAM:IS62WV51216BLL(SRAM,1MB)
外部 FLASH:W25Q64(SPI,8MB)
常用外设
LED:1个RGB灯;2个普通LED,D4(蓝色,PF7),D5(蓝色,PF8)
按键:2个,K1(兼具唤醒功能,PA0),K2(PC13)
常用接口:USB 转串口、SD 卡接口、以太网接口、LCD 接口
调试接口,标准 JTAG/SWD
开发板更多详细信息请参考 野火官方淘宝店铺宝贝介绍。

准备工作

野火霸道 STM32F103 板级支持包提供 MDK4、MDK5 和 IAR 工程,并且支持 GCC 开发环境,下面以 MDK5 开发环境为例,介绍如何将示例程序运行起来。运行示例程序前需要做如下准备工作:

1.MDK 开发环境

需要安装 MDK-ARM 5.24 (正式版或评估版,5.14 版本及以上版本均可),这个版本也是当前比较新的版本,它能够提供相对比较完善的调试功能。安装方法可以参考 Keil MDK安装。

2.源码获取

从 Github 获取 或 从 Gitee 获取。

源码目录说明
rt-thread 源码的目录文件说明
rt-thread 目录

下图是打开 rt-thread 源码的目录,下表是该目录的简单说明。

在这里插入图片描述


源码目录

目录名 描述
bsp Board support package,RT-Thread 板级支持包
(IAR/MDK 工程在 BSP 目录下的具体的 BSP 中)
components RT-Thread 的各个组件目录
documentation 一些说明文件,如代码风格说明
include RT-Thread 内核的头文件
libcpu 各类芯片的移植代码,此处包含了 STM32 的移植文件
src RT-Thread 内核的源文件
tools RT-Thread 命令构建工具的脚本文件
BSP 目录
打开 BSP 目录,里面包含 RT-Thread 已经支持的所有 bsp

在这里插入图片描述

bsp目录

在这里插入图片描述

打开一个 bsp

如打开bsp stm32f407-atk-explorer,下表是该目录的简单说明。

在这里插入图片描述


bsp-探索者

目录名 描述
applications RT-Thread 应用程序
board 与开发板相关的配置文件
project.eww
project.uvproj
project.uvprojx iar 的工程文件
keil4 工程文件
keil5 工程文件

在这里插入图片描述

3.使用 USB 线连接开发板的 USB 转串口 到 PC 机。

在这里插入图片描述


连接到 PC

运行第一个示例程序

编译下载

进入到 rt-thread\bsp\stm32\stm32f103-fire-arbitrary 文件夹中,双击 project.uvprojx 文件,打开 MDK5 工程。

在这里插入图片描述


工程目录

执行编译,编译完成后,点击下载按钮将固件下载至开发板,下载完成后,程序会自动开始运行,观察程序运行状况。

提示:工程默认配置使用 JLink 下载程序,在通过 JLink 连接开发板的基础上,点击下载按钮即可下载程序到开发板

在这里插入图片描述


编译下载方法

运行

如没有自动运行,按下复位按键重启开发板,观察开发板上 LED 的实际效果。正常运行后,LED 灯会周期性闪烁,如下图所示:

在这里插入图片描述


run

连接开发板对应串口到 PC , 在串口工具里打开相应的串口(115200-8-1-N) ,复位设备后,可以看到 RT-Thread 的输出信息:

提示:注:野火一键下载电路和终端工具冲突,在使用终端工具如:PuTTy、XShell 时,会出现系统不能启动的问题,推荐使用串口调试助手如:sscom

 \ | /
- RT -     Thread Operating System
 / | \     3.1.1 build Nov 19 2018
 2006 - 2018 Copyright by rt-thread team
msh >

继续学习

已完成 RT-Thread 快速上手!点击这里进行 内核学习 。

src/scheduler_up.c源代码

/*
 * Copyright (c) 2006-2023, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2006-03-17     Bernard      the first version
 * 2006-04-28     Bernard      fix the scheduler algorthm
 * 2006-04-30     Bernard      add SCHEDULER_DEBUG
 * 2006-05-27     Bernard      fix the scheduler algorthm for same priority
 *                             thread schedule
 * 2006-06-04     Bernard      rewrite the scheduler algorithm
 * 2006-08-03     Bernard      add hook support
 * 2006-09-05     Bernard      add 32 priority level support
 * 2006-09-24     Bernard      add rt_system_scheduler_start function
 * 2009-09-16     Bernard      fix _rt_scheduler_stack_check
 * 2010-04-11     yi.qiu       add module feature
 * 2010-07-13     Bernard      fix the maximal number of rt_scheduler_lock_nest
 *                             issue found by kuronca
 * 2010-12-13     Bernard      add defunct list initialization even if not use heap.
 * 2011-05-10     Bernard      clean scheduler debug log.
 * 2013-12-21     Grissiom     add rt_critical_level
 * 2018-11-22     Jesven       remove the current task from ready queue
 *                             add per cpu ready queue
 *                             add _scheduler_get_highest_priority_thread to find highest priority task
 *                             rt_schedule_insert_thread won't insert current task to ready queue
 *                             in smp version, rt_hw_context_switch_interrupt maybe switch to
 *                             new task directly
 * 2022-01-07     Gabriel      Moving __on_rt_xxxxx_hook to scheduler.c
 * 2023-03-27     rose_man     Split into scheduler upc and scheduler_mp.c
 * 2023-10-17     ChuShicheng  Modify the timing of clearing RT_THREAD_STAT_YIELD flag bits
 */

#include <rtthread.h>
#include <rthw.h>

#define DBG_TAG           "kernel.scheduler"
#define DBG_LVL           DBG_INFO
#include <rtdbg.h>

rt_list_t rt_thread_priority_table[RT_THREAD_PRIORITY_MAX];
rt_uint32_t rt_thread_ready_priority_group;
#if RT_THREAD_PRIORITY_MAX > 32
/* Maximum priority level, 256 */
rt_uint8_t rt_thread_ready_table[32];
#endif /* RT_THREAD_PRIORITY_MAX > 32 */

extern volatile rt_uint8_t rt_interrupt_nest;
static rt_int16_t rt_scheduler_lock_nest;
struct rt_thread *rt_current_thread = RT_NULL;
rt_uint8_t rt_current_priority;

#ifndef __on_rt_scheduler_hook
    #define __on_rt_scheduler_hook(from, to)        __ON_HOOK_ARGS(rt_scheduler_hook, (from, to))
#endif
#ifndef __on_rt_scheduler_switch_hook
    #define __on_rt_scheduler_switch_hook(tid)      __ON_HOOK_ARGS(rt_scheduler_switch_hook, (tid))
#endif

#if defined(RT_USING_HOOK) && defined(RT_HOOK_USING_FUNC_PTR)
static void (*rt_scheduler_hook)(struct rt_thread *from, struct rt_thread *to);
static void (*rt_scheduler_switch_hook)(struct rt_thread *tid);

/**
 * @addtogroup Hook
 */

/**@{*/

/**
 * @brief This function will set a hook function, which will be invoked when thread
 *        switch happens.
 *
 * @param hook is the hook function.
 */
void rt_scheduler_sethook(void (*hook)(struct rt_thread *from, struct rt_thread *to))
{
    rt_scheduler_hook = hook;
}

/**
 * @brief This function will set a hook function, which will be invoked when context
 *        switch happens.
 *
 * @param hook is the hook function.
 */
void rt_scheduler_switch_sethook(void (*hook)(struct rt_thread *tid))
{
    rt_scheduler_switch_hook = hook;
}

/**@}*/
#endif /* RT_USING_HOOK */

#ifdef RT_USING_OVERFLOW_CHECK
static void _scheduler_stack_check(struct rt_thread *thread)
{
    RT_ASSERT(thread != RT_NULL);

#ifdef RT_USING_SMART
#ifndef ARCH_MM_MMU
    struct rt_lwp *lwp = thread ? (struct rt_lwp *)thread->lwp : 0;

    /* if stack pointer locate in user data section skip stack check. */
    if (lwp && ((rt_uint32_t)thread->sp > (rt_uint32_t)lwp->data_entry &&
    (rt_uint32_t)thread->sp <= (rt_uint32_t)lwp->data_entry + (rt_uint32_t)lwp->data_size))
    {
        return;
    }
#endif /* not defined ARCH_MM_MMU */
#endif /* RT_USING_SMART */

#ifndef RT_USING_HW_STACK_GUARD
#ifdef ARCH_CPU_STACK_GROWS_UPWARD
    if (*((rt_uint8_t *)((rt_ubase_t)thread->stack_addr + thread->stack_size - 1)) != '#' ||
#else
    if (*((rt_uint8_t *)thread->stack_addr) != '#' ||
#endif /* ARCH_CPU_STACK_GROWS_UPWARD */
        (rt_ubase_t)thread->sp <= (rt_ubase_t)thread->stack_addr ||
        (rt_ubase_t)thread->sp >
        (rt_ubase_t)thread->stack_addr + (rt_ubase_t)thread->stack_size)
    {
        rt_base_t level;

        rt_kprintf("thread:%s stack overflow\n", thread->parent.name);

        level = rt_hw_interrupt_disable();
        while (level);
    }
#endif
#ifdef ARCH_CPU_STACK_GROWS_UPWARD
#ifndef RT_USING_HW_STACK_GUARD
    else if ((rt_ubase_t)thread->sp > ((rt_ubase_t)thread->stack_addr + thread->stack_size))
#else
    if ((rt_ubase_t)thread->sp > ((rt_ubase_t)thread->stack_addr + thread->stack_size))
#endif
    {
        rt_kprintf("warning: %s stack is close to the top of stack address.\n",
                   thread->parent.name);
    }
#else
#ifndef RT_USING_HW_STACK_GUARD
    else if ((rt_ubase_t)thread->sp <= ((rt_ubase_t)thread->stack_addr + 32))
#else
    if ((rt_ubase_t)thread->sp <= ((rt_ubase_t)thread->stack_addr + 32))
#endif
    {
        rt_kprintf("warning: %s stack is close to end of stack address.\n",
                   thread->parent.name);
    }
#endif /* ARCH_CPU_STACK_GROWS_UPWARD */
}
#endif /* RT_USING_OVERFLOW_CHECK */

static struct rt_thread* _scheduler_get_highest_priority_thread(rt_ubase_t *highest_prio)
{
    struct rt_thread *highest_priority_thread;
    rt_ubase_t highest_ready_priority;

#if RT_THREAD_PRIORITY_MAX > 32
    rt_ubase_t number;

    number = __rt_ffs(rt_thread_ready_priority_group) - 1;
    highest_ready_priority = (number << 3) + __rt_ffs(rt_thread_ready_table[number]) - 1;
#else
    highest_ready_priority = __rt_ffs(rt_thread_ready_priority_group) - 1;
#endif /* RT_THREAD_PRIORITY_MAX > 32 */

    /* get highest ready priority thread */
    highest_priority_thread = rt_list_entry(rt_thread_priority_table[highest_ready_priority].next,
                              struct rt_thread,
                              tlist);

    *highest_prio = highest_ready_priority;

    return highest_priority_thread;
}

/**
 * @brief This function will initialize the system scheduler.
 */
void rt_system_scheduler_init(void)
{
    rt_base_t offset;
    rt_scheduler_lock_nest = 0;

    LOG_D("start scheduler: max priority 0x%02x",
          RT_THREAD_PRIORITY_MAX);

    for (offset = 0; offset < RT_THREAD_PRIORITY_MAX; offset ++)
    {
        rt_list_init(&rt_thread_priority_table[offset]);
    }

    /* initialize ready priority group */
    rt_thread_ready_priority_group = 0;

#if RT_THREAD_PRIORITY_MAX > 32
    /* initialize ready table */
    rt_memset(rt_thread_ready_table, 0, sizeof(rt_thread_ready_table));
#endif /* RT_THREAD_PRIORITY_MAX > 32 */
}

/**
 * @brief This function will startup the scheduler. It will select one thread
 *        with the highest priority level, then switch to it.
 */
void rt_system_scheduler_start(void)
{
    struct rt_thread *to_thread;
    rt_ubase_t highest_ready_priority;

    to_thread = _scheduler_get_highest_priority_thread(&highest_ready_priority);

    rt_current_thread = to_thread;

    rt_schedule_remove_thread(to_thread);
    to_thread->stat = RT_THREAD_RUNNING;

    /* switch to new thread */

    rt_hw_context_switch_to((rt_ubase_t)&to_thread->sp);

    /* never come back */
}

/**
 * @addtogroup Thread
 * @cond
 */

/**@{*/



维护人:

...全文
成就一亿技术人!
拼手气红包 5.00元
7347 回复 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

35,895

社区成员

发帖
与我相关
我的任务
社区描述
成功不是将来才有的,而是从决定去做那一刻起,持续累积而成!
spring cloudspring bootjava 个人社区 上海·黄浦区
社区管理员
  • Ethan Tung
  • 不断前进的皮卡丘
  • 我真不是红中
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧