前几天拿到了一块板子FS4412是基于samsung的arm Cortex-A9的Exynos4412的板子,Exynos4412采用了32nm HKMG工艺,是samsung的第一款四核芯片,Exynos 4412有两种封装SCP和POP;Exynos 4412处理器当前sanmung推出了两个封装版本(PoP和SCP),其中PoP封装主要是针对智能手机等产品体积要求严格的项目中使用。由于采用了DDR和处理器叠层的焊接工艺,使得设计者对于DDR部分的LAYOUT节省了大量的工程周期,且解决了EMI等复杂电气问题,但同时也导致其他有一些问题呈现出来。
1, Exynos 4412的PoP版本当前大DDR为1GB, 如果客户有内存扩容的可能,将后悔莫及;
2, Exynos 4412的BGA间距为0.4mm,这是当前焊接工厂的极限能力,客户在生产工厂的选择上增加了难度,且成品的报废率明显上升;
3, 由于BGA间距太小,PCB布线方面通常需要二阶盲埋孔的HDI板才能完成,使得PCB的成本和周期大大增加;
4, Exynos 4412的PoP版本官方不再对大众用户做进一步的技术支持和文档的开放。
【实验内容】
编写GPIO模块程序,点亮FS_4412开发板上的LED灯。
【实验目的】
熟悉开发环境的使用
掌握Exynos4412处理器GPIO功能
【实验平台】
FS_4412 Cortex-A9开发板、FS_Jtag仿真器、Eclipse
#define GPX2CON (volatile unsigned int *)0x11000c40
#define GPX2DAT (volatile unsigned int *)0x11000c44
int main()
{
*GPX2CON &= ~(0xf<<28);
*GPX2CON |=(1<<28);//设置管脚为输出
*GPX2DAT &=~(1<<7); //关闭LED2
while(1); //让程序在这里循环,防止跑飞
return 0;
}
FS4412的工程模板:link
如果要编译上述代码,需要安装ARM架构的编译器
ARM架构的编译器文件:gcc-4.6.4.tar
安装这个编译器——ARM
这还需要FS4412手册和原理图文件——见我空间资源有
就像上面一样
LED2=GTX2
LED3=GTX1
LED4=GTX3
LED5=GTX3
从手册中查找LED3的GTX1_0
设置管脚输出:
像上面的一样:
#define LED3CON (volatile unsigned int *)0x11000c20
#define LED3DAT (volatile unsigned int *)0x11000c24
//led3设置为输出
*LED3CON &=~(0xf<<0);
*LED3CON |= (1<<0);
//关闭led3
*LED3DAT &=~(1<<0);
LED4的为:
#define LED4CON (volatile unsigned int *)0x114001e0
#define LED4DAT (volatile unsigned int *)0x114001e4
//led4设置为输出
*LED4CON &= ~(0xf<<16);
*LED4CON |= (1<<16);
//关闭led4
*LED4DAT &= ~(1<<4);
LED5与LED4的寄存器相同
#define LED5CON (volatile unsigned int *)0x114001e0
#define LED5DAT (volatile unsigned int *)0x114001e4
//led5设置为输出
*LED5CON &= ~(0xf<<20);
*LED5CON |= (1<<20);
//关闭led5
*LED5DAT &= ~(1<<5);
延时代码:
void delay_ms(int z)
{
int x,y;
for(x=z;x>0;x--)
for(y=2500;y>0;y--);
}
总体代码:
#define LED2CON (volatile unsigned int *)0x11000c40
#define LED2DAT (volatile unsigned int *)0x11000c44
#define LED3CON (volatile unsigned int *)0x11000c20
#define LED3DAT (volatile unsigned int *)0x11000c24
#define LED4CON (volatile unsigned int *)0x114001e0
#define LED4DAT (volatile unsigned int *)0x114001e4
#define LED5CON (volatile unsigned int *)0x114001e0
#define LED5DAT (volatile unsigned int *)0x114001e4
void delay_ms(int z)
{
int x,y;
for(x=z;x>0;x--)
for(y=2500;y>0;y--);
}
int main()
{
//led2设置为输出
*LED2CON &= ~(0xf<<28);
*LED2CON |= (1<<28); //设置管脚为输出
//关闭led2
*LED2DAT &=~(1<<7); //关闭LED2
//led3设置为输出
*LED3CON &=~(0xf<<0);
*LED3CON |= (1<<0);
//关闭led3
*LED3DAT &=~(1<<0);
//led4设置为输出
*LED4CON &= ~(0xf<<16);
*LED4CON |= (1<<16);
//关闭led4
*LED4DAT &= ~(1<<4);
//led5设置为输出
*LED5CON &= ~(0xf<<20);
*LED5CON |= (1<<20);
//关闭led5
*LED5DAT &= ~(1<<5);
while(1)
{
*LED2DAT |= (1<<7); //灯亮
delay_ms(1000);
*LED2DAT &=~(1<<7); //灯灭
delay_ms(1000);
*LED3DAT |= (1<<0); //灯亮
delay_ms(1000);
*LED3DAT &=~(1<<0); //灯灭
delay_ms(1000);
*LED4DAT |= (1<<4); //灯亮
delay_ms(1000);
*LED4DAT &=~(1<<4); //灯灭
delay_ms(1000);
*LED5DAT |= (1<<5); //灯亮
delay_ms(1000);
*LED5DAT &=~(1<<5); //灯灭
delay_ms(1000);
}
return 0;
}
优化代码:
#define LED2CON (volatile unsigned int *)0x11000c40
#define LED2DAT (volatile unsigned int *)0x11000c44
#define LED3CON (volatile unsigned int *)0x11000c20
#define LED3DAT (volatile unsigned int *)0x11000c24
#define LED4CON (volatile unsigned int *)0x114001e0
#define LED4DAT (volatile unsigned int *)0x114001e4
#define LED5CON (volatile unsigned int *)0x114001e0
#define LED5DAT (volatile unsigned int *)0x114001e4
#define LED2 2
#define LED3 3
#define LED4 4
#define LED5 5
#define ON 1
#define OFF 0
void delay_ms(int z)
{
int x,y;
for(x=z;x>0;x--)
for(y=2500;y>0;y--);
}
void led_init()
{
//led2设置为输出
*LED2CON &= ~(0xf<<28);
*LED2CON |= (1<<28); //设置管脚为输出
//关闭led2
*LED2DAT &=~(1<<7); //关闭LED2
//led3设置为输出
*LED3CON &=~(0xf<<0);
*LED3CON |= (1<<0);
//关闭led3
*LED3DAT &=~(1<<0);
//led4设置为输出
*LED4CON &= ~(0xf<<16);
*LED4CON |= (1<<16);
//关闭led4
*LED4DAT &= ~(1<<4);
//led5设置为输出
*LED5CON &= ~(0xf<<20);
*LED5CON |= (1<<20);
//关闭led5
*LED5DAT &= ~(1<<5);
}
void led_set_value(int which,int status)
{
switch(which){
case LED2:status?(*LED2DAT|=(1<<7)):(*LED2DAT&=~(1<<7));
break;
case LED3:status?(*LED3DAT|=(1<<0)):(*LED3DAT&=~(1<<0));
break;
case LED4:status?(*LED4DAT|=(1<<4)):(*LED4DAT&=~(1<<4));
break;
case LED5:status?(*LED5DAT|=(1<<5)):(*LED5DAT&=~(1<<5));
break;
}
}
void led_set_blink(int which,int dms)
{
led_set_value(which,ON);
delay_ms(dms);
led_set_value(which,OFF);
delay_ms(dms);
}
int main()
{
//init all led
led_init();
while(1){
led_set_blink(LED2,1000);
led_set_blink(LED3,1000);
led_set_blink(LED4,1000);
led_set_blink(LED5,1000);
}
return 0;
}
编译的过程
【2】LED灯代码编写(ARM)
将这个压缩包demo.tar.gz拷贝到ubuntu中
并解压(工程模板)
start/ ===>系统的启动代码
map.lds ===>链接脚本,在编译和执行的时候会用到
*Makefile ===>编译代码的脚本
*interface.c ===>你需要编写的文件
common ===>移植好的代码(printf)
interface.c
#define GPX2CON (volatile unsigned int *)0x11000c40
#define GPX2DAT (volatile unsigned int *)0x11000c44
int main()
{
*GPX2CON &= ~(0xf<<28);
*GPX2CON |= (1<<28); //设置管脚为输出
*GPX2DAT &=~(1<<7); //关闭LED2
while(1); //让程序在这里循环,防止跑飞
return 0;
}
如果要编译上述编写好的代码,需要安装ARM架构的编译器
gcc-4.6.4.tar.xz
【3】如何安装交叉编译器
1.将ARM架构的编译拿到ubuntu中
将编译器从windows直接拖到ubuntu的终端上
mv xxxxxxxxxxx/gcc-4.6.4.tar.xz .
2.在用户的家目录下创建tools
cd
mkdir tools
mv ~/gcc-4.6.4.tar.xz ~/tools
cd tools
3.解压
tar -xvf gcc-4.6.4.tar.xz
解压后生成===>gcc-4.6.4
4.安装交叉编译器
sudo vi /etc/environment
PATH=xxxxxxxxx:/home/edu/tools/gcc-4.6.4/bin/"
保存退出后
5.重启ubuntu让编译器生效
sudo reboot
6.验证
arm-linux-gcc -v
如果能看到gcc 4.6.4说明安装成功了
【4】如何编译代码
vi Makefile
CROSS_COMPILE = arm-linux-
保存退出
编译:make ===========>interface.bin
清楚编译:make clean
【5】如何下载程序到开发板上
FS4412 # loadb 0x40008000 (下载二进制文件到0x40008000内存上)
## Ready for binary (kermit) download to 0x40008000 at 115200 bps...
将二进制文件通过串口软件发送给开发板
Transfer->send kermit-->找到.bin文件点击OK
跳转到40008000内存地址执行即可