S3C2410触摸屏驱动移植的完整过程(论文的操作部分,所以从第七章开始)
七 实验步骤:7.1 配置虚拟机网络配置:PC:右键点击主机右下角“网络”图标,选择“打开网络连接”,弹出如下图的对话框,Vmnet1是hostonly的接口,Vmnet8是NAT的网络接口。右键点击“本地连接”,选择属性 先勾选“VMwareBridge Protocol”。然后选中“Internet协议(TCP/IP)”,点击“属性”:弹出设
七 实验步骤:
7.1 配置虚拟机
网络配置:
PC:右键点击主机右下角“网络”图标,选择“打开网络连接”,弹出如下图的对话框,Vmnet1是hostonly的接口,Vmnet8是NAT的网络接口。右键点击“本地连接”,选择属性
先勾选“VMwareBridge Protocol”。
然后选中“Internet协议(TCP/IP)”,点击“属性”:
弹出设置IP和DNS服务器的对话框。首先IP地址选择“使用下面的IP的地址”,并分别填入IP地址,子网掩码和默认网关,DNS服务器不用管。
点击“确定”退出。
在cmd中,可以查看IP地址。
关闭windows防火墙。
在控制面板中关闭防火墙
在Vmware中,点击虚拟机右下角网络图标,右键选择“Edit”:
“Networkconnection”选择“Bridged”方式。
点击虚拟机菜单栏的”Edit”-->”VirtualNetworking Setting”
将vmnet0设置为主机的网卡,如下图所示:
在虚拟机内,开始-->系统设置-->网络—>编辑:
确定后,然后点击激活。
重启网络:$sudo service network restart
正在关闭接口eth0: [ 确定 ]
关闭环回接口: [ 确定 ]
设置网络参数: [ 确定 ]
弹出环回接口: [ 确定 ]
弹出界面eth0: [ 确定 ]
关闭防火墙。sudoservice iptables stop
[maming@localhostetc]$ sudo service iptables stop
清除所有链: [ 确定 ]
删除用户定义的链: [ 确定 ]
将内建链重设为默认的“ACCEPT”策略: [ 确定 ]
7.2 建立嵌入式开发环境
7.2.1建立嵌入式交叉编译环境
对于linux所有源代码的编译都使用ARM公司推出的新一代EABI编译器。
资料附件中提供了一个编译器。将arm-2008q3.tar.bz2这个文件复制到linux主机的/root目录下,并在终端中执行下面的解压缩命令:
tar–xjvf arm-2008q3.tar.bz2
即可得到arm-none-linux-gnueabi-4.3.2目录。
为了使用方便,还可以编辑/etc/bash.bashrc文件添加把编译器路径到环境变量PATH中,只要在这个文件中添加下面这2个语句即可:
PATH=/root/arm-none-linux-gnueabi-4.1.0/bin:$PATH
ExportPATH
编辑完毕后使用source/etc/bash.bashrc命令执行以下这个文件,让设置生效,之后再输入:
arm-none-linux-gnueabi-gcc–v
如果输出下面的信息则表面设置成功:
figo@figo-desktop:~$ arm-none-linux-gnueabi-gcc -v Using built-in specs. Target: arm-none-linux-gnueabi Configured with: /scratch/julian/lite-respin/linux/src/gcc-4.3/configure --build=i686-pc-linux-gnu --host=i686-pc-linux-gnu --target=arm-none-linux-gnueabi --enable-threads --disable-libmudflap --disable-libssp --disable-libstdcxx-pch --with-gnu-as --with-gnu-ld --enable-languages=c,c++ --enable-shared --enable-symvers=gnu --enable-__cxa_atexit --with-pkgversion='Sourcery G++ Lite 2008q3-72' --with-bugurl=https://support.codesourcery.com/GNUToolchain/ --disable-nls --prefix=/opt/codesourcery --with-sysroot=/opt/codesourcery/arm-none-linux-gnueabi/libc --with-build-sysroot=/scratch/julian/lite-respin/linux/install/arm-none-linux-gnueabi/libc --with-gmp=/scratch/julian/lite-respin/linux/obj/host-libs-2008q3-72-arm-none-linux-gnueabi-i68 6-pc-linux-gnu/usr --with-mpfr=/scratch/julian/lite-respin/linux/obj/host-libs-2008q3-72-arm-none-linux-gnueabi-i686-pc-linux-gnu/usr --disable-libgomp --enable-poison-system-directories --with-build-time-tools=/scratch/julian/lite-respin/linux/install/arm-none-linux-gnueabi/bin --with-build-time-tools=/scratch/julian/lite-respin/linux/install/arm-none-linux-gnueabi/bin Thread model: posix gcc version 4.3.2 (Sourcery G++ Lite 2008q3-72) |
7.2.2 建立tftp服务器
一共两种方法,读者可自行选择(另一种方法在后面)。
打开redhat虚拟机,在虚拟机中建立tftp和nfs服务器,tftp用来传送文件,nfs是一个网络文件系统,该文件系统方便了开发人员的调试工作。
需要说明的是不同版本的Linux内核其建立tftp服务器的命令也不同,本文中虚拟机中redhatlinux版本较低,如果要在高版本的操作系统上安装tftp,相关命令请在网上查找。
tftp(trivial file transfer protocol)
功能说明:传输文件。
语 法:tftp[主机名称或IP地址]
补充说明:FTP让用户得以下载存放于远端主机的文件,也能将文件上传到远端主机放置。tftp是简单的文字模式ftp程序,它所使用的指令和FTP类似。
Linux下TFTP服务器架设
(1)安装tftpd(服务器端程序)、tftp(客户端程序)、openbsd-inet
在系统工具中启用超级用户终端,执行
# sudoapt-get install tftpd
#sudo apt-get install tftp
系统自动进行下载安装过程。
(2)编辑inetd.conf文件
此文件是tftp的配置文件。
执行#sudo gedit/etc/inetd.conf
进行编辑,更改内容如下:
#:BOOT:TFTP service is providedprimarily for booting. Most sites
# runthis only on machines acting as “boot servers.”
Tftpdgram udp wait nobody /usr/sbin/tcpd /usr/sbin/in.tftpd /tftpboot
(3)设定目录
根目录下建立文件夹tftpboot。
执行# cd /
# sudo chmod 777 tftpboot
此处将tftp文件夹权限边更为777,以使所有用户获得读写tftpboot文件夹中文件权限,否则将无法上传文件。
(4)重启tftp服务
执行# sudo /etc/init.d/openbsd-inetd reload
显示:
Reloadinginternet superserverinetd [ OK ]
(5)测试
/tftpboot下建立test文件。
执行#tftp localhost
# get test
经检验/tftpboot下有文件test,实验成功。
如果出现问题,使用关闭防火墙命令
ufwdisable
同时应该关闭虚拟机宿主机的防火墙。
如果没有条件在虚拟机操作系统上建立tftp服务器,那么可以在宿主机WinXP系统下使用资料中提供的tftpd32.exe软件建立tftp服务器。
首先在桌面上建立一个文件夹,将tftpd32.exe和要上传到开发板的文件(uImage,后面会提到)拷贝到该文件下,双击tftpd32.exe即可。
7.2.3 建立nfs服务器
在终端上以此输入以下命令:
sudoapt-get install portmap
sudoapt-get install nfs-kernel-server
sudovi /etc/exports
在文件的最后一行添加:
/nfsboot *(rw,sync,no_root_squash,insecure)
/nfsboot是根目录下的一个文件夹
# *表示任何IP都可以共享,如果你想限定个别IP,用IP替代
#no_root_squash不太安全,可以改为root_squash,这里是特殊应用
保存并退出
启动NFS服务
sudo/etc/init.d/portmap restart
sudo/etc/init.d/nfs-kernel-server restart
配置NFS工作完成
测试NFS
sudomount (-t nfs -o nolock)192.168.1.178:/ nfsboot /tmp
#192.168.1.178是我虚拟机Linux的IP地址
如果/nfsboot 中文件信息能够在/tmp中出现,则表示NFS设置成功
sudoumount /tmp 卸载文件
运行$ df 看看结果
$sudo umount /mnt
7.3 配置根文件系统
将资料中的root_mkfs.tar.bz2解压出来的文件全部拷贝到nfsboot文件夹下,注意/nfsboot目录下应该就是整个文件系统,而不是一个单独的文件夹。
在终端下进入/dev文件夹中输入如下命令:
mknod -m 660null c 1 3
mknod -m 660console c 5 1
ln –s /dev/fb/0/fb0
ln –s /dev/vc/0/tty0
7.4 烧写Uboot到S3C2410开发板
使用并口烧写uboot,uboot.bin在资料文件夹下
使用并口连接开发板和PC,并正确安装好并口驱动后,将开发板上电.进入WINXP的CMD模式下:
1:
C:\image> sjf2410.exe/f:uboot.bin
这时出现下面显示才表示JTAG找到了CPU,即硬件连接和驱动正常:
+----------------------------------------------+
|SEC JTAG FLASH(SJF)V0.4 |
|<S3C2410X & SMDK2410 B/D> |
+----------------------------------------------+
S3C2410X(ID=0x0032409d)is detected.
2:
Selectthe function to test: 0 选0->K9S1208prog
C:Select the function to test: 0 选0->K9S1208Program
Availabletarget block number: 0~4095
D:Input target block number: 0 选0
STATUS:Epppppppppppppppppp
Eppppppppppppppppppppppppp
Eppppppppppppppppppppppppp
烧完后选2(exit)并重启开发板,通过超级终端进入uboot.
7.5 建立windows超级终端
在开始->程序->附件->通讯中打开超级终端,如上图所示。
将名称命名为ts_exp,然后点击确定。
选择com1。
每秒位数选择115200,数据位选择8,奇偶校验选择无,停止位选择1,数据流控制选择无。
7.6 移植触摸屏驱动程序
在linux2.6.22中没有提供s3c2410触摸屏的驱动程序,所以我们要手动创建驱动程序文件。将资料文件夹中的linux-2.6.22.gz复制到虚拟机中任意一处文件加下(记住名字,最好是自己建立一个空文件夹),并解压到该文件夹下。
解压好后,在Linux内核文件夹/drivers/input/touchscreen/文件夹下建立一个新的文件s3c-ts.c(该文件在附件中提供),在include/asm-arch/arch-s3c2410/下建立ts.h文件。
1.修改linux2.6.22/drivers/input/touchscreen目录下的Makefile文件,在文件的末尾添加:
obj-$(CONFIG_TOUCHSCREEN_S3C2410)+=s3c-ts.o |
添加这句话的主要目的是为了使得工程能够自动编译s3c-ts.c文件。
2.修改linux2.6.22/drivers/input/touchscreen下的Kconfig文件,在其中添加:
config TOUCHSCREEN_S3C2410 tristate "Samsung S3C2410 touchscreen input driver" depends on ARCH_SMDK2410 && INPUT && INPUT_TOUCHSCREEN select SERIO help Say Y here if you have the s3c2410 touchscreen. If unsure, say N. To compile this driver as a module, choose M here: the module will be called s3c-ts. config TOUCHSCREEN_S3C2410_DEBUG boolean "Samsung S3C2410 touchscreen debug messages" depends on TOUCHSCREEN_S3C2410 help Select this if you want debug messages |
添加这段内容是在编译选项菜单中添加TOUCHSCREEN_S3C2410项目。
修改完成以后,在我们配置内核的时候,就会增加关于s3c2410的触摸屏配置选项,我们选择这些选项就可以把驱动增加进去了。
具体选择的路径如下:
Devicedrivers →
Inputdevice support →
Touchscreens →
<*>SamsungS3C2410 touchscreen input driver
[ ]Samsung s3c2410 touchscreen debug message
3.然后在/linux-2.6.22/arch/arm/mach-s3c2410/mach-smdk2410.c中增加如下内容:
加头文件如下:
#include <asm-arm/arch-s3c2410/ts.h> |
同时加入以下内容:
static struct s3c_ts_mach_info s3c_ts_platform __initdata = { .delay = 10000, .presc = 49, .oversampling_shift = 2, .resol_bit = 12, .s3c_adc_con = ADC_TYPE_2, }; |
这是初始化值结构体。
在structplatform_device *smdk2410_devices[]__initdata数组中加入&s3c_device_ts,
同时在staticvoid __init smdk2410_map_io(void){}函数中加入:
s3c_ts_set_platdata($s3c_ts_platform);语句。
4.在linux-2.6.22/include/asm-arm/plat-s3c24xx目录下devs.h文件中加入:
头文件:
#include<asm-arm/arch-s3c2410/ts.h>
同时加入:
externstruct platform_device s3c_device_ts;
在s3c-ts.c中加入如下内容:
头文件:
#include <asm-arm/arch-s3c2410/hardware.h> #include <asm-arm/arch-s3c2410/regs-adc.h> #include <asm-arm/arch-s3c2410/regs-gpio.h> #include <asm-arm/arch-s3c2410/ts.h> #include <asm-arm/arch-s3c2410/irqs.h> |
将原来对应的项目注释掉(为避免麻烦,这里s3c-ts.c文件已经改好了,只需要读懂此段内容即可)。
加入:
struct s3c_ts_mach_info s3c_ts_default_cfg __initdata = { .delay = 1000, .presc = 49, .oversampling_shift = 3, .resol_bit = 10 }; |
按照regs-adc.h中的寄存器命名方式修改寄存器名称(如S3C_ADCDAT0要改为S3C2410_ADCDAT0)。
将s3c2410中没有的寄存器操作语句注释掉。
5.在linux-2.6.22/include/linux目录下bitops.h文件中添加:
#ifdef __KERNEL__ #define BIT(nr) (1UL << (nr)) #define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) #define BIT_WORD(nr) ((nr) / BITS_PER_LONG) #define BITS_PER_BYTE 8 #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) #endif |
在linux-2.6.22/arch/arm/plat-s3c24xx下devs.c文件中添加:
/* Touchscreen */ static struct s3c_ts_mach_info s3c2410ts_info; void __init s3c_ts_set_platdata(struct s3c_ts_mach_info *hard_s3c2410ts_info) { memcpy(&s3c2410ts_info,hard_s3c2410ts_info,sizeof(struct s3c_ts_mach_info)); } EXPORT_SYMBOL(s3c_ts_set_platdata); struct platform_device s3c_device_ts = { .name = "s3c-ts", .id = -1, .dev = { .platform_data = &s3c2410ts_info, } }; EXPORT_SYMBOL(s3c_device_ts);
|
7.7 添加好了驱动程序后,就可以编译内核了
在终端中进入到内核文件夹下,输入命令makemenuconfig,会弹出一个菜单,选择DeviceDrivers
选择select然后回车进入DeviceDrivers的子菜单
将光标停留在Touchscreeninterface上按空格,直到尖括号内显示*号即可。同理选择好Eventinterface和Eventdebugging两个选项,如果不选这三项,后面会出现许多意想不到的错误。
然后选择Exit按回车回到上级菜单。
选择KernelFeatures选项按回车进入子菜单。
将Usethe ARM EABI to compile the kernel选择上,如果这项不选,编译好的内核不能支持某些程序。
选择好这些选项后,退出菜单并保存,在内核文件夹下会生成一个.config文件。
在终端中输入makezImage命令,就开始自动编译内核生成zImage,编译完成之后在一般而言是在Linux-2.6.26/arch/$ARCH/boot里可以找到zImage文件。
7.8 制作uImage映像文件
首先说明为什么要生成uImage文件。uImage是由zImage生成的。
通常,u-boot为kernel提供一些kernel无法知道的信息,比如ramdisk在RAM中的地址。kernel也必须为U-boot提供必要的信息,如通过mkimage这个工具(在u-boot代码的tools目录中)可以给zImage添加一个header,也就是使得通常编译的内核zImage添加一个数据头,把添加头后的image通常叫uImage,uImage是可以被U-boot直接引导的内核镜像。
下面是制作uImage的步骤(制作好的uImage在资料文件夹下):
将资料文件夹下的my-u-boot-1.2.0.rar复制到虚拟机一处空文件夹内(可自行建立),并在该文件夹下解压。
将编译生成的zImage文件拷贝到uboot文件夹下的tools目录下,将mkimage文件(资料文件夹中)拷贝到该目录下,同时命令行终端进入到该目录下输入并执行如下命令:
./mkimage -A arm -O linux -T kernel -C none -a 30008000 -e 30008040 -n linux-2.6.22 -d zImage uImage |
解释一下这个命令中的用法:
首先查看mkimage的命令参数
./mkimage -l image -l ==< list image header information
./mkimage [-x] -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file [:data_file...] image -A ==< set architecture to 'arch' //用于指定CPU类型,比如ARM -O ==< set operating system to 'os' //用于指定操作系统,比如Linux -T ==< set image type to 'type' //用于指定image类型,比如Kernel -C ==< set compression type 'comp' //指定压缩类型 -a ==< set load address to 'addr' (hex) //指定image的载入地址 -e ==< set entry point to 'ep' (hex) //内核的入口地址,一般是:image的载入地址+0x40(信息头的大小) -n ==< set image name to 'name' //image在头结构中的命名 -d ==< use image data from 'datafile' //无头信息的image文件名 -x ==< set XIP (execute in place) //设置执行位置 -a参数后是内核的运行地址,-e参数后是入口地址 |
(1)如果我们没用mkimage对内核进行处理的话,那直接把内核下载到0x30008000再运行就行,内核会自解压运行(不过内核运行需要一个tag来传递参数,而这个tag建议是由bootloader提供的,在u-boot下默认是由bootm命令建立的)。
(2)如果使用mkimage生成内核镜像文件的话,会在内核的前头加上了64byte的信息,供建立tag之用。bootm命令会首先判断bootmxxxx 这个指定的地址xxxx是否与-a指定的加载地址相同。
1)如果不同的话会从这个地址开始提取出这个64byte的头部,对其进行分析,然后把去掉头部的内核复制到-a指定的load地址中去运行之
2)如果相同的话那就让其原封不同的放在那,但-e指定的入口地址会推后64byte,以跳过这64byte的头部。
当uImage生成好后会有如下的信息:
7.9 烧写uImage
将uImage拷贝至虚拟机操作系统根目录下/tftpboot目录下(或者宿主机上前面建立的文件夹,内有tftpd32.exe)。
连接好网线和串口线,设置虚拟机ip为192.168.1.178(前面已经完成)。
开启开发箱电源,超级终端显示u-boot启动信息,在倒计时没有结束前按回车进入u-boot界面。
输入printenv可以查看u-boot的环境变量值。
配置u-boot环境变量参数:(输入如下命令)
setenv bootargs noinitrd mem=64M console=ttySAC0 root=/dev/nfs nfsroot=192.168.1.178:/nfsboot wsize=1500 rsize=1500 ip=192.168.1.20:192.168.1.178:192.168.1.1:255.255.255.0::eth0:on |
之后保存设置好的环境变量:
输入saveenv命令。
重新启动开发箱电源,进入到uboot下:
输入命令:tftp0x30008000 uImage
如果下载uImage失败,那么先检查tftpboot文件夹下是否有uImage文件,再检查开发板是否能ping通电脑主机,如果上述都没问题那么在uImage前加上tftp的绝对路径。
下载好之后,输入bootm启动内核。
在内核启动信息中可以看到触摸屏的加载信息。
在Linux内核启动信息中可以看到驱动程序已经被正确加载。
输入cat/proc/bus/input/devices
可以看到触摸屏已经成功加载。
由上图可以看到触摸屏的handler有mouse0、event0、ts0和evbug。
在终端中输入dmesg命令可以看到evbug上报的事件(触摸的坐标等)。
7.10 测试驱动程序
将资料文件夹中提供的my_test文件拷贝到nfsboot/usr目录下,在超级终端上输入:
cd /usr
./my_test
然后点击触摸屏就会显示点击的坐标值和触击、释放事件。
更多推荐
所有评论(0)