nanoPc T2裸机开发(二)

---------------------------写在前面

已经好久没有玩单片机了,之前玩的stm32根本就不算是学习,只是单纯地使用之前学过的51知识和调用原子的库函数,菜得一匹。有什么不对的地方,还请大家指正,谢谢。

参考:

http://wiki.friendlyarm.com/wiki/index.php/NanoPC-T2/zh#.E7.BC.96.E8.AF.91U-Boot

开发板是使用友善之臂的nanoPc T2,Soc是S5P4418,其他的外设自己看wiki吧,上面都有。我觉得挺不错的,虽然我就只用过这家的,但是用起来还是不错的。

http://weibo.com/p/1001603914482173772682

这是我参考的例程,虽然我没有进去看,(因为我没有微博。。。。)但是我有他的全部相关资料源码,就是整理的微博上的。叫做迪卡大佬,强得一匹。


----------------------------正文

3.编译生成bin文件的话,我们需要s5p4418认可的二进制“语言”,他才能够按照我们的命令执行。所以,我们需要的工具有:

交叉编译工具链:arm-linux-gcc,这个从友善的wiki上面下载,那是肯定没问题的,自己捣鼓的话,就怕下载的编译器不适用于该硬件平台,我就有过这经历,那时候是第一次进行交叉编译,目的是为了编译出arm上能用的qt库,和让他能运行qt程序。这里就不多说了,qt的博文得等以后把一些坑给解决后再一起写了。总之,就是交叉编译工具必须要配对,而官方给的肯定是ok的。

dd工具或者winhex烧写程序:dd是linux平台上面的一个工具,作用是把某些数据转移到某个文件上,通常是用于写img啥的。winhex就是一个dd的IDE,可以在win下面运行的程序,等下我都介绍一下,并且说明为啥要用他们。

ok,首先你先下载好交叉编译工具链,

arm-linux-gcc -c inputfile -o outputfile 这个命令是只编译生成汇编生成目标文件不链接。

arm-linux-ld -Ttext=0x42c00000 inputfile -o outputfile 这个命令是链接用的

下面我来解释一下:

1.分开来编译链接是因为我们要写出一个裸机程序,我们的目标机(即nanoPc)上没有跑系统,所以我们如果用arm-linux-gcc直接编译链接的话,生成的文件头格式中包含了很多信息,而且我往下讲到我们这里使用的方法你就会明白了。

2.使用这个数据搬移的工具要干啥的?首先,我们要先了解s5p4418的启动过程,参考:

https://blog.csdn.net/hkchenhao/article/details/51277037

他上面有张图,我们在winhex上就可以非常清楚的看到sd card 的地址了,这就是我们使用这个工具的原因。我们可以知道,block0(0x0-0x1ff)不能改,block1-block64(0x200-0x81ff)是2ndboot,2ndboot是一个三星公司的一个启动自检的工具,具体暂时不用管,这个不能改,所以不管。0x8200往后是uboot,这个是一个bootloader的开源程序,我们现在不跑系统,暂时用不到,也不是本系列的重点,暂时不管,可以更改。

所以,我们的程序应该是要在0x8200之后按顺序运行的,之前我已经讲过,单片机其实就是0 1 的世界,根据0 1来运行,如果,你可以背得程序的二进制代码的话,你也可以直接输入二进制数值到相应的位置,他也是可以运行的,当然这很难,也没必要。

到了8200就要运行我们的程序了,就是到了8200就要受到我们的控制,不然他下面的杂乱的二进制不知道在干啥。换句话说,你生成的二进制数值序列中,我只要修改其中一处,都可以导致他不能运行,所以如果,我们运行的开头放在8201,而不是8200的话,有可能他也不能运行成功。然后回到第1点中,我没试验过,但是他用完整的arm-linux-gcc进行编译链接是加上了系统平台的信息没错了,现在我们并没有跑系统,所以我猜不行,所以,你们也可以试试,然后把结果告诉我,大家一起学习。

3.arm-linux-ld -Ttext=0x42c00000这个0x42c00000是什么啊?Ttext是链接时的代码段设置,这个就涉及了汇编编译原理的知识了,c/c++编译原理博主也写过一些心得,但是也是在学习中,(逃。。。这个0x42c00000就是我们代码段的首地址了,我们程序编译会分成代码段,数据段等,里面使用的都是相对地址,链接时会把各个.o文件中的各个代码段数据段搬运到一起,然后设定他的代码段首地址为0x42c00000,至于为什么是这个就不知道了,可能是他的start就是这里把?

4.编译的时候,你会发现还有一个start.s文件,这个在写stm32的时候也有见到过,但是也是水过去了,没注意。迪卡大佬的文章中有说明。

.text                                                         @说明下面是代码段

.global _start                                          @global声明 _start为全局变量,不然的话在链接的时候会出现一个

                                                                @warming,提示说找不到代码段的头地址,默认设定为0x42c00000

                                                                @虽然也能用,但是感觉很不好,所以得出结论为,我猜_start为代码段的首地址

_start:    
    b start                                                @b:跳转到start ,这个是汇编的指令,这个我就不多说了,直接给结果
    .word 0x00000000                            @声明了一个数据常量,其实没啥用
    .word 0x00000000
    .word 0x00000000
    .word 0x00000000
    .word 0x00000000
    .word 0x00000000
    .word 0x00000000
start:
    b main

以上一整个文件,就是提供文件的首地址,而不是功能程序的首地址,因为我们的整体架构还有一些中断没有设定,

    b start                                           @0x00:复位
    .word 0x00000000                           @0x04: 未定义指令异常
    .word 0x00000000                           @0x08: 软件中断异常
    .word 0x00000000                           @0x0c: 存储访问异常
    .word 0x00000000                          @0x10: 数据访问内存中断
    .word 0x00000000                           @0x14: 没有使用
    .word 0x00000000                        @0x18: 中断请求异常
    .word 0x00000000                       @0x1c: 快速中断异常

以上8段对应上面的_start下的8段,是表示如果发生了以上的异常中断就跳到这里运行,.word 0x00000000运行也没啥事,就结束了,其实我们的led也没用上这些,就一开始的复位而已。

这就是举个例子,在8200以后粘贴过来。

那么2ndroot在哪来呢?去友善的img中“偷”来,还是那个规则,在200-81ff都是2ndroot全部copy过来,然后再把程序从8200开始copy过来,然后就保存万事大吉。

4.下载到目标机中,其实我们就是利用了sd card启动方式,上面已经说了,我们理成功就只剩下一步了,就是插入sd card,以sd card方式启动,ok,led闪烁,完成。

整个一个流程就是这样,非常简单,但是,非常麻烦,不过我们只是用来理解而已,开发的话,应该不这么做的。

接下来,我将进行更进一步的理论部分,编译链接烧写的过程就不讲了,这些不是重点。









猜你喜欢

转载自blog.csdn.net/qq_38960899/article/details/80216018
今日推荐