前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >龙芯ls2k1000开发板移植rt-thread笔记

龙芯ls2k1000开发板移植rt-thread笔记

作者头像
bigmagic
发布2020-05-08 14:23:17
2.8K0
发布2020-05-08 14:23:17
举报
文章被收录于专栏:嵌入式iot嵌入式iot

ls2k1000开发板移植rt-thread笔记

  • 1.前言
  • 2.龙芯派基本介绍
  • 3.rt-thread在龙芯派上的运行过程
  • 4.rtt的启动分析
    • 4.1 启动代码引导
    • 4.2 rt-thread的启动流程
  • 5.关键部分驱动的初始化
  • 6.Stack Frame
  • 7.总结

1.前言

龙芯2k1000开发板拥有非常丰富的外设资源,板子设计也非常的精致。

所以打算运行一下rt-thread,然后进行相关的开发操作。

本文主要针对龙芯2k1000的龙芯派的开发板进行rt-thread移植,通过这篇文章,基本上掌握rt-thread对于一个新的体系架构上的移植过程,同时也可以很好的掌握mips64体系架构上的相关知识,同时熟悉使用龙芯派2k1000。

由于裸机开发与rtos开发有着一定的联系,所以如果要想理解rt-thread更加底层的东西,一定需要理解芯片的设计以及各种体系架构的设计。

2.龙芯派基本介绍

龙芯派就是面对普通开发群体的一个开发板,龙芯派搭载 2K1000 处理器(主频 1GHz),板载 DDR3 颗粒,实现 DDR3 的运行存储功能。实现了 GPIO 的输入输出,中断功能。板上集成 1 个网 口,集成 3 个 USB 接口,HDMI 接口,LCD 接口,音频输入/输出,集成 SD 卡接口,集成 2 个 CAN 接口,集成 RTC 计时功能。可以外扩 WIFI 模块。2K 龙芯派可以广泛应用于信息安 全、电力、轨道交通、工业控制、信号处理、数据通信、信息教育等领域。

由于其强大的性能以及多接口,也让更多方案实现变的可能。

龙芯派拥有8Mb的SPI Flash,龙芯的BIOS就是存放在这个SPI Flash中,龙芯叫pmon。可以理解为uboot,由于龙芯的pmon的使用,我们为了验证和体验效果,并且方便开发测试,我们可以利用pmon的tftp的下载功能,将固件拷贝到内存中,然后直接执行即可。这种方式有利于程序的调试和开发。

当实际应用到生产环境中时,可以将rt-thread固化到spi flash中,这样就可以很好的加快启动速度了。现在我们只讲开发阶段的启动过程。

3.rt-thread在龙芯派上的运行过程

龙芯派是通过网络下载方式将固件进行烧录的,所以首先启动了pmon,然后将rt-thread固件转移到ddr中。

上电之后,龙芯的pmon开始启动,当串口打印过程中,我们可以通过输入键盘上的c字符进入pmon的控制台中,这样就可以利用pmon的tftp将固件加载到ddr中,然后跳转到ddr中去执行。

代码语言:javascript
复制
ifaddr syn0 192.168.12.100
load tftp://192.168.12.35/rtthread.elf;
g

其中ifaddr为设置开发板的ip地址,syn0表示第一个网卡,load加载程序到内存,g开始执行。

接着,rt-thread启动初始化流程,初始化串口,初始化中断,然后开启中断,线程开始调度,rt-thread开始进行任务调度。

这就是一个龙芯派执行的完整流程。

4.rtt的启动分析

对于龙芯派的移植,或者说对于一个新的体系架构移植rt-thread,基本过程分为如下几个部分:

1.裸机代码引导,初始化栈空间与bss段,为运行c代码提供环境

2.关闭中断,直到所有的流程初始化完成,第一个最高优先级的线程出栈时,打开中断

3.初始化uart

4.初始化os tick中断

5.控制台输出logo

6.初始化ipc,以及组件,初始化timer()以及idle线程

4.1 启动代码引导

这部分的主要功能就是为启动C代码做准备。

