S3C6410开发(3)-编译运行第一个流水灯程序

发布者:Xiaoxue666最新更新时间:2022-06-16 来源: eefocus关键字:S3C6410  编译运行  流水灯程序 手机看文章 扫描二维码
随时随地手机看文章

编写程序

由于我们是在纯裸机上编程,没有uboot之类的程序为我们初始化硬件资源,所以我们要编写一个带有初始化功能的汇编文件。同时为了直观地感受到程序的运行,我们在里面添加一个流水灯的小程序。在工作目录新建一个 statup.s 的文件,编写初始化程序并根据电路板原理图配置LED的GPIO的模式和输出电平


.global _start


_start:

    // 把外设的基地址告诉CPU

    ldr r0, =0x70000000    // 对于6410来说内存(0x00000000~0x60000000)

                           // 外设(0x70000000-0x7fffffff)

    orr r0, r0, #0x13           // 外设大小:256M

    mcr p15,0,r0,c15,c2,4       // 把r0的值(包括了外设基地址+外设大小)告诉cpu


    // 关看门狗

    ldr r0, =0x7E004000

    mov r1, #0

    str r1, [r0] 


    // 设置GPMCON

    ldr r1, =0x7F008820                 

    ldr r0, =0x00001111                                                               

    str r0, [r1]


    mov r2, #0x1000

led_blink:

    // 设置GPMDAT,使GPM 1/2/3/4引脚输出低电平,LED亮

    ldr r1, =0x7F008824                     

    mov r0, #0x0

    str r0, [r1]


    // 延时

    bl delay                            


    // 设置GPMDAT,使GPM 1/2/3/4引脚输出高电平,LED灭

    ldr r1, =0x7F008824                     

    mov r0, #0xF

    str r0, [r1]


    // 延时

    bl delay    


    sub r2, r2, #1

    cmp r2,#0

    bne led_blink


halt:

    b halt



delay:

    mov r0, #0x100000      // 延时时间

delay_loop:

    cmp r0, #0

    sub r0, r0, #1

    bne delay_loop

    mov pc, lr


这段程序的意思大家一个一个的查汇编指令和6410的寄存器说明书来理解,这里就不过多解释了。修改里面的寄存器地址来匹配你自己开发板的LED端口,然后我们保存并关闭该文件,开始编写makefile


makefile

我们这里用的makefile是我从stm32的那个标准工程复制修改过来的,删除了一些没用的参数,并修改了一些参数,我们先来看具体内容。


################################################################################

#   简介:编译S3C6410裸机程序的makefile

#   

#   作者:tuzhi

#   日期:2017.9.1

#

################################################################################



#--------------------------------- 编译参数 ------------------------------------

ifneq ($(V),1)

Q       := @

NULL    := 2>/dev/null

endif



TARGET := LEDasm


# 设置内核型号

ARCH_FLAGS += -mcpu=arm1176jzf-s


# 搜索目录下asm文件

AS_SRC := $(shell find ./ -name '*.s')  

AS_OBJ := $(AS_SRC:%.s=%.o)



# Linker flags

LDFLAGS     := --static

LDFLAGS     += -Ttext 0xc000000


# OBJ

OBJ = $(AS_OBJ) 


#-------------------------------- 编译器调用指令 --------------------------------

PREFIX  := arm-none-eabi


LD      := $(PREFIX)-ld

AS      := $(PREFIX)-as

OBJCOPY := $(PREFIX)-objcopy

OBJDUMP := $(PREFIX)-objdump

GDB     := $(PREFIX)-gdb



#----------------------------------- 编译对象 -----------------------------------

.SUFFIXES: .elf .bin .list

.SECONDEXPANSION:

.SECONDARY:


all: elf


elf: $(TARGET).elf

bin: $(TARGET).bin

list: $(TARGET).list



%.bin: %.elf          

    @printf "  OBJCOPY $(*).binn"

    $(Q)$(OBJCOPY) -Obinary $(*).elf $(*).bin


%.list: %.elf

    @printf "  OBJDUMP $(*).listn"

    $(Q)$(OBJDUMP) -S $(*).elf > $(*).list


%.elf: $(OBJ)

    @printf "  LD      $(TARGET).elfn"

    $(Q)$(LD) $(OBJ) $(LDFLAGS) -o $(TARGET).elf


$(AS_OBJ): %.o:%.s

    @printf "  AS      $(*).sn"

    $(Q)$(AS) $(ARCH_FLAGS) -o $(*).o -c $(*).s


clean:

    @#printf "  CLEANn"

    $(Q)$(RM) $(shell find -name '*.o' -o -name '*.d' -o -name '*.elf' -o -name '*.bin') 

    $(Q)$(RM) $(shell find -name '*.hex' -o -name '*.srec' -o -name '*.list' -o -name '*.map') 

    $(Q)$(RM) $(shell find -name 'generated.*' -o -name '*.srec' -o -name '*.list' -o -name '*.map') 


