iTOP-4412全能版采用四核Cortex-A9,主频为1.4GHz-1.6GHz,配备S5M8767 电源管理,集成USB HUB,选用高品质板对板连接器稳定可靠,大厂生产,做工精良。接口一应俱全,开发更简单,搭载全网通4G、支持WIFI、蓝牙、陀螺仪、CAN总线、RS485总线、500万摄像头等模块,稳定运行Android 4.0.3/Android 4.4操作,系统通用Linux-3.0.15+Qt操作系统(QT支持5.7版本),Ubuntu版本:12.04,接口智能分配 方便好用。
【交流群2】258811263(获取开源资料)
【迅为B站】北京迅为电子的个人空间-北京迅为电子个人主页-哔哩哔哩视频
96.14 Linux下GPS的驱动配置以及使用方法
96.14.1 安卓配置
iTOP-4412 开发板支持两种 GPS 模块,分别为 GNS7560 和 UBLOX,下面讲解一下代码里面怎么选择对应的驱动:
这两种 GPS 模块都是通过串口来传输数据的,linux 内核里面已经支持串口的驱动了,所以我们需要修改的只是 android 代码,通过配置对应的宏来选择支持我们使用的GPS,进入到 “iTop4412_ICS” android 的源码目录,如下图:
然后输入“vi device/samsung/smdk4x12/BoardConfig.mk”命令,如下图:
然后在 BoardConfig.mk 文件里面找到“BOARD_HAVE_GNS7560 := false”,如下图:
如果使用 GNS7560 模块,需要把这行改成:
BOARD_HAVE_GNS7560 := true
如果使用 UBLOX 模块,需要把这行改成:
BOARD_HAVE_GNS7560 := false
修改完成以后,保存并退出。然后在终端依次输入下面的两条命令:
make clobber
./build_android.sh
重新编译 android 就可以了,最后会生成镜像。
接下来给大家介绍一下在最小 Linux 系统环境下 iTOP-4412 GPS 实验调试步骤。我们给用户提供了“iTOP-4412-MiniLinux-GPS_V1.0.zip”压缩包,即 GPS 实验 C 程序源码。
利用 GPS 定位卫星,在全球范围内实时进行定位、导航的系统,称为全球卫星定位系统,简称 GPS。GPS 是由美国国防部研制建立的一种具有全方位、全天候、全时段、高精度的卫星导航系统,能为全球用户提供低成本、高精度的三维位置、速度和精确定时等导航信息,是卫星通信技术在导航领域的应用典范,它极大地提高了地球社会的信息化水平,有力地推动了数字经济的发展。
说到定位和导航,大家容易有几个误区,请务必理解以下知识点。
GPS 导航,在嵌入式领域,一般指的是通过卫星信号导航。GPS 卫星高度一般在 2 万公里左右,频段在 1Ghz-2Ghz,先不介绍 GPS 信号,通过对比 WIFI 路由器和 GPS 来了解关于 GPS 的常识。
当使用的 WIFI 路由器的时候,WIFI 信号在周围空旷的情况下可以传输 2 百米左右,信号传输距离和功率有关系,GPS 卫星上的发射功率比一般的 WIFI 天线强,但是要将 GPS 信号发射 2 万公里远,卫星体积重量也是有限的,所以到地面的时候,信号相对是比较弱的。
WIFI 信号频段一般在 2.4G 左右,和 GPS 信号频段差距不大。在屋子内部使用无线 WIFI 的时候,如果中间墙隔着,信号拐几个弯之后,信号就会变的非常弱。在电磁场理论中,频段越高,穿透能力越强,散射能力越弱。直白的解释就是,频段高了,就拐不了弯了,它更喜欢直着走。所以,WIFI 信号转弯之后,信号就会弱,GPS 信号也是同样的道理,高山和高楼都很容易阻挡 GPS 信号。
所以,在测试 GPS 信号的时候,尽量在空旷室外,周围没有高楼,不是山洼的地方测试,这种情况信号会强一些。
可能有人有疑问,为什么手机导航定位在屋子里面可以,而且那么精准。请注意,一般的手机中,是没有 GPS 卫星定位功能的,手机是通过 WIFI 或者 3G/4G 定位的,必须要有WIFI 或者流量才能定位。大家可以先关闭 WIFI 和流量,再尝试用 GPS 来定位,肯定是不行的。
WIFI 定位的原理是通过路由器来实现的,每一个公司或者普通居民家里的光纤和宽带, 都有唯一的标识,这个标识是和位置一一对应的,通过标识当然就可以定位。
3G/4G 的流量定位,是通过信号塔来实现的,手机可以接收到信号塔(打电话,通过流量上网,都是通过信号塔,可以搜索“铁塔公司”,国内的信号塔都是属于这个公司的),信号塔的位置是固定的,通过信号塔当然也是可以定位。
无论是 WIFI 还是流量定位,它们都不是严格意义上的 GPS 卫星定位。
可能有人有疑问,GPS 定位好像不如通过 3G/4G 和 WIFI 定位,有什么用?
GPS 导航仪,汽车上使用,汽车在路中间行驶,信号还是蛮好的^_^,而且买了设备之后,不用每个月都缴费,汽车上如果使用的是 GPS 定位,在前挡风玻璃雨刮器下方都有引出来的天线。
另外像野外施工作业,手机信号可能都没有(一般使用卫星电话),就更别提 WIFI 了, GPS 卫星定位是非常好的选择。类似,在阿富汗作战的美国大兵,肯定也是用的卫星定位。
另外可能有疑问,为什么收音机接收广播信号的时候,在犄角旮旯都可以收听到。就一个发射塔,可以穿越整个地球,用这么小的收音机接收信号。广播信号的频段是很特殊的,它是通过大气的电离层来实现远距离传输的,这是另外一个课题了,如果大家对无线电感兴趣, 可以找电磁场或者无线电相关的书籍来看一看。
96.14.2 硬件连接
笔者测试 GPS 模块,使用的是 iTOP-4412 全能板开发板。笔者使用 GPS 专用天线,并将探头延伸至窗外,以确保 GPS 信号强度,如下图所示。
96.14.3 最小linux下测试
将“iTOP-4412-MiniLinux-GPS_V1.0”中“gps_test”目录下可执行文件“gps_test” 拷贝到 U 盘上,如下图所示 。
然后使用命令“mount /dev/udisk /mnt/disk/”将 u 盘挂载到开发板上,使用命令“ls /mnt/disk/”查看到“gps_test”,如下图所示。
使用命令“/mnt/disk/gps_test /dev/ttySAC3 &”,如下图所示 。
然后我们可在超级终端上看到 GPS 回传的信息,注意当信号不强时,部分数据读取不到,模块上电运行几分钟之后可能才会有完整信息,信号实在太弱的情况,可能什么信号都没有。
GPS 卫星有 24 颗,地球上任意一点,最多能够接收到 12 颗卫星信号。如下图所示,提示有三颗星,信号比较弱,可以勉强定位。由于作者是在室内测量,又是阴天,这种情况测量得出的数据误差就比较大,理论上三颗卫星就可以定位。但是需要更加精准,则需要更多的卫星来校准纠偏,如果能够达到 5 颗卫星以上,汽车导航仪理论上就可以接受了。
如上图所示,接收到的纬度为 N40.0452790,经度为 E116.1379283034。如下图所示,可以通过“http://www.gpsspg.com/maps.htm”等网站将经纬度转化为具体地址。
96.15 脉宽调制PWM驱动以及测试方法
大家好,本节我们来学习一下 Linux PWM 驱动的编写,用它来控制 BEEP,使其实现动听的音乐声。
在网盘资料的“iTOP4412开发板资料汇总(不含光盘内容)\iTOP-4412开发板Linux内核开发\iTOP-4412-驱动-pwm以及Linux-c测试程序.zip”目录下。
96.15.1 Makefile:
#!/bin/bash
#通知编译器我们要编译模块的哪些源码
#这里是编译 read_gpio.c 这个文件编译成中间文件 read_gpio.o obj-m += itop4412_pwmbeep.o
#源码目录变量,这里用户需要根据实际情况选择路径
#作者是将 Linux 的源码拷贝到目录/home/topeet/android4.0 下并解压的
KDIR := /home/topeet/android4.0/iTop4412_Kernel_3.0
#当前目录变量
PWD ?= $(shell pwd)
#make 命名默认寻找第一个目标#make -C 就是指调用执行的路径
#$(KDIR)Linux源码目录,作者这里指的是/home/topeet/android4.0/iTop4412_Kernel_3.0
#$(PWD)当前目录变量
#modules 要执行的操作all:
make -C $(KDIR) M=$(PWD) modules
#make clean 执行的操作是删除后缀为 o 的文件clean:
rm -rf *.o
96.15.2 驱动程序
驱动程序的名字:“itop4412_pwmbeep.c”。
这里要讲的是把它编译成模块我们将“itop4412_pwmbeep.c”和“Makefile”放到目录“/home/ada”,然后使用命令“make”使其生成“itop4412_pwmbeep.ko”文件。
96.15.3 添加设备到平台文件
最后使用命令“vim arch/arm/mach-exynos/mach-itop4412.c”,打开平台文件。添加设备,添加内容如下:
内核在编译之前应该先对其进行参数配置。具体讲解可以参考 itop-4412 开发板精英使用手册 5.3.2,这里以 POP 核心板为例编译 zImage 内核镜像,那么配置文件为config_for_linux_pop_elite 使用命令
cp config_for_linux_pop_elite .config
配置,
在内核目录下使用编译命令“make zImage”编译内核。编译完成后在目录“/home/topeet/android4.0/iTop4412_Kernel_3.0/arch/arm/boot”下找到新生成的zImage 编译到开发板,启动开发板。
96.15.4 测试程序
名字:“test_pwmbeep.c”
在 Ubuntu 系统下新建 ada 文件夹,将写好的 “test_pwmbeep.c” 拷贝到文件夹下,使用“arm-none-linux-gnueabi-gcc -o test_pwmbeep test_pwmbeep.c -static”命令编译应用。 如下图所示。
将上驱动的文件“itop4412_pwmbeep.ko”和“test_pwmbeep” 拷贝到 U 盘。 启动开发板,将 U 盘插入开发板,加载驱动文件,可以看到串口打印信息,同时听到蜂鸣器发出动听的响声。
96.16 ADC驱动以及测试例程
本章介绍 iTOP-4412 开发板的 ADC 驱动的升级和测试例程,资料包在群文件“iTOP-4412-驱动-adc驱动升级和测试例程_V2.0.zip”。在网盘资料的“iTOP4412开发板资料汇总(不含光盘内容)\iTOP-4412开发板Linux内核开发\iTOP-4412-驱动-adc驱动升级和测试例程_V2.0.zip”目录下。
自带的驱动只能支持一路 ADC,本文介绍如何修改可以支持 4 路 ADC 的控制。
96.16.1 硬件简介
如下图所示,这是 4412 的 datasheet 截图,可以看到 4412 一共有 4 路 ADC 接口。
如下图所示,这是开发板自带的 ADC 电路,ADC 接的是滑动变阻器,网络标号是XadcAIN0,因为有滑动变阻器,所以这一路测试的时候,动了滑动变阻器,就会影响 adc 的输出值。
如下图所示,是底板和核心板连接器,可以看到 XadcAIN[0:3],这四路都引到底板。
如下图所示,可以看到 ADC1 和 ADC2 引到 J38 端子。
综上,4412 开发板一共四路 ADC,通道 0 接到滑动变阻器,通道 1 和 2 通过 J38 引出,通道 4 引到底板,但是底板并没有引出。
96.16.2 驱动升级
压缩包中的“itop4412_adc.c”文件是升级之后的 adc 驱动文件,拷贝到内核源码下的“drivers/char/”目录下,将原来旧的驱动覆盖(老驱动注意备份),如下图所示,然后重新编译内核镜像,将新的内核镜像烧写到开发板中。
96.16.3 测试例程和测试方法
测试例程是压缩包中的“topeet_4412_adc.c”文件,拷贝到开发板,使用命令“arm- none-linux-gnueabi-gcc -o topeet_4412_adc topeet_4412_adc.c -static”编译,如下图所示。
将生成的测试例程 topeet_4412_adc,通过 U 盘、TF 卡或者 NFS 等方式弄到开发板。
如下图所示,在开发板控制台中,使用命令“/dev/adc”,可以看到 adc 的设备节点。
测试程序“topeet_4412_adc”需要两个参数,第一个参数是设备节点“/dev/adc”, 第二个参数是通道数 0、1、2、3。
如下图所示,使用命令“./topeet_4412_adc /dev/adc 0”可以测试滑动变阻器的 adc 值,作者测试的值为 5897。
旋转滑动变阻器的旋钮,再次测试,如下图所示,变为了 6202。
如果要测量通道 1 和 2,可以将其拉高为 1.8V(注意:不要超过 1.8V)或者 0V(接地),如下图所示,将通道 1 拉高到 1.8V,使用命令“./topeet_4412_adc /dev/adc 1”。
如果将其拉低,接地,再次测试,如下图所示,读取的值为 0。
测试通道 2 的方法和通道 1 的方法一样。最后还有通道 3,则需要从连接器下面飞线出来,或者自己做底板引出。
96.17 电源管理芯片S5M8767操作指南
本文档介绍如何操作芯片‘S5M8767’,以 camera 扩展端子的 VDD28_AF, VDD28_CAM 为例,来具体介绍驱动中如何实现电源电压和电流大小的设置。
本节将给出实现例程,用户可以将其集成到自己的驱动中,我们也提供了驱动测试例程压缩包“power_s5m8767a.tar.gz”。在网盘资料的“iTOP4412开发板资料汇总(不含光盘内容)\iTOP-4412开发板嵌入式Linux内核开发\iTOP-4412-驱动-电源管理芯片S5M8767修改输出例程_V1.0”目录下。
96.17.1 硬件分析
原理图分析
如下图所示,在底板原理图中找到 camera 扩展端子,这里以 VDD28_AF, VDD28_CAM 为例。camera 摄像头驱动中需要将其设置为 2.8v 的电压,后面我们将其修改为 3.3v 输出。
如下图所示,核心板原理图中搜索网络“VDD28_AF”和“VDD28_CAM”。可以看到“VDD28_AF”和“VDD28_CAM”分别对应电源芯片 S5M8767A 的“VLDO20”和“VLDO21”。
电源芯片S5M8767A的datasheet分析
打开 S5M8767A 的 datasheet(开发板的光盘里有提供),在 DATASHEEET 的 2.3.1 小节,如下图所示。
注意红框中的内容。最上面的红框中,表示输出的电流是 150mA,最低输出电压是0.8v,最大电压是 3.95v。下面红框中,介绍的是默认输出电压,可以看到 LDO20 和LDO21,默认输出的是 3.0v。
96.17.2 平台文件修改输出电压
如果要改变输出电压,可以通过修改 Linux 的平台文件来实现;在驱动中,可以通过函数调用,控制电源输出。
通过前面的分析可知,ldo21 和 ldo20 输出电流范围是 0.8v 到 3.95v。
在内核的“arch/arm/mach-exynos/mach-itop4412.c”文件中,如下图所示进行修改。
将
REGULATOR_INIT(ldo20, "VDD28_CAM", 2800000, 2800000, 0,REGULATOR_CHANGE_STATUS, 1);
注释掉,修改为 2800000,为 3950000(函数 REGULATOR_INIT 中的第一个参数表示8767 电源芯片的第 20 路,第三个参数表示输出最低电压,第四个参数表示输出最高电
压)。这里设置为最低和最高全部为 3.95v。同理,我们将第 21 路也修改为 3950000,如上图所示。
接着在 menuconfig 中,将 ov5640 摄像头的驱动去掉,因为在摄像头中会初始化和配置。ov5640 摄像头摄像头的配置路径如下图所示。下面截图是已经去掉的截图,而默认缺省文件是配置上的。
96.17.3 驱动例程
驱动例程“power_s5m8767a.tar.gz”和文档在同一压缩包中。编写一个简单的驱动测试程序,源码如下所示。
#include <linux/init.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/regulator/consumer.h>
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
#include <mach/regs-gpio.h>
#include <mach/regs-clock.h>
#include <linux/fs.h>
#include <linux/err.h>
struct regulator *ov_vddaf_cam_regulator = NULL;
struct regulator *ov_vdd5m_cam_regulator = NULL;
struct regulator *ov_vdd18_cam_regulator = NULL;
struct regulator *ov_vdd28_cam_regulator = NULL;
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("iTOPEET_dz");
static int power(int flag)
{
if(1 == flag){
regulator_enable(ov_vdd18_cam_regulator);
udelay(10);
regulator_enable(ov_vdd28_cam_regulator);
udelay(10);
regulator_enable(ov_vdd5m_cam_regulator); //DOVDD DVDD 1.8v
udelay(10);
regulator_enable(ov_vddaf_cam_regulator); //AVDD 2.8v
udelay(10);
}
else if(0 == flag){
regulator_disable(ov_vdd18_cam_regulator);
udelay(10);
regulator_disable(ov_vdd28_cam_regulator);
udelay(10);
regulator_disable(ov_vdd5m_cam_regulator);
udelay(10);
regulator_disable(ov_vddaf_cam_regulator);
udelay(10);
}
return 0 ;
}
static void power_init(void)
{
int ret;
ov_vdd18_cam_regulator = regulator_get(NULL, "vdd18_cam");
if (IS_ERR(ov_vdd18_cam_regulator)) {
printk("%s: failed to get %s\n", func , "vdd18_cam");
ret = -ENODEV;
goto err_regulator;
}
ov_vdd28_cam_regulator = regulator_get(NULL, "vdda28_2m");
if (IS_ERR(ov_vdd28_cam_regulator)) {
printk("%s: failed to get %s\n", func , "vdda28_2m");
ret = -ENODEV;
goto err_regulator;
}
ov_vddaf_cam_regulator = regulator_get(NULL, "vdd28_af");
if (IS_ERR(ov_vddaf_cam_regulator)) {
printk("%s: failed to get %s\n", func , "vdd28_af");
ret = -ENODEV;
goto err_regulator;
}
ov_vdd5m_cam_regulator = regulator_get(NULL, "vdd28_cam");
if (IS_ERR(ov_vdd5m_cam_regulator)) {
printk("%s: failed to get %s\n", func , "vdd28_cam");
ret = -ENODEV;
goto err_regulator;
}
err_regulator:
regulator_put(ov_vddaf_cam_regulator);
regulator_put(ov_vdd5m_cam_regulator);
regulator_put(ov_vdd18_cam_regulator);
regulator_put(ov_vdd28_cam_regulator);
}
static int hello_init(void)
{
power_init();
power(1);
printk(KERN_EMERG "Hello World enter!\n");
return 0;
}
static void hello_exit(void)
{
power(0);
printk(KERN_EMERG "Hello world exit!\n");
}
module_init(hello_init);
module_exit(hello_exit);
Makefile 如下所示。
#!/bin/bash
obj-m += power_s5m8767a_test.o
KDIR := /home/topeet/android4.0/iTop4412_Kernel_3.0
PWD ?= $(shell pwd)
all:
make -C $(KDIR) M=$(PWD) modules
clean:
rm -rf *.o modules.order *.ko *mod.c Module.symvers
使用 make 命令编译驱动模块,如下图所示。
96.17.4 测试
如下图所示,加载驱动之后,测量电压大约为 2.85 左右(有压降),卸载驱动之后,电压为 0。说明驱动运行成功,用户在自己的项目中,假如需要用到电源控制,可以参考本例程来实现。
到此,修改 S5M8767 的输出电压的方法就介绍完了。
需要进一步明确的是:如果我们想要修改 8767 的某个 LDO 的输出电压,就可以通过修改对应 LDO 的 regulator_init_data 结构体里面的电压值来实现,修改 BUCK 的电压可以使用函数 regulator_set_voltage 来实现。
注意:因为 S5M8767 的每个 BUCK 和 LDO 都有各自规定的输出最大值,因此在修改输出电压的时候,一定要参照 S5M8767 的 datasheet,确保修改的电压在 datasheet 规定的范围内。
96.18 一键实现开关机唤醒和休眠
本节介绍以开发板上的 reset 按键来实现一键开关机,休眠唤醒的功能。在网盘资料的“iTOP4412开发板资料汇总(不含光盘内容)\iTOP-4412开发板嵌入式Linux内核开发\iTOP-4412实现一键开关机休眠唤醒.zip”目录下。
96.18.1 设置启动方式
首先我们通过 reset 按键实现开机功能,在开发板的底板原理图上找到如下原理。
如上图所示,通过电阻 R173 和 R174 可以设置开发板的启动方式——上电启动。
默认是上电启动,所以我们焊了电阻 R174(把 ACOKB_CHARGER 这个网络下拉),如果改成按键启动,需要把电阻 R174 去掉,电阻 R173 焊上(通过 800K 电阻上拉)。
(注意:因为我这里的截图是精英版的,所以这两个电阻的标号是 R173 和 R174,在全功能板上这两个电阻有可能是其他的标号,大家主要是搞明白了原理,根据自己的实际需要来选择就可以了,不要纠结于电阻的标号和我上面的截图不一样。)
96.18.2 设置一键休眠唤醒关机
硬件设置为按键启动之后,修改一下软件,就可以通过 reset 按键实现休眠唤醒和关机功能。
首先用压缩包里的“samsung-keypad.c”(该文件可以再技术支持的群共享中找到)替换内核源码的“iTop4412_Kernel_3.0/drivers/input/keyboard/samsung-keypad.c”。
然后修改内核“iTop4412_Kernel_3.0/arch/arm/mach-exynos/mach-itop4412.c”文件,在这个文件找到。
然后添加“KEY(0, 5, KEY_POWER)”,修改成如下图。
修改完成后,保存并退出,然后输入“make zImage”命令开始编译内核,编译完成, 烧写生成的 zImage 到 iTOP-4412 开发板,就可以实现一键休眠唤醒和关机功能了。
96.19 通过系统总线扩展以太网的一种方法
以太网技术在工业远程监控和数据采集领域有着广泛的应用,在嵌入式 ARM 处理器的基础上引出以太网接口,是个经常会涉及的问题。
当前,在嵌入式系统的研发方面,越来越重视网络功能。尤其是以太网,它作为数据通讯最成熟的技术之一,随着互联网技术的迅猛发展,正发挥着越来越重要的作用。
本文介绍如何从当今流行的四核 ARM 处理器(三星 Exynos 4412)引出以太网接口,并给出相应的电路原理图。
这里首先介绍一下三星四核处理器 Exynos 4412:2012 年初,三星正式推出了自家首款四核移动处理器 Exynos 4412。这款新 Exynos A9 四核处理器,拥有 32nm HKMG(高 K 金属栅极技术)制程,支持双通道 LPDDR2 1066。新的 32nm HKMG 技术可以帮助降低功耗,按照官方的说法,和其前代比会减低 20% 的功耗。三星 Exynos 4412 四核处理器仍然集成 Mali-400MP 图形处理器,但三星公司已将这颗图形处理器主频由此前的 266MHz 提升至 400MHz,新闻稿指出会比现有的双核机型整体性能提升 60%,00 图像处理提升 50%。2012 年 5 月,首款采用 Exynos 4412 处理器的智能手机三星 Galaxy S III 正式上市,并取得骄人的销量。
在 Exynos 4412 上进一步扩展以太网接口,需要外接以太网控制器,这里给出多个实现方案供读者参考。
96.19.1 接口硬件设计。
LAN9215 是 SMSC 公司开发的一款以太网控制器,支持 HP Auto-MDIX 16 位 Non PCI 10/100 。他具有如下特点:
1、采用低 CPU 开销的有效架构。
2、可轻松接入大多数 16 位嵌入式 CPU。
3、集成 PHY 和 HP Auto-MDIX 支持。
4、支持基于以太网的音频和视频流,多路标清 MPEG2 流。
5、消除信息包丢失,内部缓冲内存可以存储 200 多个信息包
6、多种电源管理模式,并能工作中省电模式。
LAN9215 通过总线方式与处理器通讯:
从上图可以看出,共需要 8 条数据线以及 16 条地址线。
Exynos 4412 共有四组 BANK 可以和以太网芯片 LAN9215 相连,通过不同的地址分配来实现对 LAN9215 的读写操作,最终来实现网络通讯。
读写控制信号如下图所示:
可以看出处理器使用‘片选1’来驱动 LAN9215,通过查找4412的用户手册,可知地址范围为: 0x05000000 0x06000000.
在驱动编程的时候,处理器通过对这个范围的地址进行操作,就可以实现控制LAN9215。
另外需要注意的是,LAN9215使用的是3.3V 电平,而4412输出的是1.8V 的电平标准,所以需要电平转换来匹配双方器件,如下图所示:
更详细的电路图可参考 iTOP-4412开发板相应硬件原理图。
96.19.2 通讯接口软件设计
初始化程序设计
本系统初始化通过定义结构体的方式完成,处理器通过总线方式完成系统时钟、外设时钟、系统启动模式,中断控制寄存器、等的初始化。
Socket 初始化程序设计
Exynos 4412通过以太网和其他终端之间的数据交换有多种方式,本文采用 TCP 模式,TCP 是以连接为基础的通信方式,端口 n 在进行数据通信时,必须先建立连接。TCP 有两种建立连接方式,一种是服务器模式(被动模式),需要等待连接请求;另一种是客户端模式(主动打开),需要发送连接请求给服务器。本设计配置4412为服务器模式,只需对4412的 Socket 进行配置就可以完成网络数据的收发和启动功能。
当 Socket 作为服务器模式时,初始化端口需要设置运行模式(Sn_MR)和本机端口号(Sn_Port),并在端口命令寄存器打开(OPEN)端口。引用 Socket_Listen(SOCKET s)程序,只调用一次该程序就可使 Exynos 4412端设置为服务器模式。主要程序如下所示。
Write_E4412((E4412_S0_MR+s*0x100),S_MR_TCP);
//设置 Socket 为 TCP 模式
Write_E4412((E4412_S0_CR+s*0x100),S_CR_OPEN);
// 打 开 Socket
Write_E4412((E4412_S0_CR+s*0x100),S_CR_LISTEN);
//设置 Socket 为侦听模式
Write_E4412((E4412_S0_CR+s*0x100),S_CR_CLOSE);
//关闭 Socket
完成 Socket 的打开和设置侦听工作后,至于远程客户端是否与其连接,则需要等待 Socket 中断,在服务器侦听模式下,不需要设置目的 IP 和目的端口号。
Socket 数据接收程序设计
当端口接收数据时,产生接收中断。首先调用端口接收数据包函数Process_Socket_Data(),并对接收到的数据类型进行判断和加工。本过程先调用接收函数 S_rx_process()从处理器4412端口的接收数据缓存区读取数据,然后将读取的数据加上接收存储器读指针寄存器(S0_RX_RD)的值再写入 S0_RX_RD,最后将 RECV 命令重新写入端口0的命令寄存器(S0_CR),以等待下次数据的接收。或者将处理完的数据拷贝到发送缓冲区,再调用 S_tx_process 函数发送数据包给 CPU。主要程序如下:
Socket 数据发送程序设计
通过 Socket 发送数据时,调用发送数据函数 S_tx_process。首先把要发送的数据缓存在发送缓冲区(Tx_buffer)中。此外,在发送数据时,需先检查发送缓存区的剩余空间的大小(Sn_TX_FSR),控制发送数据的字节数,如用以太网协议发送的数据最大传送单元(MTU)不超过1 500 B。在 TCP 服务器模式下,在数据发送处理过程中,可不设置目标主机的 IP 和端口号。剩余空间的大小因写入数据的增加而减少,数据发送后又自动增加。当发送缓冲区的数据完全写入端口的发送数据缓存区后,则将数据本身长度加上端口传输写指针寄存器(Sn_TX_WR)中的值再写入 Sn_Tx_WR,再计算发送缓冲区的偏移量(tx_offset),用于指示发送数据的长度,最后启动发送(Sn_CR_SEND)。相关程序如下:
i=tx_offset/S_TX_SIZE //计算实际物理偏移值,
//S_TX_SIZE 由 TMSR 定义为2 K
tx_offset=tx_offset-i*S_TX_SIZE //计算实际物理地址
//j= W4412_TX+s*S_TX_SIZE+tx_offset
Write_E4412(j,Tx_Buffer[i]) //将发送缓冲区中的
//数据写入到端口的发送缓冲区
Write_E4412((W4412_S0_CR+s*0x100),S_CR_SEND)
本文简单介绍了通过三星四核处理器 Exynos 4412扩展以太网应用的一种方法,除此之外我们还可以选择其他的以太网控制器芯片如 DM9000AEP,或者通过 USB 接口来扩展以太网功能(如芯片 DM9621);
按照本文介绍的方法,我们甚至可以在4412处理器上同时扩展多个以太网接口,来满足不同应用需求,通过迅为电子的’iTOP-4412核心板’来扩展实现是比较容易的。
96.20 Linux开机LOGO的修改方法
96.20.1 针对配套 4.3 寸屏幕的方法
本文档主要介绍 iTOP-4412 开发板,4.3 寸屏幕,内核 logo 修改过程。默认的镜像,在4.3 寸屏幕上是不显示内核 logo 的。
本文档需要用到的工具包可以在文档压缩包中找到。用户可以自行在群文件中进行搜索。修改过程可以大致分为两个步骤:1、s3cfb_ops.c 文件修改 2、内核 logo 制作。
V1.1 版本:增加了修改位深度为 8 位的方法。
配套资料在网盘资料的“iTOP4412开发板资料汇总(不含光盘内容)\iTOP-4412开发板嵌入式Linux内核开发\iTOP-4412-驱动-linux开机logo的修改方法_V1.1.zip”目录下。
s3cfb_ops.c
在“iTop4412_Kernel_3.0/drivers/video/samsung/s3cfb_ops.c”文件中,有设置logo 显示的代码。
修改之前的代码为:
修改后的代码如下图所示:
保存,退出。
制作内核 logo,生成.h 文件
首先需要一张“272*480”大小的 bmp 格式的图片。如下图所示。
这里作者提供了一种修改位深度为 8 位的方法:
1.在百度上下载 ps 软件。
2.在 ps 中打开软件,点击图像——模式——索引,设置为下图所示。
3.点击文件——储存为.BMP 格式,设置为下图所示,点击保存。
然后,通过“Img2Lcd”软件打开该图片。设置如下图所示(其中红色部分是需要修改的地方)。
设置完成后,点击左上角的保存按钮,弹出如下图所示对话框。文件名可以自行定义,但格式要求为“.h”,此处修改为“topeet.h”,点击保存按钮,保存。
保存后,弹出如下图所示文件:
暂时关闭,待用。
修改 iBitmapData_q 数组
iBitmapData_q 数组在“iTop4412_Kernel_3.0/drivers/video/samsung/iTop- 4412.h”文件中。打开“iTop-4412.h”文件会发现两个数组:iBitmapData、iBitmapData_q。我们只需修改后者即可。
用上一小节生成的“topeet.h”数组中的内容,替换掉“iBitmapData_q”数组中的内容。完成后如下图所示。(数组比较大,用户可以使 shift 键进行选择。)
96.20.2 针对其他屏幕的LOGO修改方法(4.3寸除外)
本文档介绍 4412 开发板的内核启动 LOGO,请注意如果要修改的屏幕分辨率小于480x640,请参考上节提供的方法。
本文档 LOGO 修改方法支持迅为除 4.3 寸屏幕以外所有屏幕。
首先要准备一张 480x640 分辨率的图片,作者使用的是美图秀秀修改图片的分辨率,觉得挺好用,这里推荐给大家使用。另外如果图片显示方向不对,在保证分辨率为 640x480 的情况下,可以使用上下左右翻转功能处理图片。
然后使用转换工具 Img2Lcd(在压缩包中)把图片转换成数组文件,工具配置如下,如下图所示。
如下图所示,转化的数组文件内容,一定要保证数组长度为 921600。
在内核源码文件中“drivers/video/samsung/iTop-4412.h”,如下图所示。
如上图所示的内核文件中有两个数组,需要用到的是 iBitmapData_q 数组,将其中的内容使用前面图片导出数组内容替换。
替换完成之后,重新编译生成新的内核镜像,重新烧写到开发板中之后,就可以完成内核启动 LOGO 的更新了。
有可能我们自己制作的 logo 没有显示在屏幕的最中央,那我们需要修改下文件“drivers/video/samsung/s3cfb_ops.c”,在这个文件找到函数:s3cfb_draw_logo
int s3cfb_draw_logo(struct fb_info *fb)
{
#ifdef CONFIG_FB_S5P_SPLASH_SCREEN
struct fb_fix_screeninfo *fix = &fb->fix;
struct fb_var_screeninfo *var = &fb->var;
#if 0
struct s3c_platform_fb *pdata = to_fb_plat(fbdev->dev);
memcpy(fbdev->fb[pdata->default_win]->screen_base,
LOGO_RGB24, fix->line_length * var->yres);
#else
//u32 height = var->yres / 3;
u32 line = fix->line_length;
u32 i, j;
u32 index;
u32 top,left;
const unsigned char *pLog =NULL;
memset(fb->screen_base, 0x00, var->yres * line);
printk("\n CPU type: \n");
if(soc_is_exynos4412()){
printk(" Exynos 4412\n");
pLog = iBitmapData_q;
}else{
printk("Exynos 4212\n");
pLog = iBitmapData;
}
top = 170;
left = 230;
index = 0;
for (i = 0; i < 480; i++) {
for (j = 0; j < 640; j++) {
memset(fb->screen_base + (i + top) * line + (j + left) * 4 + 0, pLog[index], 1);//B
memset(fb->screen_base + (i + top) * line + (j + left) * 4 + 1, pLog[index+1], 1);//G
memset(fb->screen_base + (i + top) * line + (j + left) * 4 + 2, pLog[index+2], 1);//R
memset(fb->screen_base + (i + top) * line + (j + left) * 4 + 3, 0x00, 1);
index += 3;
}
}
#endif
#endif
return 0;
}
修改这个函数里面的 top 和 left 就可以控制图片在屏幕显示的位置了。