本帖最后由 微末凡尘 于 2014-7-27 01:03 编辑
从零开始点亮LED灯
HELPER2416开发板助学计划
水平不高,又想尽可能写详细些,所以可能会显得很琐碎,各位看官见谅哇……希望能帮到拿到开发板无从下手的同学,大家共同进步。
相信很多朋友和我一样,是从单片机转到ARM的。这样就总想把底层搞明白点。所以学ARM就选择了从裸机开始学习。这样可以了解更多,也可为后来学习打下坚实的基础,但是这个过程也不是那么简单,其中涉及到很多琐碎的知识。由于前几天乱插屏幕,不小心把屏幕烧坏了,于是这几天就只好乖乖点灯咯,现在把成果分享大家……【屏坏了本来准备再买一块的,看到保修,但是一般屏幕不在保修之列,就试着问了问,结果老板二话没说就让我寄回去,又给我重新发了一块新的,太感动了,过几天一定再发一帖点屏】。 我原本使用的是WMware + FC18虚拟机镜像。可是这个镜像已经配置好了,实在不便从零开始写这个帖子,就用FC12来写这篇文章吧。
一、FC12的安装
学习2416这样的开发板,很大部分同学的目的就是为了学习Linux,所以,我们尽早接触linux,先熟悉熟悉,对我们日后学习也会有不少帮助。同时在linux下面编译代码更容易让我们了解程序的本质,更好的学习。但是linux的各种配置确实比较麻烦,所以我们完全可以先使用 君益兴 光盘里面的镜像安装,省去复杂的配置,更快的学习核心的知识。有一定基础之后再自己进行配置。
1.我刚才打开FC12的镜像的独立下载链接的时候发现已经失效了,所以我们就直接到光盘里面找吧,光盘的下载链接还是存在的。在下载的光盘的 tools目录下,可以找到fc12.7z文件。
2. 在D盘建立JYX文件夹,在文件夹下面建立一个Disk文件夹。将fc12.7z解压到这个文件夹下。得到如图一个WMware虚拟磁盘文件。我的磁盘空间并不大,就将Disk里面这个fc12.7z这个压缩包删除了。
3.打开VMware软件。按照君益兴手册操作,选择目录是选择 D:\JYX,选择磁盘时选择D:\JYX\Disk下的fc12那个文件即可。
4.对开发环境进行简单测试。右键,在终端打开,打开控制台。
首先利用
cd / 命令,查看根目录下的情况,看看linux下面的目录到底是个什么样子。然后对 arm-linux-gcc 这个命令进行测试,从图中结果可以看出 ,arm-linux-gcc这个命令可以在任何地方运行,表示交叉工具链是可以正常使用的。至于交叉工具链是干嘛的?简单的说,就是在电脑上面编译链接出可以在 开发板上运行的程序的一套工具,这是我们在linux上面就行开发必不可少的一个前提。这些都做好了,我们还需要在Winsows操作系统和linux系统中共享文件,这就是我们经常提到的samba服务器啦。在查看samba服务器之前,我们先建立一个用来共享的目录,我将它命名为S3C2416。使用mkdir /S3C2416来建立这个文件夹,但是提示权限不够,所以,我们需要使用su root切换到root用户,系统会提示输入密码,这个密码为fedora(输入密码的时候,不会有显示,输入完毕后直接回车即可。FC18下面的密码为jyxtec)。输入正确密码后,我们就是root用户啦。然后再来一次 mkdir /S3C2416 在根目录下建立这么一个文件夹。最后使用
chmod 777 /S3C2416 将这个目录的权限全部打开,使所有用户都能对它进行读写以及执行操作。最后,我们可以看到,这个文件夹绿了,这也是权限修改成功的一种现象。
5.配置samba服务器
图7 - ifconfig
在配置之前,我们要确保网络通畅,使用
ifconfig命令查看网络状况(如上图7-ifconfig),这里的我的虚拟机的IP地址为
192.168.0.103,先记住它!然后使用/etc/inin.d/iptables stop来关闭防火墙(这里有一个小秘诀,我们可以用table键来补齐命令,比如这里就可以这样输入,/e(table键)/in(table键).d/ipt(table键) stop,特别是一些很长的命令,效率会提高很多,很多……)。然后,我们在window下面ping 这个地址,(如下图8-ping)表示windows跟linux网络是通的,可以进行下一步设置。
图8 -ping
确定网络通畅之后,我们就要编辑etc/samba/下面的smb.conf这个配置文件,在linux下面,我们一般使用vim作为编译,这玩意有三个模式神马的神乎其神的,我开始看到就被吓到了,其实我们根本不用管那么多。直接先用起,不懂了再翻翻书。我们就用vim打开这个配置文件
wim /etc/samba/smb.conf (记得我们的tabel神技,/e[table]/samba/smb.[table],虽然这里也没几个单词,table神技要多多练习哇)。(如图9-打开配置文件)
图9-打开配置文件
这个命令执行之后,出现如下界面:(图10,vim界面)
图10 vim界面
我们键入
:set nu (:表示进入所谓的
底行模式 后面的set nu表示显示行号),会显示出行号,如(图11-行号显示),这句执行完后 ,它又会恢复原来的模式
命令行模式(默认的模式)。
在底行模式(就是先输入一个:)的操作主要有“:set nu”-显示行号 “:set nonu”--取消行号显示 “:q”--退出(当有修改未保存时,这个命令无效) “:q!”--不保存强制退出 “:w”--保存 “:wq”--保存并退出
图11 :set nu
上面我们提到,执行完:set nu之后(也就是显示出行号),我们又退回到了默认模式(命令行模式),下面我们输入 /browseable 查找browseble这个字符串。如图12-/browseable
图12 -browseble
找到browseable之后,这里就是我们需要修改的地方。将光标通过方向键移动到【home】那一行,按下
6yy 表示复制6行,然后在上一行按下P,粘贴到这里。效果如图13
图13 粘贴
接下来我们就要做一些修改了。按下
i 进入插入模式。这时最左下方会有 插入 字样显示。我们就可以进行编辑。将home改为root,将Home Directories 改为 Root Directories。将browseable后面的no改为yes表示可浏览。添加path / ,表示共享根目录。最后加上 valid users = fedora。表示可登陆的用户为fedora。在进行玩这些修改后,需要键入
:wq,前面已经提过,这个是保存并退出。如图14-1,14-2
14-1 复制并修改 14-2 退出
在我们正式启动samba服务器之前,还需要做一个工作,就是键入
setenforce permissive 。以确保可以共享成功。如图15
图15 关闭SELinux
现在,我们终于可以打开samba服务器啦。命令是
/etc/init.d/smb start 。如图16
图16 打开samba
这些做好了之后,我们就需要通过浏览器来访问samba服务器,来和linux系统共享文件了。在windows系统下。我们打开IE浏览器(只能是IE),并在地址栏输入 我们linux的IP 我的是 192.168.0.103,如图17-1 。 然后选择使用其它账户登陆,如图17-2。 最后输入我们的账户密码fedora,fedora。FC18账户密码都是jyxtec。
图17-1 输入IP
图17-2 使用其他账户
图17-3 输入登陆账户密码
以上操作无误,我们就能看到linux下的这个目录。为了使用方便,我们将这个目录映射为网络驱动器。操作步骤如图18-1,18-2,28-3.
18-1 映射网络驱动器,注意刚才打开的窗口最好开着。
18-2 选择映射的盘符,以及文件夹的位置。
18-3 映射成功。
三、编写文件。(这里我就不贴出具体操作步骤了。将重点方面对代码的解释上)
一般一个简单的裸机工程包含一个汇编文件,一个Makefile文件。一个lds连接器脚本文件。(由于这个工程目前比较简单,暂时不含C文件)。汇编文件相信大家都熟悉。所谓Makefile文件,就是工程管理文件,简化一些操作,虽然这里就一个汇编文件,可以不用这玩意,但是我们还是拿出来,权当学习学习。至于链接脚本文件,顾名思义,就是在 预处理,编译,汇编,链接 这四步最后一步中使用的啦。
在了解这些之后,我们就先来建立这三个文件,在此之前,我们先建立一个名为led的文件夹,方便管理,并将其权限修改为777。建立文件使用
touch命令。然后再用
chmod 777 将其权限修改一下,方便在windows下面访问操作。建立文件夹如图如图19 。建立文件并在windows下查看如图20.
图19 建立文件夹
图20 建立文件并在windows通过网络驱动器查看。
我们通过wim编辑连接器脚本文件。首先说明处理器型号为arm,然后标明程序入口为_start。再标明代码从0x30000000开始存储。这里这个地址其实就是RAM的地址啦。然后分别指明代码段,数据段,bss段。其代码如下:
- OUTPUT_ARCH(arm)
- ENTRY(_start)
- SECTIONS
- {
- . = 0x30000000;
-
- . = ALIGN(4);
- .text :
- {
- start.o(.text)
- *(.text)
- }
-
- . = ALIGN(4);
- .data :
- {
- *(.data)
- }
-
- . = ALIGN(4);
- __bss_start = .;
- .bss :
- {
- *(.bss)
- }
- bss_end = .;
- }
复制代码 然后我们再来看Makefile文件
- all : start.o
- arm-linux-ld -Tled.lds -o led.elf $^
- arm-linux-objcopy -O binary led.elf led.bin
-
- %.o : %.S
- arm-linux-gcc -g -c $^
-
- %.o : %.c
- arm-linux-gcc -g -c $^
-
- .PHONY:clean
- clean :
- rm *.o *.elf *.bin
复制代码 我们首先解读这一句代码:
%.o : %.S
arm-linux-gcc -g -c $^
%.o代表 任何 “.o”文件,%.S 代表任何 ".S"即汇编文件。它们中间有一个":",冒号左边表示命令要生成的目标,右边表示生成这些目标需要的依赖。而下面的
arm-linux-gcc -g -c $^ 则是一条编译命令了。表示用&^生成相应的 ".o"文件。而这里的$^则代表所有依赖。这里就是%.S。如果使用到我们这个工程中就是 start.S啦。
%.o : %.c
arm-linux-gcc -g -c $^ ,这一句跟上一句没什么区别,就不做解释啦。
clean :
rm *.o *.elf *.bin ,然后便是这么一句,它是不是很奇怪,居然没有依赖。所以嘛,大家看,它上面多了一行,
.PHONY:clean 。这句就是说明,它是一个奇葩咯。我们一般使用 make clean来执行它下面的命令,做一些清除工作。一般拿到别人的一个工程,第一步就是清除之前编译配置产生的文件。防止再次编译出错。
all : start.o
arm-linux-ld -Tled.lds -o led.elf $^
arm-linux-objcopy -O binary led.elf led.bin
最后这个部分也有点小奇葩,它的目标竟然是all,野心不小哇。所以呢,执行它就只是需要键入 make ,后面什么都不用跟。一般我们编译就是接使用make。 而这个的依赖是start.o。而".o"文件又是下面两段的目标。所以,它便会先执行下面两段,为all这一段产生出这个依赖。然后开始下面的执行。arm-linux-ld -Tvboot.lds -o led.elf $^,这句表示使用start.o按照led.lds这个链接脚本文件 生成led.elf文件.但是这个elf文件不是二进制的,所以,我们再使用arm-linux-objcopy -O binary led.elf led.bin 将这个elf文件转换为led.bin文件,以供下载。
这样一来,就只剩下我们最后那个start.S文件了。这个文件就稍微复杂一点。跟S3C2416有直接联系,但也是最有意思的地方,各位打起精神咯……呼呼……
首先,我们得知道,我们这个代码就是弄成nand flash启动的。而helper2416的nana flash启动就是和传统的2440开发板是一样的,就是它的垫脚石比2440大点。(但是大家也不要以为2416就和2440区别不大,毕竟2416是支持IROM模式的SD卡启动的。这个可是S3C6410的技能噢,不过S3C6410的nand flash启动一般也是在IROM模式下,但是helper2416因为一个烧写工具不方便在前面加校验码(S3C6410不用加)的原因而没有使用IROM下的nand flash启动)。后来的cortex-a8系列的210,其实也有这个校验码,所以一般都要使用一个专门的加头软件。扯远啦。还是回来吧……
我们先来分析一下,要点亮led。我们首先需要处理器哪些地方弄好呢?首先有一个异常向量表(1),然后呢,就是设置为svc模式(2),然后就是关闭看门狗(3),关闭中断(4),关闭mmu和cache(5)(为了简单,我们将这些东西全部先关掉)。然后就操作寄存器,点亮LED灯咯(6)。
其实一共也就6步,我们一步一步来。其实这个文件的编写,大家使用windos下的记事本之类的,或者是linux下的vim都可以,因为我们早就把linux那个目录,变成我们windows下面的一部分了哇。
(1)异常向量表。我们复位之后当然是进入reset里面执行,所以第一句就是b reset啦。我们定义
_undefined_instruction的值为函数undefined_instruction的地址。通过ldr pc,_undefined_instruction,就可以跳到那个地方啦。这也是uboot等的写法。至于异常向量表为什么这样,论坛里面有很多帖子了,我这篇终究还是以实践为主,就不深究这一部分啦。大家也可先直接抄下,点亮灯了再来研究。
- .text
- .global _start
- _start:
- b reset
- ldr pc, _undefined_instruction
- ldr pc, _software_interrupt
- ldr pc, _prefetch_abort
- ldr pc, _data_abort
- ldr pc, _not_used
- ldr pc, _irq
- ldr pc, _fiq
-
- _undefined_instruction:
- .word undefined_instruction
- _software_interrupt:
- .word software_interrupt
- _prefetch_abort:
- .word prefetch_abort
- _data_abort:
- .word data_abort
- _not_used:
- .word not_used
- _irq:
- .word irq
- _fiq:
- .word fiq
-
- undefined_instruction:
- nop
- software_interrupt:
- nop
- prefetch_abort:
- nop
- data_abort:
- nop
- not_used:
- nop
- irq:
- nop
- fiq:
- nop
- reset:
复制代码
(2) 设置为svc模式
为什么要进入SVC模式,你要我干活,总得给个理由吧。关于SVC我们在《ARM Architecture Reference Manual》这个手册中可以看到。手册奉上:
ARM Architecture Reference Manual.pdf
(5.53 MB, 下载次数: 0)
。 手册中svc是Supervisor。为了让程序运行时,不因为权限出错。我们就先启动这种高端大气的模式吧。
但是现在我们只知道了SVC是啥,并不知道怎么操作哇,就在相同的手册中,有这么一段:如图22
图22,cpsr,这M【4:0】,就是更改模式的位置啦。
同时,我们发现这个寄存器中的I和F位,有清除中断标志位的作用,我们这里一并置位了吧。
我们先在reset下面加一行代码,跳去执行set_svc。
然后便是具体代码
- set_svc:
- mrs r0, cpsr /* r0 < ---cpsr */
- bic r0, r0, #0x1f /* r0 < ---(clear r0[4:0]) */
- orr r0, r0, #0xd3 /* set to svc , disable irq and fiq */
- msr cpsr, r0 /* cpsr< ---r0 */
- mov pc, lr
复制代码
(3)关闭看门狗
我们先在reset下面加一行代码
bl disable_watchdog,跳去执行
disable_watchdog。
- reset:
- bl set_svc
- bl disable_watchdog
复制代码 具体代码
- #define pWTCON 0x53000000
- disable_watchdog:
- ldr r0, =pWTCON
- mov r1, #0x0
- str r1, [r0]
- mov pc, lr
复制代码 ldr r0,=pWTCON 将WTCON寄存器的地址存入
mov r1,#0x0 将r1全置为0
str r1 ,[r0] 直接将全0写入WTCON。简单粗暴。
mov pc ,lr 返回
(4)关闭中断 这个部分也在S3C2416手册里面,几个位置1,就关闭相应中断。我们干脆将其全部置1
现在reset后面添加一句,这里就不贴出来了,然后是具体代码:
- #define ELFIN_INTERRUPT_BASE 0x4a000000
-
- #define INTMSK1_OFFSET 0x08
- #define INTMSK2_OFFSET 0x48
- #define INTSUBMSK_OFFSET 0x1c
- disable_interrupt:
- ldr r0, =ELFIN_INTERRUPT_BASE
- mvn r1, #0x0 /* 先将0按位取反,然后送入R1 */
- str r1, [r0, #INTMSK1_OFFSET]
- str r1, [r0, #INTMSK2_OFFSET]
- str r1, [r0, #INTSUBMSK_OFFSET]
- mov pc, lr
复制代码
(5) 关闭mmu和cache
MMU和cache的部分在核的手册里面。S3C2416使用的是《ARM_926EJS_TRM》,附上文档
ARM_926EJS_TRM.pdf
(1.62 MB, 下载次数: 1)
这一部分在cp15协处理中。如下图:
在CP15 Control部分
CP15的C1寄存器
第0位清除MMU,第2位,关闭D cachel
甚至这个手册中都给出了代码怎么写。第一句,Invalidate ICache and DCache(关闭ID cache)。后面还有单独关闭D cache之类的代码,在第50面。大家可自行查看。
具体代码如下:
- disable_mmu:
- mcr p15,0,r0,c7,c7,0
- mrc p15,0,r0,c1,c0,0
- bic r0,r0,#0x00000007
- mcr p15,0,r0,c1,c0,0
- mov pc, lr
复制代码 这部分代码对于2440,2416,6410,210(A8)都是适用的。所以百度等等也比较容易找到,就不具体解释了。
(6) 点亮LED灯咯
话就不多说啦,这段代码就是将IO口设置为输出,然后GPB1为输出低电平。
- #define GPBCON 0x56000010
- #define GPBDAT 0x56000014
- light_led:
- ldr r0, =GPBCON
- ldr r1, =0xFFFFFFF7
- str r1, [r0]
-
- ldr r0, =GPBDAT
- ldr r1, =0xFFFFFFFD
- str r1, [r0]
- mov pc, lr
复制代码
四 、编译
至此,整个代码都完毕了。我上传我整理过的。大家可以对比下。
led.zip
(1.88 KB, 下载次数: 9)
然后,我们通过make命令,来编译,如图24
图 24-编译
编译完之后,我们可以在windows的虚拟磁盘上看到这个bin文件。将其拷贝出来。以便我们下载到单片机中。
图25 -生成文件
最后,我们可以通过 make clean 将我们编译过程生成的文件清除。如图26
图26 清除文件
五、烧录到开发板
烧录得准备的文件如下:
其中u-boot.534.64m-movi.bin也可以换为u-boot.600.64m-movi.bin。
然后打开IROM_Fusing_Tool.exe。按照如下格式设置:
将开发板设置为SD卡启动。在出现如下解码时,敲入y然后回车(推荐使用SecureCRT)
静静等待直至这个界面出现。然后将开发板调回NANDFLASH启动。
下面我们可以看到,我们LED灯亮起来啦。
大家还可以将IO口设置为高电平,LED灯灭。确定确实是我们程序使LED这样变化的。
论坛ID:微末凡尘
提交时间:2014.07.27