OOCD         := openocd

OOCDFLAGS        += -f openocd.cfg


debug: $(TARGET).elf

    @printf "  GDB DEBUG $    $(Q)$(GDB) -iex 'target extended | $(OOCD) $(OOCDFLAGS) -c "gdb_port pipe"'

    -iex 'monitor reset halt' -ex 'load'  $(TARGET).elf


.PHONY: clean elf bin list debug


先不要看下面debug目标的内容,我们先来看一看编译的参数,与stm32不同的是,由于我们这个工程内没有C语言文件,所以我们首先删除了与C有关的编译参数,然后将.s文件的编译器改回为as,将链接器改回为ld,之前这样设置是为了通用性和能将C和C++代码一起链接,此部分内容在工具链官方说明书中有讲解,而此处是为了不使编译报错(由于缺少C编译参数和main函数的)。


在文件夹下运行make,编译成功,你也可以运行make V=1来查看实际的编译指令


$ make V=1

  AS      start.s

arm-none-eabi-as -mcpu=arm1176jzf-s -o start.o -c start.s

  LD      LEDasm.elf

arm-none-eabi-ld ./start.o  --static -Ttext 0xc000000 -o LEDasm.elf


注意我们这里最后的链接部分没有使用链接规则文件,而直接使用了 -Ttext 0xc000000的参数表面的程序储存地址,这里0xc000000是6410中的内置ram地址,一共4K大小,原本是用来为bootloader运行启动准备的,系统上电后会自动将nand flash的前4K内容复制到此处运行,由于我们没有在程序中初始化ram的外部芯片,所以这里我们就只能将程序下载到这个地址上运行了。


运行并调试

同stm32一样,在makfile的最后我们使用了一段命令通过管道直接将开启了openOCD连接了目标板,并load了elf文件,不过在执行这个指令之前,我们还需要编写一个openOCD的配置文件,来供软件调用。我们在工程目录下新建一个文件 openocd.cfg


source [find interface/jlink.cfg]


adapter_khz 500


source [find target/samsung_s3c6410.cfg]


一切准备就绪后,我们运行make debug,启动jlink连接目标板


Reading symbols from LEDasm.elf...(no debugging symbols found)...done.

Loading section .text, size 0x7c lma 0xc000000

Start address 0xc000000, load size 124

Error: 16 words out of 31 not transferred

Transfer rate: 992 bits in <1 sec, 124 bytes/write.

(gdb) 


由于gdb不识别汇编文件,使用list是看不到源代码的(我试了几个办法都不行,貌似是因为汇编文件没有 -g 输出调试信息的原因,不知道大家有没有什么方法),我们使用display来显示当前运行的汇编代码。


(gdb) display /i $pc

1: x/i $pc

=> 0xc000000 <_start>:  mov r0, #1879048192 ; 0x70000000


不同于C语言的调试这里我们需要使用 si 的指令来进行step操作,具体的可以大致参考博主Liigo GDB十分钟教程这篇文章来学习调试方式。这里我们直接使用 c 指令运行代码,blinblin~ 板子上的LED开始闪烁,证明我们的程序正确的加载到了内存中并运行了。

关键字:S3C6410  编译运行  流水灯程序 引用地址:S3C6410开发(3)-编译运行第一个流水灯程序

上一篇:S3C6410开发(2)-构建开发环境
下一篇:u-boot-2009.08在mini2440上的移植(一)---建立mini2440工程环境(3)

推荐阅读最新更新时间:2024-11-05 15:23

