硬件平台:JZ2440
实现功能:向串口软件实现输出putchar函数
start.s --> 设置堆栈,关闭看门狗,初始化时钟,初始化sdram
init.c -->初始化函数
uart.c -->初始化串口寄存器
uart.h -->
main.c -->
start.s源码:
.extern main .text .global _start _start: ldr sp,=4096 bl watchdog_init bl clock_init bl sdram_init bl copy_steppingstone_to_sdram ldr pc,=sdram sdram: ldr sp,=0x34000000 ldr lr,=main_return ldr pc,=main main_return: b main_return
init.c 源码:
//watchdog #define WTCON (*(volatile unsigned long *)0x53000000) //clock #define LOCKTIME (*(volatile unsigned long *)0x4c000000) #define MPLLCON (*(volatile unsigned long *)0x4c000004) #define CLKDIVN (*(volatile unsigned long *)0x4c000014) //sdram #define BWSCON (*(volatile unsigned long *)0x48000000) #define BANKCON0 (*(volatile unsigned long *)0x48000004) #define BANKCON1 (*(volatile unsigned long *)0x48000008) #define BANKCON2 (*(volatile unsigned long *)0x4800000c) #define BANKCON3 (*(volatile unsigned long *)0x48000010) #define BANKCON4 (*(volatile unsigned long *)0x48000014) #define BANKCON5 (*(volatile unsigned long *)0x48000018) #define BANKCON6 (*(volatile unsigned long *)0x4800001c) #define BANKCON7 (*(volatile unsigned long *)0x48000020) #define REFRESH (*(volatile unsigned long *)0x48000024) #define BANKSIZE (*(volatile unsigned long *)0x48000028) #define MRSRB6 (*(volatile unsigned long *)0x4800002c) #define MRSRB7 (*(volatile unsigned long *)0x48000030) void watchdog_init(void) { WTCON=0; } void clock_init(void) { CLKDIVN=0x03; __asm__ ( "mrc p15,0,r1,c1,c0,0 " "orr r1,r1,#0xc0000000 " "mcr p15,0,r1,c1,c0,0 " ); MPLLCON=((0x5c<<12)|(0x01<<4)|(0x02)); } void sdram_init(void) { volatile unsigned long *sdram_base=(volatile unsigned long *)0x48000000; sdram_base[0] = 0x22011110; sdram_base[1] = 0x00000700; sdram_base[2] = 0x00000700; sdram_base[3] = 0x00000700; sdram_base[4] = 0x00000700; sdram_base[5] = 0x00000700; sdram_base[6] = 0x00000700; sdram_base[7] = 0x00018005; sdram_base[8] = 0x00018005; sdram_base[9] = 0x008C04F4; sdram_base[10] = 0x000000B1; sdram_base[11] = 0x00000030; sdram_base[12] = 0x00000030; } void copy_steppingstone_to_sdram(void) { unsigned int *sour=(unsigned int *)0x00000000; unsigned int *dest=(unsigned int *)0x30000000; while(sour<=(unsigned int *)4096) { *dest++=*sour++; } }
uart.c 源码:
//uart #define ULCON0 (*(volatile unsigned long *)0x50000000) #define UCON0 (*(volatile unsigned long *)0x50000004) #define UFCON0 (*(volatile unsigned long *)0x50000008) #define UMCON0 (*(volatile unsigned long *)0x5000000c) #define UTRSTAT0 (*(volatile unsigned long *)0x50000010) #define UERSTAT0 (*(volatile unsigned long *)0x50000014) #define UTXH0 (*(volatile unsigned char *)0x50000020) #define URXH0 (*(volatile unsigned char *)0x50000024) #define UBRDIV0 (*(volatile unsigned long *)0x50000028) //GPH #define GPHCON (*(volatile unsigned long *)0x56000070) #define GPHDAT (*(volatile unsigned long *)0x56000074) #define GPHUP (*(volatile unsigned long *)0x56000078) void uart0_init(void) { GPHCON|=0xa0; GPHUP=0x0c; ULCON0=0x03; UCON0=0x05; UFCON0=0x00; UMCON0=0x00; UBRDIV0=((50000000/(115200*16))-1); } unsigned char getc(void) { while(!(UTRSTAT0 & 0x01)); return URXH0; } void putc(unsigned char date) { while(!(UTRSTAT0 & 0x02)); UTXH0=date; }
uart.h 源码:
#ifndef _UART_H_ #define _UART_H_ void uart0_init(void); unsigned char getc(void); void putc(unsigned char date); #endif
main.c 源码:
#include"uart.h" int main(void) { uart0_init(); while(1) putc(getc()+1); return 0; }
连接脚本uart.lds :
SECTIONS { . = 0x30000000; .text : {*(.test)} .rodata : {*(.rodata)} .dtat : {*(.data)} .bss : {*(.bss) *(COMMON)} }
Makefile:
objs:= start.o init.o uart.o main.o uart.bin:$(objs) arm-linux-ld -Tuart.lds -o uart_elf $^ arm-linux-objcopy -O binary -S uart_elf $@ arm-linux-objdump -D -m arm uart_elf > uart.dis %.o:%.s arm-linux-gcc -o $@ -c $< %.o:%.c arm-linux-gcc -o $@ -c $< clean: rm -f *.o *.bin *.dis uart_elf