u-boot-2014.10移植第4天----裸機蜂鳴器程序
來源:程序員人生 發布時間:2015-02-28 08:36:38 閱讀次數:3964次
硬件平臺:tq2440
開發環境:Ubuntu⑶.11
u-boot版本:2014.10
本文允許轉載,請注明出處:http://blog.csdn.net/fulinus
1、蜂鳴器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文件與昨天的文件1樣,只是將履行文件名改了1下:
BINAME = beep
2、ARM匯編和C語言結合
從asm中跳轉到C函數中也是1個重要的技術要點,我們在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 main
halt_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 40000000
static inline void delay (unsigned long loops)
{
__asm__ volatile ("1:
"
"subs %0, %1, #1
"
"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匯編的代碼段放在首位,因此需要告知編譯器如何編譯和連接。有1個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 = beep
TEXTBASE = 0x33000000
CROSS = /opt/buildroot⑵012.08/arm920t/usr/bin/arm-linux-
CC = $(CROSS)gcc
LD = $(CROSS)ld
AR = $(CROSS)ar
OBJCOPY = $(CROSS)objcopy
OBJDUMP = $(CROSS)objdump
STRIP = $(CROSS)strip
READELF = $(CROSS)readelf
CFLAGS = -g -O2 -Wall -nostdinc -nostdlib -fno-builtin
AFLAGS = $(CFLAGS) -D__ASSEMBLY__
LDSCRIPT = ${BINAME}.lds
LDFLAGS = -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 : all
all: ${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=yes
clean:
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 empeep.bin 0x33000000
setpc 0x33000000
g
你就能夠聽到天籟之音了!
3、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 40000000
static inline void delay (unsigned long loops)
{
__asm__ volatile ("1:
"
"subs %0, %1, #1
"
"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);
}
}
其他部份文件雷同,稍作修改。
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