ARM1176JZFS/S3C6410 内存地址转换
这是一份对于ARM1176JZF-S芯片上MMU内存地址转换/映射过程的整理,内容完全来自ARM官网的技术手册。 ARM1176JZF-S属于ARMv6产品系列,支持两种页表项的格式,一种是向ARMv4和ARMv5兼容的格式,另一新是ARMv6的新格式。v4/v5的格式在相应的技术手册里描述得非常清楚,但是对于v6格式的描述显得有点散,所以本文只关注ARMv6格式。 内容保持英文原文,没有翻译以免造成误解弄巧成拙。 Level 1 Translation When the CP15 Control Register c1 Bit 23 is set to 1 in the corresponding world, the
[单片机]
ARM1176JZFS/<font color='red'>S3C6410</font> 内存地址转换
51单片机学习之陆 —— 1.2 第一个c51程序(点亮流水灯
由于学校的板子跟我买的板子有些差异,为了大家的阅读,以后的所有程序编写烧录都以老师发的板子为主。 1 事先准备   a 驱动安装,注意群中已经发了,吧板子的驱动装好哦。   b 烧写软件(烧录器) stc - isp (这里说明下,板子上的芯片是stc的,你还能看到它的型号stc89c52RC,用stc的烧写软件就可以了)    提问:什么是烧写软件?     答:就是把你写好代码(C或者是汇编)专程的 机器语言 通过一定的方式下载到单片机中。称为烧写。(就先这样简单理解吧)   c 编写软件 keil uVision 4 (我仅用它编译生成hex 文件)         notpad++ (我用它写c51的代码,然
[单片机]
51单片机学习之陆 —— 1.2 第一个c51<font color='red'>程序</font>(点亮<font color='red'>流水灯</font>)
单片机左右流水灯与数码管动态显示C程序
本程序所用的原理图下载: 点这里 ,单片机芯片使用的stc89c52;找到相应部分即可.这是一整个单片机开发板的电路图其他的忽略.以下是通过测试的源代码: /* *功能:用定时器0实现定时200毫秒流水灯, * 同时用定时器1实现动态显示654321, * 且蜂鸣器发声; *日期:2014-03-24 *作者:徐冉 *注意事项:若打开两个定时器时,必须使用两个定时器, * 否则两个定时器都不工作!!! **/ /**********AT89C52-RC 51hei单片机实验板**************/ /*************51hei-开发板*********************/ #include reg52
[单片机]
S3C6410学习——Nand flash陷阱
当系统以Nand方式启动时,硬件将Nand Flash的前8KB拷贝到Steppingstone,然后从0地址开始运行程序,在这8KB以内代码中,我们需要完成必要的硬件初始化,如果代码超过8K,我们还需要将剩余代码的搬移到链接地址处,一般在SDRAM/DDR中。其中,硬件部分需要初始化系统时钟、DDR和NAND Flash三部分。这就是S3C6410以Nand方式启动时的大致流程,看上去跟ARM9(S3C2440)没有差别,但是如果您亲自动手写一下这个启动过程,你会发现ARM9跟ARM11还是存在若干差别的,这里我要说的是Nand裸机驱动的问题。述了S3C6410的Nand方式启动流程,看上去跟ARM9(S3C2440)没有太大差别
[单片机]
ARM1176JZF-S/S3C6410处理器的异常处理过程
本来准备总结一下ARM1176JZF-S/S3C6410处理器的异常处理过程,但是发现《嵌入式系统Linux内核开发实战指南》一书中的这一部分讲解得非常简明和清楚。所以就不再重复发明轮子,不过我会在以下的引用中做一些补充。 进入异常中断处理 ARM处理器发生异常中断,则ARM处理器进入如下异常中断自动处理过程(假设发生的异常中断对应的模式为mode): 将当前程序状态寄存器CPSR的值保存到SPSR_mode中; 将CPSR中的模式位设置成mode模式,将CPSR中的bit7(I)设置为1,禁止IRQ中断,如果是FIQ中断,则再将CPSR中的bit6(F)设置为1,禁止FIQ中断; 将返回地址传给lr_mode; 将该异
[单片机]
ARM1176JZF-S/<font color='red'>S3C6410</font>处理器的异常处理过程
S3C6410学习——MemoryMap
S3C6410跟S3C2440不同,S3C6410支持32位物理地址空间并将该地址空间分为2个部分,一部分是 存储空间 ,另一部分是 外设空间 。其中主存储空间通过SPINE总线访问,其地址空间为0x0000,0000~0x6FFF,FFFF,主存储空间又分为4个区域 引导镜像区(boot image area),内部存储区(internal memory area),静态存储区(static memory area)和动态存储区(dynamic memory area)。 引导镜像区(boot image area)的地址空间为0x0000,0000~0x07FF,FFFF,但是没有实际的内存映射,引导镜像区映射到内部存储区或者静
[单片机]
<font color='red'>S3C6410</font>学习——MemoryMap
51单片机学习之陆 —— 1.2 第一个c51程序(点亮流水灯
由于学校的板子跟我买的板子有些差异,为了大家的阅读,以后的所有程序编写烧录都以老师发的板子为主。 1 事先准备   a 驱动安装,注意群中已经发了,吧板子的驱动装好哦。   b 烧写软件(烧录器) stc - isp (这里说明下,板子上的芯片是stc的,你还能看到它的型号stc89c52RC,用stc的烧写软件就可以了)    提问:什么是烧写软件?     答:就是把你写好代码(C或者是汇编)专程的 机器语言 通过一定的方式下载到单片机中。称为烧写。(就先这样简单理解吧)   c 编写软件 keil uVision 4 (我仅用它编译生成hex 文件)         notpad++ (我用它写c51的代码,然
[单片机]
51单片机学习之陆 —— 1.2 第一个c51<font color='red'>程序</font>(点亮<font color='red'>流水灯</font>)
s3c6410学习笔记-将内核zImage、文件系统写到nandflash、屏幕校准
1、之前已经将uboot写到nandflash里面了,接下来将内核zImage、文件系统写到nandflash。 2、编译内核 cd linux-2.6.28_smdk6410 make clean make distclean cp smdk6410_config .config make menuconfig    将Device Drivers ---》Graphics support --- Support for frame buffer devices --- select LCD       Type 分辨率调到480*272 保存(之后要校准屏幕) make   make 完成之后将 /arch/a
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved