1. 构建S3C6410裸机开发环境,并使用GPIO控制LED灯

开发环境:

软件环境:Ubuntu12.04

硬件环境:Tiny6410 + Jlink

一、安装Jlink

   在linux下面可用的Jlink为V4.22版本的,SEGGER官网上好像有最新版本linux下面的Jlink,但是没有尝试过,听过升级了最新版本的固件之后山寨的Jlink就用不了了。

JLink_Linux_V422下载地址在我的网盘上:http://yun.baidu.com/s/1c027ogK

使用方法见README:

Requirements
============
Please make sure that you have installed libusb as this is necessary for 
the J-Link to work via USB.
You can install it the following way for all apt-able Linux derivates:

apt-get -update
apt-get -install libusb

This will update the apt-get package resources and download and install
libusb. Please unplug and replug your J-Link after successful
libusb installation.

You also need to make sure the libreadline is installed on your system.
This library is needed by the JLinkExe utility.

Installing the shared library
=============================
To install the delivered shared library in a system directory perform the following
steps as root:
- Copy the library in a system directory for example /usr/lib 
  cp libjlinkarm.so.* /usr/lib

- Update the cache of dynamic loader and setup symbolic links by running:
  ldconfig

Running JLinkExe with standard user rights
==========================================
In order to run JLinkExe with standard user rights you have to do the following:

- Place the rule file "45-jlink.rules" provided with this J-Link software package
  at /etc/udev/rules.d/

- Make sure that you are member of the group "plugdev"

- If the group "plugdev" does not exist, you have to create it:
  Command line:
  groupadd plugdev                      // Creates new group "plugdev"
    usermod -a -G plugdev <Username>      // Appends user <Username> to the group "plugdev"

- Restart your system
View Code

 

二:编写裸机程序的方法

裸机程序由两部分组成: 启动代码 + 应用程序
启动代码的作用: 初始化硬件

6410最简单的启动代码由两部分组成:
设置外设寄存器地址的范围
/* peripheral port register address range set */
ldr r0, =0x70000000@the base address of peripheral port is 0x70000000
orr r0, #0x13@address range is 256M,  0x7000 0000 -- 0x7FFF FFFF
mcr p15,0,r0,c15,c2,4
         
 关看门狗  
        /* disable the watchdog */
    ldr r0, =0x7E004000        @看门狗控制寄存器
    mov r1, #0
    str r1, [r0]

由于6410将地址划分为两部分,内存地址(0x0000 0000  -- 0x6FFF FFFF) 和 外设寄存器地址(0x7000 0000 -- 0x7FFF FFF)。
而CPU访问这两种地址是通过不同的总线完成的。所以需要通过指令告诉CPU外设寄存器地址的范围。这条指令是通过协处理器完成的。

因为6410上电时默认是使能看门狗的,所以需要关掉。
看门狗的控制寄存器起WTCON   0x7E004000 

(对于2410来说就不需要第一步,因为2410访问内存和外设寄存器地址都是使用的相同的方式。)

 

三: LED电路图的分析:

由GPK控制:
GPK4 ---- LED1
GPK5 ---- LED2
GPK6 ---- LED3
GPK7 ---- LED4

GPIO由两部分组成。分别是alive part和off part.
其中alive part在sleep 模式仍然会被供电, 但是off part在sleep模式中就不会被供电。
控制GPIO的寄存器主要有控制寄存器    数据寄存器    上/下拉寄存器    Sleep模式配置寄存器    Sleep模式上/下拉配置寄存器
其中控制GPK的寄存器有:
    GPKCON0    0x7F00 8800
    GPKCON1    0x7F00 8804
    GPKDAT        0x7F00 8808
    GPKPED        0x7F00 880C
GPKCON0 控制GPK0 -- GPK7        每个引脚占用4Bit
GPKCON1 控制GPK8 -- GPK15        可以设置引脚为GPIO输出或者输入,  或者是其他的功能。
如果Bit[31:28]=0001,那么GPK7设置为输出。

 

四:编写链接文件lds

 1 OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
 2 OUTPUT_ARCH(arm)
 3 OUTPUT(led)
 4 
 5 ENTRY(_start)
 6 SECTIONS
 7 {
 8     . = 0x0c000000;
 9     . = ALIGN(4);
10     .text : 
11     {
12         *(.text)
13     }
14 
15     . = ALIGN(4);
16     .data : 
17     {
18         *(.data)
19     }
20 
21     . = ALIGN(4);
22     bss_start = .;
23     .bss : 
24     {
25         *(.bss)
26     }
27     bss_end = .;
28 }

五:编写Makefile文件:

 1 CROSS_COMPILE=arm-linux-gnueabi-
 2 #CROSS_COMPILE=arm-linux-
 3 
 4 OBJ=led
 5 
 6 AS=$(CROSS_COMPILE)as
 7 LD=$(CROSS_COMPILE)ld
 8 OBJCOPY=$(CROSS_COMPILE)objcopy
 9 OBJDUMP=$(CROSS_COMPILE)objdump
10 AS_FLAGS=-march=armv6 -mcpu=arm1176jzf-s -mfloat-abi=softfp -mfpu=vfp
11 LD_FLAGS=-Bstatic -T $(OBJ).lds
12 
13 
14 $(OBJ).bin:$(OBJ).o
15     $(LD) -o $(OBJ) $(LD_FLAGS) $^
16     $(OBJCOPY) -O binary $(OBJ) $@
17     $(OBJDUMP) -D $(OBJ) > $(OBJ).dis
18 
19 $(OBJ).o:$(OBJ).S
20     $(AS) $(AS_FLAGS) $< -o $@
21 
22 .PHONY:clean
23 clean:
24     rm -f $(OBJ).o $(OBJ) $(OBJ).bin $(OBJ).dis

六:编写LED的汇编代码

这是采用的AT&T风格的汇编代码,

.global定义了一个全局标号,可以被外部文件引用,相当与extern的作用。

.section是用来定义段的,.text表示代码段

 1 .global _start
 2 .section .text
 3 
 4 _start:
 5 
 6     /*
 7      * set the CPU to SVC32 mode
 8      */
 9     mrs r0,cpsr
10     bic r0,r0,#0x1f        @ clear the last 5 bits
11     orr r0,r0,#0xd3        @ 0b11010011, set the svc mod, and disable fiq irq
12     msr cpsr,r0
13 
14     /*
15      * flush v4 I/D cahces
16      */
17     mov r0,#0
18     mcr p15, 0, r0, c7, c7, 0        /* flush v3/v4 cache */
19     mcr p15, 0, r0, c8, c7, 0        /* flush the v4 TLB */
20 
21     /*
22      * disable MMU stuff and caches
23      */
24     mrc p15, 0, r0, c1, c0, 0
25     bic    r0, r0, #0x00002300    @ clear bits 13, 9:8 (--V- --RS)
26     bic    r0, r0, #0x00000087    @ clear bits 7, 2:0 (B--- -CAM)
27     orr    r0, r0, #0x00000002    @ set bit 2 (A) Align
28     orr    r0, r0, #0x00001000    @ set bit 12 (I) I-Cache
29     mcr    p15, 0, r0, c1, c0, 0
30 
31     /* peripheral port register address range set */
32     ldr r0, =0x70000000    @the base address of peripheral port is 0x70000000
33     orr r0, #0x13        @address range is 256M,  0x7000 0000 -- 0x7FFF FFFF
34     mcr p15,0,r0,c15,c2,4
35     
36     /* disable the watchdog */
37     ldr r0, =0x7E004000
38     mov r1, #0
39     str r1, [r0]
40     
41     b user_program
42 
43     /*
44      * LED1 <----> GPK4
45      * LED2 <----> GPK5
46      * LED3 <----> GPK6
47      * LED4 <----> GPK7
48      */
49 user_program:
50     /************** control the led ***************/
51     /* control led1 GPK4 */
52     ldr r0, =0x7F008800
53     ldr r1, =0x00100000
54     str r1, [r0]        /* set GPK5 as output*/
55 
56     ldr r0, =0x7F008808
57     ldr r1, [r0]
58     bic r1, #0x20        /* clear the bit 5 */
59     str r1, [r0]
60     b loop
61 
62 loop:
63     b loop
64 
65 .end

七:安装交叉编译工具链

我使用的是ELDK5.2,可以在DENX的官网下载,地址ftp://ftp.denx.de/pub/eldk/

当前最新的版本是5.5

具体安装方法参考denx的网站的Documents

也可以使用其他的交叉编译工具,比如FriendlyARM提供的arm-linux-gcc-4.5.1-v6-vfp-20101103.tgz,可以到我的网盘下载http://pan.baidu.com/s/1hqge03i

 

八:编译

导入环境变量,我的ELDK安装的路径是/opt/eldk-5.2.1

source /opt/eldk-5.2.1/armv6/environment-setup-armv6-vfp-linux-gnueabi

Make:

caodan@caodan-Ubuntu:~/code/asm/S3C6410/led1$ make
arm-linux-gnueabi-as -march=armv6 -mcpu=arm1176jzf-s -mfloat-abi=softfp -mfpu=vfp led.S -o led.o
arm-linux-gnueabi-ld -o led -Bstatic -T led.lds led.o
arm-linux-gnueabi-objcopy -O binary led led.bin
arm-linux-gnueabi-objdump -D led > led.dis

其中生成的led.bin是要下载到CPU中运行的二进制代码。

 

九:下载运行

由于tiny6410的启动方式的NANDFlash启动,所以上电的时候会自动加载NANDFLASH中的前4K内容加载到SteppingStone区域(0x0c000000这个地址),SteppingStone是一个内部的SRAM,所以是可读写的。同事SteppingStone又会自动被映射到0地址处,这就是NANDFLASH启动的原理。

可以利用这个特性,直接将刚才编译生成的代码下载到SteppingStone中运行。

启动Jlink

caodan@caodan-Ubuntu:~/code/asm/S3C6410/led1$ jlink
SEGGER J-Link Commander V4.22 ('?' for help)
Compiled Dec 17 2010 17:41:09
DLL version V4.22, compiled Dec 17 2010 17:41:06
Firmware: J-Link ARM V8 compiled Dec 16 2010 20:21:29
Hardware: V8.00
S/N: 20100213 
Feature(s): RDI,FlashDL,FlashBP,JFlash,GDBFULL 
VTarget = 3.248V
Info: TotalIRLen = 9, IRPrint = 0x0011
Found 2 JTAG devices, Total IRLen = 5:
 #0 Id: 0x2B900F0F, IRLen: 04, IRPrint: 0x0, ARM ETB
 #1 Id: 0x07B76F0F, IRLen: 05, IRPrint: 0x1, ARM1176 Core
ARM11 identified.
JTAG speed: 100 kHz
J-Link>

加载程序到0x0c000000

J-Link>loadbin /home/caodan/code/asm/S3C6410/led1/led.bin 0c000000
Loading binary file... [/home/caodan/code/asm/S3C6410/led1/led.bin]
Writing bin data into target memory @ 0x0C000000.
J-Link: ARM11 CP15 Settings changed: 0x00450078 from 0x00001002, MMU Off, ICache Off, DCache Off
Info: CP15.0.0: 0x410FB766: ARM, Architecture Unknown architecture
Info: CP15.0.1: 0x1D152152: ICache: 16kB (4*128*32), DCache: 16kB (4*128*32)
DIDR: 6 Breakpoints available and 2 Watchpoints available.

设置PC指针,并跳转到0x0c000000处运行

J-Link>setpc 0x0c000000
J-Link>g

此时就可以看到核心板上的LED2亮起来了。

 

 

 

 

 

 

 

posted @ 2014-03-21 11:00  xiaoying_  阅读(1285)  评论(0编辑  收藏  举报