如何在树莓派2上移植rt-thread操作系统

如何在树莓派2上移植rt-thread操作系统

1.准备工作

硬件

1.树莓派2开发板(如果没有,可以直接用qemu替代)。

软件

1.window上可以采用rt-thread提供的env工具

2.Ubuntu上需要装scons,因为rt-thread操作系统是通过scons组织的。

3.git工具,进行代码管理

4.qemu,模拟开发板

5.arm gcc版本gcc-arm-none-eabi-5_4-2016q3

以下文章的实验都是在Ubuntu16.04下进行,用qemu仿真树莓派2。实际硬件也进行过测试,效果一样。

2.移植思路

树莓派2的启动上电流程是先启动gpu,从sd卡中读取kernel固件。所以如果要自己实现kernel,也需要做类似的处理,编译一个kernel7.img的固件放在sd卡中。如果直接用qemu操作,那么就不需要这么多复杂的操作,直接本地模拟就可以了。

如果要实现移植rt-thread操作系统到树莓派上,要点是什么?

1.启动代码

当树莓派的gpu加载kernel7.img到sdram开始执行的时候,首先需要做必要的初始化工作。所以链接地址0x00008000需要正确的给予。初始化必要的设备,由于前期没有分配栈,只能使用汇编进行初始化。简而言之,进行必要的操作。那么这些必要的操作有那些?由于树莓派2的芯片采用bcm2835,里面有4个核在工作,所以只能让一个核工作,其他三个核睡眠。然后关闭mmu,分配栈空间,清除bss段。此时可以跳转到C语言去执行相关的逻辑操作了。毕竟C语言的操作比汇编看起来让人清晰。

2.中断向量初始化

这里需要指定中断向量表,指定中断函数的处理函数。根据armv7的体系架构,整理中断向量表的偏移。然后初始化rt-thread中断向量表的初始化。当然,这些已经在操作系统里面完成了。

3.tick

rt-thread操作系统需要有时钟tick,也就是定时中断。对于这部分来说,需要自己实现一个timer中断。在实体硬件上,我们可以采用的是树莓派内部自带的一个名为SP802的时钟模块产生的中断,但是qemu并没有实现,只实现gtimer。所以为了保证硬件和qemu都能运行,实验中采用的是gtimer。

4.上下文切换

如果要实现中断现场的返回和线程切换现场的返回,少不了上下文切换的逻辑,也就是context。这部分主要完成的是切换上下文前保存状态寄存器,切换完成后恢复寄存器的内容。这样就能够恢复上次的现场了。

5.uart

如果要调试rt-thread程序,当然少不了串口打印,rt-thread操作系统的一大特色就是支持shell。可以通过命令来操作系统,查看信息。树莓派有两个串口,一个是直接通过内部时钟驱动的mini uart。另外一个是pl011串口模块,两者操作的寄存器地址不一样。

以上5点也是整个最小系统移植关键。现在笔者已经将这个树莓派rt-thread最小系统移植上去了。有兴趣的自己可以玩一下。https://github.com/bigmagic123/raspi-littlevgl。这个项目的是为了在树莓派上移植littlevgl。初代版本就是最小系统。

3.操作步骤

首先需要将代码clone下来。

git clone git@github.com:bigmagic123/raspi-littlevgl.git

然后进入到工程目录/bsp/raspi2。这里需要修改的是rtconfig.py文件中的GCC路径。

这里需要改成自己的gcc路径。

然后打开vscode上的Terminal --> new Terminal可以看到控制台窗口的出现。

输入scons进行编译。现象如下则表示成功。

QEMU运行

如果此时电脑上已经装了qemu,那么直接启动脚本即可正常运行了。

此时表示系统正常运行成功。

树莓派2硬件运行

连接树莓派用USB转TTL模块。然后将刚才编译好的文件放到SD卡目录中。

SD卡文件只留下这三个文件就可以了,其中kernel7.img就是我们刚才用scons编译出来的rtthread固件。

4.代码分析

相关的内核代码可以在rt-thread的官方网站上进行下载。笔者只是改了一些bsp文件。

CPU相关

与cpu相关的在bsp/raspi2/cpu目录下。

启动从start_gcc.S开始。上下文切换在context_gcc.S文件中。

外设相关

外设相关的代码在driver目录下。目前只有实现uart和tick。

用户操作代码

用户操作代码在applications文件中,其中启动的第一个线程就是在main函数中

int main(int argc, char** argv)
{
    rt_kprintf("Hello RT-Thread!\n");
    while(1)
    {
        rt_kprintf("cur tick is %d\n",rt_tick_get());
        rt_thread_delay(1000);
    }
    return 0;
}

如果用户需要自己创建线程,可以参考rt-thread官方文档进行操作。https://www.rt-thread.org/document/site/

5.后期计划

系统移植只是其中的一个很小的步骤,打算先做一下littlevgl的移植,相关的移植会在后续的文章中不断的更新。采用qemu模拟器进行rtthread+littlevgl图形界面的开发和实验。也欢迎大家多多支持,参与这个项目的推进工作。可以直接加我qq邮箱565658641@qq.com联系我。或者到github发issue来推进这个项目。让更多初学rt-thread与littlevgl的人更加方便。





posted @ 2019-12-25 17:30  bigmagic  阅读(1639)  评论(0编辑  收藏  举报