u-boot-2014.10移植第4天----裸机蜂鸣器程序

来源:互联网 发布:骷髅会 知乎 编辑:程序博客网 时间:2024/03/28 17:52

硬件平台:tq2440

开发环境:Ubuntu-3.11

u-boot版本:2014.10

本文允许转载,请注明出处:http://blog.csdn.net/fulinus


一、蜂鸣器asm汇编程序:

/*********************************************************************** *        File:  beep.S *     Version:  1.0.0 *   Copyright:  2014 (c) fulinux <fulinux@sina.com> * Description:  This ASM code used to turn beep on/off on TQ2440 board ***********************************************************************/#define GPBCON   0x56000010#define GPBDAT   0x56000014#define GPBUP    0x56000018#define DELAY    0X40000000    .text    .align 2    .global _start_start:    /*Set GPB5,GPB6,GPB7,GPB8 as GPIO OUTPUT mode*/    ldr     r0, =GPBCON    ldr     r1, [r0]    bic     r1, r1, #0x03       /*Set GPBCON for GPB0 as 00 */    orr     r1, r1, #0x01       /*Set GPBCON for GPB0 as GPIOOUT, 0x01*/    str     r1, [r0]    /*Set internal pullup resister*/    ldr     r0, =GPBUP    ldr     r1, [r0]    @orr     r1, r1, #0x01     /*Set bit 0, disable pullup resister*/    bic     r1, r1, #0x01      /*Clear bit 0, enable pullup resister*/    str     r1, [r0]loop:    /*Turn off beep*/    ldr     r2, =GPBDAT    ldr     r3, [r2]    orr     r3, r3, #1          /*Set bit 0 as high level*/    str     r3, [r2]    ldr     r0, =DELAY          /*Sleep for a while*/    bl      delay    /*Turn on beep*/    ldr     r3, [r2]    bic     r3, r3, #1          /*Set bit 0 as high level*/    str     r3, [r2]    ldr     r0, =DELAY          /*Sleep for a while*/    bl      delay    b       loop                /*Loop running*/delay:    sub     r0, r0, #1    cmp     r0, #0x0    bne     delay    mov     pc, lr

该程序主要是根据昨天led.S程序修改而来。makefile文件与昨天的文件一样,只是将执行文件名改了一下:

BINAME = beep

二、ARM汇编和C语言结合

从asm中跳转到C函数中也是一个重要的技术要点,我们在ARM汇编程序中要做如下工作

1、关看门狗;

2、屏蔽中断;

3、跳转到C代码中的main函数中去。

1、ARM汇编程序

/*********************************************************************** *        File:  start.S *     Version:  1.0.0 *   Copyright:  2011 (c) Guo Wenxue <guowenxue@gmail.com> * Description:  This ASM used to disable watch dog and interrupt, then call C code to  *               turn the buzzer on/off on FL2440 board. *   ChangeLog:  1, Release initial version on "Mon Mar 21 21:09:52 CST 2011" * ***********************************************************************/#define pWTCON    0x53000000  /* Watch dog register address */#define INTMSK    0x4A000008  /* Interupt-Controller base addresses */#define INTSUBMSK 0x4A00001C    .text    .align 2    .global _start_start:    /* Disable watch dog */    ldr r0, =pWTCON  /*Save pwTCON address in r0*/    mov r1, #0x0     /*Set r1=0x0*/    str r1, [r0]     /*Move the data in r1 to the address specify by r0*/    /* mask all IRQs by setting all bits in the INTMR - default */    mov r1, #0xffffffff    ldr r0, =INTMSK    str r1, [r0]    ldr r0, =INTSUBMSK    ldr r1, =0x7fff    /*There are 15 bits used in INTSUBMSK on S3C2440*/    str r1, [r0]    bl mainhalt_loop:    b halt_loop

2、C语言程序

/*********************************************************************** *        File:  beep.c *     Version:  1.0.0 *   Copyright:  2011 (c) Guo Wenxue <guowenxue@gmail.com> * Description:  This C code used to turn buzzer on/off on FL2440 board *   ChangeLog:  1, Release initial version on "Mon Mar 21 21:09:52 CST 2011" * ***********************************************************************/#define GPBCON   (*(unsigned long volatile *)0x56000010)#define GPBDAT   (*(unsigned long volatile *)0x56000014)#define GPBUP    (*(unsigned long volatile *)0x56000018)#define BEEP         0    /*Buzzer us GPB0 */#define DELAY_TIME   40000000static inline void delay (unsigned long loops){    __asm__ volatile ("1:\n"            "subs %0, %1, #1\n"            "bne 1b":"=r" (loops):"0" (loops));}int main(void){    GPBCON = (GPBCON|0x3)&0x1; /* Set GPB0 as GPIO output mode(0x01) */    GPBUP &= ~1;               /* Enable pullup resister */    GPBDAT |= 0x560;    while(1)    {        GPBDAT &= ~(1<<BEEP);  /* Set Beep GPIO as low level */        delay(DELAY_TIME);        GPBDAT |= 1<<BEEP;     /* Set Beep GPIO as high level */        delay(DELAY_TIME);    }}

显然,我们这里首先需要执行ARM汇编程序,再由汇编程序跳转到C程序中,但是编译器并不清楚是将C语言的代码段还是将ARM汇编的代码段放在首位,因此需要告知编译器如何编译和连接。有一个lds文件,该文件中的内容决定程序中各个代码段的位置摆放关系,可以在下面的makefile文件中看到是如何将该文件传给编译器的。

3、lds文件

/*********************************************************************** *        File:  beep.lds *     Version:  1.0.0 *   Copyright:  2011 (c) Guo Wenxue <guowenxue@gmail.com> * Description:  Cross tool link text, refer to u-boot.lds *   ChangeLog:  1, Release initial version on "Mon Mar 21 21:09:52 CST 2011" ***********************************************************************/                             OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")OUTPUT_ARCH(arm)ENTRY(_start)SECTIONS{    . = 0x33000000;    .text : {        start.o(.text*) /* by fulinux modified */        *(.text*)                            *(.rodata)    }    .data ALIGN(4): {        *(.data)    }    .bss ALIGN(4): {        *(.bss)    }


4、makefile文件

# ***********************************************************************# *        File:  makefile# *     Version:  1.0.0# *   Copyright:  2011 (c) Guo Wenxue <guowenxue@gmail.com># * Description:  Makefile used to cross compile the ASM and C source code# *   ChangeLog:  1, Release initial version on "Mon Mar 21 21:09:52 CST 2011"# *# ***********************************************************************BINAME = beepTEXTBASE = 0x33000000CROSS = /opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-CC      = $(CROSS)gccLD      = $(CROSS)ldAR      = $(CROSS)arOBJCOPY = $(CROSS)objcopyOBJDUMP = $(CROSS)objdumpSTRIP   = $(CROSS)stripREADELF = $(CROSS)readelfCFLAGS  = -g -O2 -Wall -nostdinc -nostdlib -fno-builtinAFLAGS  = $(CFLAGS) -D__ASSEMBLY__LDSCRIPT = ${BINAME}.ldsLDFLAGS  = -nostartfiles -T $(LDSCRIPT) -Ttext $(TEXTBASE)SRC_C   = $(wildcard *.c)SRC_S   = $(wildcard *.S)OBJ_C   = $(patsubst %.c,%.o,$(SRC_C))OBJ_S   = $(patsubst %.S,%.o,$(SRC_S))OBJ_ALL = $(OBJ_C) $(OBJ_S).PHONY : allall: ${OBJ_ALL}    ${LD} $(LDFLAGS) -o ${BINAME}.elf ${OBJ_ALL}    ${OBJCOPY} -O binary -S ${BINAME}.elf ${BINAME}.bin    rm -f *.elf *.o%.o: %.S            $(CC) $(AFLAGS) -c -o $@ $<%.o: %.c            $(CC) $(CFLAGS) -c -o $@ $<install:    cp ${BINAME}.bin ~/winxp -f --reply=yesclean:    rm -f *.elf *.o    rm -f ${BINAME}.bin

文件中

LDSCRIPT = ${BINAME}.lds

即是beep.lds文件。

5、编译运行

编译之后通过J-link将beep.bin程序烧了录到SDRAM中去执行:

h  speed 12000  loadbin D:\kupan\temp\beep.bin 0x33000000  setpc 0x33000000  g

你就可以听到天籁之音了!



三、led跑马灯的ARM汇编与C语言程序

LED跑马灯C程序如下:
/*********************************************************************** *        File:  led.c *     Version:  1.0.0 *   Copyright:  2011 (c) Guo Wenxue <guowenxue@gmail.com> * Description:  This C code used to turn LED0~LED4 on on FL2440 board *   ChangeLog:  1, Release initial version on "Mon Mar 21 21:09:52 CST 2011" *      Modify:  fulinux@sina.com ***********************************************************************/#define GPBCON   (*(unsigned long volatile *)0x56000010)#define GPBDAT   (*(unsigned long volatile *)0x56000014)#define GPBUP    (*(unsigned long volatile *)0x56000018)#define LED0     5    /*LED0 use GPB5*/#define LED1     6    /*LED1 use GPB6*/#define LED2     7    /*LED2 use GPB7*/#define LED3     8    /*LED3 use GPB8*/#define DELAY_TIME   40000000static inline void delay (unsigned long loops){    __asm__ volatile ("1:\n"        "subs %0, %1, #1\n"        "bne 1b":"=r" (loops):"0" (loops));}void led_init(void){    /*  Set GPB5,GPB6,GPB7,GPB8 as GPIO mode(0x01) */     GPBCON = (GPBCON & ~0x3FC00) | 0x15400;    GPBUP &= ~0x01E0;    /* Set GPB5,GPB6,GPB7,GPB8 as high level, to turn LED0,LED1,LED2,LED3 off */    GPBDAT |= 0x01E0;}void led_off(void){    /* Set GPB5,GPB6,GPB7,GPB8 as high level, to turn LED0,LED1,LED2,LED3 off */    GPBDAT |= 0x01E0;    delay(DELAY_TIME);}void led_on(int led){    /* Turn LED0 on */    GPBDAT &= ~(1<<led);    delay(DELAY_TIME);}int main(void){    led_init();    while(1)    {        led_off();        led_on(LED0);        led_on(LED1);        led_on(LED2);        led_on(LED3);    }}

其他部分文件雷同,稍作修改。



1 0