这部分的代码一般是由汇编写的,准备好sp的栈指针,然后清空bss段然后直接跳转到了rtthread_startup函数中。

然后就进入rt-thread入口函数。

4.2 rt-thread的启动流程

简述一下rt-thread的启动流程如下:

1.关闭全局中断

2.板级驱动初始化(关键初始化,timer、uart等,移植大部分工作)

3.初始化选中的rtt组件

4.打印logo

5.调度器初始化

6.初始化main、idle等线程

7.启动调度(出栈时开启全局中断)

8.线程开始调度

5.关键部分驱动的初始化

对于龙芯2k1000来说,我们需要关注的是rt_hw_board_init里面关键外设的初始化。这里主要涉及到两个,一个是uart驱动初始化,另外一个就是timer初始化。

对于tick,我们采用mips中的c0寄存器进行比较。

HPET 控制器

通过配置,每个定时器都能独立产生中断。

这组定时器由一个向上累加的主计时器(up-counter)以及一组比较器构成。这个计时器以固定的频率(125MHz)向上累加,因此当软件两次读取计时器的值时,除非遇到计时器溢出,否则第二次读取的值总是比第一次读取的值大。而每个定时器都包含一个 match 寄存器以及一个比较器。当 match 寄存器的值与主计时器相等时,那么定时器产生中断。部分定时器可产生周期性中断。HPET 模块包括一个主计数器(main count)以及三个比较器(comparator),且他们的宽度都是 32 位。在这三个比较器中,有且仅有一个比较器支持周期性中断(periodic-capable),这三个比较器都支持非周期性中断。

而在我们的rtt中正常情况下是使用非周期性中断。相关的寄存器不展开描述,使用的过程中配置好即可。

uart控制器

作为rtt的控制台,串口这部分也是必不可少的,在使用ls2k1000的时候,需要充分考虑到uart资源使用情况。

2K1000 集成了 12 个 UART 控制器,通过 APB 总线与总线桥通信。虽然说有这么多串口控制器,但是实际上很多都是复用的串口控制器,所以实际上只能最大同时使用的是4路uart接口。

其uart控制器有如下几个部分:

1.发送和接收控制器负责将fifo中的数据进行分发或者接收

2.moden寄存器控制着串口的输出信号 DTR 和 RTS 的状以及相关的校验状态。

3.中断仲裁模块:当任何一种中断条件被满足,并且在中断使能寄存器(IER)中相应位置 1,那么 UART 的中断请求信号 UAT_INT 被置为有效状态。

4.访问寄存器模块:当 UART 模块被选中时,CPU 可通过读或写操作访问被地址线选中的寄存器。

其中中断这一块必须十分的小心,因为串口的使用,涉及到fifo的时候,需要知道空闲状态以及相关的半满或者全满或者32字节产生中断等属性。否则读取数据出来将异常复杂。

6.Stack Frame

栈帧这部分与编译器相关,也与体系架构相关,所以在使用的时候,需要知道栈的活动轨迹。函数的压栈与出栈,操作系统的调用,都和这部分相关。

rt-thread的压栈操作在libcpu的特定的体系架构的stack.c文件中。

每个线程在初始化的时候,都会进行压栈操作。出栈的操作在context_gcc.S文件中。

压栈除了压入通用寄存器外,还会涉及到状态寄存器,比如spsr或者cpsr等等,如果有FPU,也需考虑进去。

需要注意的是,压栈的顺序与出栈的顺序必须是一一对应的。这部分的调试功能比较繁琐,需要一步一步的进行跟踪。

7.总结

移植rt-thread到ls2k1000的开发板的过程主要如上述所示。如果有新的体系架构要移植到rt-thread上,需要充分的考虑移植的过程与移植的流程。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 嵌入式IoT 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ls2k1000开发板移植rt-thread笔记
    • 1.前言
      • 2.龙芯派基本介绍
        • 3.rt-thread在龙芯派上的运行过程
          • 4.rtt的启动分析
            • 4.1 启动代码引导
            • 4.2 rt-thread的启动流程
          • 5.关键部分驱动的初始化
            • 6.Stack Frame
              • 7.总结
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档