RT-Thread启动流程

Posted xqyjlj

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RT-Thread启动流程相关的知识,希望对你有一定的参考价值。

RT-Thread启动流程

我们第一步理所当然要从启动文件(startup_stm32f429xx.S)分析:

/* Call the clock system intitialization function.*/
  bl  SystemInit   
/* Call static constructors */
    /* bl __libc_init_array */
/* Call the application‘s entry point.*/
  bl  entry   

第一步

? 执行函数SystemInit(),该函数位于文件system_stm32f4xx.c中。

void SystemInit(void)
{
  /* FPU 设置 ------------------------------------------------------------*/
  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
  #endif
  /*将RCC时钟配置重置为默认重置状态------------ */
  /* Set HSION bit */
  RCC->CR |= (uint32_t)0x00000001;

  /* Reset CFGR register */
  RCC->CFGR = 0x00000000;

  /* Reset HSEON, CSSON and PLLON bits */
  RCC->CR &= (uint32_t)0xFEF6FFFF;

  /* Reset PLLCFGR register */
  RCC->PLLCFGR = 0x24003010;

  /* Reset HSEBYP bit */
  RCC->CR &= (uint32_t)0xFFFBFFFF;

  /* 关闭所有中断 */
  RCC->CIR = 0x00000000;

#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
  SystemInit_ExtMemCtl(); 
#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */

  /* 配置向量表位置添加偏移地址------------------*/
#ifdef VECT_TAB_SRAM
  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* 位于SRAM的中断向量表 */
#else
  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* 位于Flash的中断向量表 */
#endif
}

其功能为:(初始化FPU设置,向量表位置和外部存储器)而并不是网上传言的初始化系统时钟。

第二步

? 执行函数entry(),该函数位于文件components.c

在keil环境下没有这个函数,而是会执行到函数$Sub$$main()

int entry(void)
{
    rtthread_startup();
    return 0;
}

可以看出,该函数其实是调用了函数rtthread_startup(),该函数也位于文件components.c

int rtthread_startup(void)
{
    rt_hw_interrupt_disable();			/* 关闭所有中断 */

    /* board level initialization
     * NOTE: please initialize heap inside board initialization.
     */
    rt_hw_board_init();

    /* show RT-Thread version */
    rt_show_version();

    /* 初始化系统系统定时器 */
    rt_system_timer_init();

    /* 初始化系统调度器 */
    rt_system_scheduler_init();

#ifdef RT_USING_SIGNALS
    /* signal system initialization */
    rt_system_signal_init();
#endif

    /* 创建用户线程 在这里创建main线程 */
    rt_application_init();

    /* 初始化系统定时器线程 */
    rt_system_timer_thread_init();

    /* 空闲线程初始化 */
    rt_thread_idle_init();

#ifdef RT_USING_SMP
    rt_hw_spin_lock(&_cpus_lock);
#endif /*RT_USING_SMP*/

    /* 开启调度器 */
    rt_system_scheduler_start();

    /* never reach here */
    return 0;
}

第三步

我们来介绍rt_hw_board_init()这个函数,位于board.c

RT_WEAK void rt_hw_board_init()
{
    extern void hw_board_init(char *clock_src, int32_t clock_src_freq, int32_t clock_target_freq);

    /* 内存堆初始化 */
#if defined(RT_USING_MEMHEAP) && defined(RT_USING_MEMHEAP_AS_HEAP)
    rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
    rt_memheap_init(&system_heap, "sram2", (void *)STM32_SRAM2_BEGIN, STM32_SRAM2_HEAP_SIZE);
#else
    rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
#endif

	/* 初始化时钟 HAL库,串口设备等 */
    hw_board_init(BSP_CLOCK_SOURCE, BSP_CLOCK_SOURCE_FREQ_MHZ, BSP_CLOCK_SYSTEM_FREQ_MHZ);

    /* 设置shell控制台设备 */
#if defined(RT_USING_DEVICE) && defined(RT_USING_CONSOLE)
    rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif

    /* 板级硬件初始化 */
#ifdef RT_USING_COMPONENTS_INIT
    rt_components_board_init();
#endif

}

用一个图就可以概括:

技术图片

到此我们才真正进入了main函数

以上是关于RT-Thread启动流程的主要内容,如果未能解决你的问题,请参考以下文章

springboot启动流程构造SpringApplication实例对象

VSCode自定义代码片段——git命令操作一个完整流程

VSCode自定义代码片段15——git命令操作一个完整流程

VSCode自定义代码片段15——git命令操作一个完整流程

强烈推荐一款国产物联网实时操作系统RT-Thread

强烈推荐一款国产物联网实时操作系统RT-Thread