Rtthread学习笔记<一>

RT-thread内核文档学习<一>内核基础

  • Rtthread的初始化过程
纯属个人学习笔记,敬请指正

一、系统初始化

启动流程

首先初始化会进入一个被Sub和super修饰的main函数,由于我从来没有见过于是就看了官方的文档,做出了如下总结。

附:

相关文档1-ARM Compiler v5.06 for µVision armlink User Guide

相关文档2-内核基础

1.1 扩展补丁Sub和super的作用

** ∗ ∗ s u p e r ∗ ∗ ** super** super ∗ ∗ f o o 和 ∗ ∗ **foo 和 ** fooSub$$**foo的使用方法如下

例如,如果它位于外部库中或ROM代码中,则无法修改现有符号。 在这种情况下,您可以使用 Super ​和 sub ​模式来修补现有符号。

修补函数foo()的定义:

** ∗ ∗ s u p e r ∗ ∗ ** super** super$**foo():为原始未扩展的函数foo()。 使用它直接调用原始函数。

** ∗ ∗ S u b ∗ ∗ **Sub** Sub$**foo():为的新函数而不是原始函数foo()。可以在此函数对super函数进行一些额外的处理。

注意:Sub和Super机制仅在静态链路时间工作,不能导入或导出到动态符号表中。

例如:以下示例显示了如何使用$ super KaTeX parse error: Can't use function '$' in math mode at position 2: 和$̲ sub ,以在调用传统功能foo()之前插入函数Extrafunc()的调用。

void Extrafunc(void;//额外的功能调用
void $ super $$ foo(void):/ *此函数称为原始foo()* /

void $ sub $$ foo(void{
	Extrafunc(); / *是否有一些额外的设置工作* /
	$ super $$ foo(); / *调用原始foo()函数* /
/*避免调用原始foo()函数
 *省略$ super $$ foo(); 函数调用。
 */
}

首先以我的理解来描述一下这个补丁的作用:可以说这是在原有函数不改变的前提下,对函数的扩展或重写的一种方法

总结一下使用的方法:

  • ①将原有函数用 ∗ ∗ s u p e r ∗ ∗ ** super** super$ 这样的字段进行描述,表示将要进行额外的功能添加。
  • ②重新定义一个与原函数同名的函数并使用** ∗ ∗ S u b ∗ ∗ **Sub** Sub$**字段进行描述,表示此函数为扩展后的函数。
  • ③在使用** ∗ ∗ S u b ∗ ∗ **Sub** Sub$**描述的新函数中添加所需的功能代码,如果需要使用原有功能,那么加入原有函数的调用即可(描述字段不可省)。

好了我大致知道了这个特殊的main的运行机制后,我们继续探索系统的启动流程。按照官方的描述接下来是进入rtthread_startup()函数,我看到了如下代码,以及描述信息,大致可以猜测在这是衔接汇编和C的一个入口函数,如下enter函数:

image-20210702203517593

接着就正真开始系统的启动开始:

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();

    /* 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

    /* 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;
}
  • rt_hw_interrupt_disable();

系统中断失能,在汇编文件context_gcc.S中实现。

  • rt_hw_board_init();

板载资源初始化,堆内存分配,HAL库MSP(中断优先级分组、嘀嗒定时器使能。引脚使能、端口时钟使能),系统时钟使能72M,以及系统元件初始化。

  • rt_show_version();

在串口上位机中打印系统版本信息。

  • rt_system_timer_init();

系统中的定时器容器中的定时器进行初始化。

  • rt_system_scheduler_init();

线程调度器初始化,其中包括线程的初始化。

  • rt_application_init();

main函数线程在此创建,应用线程初始化。

  • rt_system_timer_thread_init();

定时器线程在此创建,创建此线程之前,又对定时器容器进行了一次初始化。

  • rt_thread_idle_init();

空闲线程在此初始化。

  • rt_system_scheduler_start();

系统调度开始。

我来总结一下到目前为止,系统都做了些什么工作:

  • 开启了三个线程 main、timer、idle线程开启
  • 板级的硬件也初始化完毕

那么接下来我们要做什么????或者说我们在实际使用操作系统的时候要怎么去做,以下是我个人的看法,具体还得自己去实践才知道好坏。

在这我进行了思考,我们要怎么把cubemx生成的硬件配置代码运用到系统中来。

首先我知道对于操作系统下有两种开发模式:

  • 使用操作系统驱动库对mcu进行控制。drivers驱动
  • 使用mcu原有库对mcu进行控制。Hal库

其次我知道操控一个外设需要的几步流程:

  • 相关引脚时钟,以及IO口需要使能
  • 相关外设功能需要配置,以及使能
  • 配置完毕就可以使用了

那么我们需要在系统启动的那个阶段进行以上操作合适呢????我们慢慢探讨一下这个问题。

到这里系统内核的初始化已经全部启动完毕了,接下来就是三个线程对系统的调度了,套娃模式开启,线程中操作其他线程的创建和删除,多美妙呀!!!如图:(图示例中的其他线程,具体我不了解,在我的理解是可能在之前的初始化中,用户创建了新的线程,也可能是main函数中创建的线程也开始进入了系统的调度)

image-20210703010205366

我们来看看main函数的入口函数的执行:

void main_thread_entry(void *parameter)
{
    extern int main(void);
    extern int $Super$$main(void);
    
#ifdef RT_USING_COMPONENTS_INIT
    /* RT-Thread components initialization */
    rt_components_init();
#endif    
#ifdef RT_USING_SMP
    rt_hw_secondary_cpu_up();
#endif
    /* invoke system main function */
#if defined(__CC_ARM) || defined(__CLANG_ARM)
    $Super$$main(); /* for ARMCC. */
#elif defined(__ICCARM__) || defined(__GNUC__)
    main();
#endif
}
  • rt_components_init();

系统元件的初始化。

  • main();

进入main函数,进行用户应用层的操作。

接近尾声了,最后要做的就是在不同的线程中完成要做的任务,以及信息处理IPC的工作了,我们下次再进行讨论,时间不早了,我也该睡觉了Zzz!

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值