全志A10是性能很好的国产SOC,看到这么多的A10平板就知道了。A10采用Crotex A8核心,主频达到1.2GHz,性价比极高,但网上资料很少,下面给大家分享我的A10学习日记,希望越来越多的人使用国产芯片。
我学处理器,喜欢从CPU执行的第一条指令开始,这样能够彻底搞清楚CPU的启动过程,为后面的u-boot以及内核移植做准备。下面是我写的第一个A10裸板串口实验,给大家分享写的全过程:
开发环境:
ubuntu 10.04.4
pcDuino
arm-none-linux-gnueabi-gcc(arm-2009q3)
首先是UARTO实验的第一个汇编文件start.S:
.global _start
_start:
ldr sp, =0x00007f00 //条用C程序之前设置好堆栈
b main
汇编很头痛,就先写这几句吧很简单,接下来都是C程序。
文件main.c:
#include “clock.h”
#include “uart.h”
#include “lib.h”
#define PB_CFG2 (*(volatile unsigned int *)0x01c2082c)
void gpio_init()
{
PB_CFG2 |= ((0×2<<24)|(0×2<<28));
}
int main(void)
{
char c;
clock_init();
gpio_init();
uart_init();
uart_putchar(‘O’);
uart_putchar(‘K’);
while (1)
{
do {
c = uart_getchar();
if (c == ‘\n’ || c == ‘\r’)
{
putchar(‘\n’);
putchar(‘\r’);
}
else
{
putchar(c);
}
} while (c == ‘\n’ || c == ‘\r’);
}
return 0;
}
串口测试主程序很简单,就不说啦,接下来初始化时钟。
文件clock.c:
#define CPU_AHB_APB0_CFG (*(volatile unsigned int *)0x01c20054)
#define PLL1_CFG (*(volatile unsigned int *)0x01c20000)
#define APB1_CLK_DIV_CFG (*(volatile unsigned int *)0x01c20058)
#define APB1_GATE (*(volatile unsigned int *)0x01c2006C)
void sdelay(unsigned long loops)
{
__asm__ volatile(“1:\n” “subs %0, %1, #1\n”
”bne 1b”:”=r” (loops):”0″(loops));
}
void clock_init(void)
{
CPU_AHB_APB0_CFG = ((0<<0)|(0×1<<4)|(0<<8)|(1<<16));
PLL1_CFG = 0xa1005000;
sdelay(200);
CPU_AHB_APB0_CFG = ((0<<0)|(0×1<<4)|(0<<8)|(2<<16));//CPU_CLK_SRC_SEL 10:PLL1
APB1_CLK_DIV_CFG = ((0<<5)|(0<<16)|(0<<24));
APB1_GATE = (0×1<<16);
}
文件clock.h:
初始化过程有点繁琐,对的手册写了点注释,没的说,自己看手册。接下来初始化串口:
文件uart.c:
#define UART0_LCR (*(volatile unsigned int *)0x01C2800C)
#define UART0_DLH (*(volatile unsigned int *)0x01C28004)
#define UART0_DLL (*(volatile unsigned int *)0x01C28000)
#define UART0_LSR (*(volatile unsigned int *)0x01C28014)
#define UART0_THR (*(volatile unsigned int *)0x01C28000)
#define UART0_RBR (*(volatile unsigned int *)0x01C28000)
void uart_init(void)
{
UART0_LCR = 0×80;
UART0_DLH = 0×0;
UART0_DLL = 0xd;
UART0_LCR = ((0<<3)|(0<<2)|0×3);
}
char uart_getchar(void)
{
char c;
while (!(UART0_LSR & (1<<0)));
c = UART0_RBR;
return c;
}
void uart_putchar(char c)
{
while (!(UART0_LSR & (1<<6)));
UART0_THR = c;
return;
}
文件uart.h:
void uart_init(void);
char uart_getchar(void);
void uart_putchar(char c);
基本上参考A10的手册写就没问题,设置115200 8 n 1。接下来还写个lib.c,先写一个putchar(),以后再扩展
文件lib.c:
int putchar(int c)
{
if (c == ‘\n’)
uart_putchar(‘\r’);
uart_putchar(c);
return 0;
}
文件lib.h
int putchar(int c);
程序代码部分就写完了,接下来写个简单点的Makefile
文件Makefile:
uart.bin:start.S main.c uart.c clock.c lib.c
arm-none-linux-gnueabi-gcc -nostdlib -c start.S -o start.o
arm-none-linux-gnueabi-gcc -nostdlib -c main.c -o main.o
arm-none-linux-gnueabi-gcc -nostdlib -c uart.c -o uart.o
arm-none-linux-gnueabi-gcc -nostdlib -c lib.c -o lib.o
arm-none-linux-gnueabi-gcc -nostdlib -c clock.c -o clock.o
arm-none-linux-gnueabi-ld -Ttext 0xD0020010 start.o main.o uart.o lib.o clock.o -o uart_elf
arm-none-linux-gnueabi-objcopy -O binary -S uart_elf uart.bin
clean:
rm -rf *.o *.bin uart_elf *.dis
这个arm-none-linux-gnueabi-gcc是我的默认编译器,根据自己编译器器修改吧
接下来make就OK了,顺利的话最终会生成二进制文件uart.bin,这里的uart.bin还不能直接使用,需要根据A10内部固化ROM添加头部。这里需要一个工具,以后再分析工具源码,先用再说
./mksunxiboot uart.bin uarts.bin
生成的uarts.bin,就可以烧到tf卡,直接在板子上运行,写tf卡ubuntu命令如下:
sudo dd if=/dev/zero of=/dev/sdb bs=1M count=1
sudo dd if=work/programe/A10/1_uart0/uarts.bin of=/dev/sdb bs=1024 seek=8
我的tf卡设备是/dev/sdb,uarts.bin路径work/programe/A10/1_uart0/uarts.bin,根据自己情况修改
再取下tf卡,放到pcDuino,打开串口设置115200 8 n 1 没有Flow Control,就可以跑起来了。