之前学习ARM时记录的零散的笔记,现在先记录下来,方便后面查看。
CMOS摄像头
目的:
将摄像头采集到的数据实时的在LCD上进行显示
一 硬件原理
自然景观->摄像头模块->接口->S3C2440的摄像头控制器->LCD
ov7740(摄像头模块)
输入信号: 自然景观等的模拟信号
输出信号: RGB、YUV格式的数字信号
1). 常用参数
输入信号: 自然景观等的模拟信号
输出信号:
输出格式为:RAW RGB、YUV
输出分辨率为:VGA(640*480)、QVGA(240*320)、CIF(352*288)、更小的任意大小
有效感光阵列的大小:656*488 = 320128(30W)
镜头的大小:1/5寸
像素点颗粒的大小: 4.2um * 4.2um
总结:
以上三个参数,都是用来描述感光阵列,即使同为30W像素的摄像头,如果它的
镜头尺寸大小越小,那么对应的像素点颗粒的大小就越小,从而感光性就越差,进而
拍摄的效果就越差。
输入时钟频率: 6~27MHz
即0V7740摄像头模组的工作频率范围。
扫描模式: 连续扫描(P)
2). 内部数据的处理流程
a.isc部分:
翻转、增益大小调整、黑电平校准、饱和度的控制、OTP存储器
b.isp部分:
提供测试功能、镜头补偿功能、自动白平衡、RAW RGB->RGB、RGB->YUV、
窗口功能、缩小放大功能
c.ioi部分:
RAW RGB/YUV、VGA/QVGA、BT601/BT656
问:以上这些处理过程,不需要我们人为的做任何设置,它们都能自动完成吗?
答:以上这些处理过程,只有极少部分是自动完成的,而剩余部分是需要我们设
置后,才能完成。
问:怎么对它们进行设置呢?
答:是通过IIC总线,操作OV7740的寄存器来进行设置的。
问:RAW RGB与RGB的区别是什么?
答:所谓的RAW RGB就是只有红绿蓝三种颜色的数据。而RGB数据,它不仅只表示红绿蓝
三种颜色,而且还能表示由红绿蓝组合成的任何一种颜色。
问:RGB、YUV又分别是什么?
答:RGB、YUV是两种完全不同的颜色空间,它们之间可以相互转换。
原理图(接口)
控制类:
IICSDA -- IIC总线的数据线
IICSCL -- IIC总线的时钟线
数据传输类:
CAMRST -- 复位CMOS摄像头模块
CAMCLK -- 摄像头模块工作的系统时钟(24MHz)
CAM_HREF -- 行同步信号
CAM_VSYNC -- 帧同步信号
CAM_PCLK -- 像素时钟
CAMDATA0~7-- 数据线
总结:
1.CMOS摄像头模块的接口分为两类:
(1).控制类
-- 初始化:对摄像头模块进行相应的初始化操作
,让摄像头模块能够正常的输出摄像头数据
-- 控制: 设置亮度、旋转、缩放等等的操作
(2).数据传输类: 与LCD的接口完全一样。
2.CMOS摄像头模块,是一个IIC设备,需要给它写符合IIC设备那套架构的
驱动,从而实现初始化和灵活的控制。
640*480、30fps、YUV、BT601
s3c2440摄像头控制器(CAMIF)
问:BT601与BT656的传输方式有什么区别?
答:BT601有独立的行同步信号线、帧同步信号线,而BT656是将这两种信号
内嵌到数据中的。
三,从零写CMOS摄像头驱动
使用的内核:linux-3.4.2
参考源码:
第32课_新内核下的I2C驱动\i2c\1th_i2c_new_device
第2课第1.1.7节文档和图片(从0写USB摄像头)\myuvc
设备地址:
写 -- 0x42(01000010)
读 -- 0x43(01000011)
8bit的地址 = 7bit设备地址 + 1bit的读/写控制位
设备地址 = 0100001 = 0x21
问:为什么需要复位摄像头模块?
答:IIC能够正常操作CMOS摄像头模块内部的寄存器的前提是:
-- 提供符合它需求的系统时钟(CAMCLK)
-- 需要给它一个复位信号
问:怎样才能复位摄像头模块?
答:通过操作CAMIF控制器中相应的寄存器,让CAMRST发出复位
信号,从而复位摄像头模块,具体操作见驱动源码。
48字节 = 10字节 + 10字节 + 10字节 + 10字节 + 8字节
驱动测试条件:
1.
要有IIC总线驱动;
要有LCD驱动;
2.
要配置上V4L2相关选项
Device Drivers --->
<*> Multimedia support --->
<*> Video For Linux
[*] Video capture adapters (NEW) --->
[*] V4L USB devices (NEW) --->
[*] V4L platform devices --->
准备工作:
1. 准备虚拟机
2.安装工具链
sudo tar xjf arm-linux-gcc-4.3.2.tar.bz2 -C /
设置环境变量:
sudo vi /etc/environment : PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/arm/4.3.2/bin"
3. 编译uboot 2012 make smdk2440_config
//
1、make smdk2410_config //该文件在include/configs中
相当于执行 ./mkconfig smdk2410 arm arm920t smdk2410 NULL s3c24x0
//
$ tar xjf u-boot-1.1.6.tar.bz2 //解压u-boot-1.1.6.tar.bz2 压缩包
$ cd u-boot-1.1.6 //进入u-boot-1.1.6 目录
$ patch -p1 < ../u-boot-1.1.6_jz2440.patch //对u-boot-1.1.6 打patch 补丁
$ make 100ask24x0_config //配置
$ make //编译u-boot.bin
//说明: 在include/config目录下有一个100ask24x0.h
如果开发板中没有uboot 可以用openJtag烧录烧录方法为:
在cmd界面,将要烧写的bin文件放在D盘
输入 d:
dir 看到文件目录
oflash uboot.bin 0 1 0 0 0
或者直接通过uboot更新
4. 编译内核
tar xjf linux-3.4.2.tar.bz2
cd linux-3.4.2
//#
if 1 可以使用我们制作好的补丁:
linux-3.4.2_camera_jz2440.patch
linux-3.4.2_camera_mini2440.patch
linux-3.4.2_camera_tq2440.patch
patch -p1 < ../linux-3.4.2_camera_jz2440.patch
cp config_ok .config
make uImage
else 也可以从毕业班的内核补丁、驱动程序,自己修改、编译:
patch -p1 < ../linux-3.4.2_100ask.patch
把 lcd_4.3.c 复制到 /work/projects/linux-3.4.2/drivers/video
修改/work/projects/linux-3.4.2/drivers/video/Makefile
#obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o
obj-$(CONFIG_FB_S3C2410) += lcd_4.3.o
把dm9dev9000c.c、dm9000.h复制到/work/projects/linux-3.4.2/drivers/net/ethernet/davicom
修改/work/projects/linux-3.4.2/drivers/net/ethernet/davicom/Makefile
cp config_ok .config
make menuconfig
<*> Multimedia support --->
<*> Video For Linux
[*] Video capture adapters (NEW) --->
[*] V4L USB devices (NEW) --->
<*> USB Video Class (UVC)
// 如果你使用的是百问网自制的USB摄像头,
// 还需要参考第2课1.1.9节视频修改UVC驱动
endif
编译出内核文件
make uImage
#//
如果第一次编译的时候报错,错误与以下字眼相关
将kernel/timeconst.pl中第373行的defined()去掉,只留下 !@val 就可以了,去掉后如下
将内核文件uImage拷贝到根文件系统下,并命名为uImage_new
cp arch/arm/boot/uImage /work/nfs_root/uImage_new
4. 文件系统:
cd /work/samba_root/nfs_root
sudo tar xjf fs_mini_mdev_new.tar.bz2
sudo chown book:book fs_mini_mdev_new
制作补丁
make distclean (清除之前编译生成的所有文件)
rm u-boot.dis
cd ..
mv u-boot-2016.03 u-boot-2016.03_jz2440 (重命名)
tar xjf u-boot-2016.03.tar.bz2 (解压得到源码)
diff -urN u-boot-2016.03 u-boot-2016.03_jz2440 > u-boot-2016.03_jz2440.patch (这就是补丁文件名)
5. 用新内核、新文件系统启动开发板
启动开发板至UBOOT
设置UBOOT的环境变量:直接从根文件系统启动内核
设置开发板的ip
set ipaddr 192.168.1.17
下载内核
set bootcmd 'nfs 32000000 192.168.1.23:/work/nfs_root/uImage_new; bootm 32000000'
挂载网络文件系统
set bootargs console=ttySAC0,115200 root=/dev/nfs nfsroot=192.168.1.23:/work/nfs_root/fs_mini_mdev_new ip=192.168.1.17
重新设置内核分区
setenv mtdparts mtdparts=nandflash0:256k@0(bootloader),128k(params),4m(kernel),-(root)
save
boot //启动内核与文件系统
//相当于将单板目录挂载在服务器上的/work/system/nfs_root/fs_mini_mdev_new目录下
//下面两句话没有用 用来挂载文件系统
启动开发板后挂载nfs,将开发板挂载在服务器上
mount -t nfs -o nolock 192.168.1.23:/work/nfs_root/fs_mini_mdev /mnt
setenv serverip 192.168.1.23
setenv ipaddr 192.168.1.17
save
nfs 300000000 192.168.1.23:/work/nfs_root/fs_mini_mdev_new/uImage_new
nand erase 0xa0000 0x400000
nand write.jffs2 30000000 0xa0000 0x400000
烧写文件系统也是同样的方式 或者
2 使用nfs作为根文件系统启动
bootargs=console=ttySAC0 root=/dev/mtdblock3
tftp方式挂载
设置服务器ip位电脑ip
setenv serverip 192.168.1.22
setenv ipaddr 192.168.1.23 ubuntu ip
save
打开TFTP软件,选择内核所在目录 选择ip为192.168.1.22
下载内核 将u-boot下载到nor flash中30000000去
tftp 30000000 uImage
启动内核
bootm 30000000
nfs 30000000 192.168.1.23:/home/book/works/nfs_root/fs_mini_mdev.yaffs2
nand erase.part rootfs
nand write.yaffs 30000000 rootfs $filesize //烧写文件系统
setenv bootargs console=ttySAC0 root=/dev/mtdblock3 rootfstype=yaffs
nfs 32000000 192.168.1.23:/home/book/works/nfs_root/uImage_4.3 //该uImage_4.3是Jz2440开发板资料提供的映像文件
bootm 32000000
将makefile中的内核路径改为服务器上的内核路径
KERN_DIR = /work/system/kernel/linux-3.4.2/linux-3.4.2
在挂载文件系统的目录下编译驱动/work/system/nfs_root/fs_mini_mdev_new/mnt/ov7740
make 得到驱动程序
在/work/system/nfs_root/fs_mini_mdev_new目录下新建work目录
将驱动复制在开发板目录下
在/work/samba_root/nfs_root/fs_mini_mdev_new/mnt/test_camera 目录下编译应用程序
make 得到可执行程序test_camera
将应用程序复制到开发板目录下
cp test_camera /work/nfs_root/fs_mini_mdev_new/work
/work/samba_root/kernel/linux-3.4.2/linux-3.4.2/arch/arm/boot //内核目录
将HZK16拷贝到开发板目录下
cp HZK16 /work/samba_root/nfs_root/fs_mini_mdev_new/work
在/work/samba_root/nfs_root/fs_mini_mdev_new/mnt/test_camera目录下编译I2C驱动程序
make
将i2c驱动程序复制到开发板目录
cp i2c_bus_s3c2440.ko /work/samba_root/nfs_root/fs_mini_mdev_new/work
在根目录/work下就能看到驱动文件
insmod i2c_bus_s3c2440.ko
insmod cmos_ov7740_dev.ko
insmod cmos_ov7740_drv.ko
./test_camera
即可看到摄像头成像。
怎么写一个LCD驱动程序
1. 分配一个fb_info结构体: framebuffer_alloc
2. 设置
3. 注册: register_framebuffer
4. 硬件相关的操作
把 lcd_4.3.c 复制到 /work/projects/linux-3.4.2/drivers/video
修改/work/projects/linux-3.4.2/drivers/video/Makefile
#obj-$(CONFIG_FB_S3C2410)
+= s3c2410fb.o obj-$(CONFIG_FB_S3C2410)
+= lcd_4.3.o
测试:
1. 在内核中使用make menuconfig命令去掉原来的驱动程序
-> Device Drivers
-> Graphics support
<M> S3C2410 LCD framebuffer support
2. make uImage
make modules
将驱动复制在开发板目录下,可用ls查看驱动
cp *.ko /work/nfs_root/fs_mini_mdev_new/work
3. 使用新的uImage启动开发板:
4 在/work/nfs_root/fs_mini_mdev_new/mnt/lcd目录下编译
make
将lcd驱动拷贝到开发板目录
cp lcd.ko /work/nfs_root/fs_mini_mdev_new/work
5.装载驱动
insmod cfbcopyarea.ko
insmod cfbfillrect.ko
insmod cfbimgblt.ko
insmod lcd.ko
echo hello > /dev/tty1 // 可以在LCD上看见hello
cat lcd.ko > /dev/fb0 // 花屏
6. 修改 /etc/inittab
tty1::askfirst:-/bin/sh
用新内核重启开发板
insmod cfbcopyarea.ko
insmod cfbfillrect.ko
insmod cfbimgblt.ko
insmod lcd.ko
insmod buttons.ko
问题1 如何定制开机画
目的:
JZ2440开机logo默认是一只可爱的小企鹅。我们把它替换成我们自己喜爱的图片
准备工作:
准备好BMP或者PNG 图片,若是别的格式的图片,可以使用
Windows自带的画图软件打开,然后另存为BMP或者PNG格式
Logo图片分辨率不大于JZ2440分辨率480*272,否则显示不了。
步骤:
1. 安装资料光盘Ubuntu 9.10没有的图片转换工具netpbm
$ sudo apt-get install netpbm 然后输入y //前提是ubuntu能上网
制作linux logo图片
假设图片为 jz2440.png(png格式图片)
$ pngtopnm jz2440.png > jz2440.pnm
$ pnmquant 224 jz2440.pnm > logo224.pnm
$ pnmtoplainpnm logo224.pnm > logo_linux_clut224.ppm
假设图片为 jz2440.bmp(BMP格式图片)
$ bmptopnm jz2440.bmp > jz2440.pnm
$ pnmquant 224 logo.pnm > logo224.pnm
$ pnmtoplainpnm logo224.pnm > logo_linux_clut224.ppm
注意:转换后的文件名有规定,必须是logo_linux_clut224.ppm
3.生成的logo_linux_clut224.ppm就是我们需要的logo文件,把它拷贝到内核目录
覆盖原来的logo文件
$ cd /work/system/linux-3.4.2/drivers/video/logo/
$ cp /work/logo_linux_clut224.ppm . //笔者制作的logo文件在/work/目录
查看logo目录是否存在logo_linux_clut224.o的文件,如果有一定要删除!
$ rm logo_linux_clut224.o
配置内核支持logo显示(如果内核用的是linux-2.6.22.6_jz2440.patch补丁,默认已经支持logo显示)
$ make menuconfig
Device Drivers —>
Graphics support —>
Console display driver support—>
<*>Framebuffer console support
Bootup logo —>
<*> Standart 224-color linux logo
logo居中:
在vidrivers/video/fbmem.c文件中找到"fb_show_logo_line"函数,把
image.dx =0;
image.dy =y;
改为
image.dx = (info->var.xres - logo->width) / 2;
image.dy = (info->var.yres - logo->height) / 2;
6.重新编译内核,烧写
$make uImage
二 将驱动编译进内核
我们知道要给linux内核添加模块(驱动)有两种方式:
1 动态模式:采用insmod命令来给运行中的linux加载
2 静态模式:修改linux的配置菜单,添加模块相关文件到源码对应目录,
然后把模块直接编译进内核。
不加自己目录的情况
(1)把我们的驱动源文件(xxoo.c)放到对应目录下,具体放到哪里需要根据驱动的类型和特点。
这里假设我们放到./driver/char下。
(2)然后我们修改./driver/char下的Kconfig文件,依葫芦添加即可,如下所示:
config LT_XXOO
tristate "XXOO driver for LT"
help
this is XXOO driver for LT's board
config MINI2440_BUTTONS
tristate "Buttons driver for FriendlyARM"
DEPENDS on MACH_MINI2440
default y if MATH_MINI2440
help
this is buttons driver for FriendlyARM Mini2440
注意这里的LT_XXOO这个名字可以随便写,但需要保持这个格式,
他并不需要跟驱动源文件保持一致,但最好保持一致,
等下我们在修改Makefile时会用到这个名字,他将会变成CONFIG_LT_XXOO,
那个名字必须与这个名字对应。如上所示,
tristate定义了这个配置选项的可选项有几个,
help定义了这个配置选项的帮助信息,具体更多的规则这里不讲了。
(3)然后我们修改./driver/char下的Makefile文件,如下所示:
obj-$(CONFIG_LT_XXOO) += lt_xxoo.o
obj-$(CONFIG_LEGACY_PTYS) += pty.o
这里我们可以看到,前面Kconfig里出现的LT_XXOO,
在这里我们就需要使用到CONFIG_XXOO,实际上逻辑是这样:
在Kconfig里定义了LT_XXOO,然后配置完成后,
在顶层的.config里会产生CONFIG_XXOO,然后这里我们使用这个变量。
声卡驱动
修改内核支持声卡wm8976 mach-smdk2440.c中添加
#include <sound/s3c24xx_uda134x.h>
static struct s3c24xx_uda134x_platform_data smdk2440_audio_pins = {
.l3_clk = S3C2410_GPB(4),
.l3_mode = S3C2410_GPB(2),
.l3_data = S3C2410_GPB(3),
.model = UDA134X_UDA1341
};
static struct platform_device smdk2440_audio = {
.name = "s3c24xx_uda134x",
.id = 0,
.dev = {
.platform_data = &smdk2440_audio_pins,
},
};
static struct platform_device uda1340_codec = {
.name = "uda134x-codec",
.id = -1,
};
在static struct platform_device *smdk2440_devices[] __initdata = {中添加
&smdk2440_audio,
&samsung_asoc_dma,
&uda1340_codec,
修改bug: sound\soc\samsung\dma.c
将 pos += prtd->dma_period;
改为 pos += prtd->dma_period*limit;
添加驱动文件进内核
1、虚拟机cd到linux3.4.2源码目录
2、添加文件sound/soc/codecs下面添加wm8976.c和wm8976.h文件,
添加soc/samsung/s3c2440_wm8976.c文件
3、修改文件
3.1 sound/soc/codecs/Kconfig
在select SND_SOC_UDA134X下面添加(前面加个tab键,不是空格~~~)
<TAB>select SND_SOC_WM8976
3.2在
config SND_SOC_UDA134X
tristate
下面添加
config SND_SOC_WM8976
<space>tristate
3.3 sound/soc/codecs/Makefile
在snd-soc-wm1250-ev1-objs := wm1250-ev1.o下面添加
snd-soc-wm8976-objs := wm8976.o
在obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o下面添加
obj-$(CONFIG_SND_SOC_WM8976) += snd-soc-wm8976.o
修改bug: sound\soc\samsung\dma.c
pos += prtd->dma_period;
改为
pos += prtd->dma_period*limit;
在static void audio_buffdone(void *data)函数中
注释掉:
/* prtd->dma_pos += prtd->dma_period;
if (prtd->dma_pos >= prtd->dma_end)
prtd->dma_pos = prtd->dma_start;
if (substream)
snd_pcm_period_elapsed(substream);
*/
在 spin_unlock(&prtd->lock);下面添加
/*add by pang 2017-6-13*/
if (substream)
snd_pcm_period_elapsed(substream);
3.5 gedit sound/soc/samsung/Kconfig
在
select SND_SOC_L3
select SND_SOC_UDA134X下面添加
config SND_SOC_SAMSUNG_S3C24XX_WM8976
tristate "SoC I2S Audio support WM8976 wired to a S3C24XX"
depends on SND_SOC_SAMSUNG && ARCH_S3C24XX
select SND_S3C24XX_I2S
select SND_SOC_L3
select SND_SOC_WM8976
3.6 gedit sound/soc/samsung/Makefile
在snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o下面添加
snd-soc-s3c24xx-wm8976-objs := s3c2440_wm8976.o
在obj-$(CONFIG_SND_SOC_SAMSUNG_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o下面添加
obj-$(CONFIG_SND_SOC_SAMSUNG_S3C24XX_WM8976) += snd-soc-s3c24xx-wm8976.o
3.7修改mach-smdk2440.c,添加初始化模块
gedit arch/arm/mach-s3c24xx/mach-smdk2440.c
在#include <plat/common-smdk.h>下面添加
#include <sound/s3c24xx_uda134x.h>
在该文件的前面添加下面几个函数(后面用到)
/*add by pang 2017-6-13*/
static struct s3c24xx_uda134x_platform_data smdk2440_audio_pins = {
.l3_clk = S3C2410_GPB(4),
.l3_mode = S3C2410_GPB(2),
.l3_data = S3C2410_GPB(3),
.model = UDA134X_UDA1341
};
/*add by pang 2017-6-13*/
static struct platform_device smdk2440_audio = {
.name = "s3c24xx_uda134x",
.id = 0,
.dev = {
.platform_data = &smdk2440_audio_pins,
},
};
/*add by pang 2017-6-13*/
static struct platform_device uda1340_codec = {
.name = "uda134x-codec",
.id = -1,
};
在函数
static struct platform_device *smdk2440_devices[] __initdata = {
&s3c_device_ohci,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
下面添加:
&smdk2440_audio, /*modify by pang 2017-6-13*/
&samsung_asoc_dma, /*modify by pang 2017-6-13*/
/*modify by pang ,this will case problem of touchscreens and sounddevice has problem when play audio in jz2440 2017-6-13*/
//&uda1340_codec,
把s3c24xx_init_clocks(16934400);改为
s3c24xx_init_clocks(12000000);
3.8配置内核编译菜单
-> Device Drivers
-> Sound card support
-> Advanced Linux Sound Architecture
-> ALSA for SoC audio support
<*> ASoC support for Samsung // CONFIG_SND_SOC_SAMSUNG
<*> SoC I2S Audio support UDA134X wired to a S3C24XX // CONFIG_SND_SOC_SAMSUNG_S3C24XX_UDA134X // s3c24xx_uda134x.c
-> System Type
• S3C2410 DMA support
声卡驱动后
编译alsa-lib, alsa-util以使用声卡:
1.1 alsa-lib:
mkdir tools //先新建一个目录放安装包
cd tools
tar xjf alsa-lib-1.0.27.2.tar.bz2 //将安装包放入tools目录下解压
sudo su
echo $PATH //查看环境路径
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/local/arm/4.3.2/bin
mv /usr /usr_bak //将原先的usr目录改为usr_bak
修改环境变量
export PATH=/usr_bak/local/sbin:/usr_bak/local/bin:/usr_bak/sbin:/usr_bak/bin:/sbin:/bin:/usr_bak/games:/usr_bak/local/games:/usr_bak/local/arm/4.3.2/bin
cd /home/book/tools
cd alsa-lib-1.0.27.2
./configure --host=arm-linux
make mkdir /usr
chown book:book /usr
make install
cd /usr
ls cd
cp -rf /usr /work/projects/alsa/
rm -rf /usr
mv /usr_bak /usr
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/arm/4.3.2/bin
把头文件和库复制进交叉工具链里
cd /work/projects/alsa/usr/include
sudo cp * -rfd /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/usr/include
cd /work/projects/alsa/usr/lib
sudo cp * -rfd /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/lib
把库复制到根文件系统的lib目录下
cd /work/projects/alsa
cp -rfd usr /work/nfs_root/fs_mini_mdev_new
3.2 alsa-util
3.2.1 先编译依赖:ncurses-5.9.tar.gz
cd /home/book/tools
tar zxvf ncurses-5.9.tar.gz
./configure --host=arm-linux --prefix=$PWD/tmp --with-shared make && make install
把头文件和库复制进交叉工具链里
cd /home/book/tools
cd ncurses-5.9/tmp/include/ncurses
cp * -rfd /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/usr/include cd /home/book/tools/ncurses-5.9/tmp/include/ cp * -rfd /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/usr/include
cd /home/book/tools/ncurses-5.9/tmp/lib
cp * -rfd /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/lib
把库复制到根文件系统的lib目录下
cd /home/book/tools/ncurses-5.9/tmp/lib
cp *so* -rfd /work/nfs_root/fs_mini_mdev_new/lib
3.2.2 编译alsa-util:
cd /home/book/tools
tar xjf alsa-utils-1.0.27.2.tar.bz2 cd alsa-utils-1.0.27.2.tar.bz2
./configure --prefix=$PWD/tmp --host=arm-linux --disable-xmlto --disable-alsamixer --disable-nls
cd tmp
cp * -rfd /work/nfs_root/fs_mini_mdev_new/usr/
3.2.3 测试
mkdir /dev/snd
cd /dev/snd/
ln -s /dev/controlC0 // 用于声卡的控制 通道选择 混音 麦克风的控制等
ln -s /dev/pcmC0D0p //用于播放的pcm设备
ln -s /dev/pcmC0D0c //用于录音的pcm设备
播放: aplay Windows.wav
调音量: amixer controls
amixer cget numid=1
amixer cset numid=1 30
问题:rmmod: chdir(/lib/modules): No such file or directory
该问题是由于新内核要将所有的驱动程序加载进一个与内核版本对应的文件夹下
解决办法
mkdir /lib/moudles/3.4.2
将驱动程序放入该目录下即可实现insmod rmmod模块了
卸载模块时命令为
rmmod touch (不加.ko)
问题: error: stray '\244' in program
编译时出现这种错误,一般为拷贝代码有空格。
触摸屏设备,在input子系统中,通过配置文件查找,在开发板中端输入
cat /proc/bus/input/devices
其中“Handlers”后面的就是触摸屏设备
使用另外的命令hexdump /dev/event0
能获得input子系统hex格式的数据输出。其中每一行为一条上报信息。
问题: 将内核源码全部导入sourceinsight导致重复头文件太多,不能准确定位文件
目标: 只导入相关平台代码,减少重复头文件
1 编译内核,将输出保存,命令为
make ARCH=arm > build_log.txt
2 编辑一个脚本命名为sg.sh复制代码到脚本文件
#!/bin/sh
ARCH=arm
MACH=s5pv210
FILE_IN=$1
FILE_OUT=$2
# .c
SOURCE_LIST=""
# generated file list
FILE_LIST=""
# nest depth for function get_includes()
NEST_DTPTH=0
# recursive function, used to get included files from files.
# result is stored in FILE_LIST
# $1 : file list, e.g. "fs/ext4/file.c fs/ext4/fsync.c"
get_includes()
{
local includes
local file
for file in $1
do
if [ ! -e ${file} ]; then
continue
fi
if echo "${FILE_LIST}" | grep -E ${file} > /dev/null; then
continue
fi
FILE_LIST="${FILE_LIST} ${file}"
NEST_DTPTH=$((NEST_DTPTH+1))
echo "<${NEST_DTPTH} : ${file}"
includes=$( \
grep -E -H '^#include' ${file} | \
sed -r \
-e 's@^.*<(acpi/.*)>@include/\1@' \
-e 's@^.*<(asm-generic/.*)>@include/\1@'\
-e 's@^.*<(config/.*)>@include/\1@' \
-e 's@^.*<(crypto/.*)>@include/\1@' \
-e 's@^.*<(drm/.*)>@include/\1@' \
-e 's@^.*<(generated/.*)>@include/\1@' \
-e 's@^.*<(keys/.*)>@include/\1@' \
-e 's@^.*<(linux/.*)>@include/\1@' \
-e 's@^.*<(math-emu/.*)>@include/\1@' \
-e 's@^.*<(media/.*)>@include/\1@' \
-e 's@^.*<(misc/.*)>@include/\1@' \
-e 's@^.*<(mtd/.*)>@include/\1@' \
-e 's@^.*<(net/.*)>@include/\1@' \
-e 's@^.*<(pcmcia/.*)>@include/\1@' \
-e 's@^.*<(rdma/.*)>@include/\1@' \
-e 's@^.*<(rxrpc/.*)>@include/\1@' \
-e 's@^.*<(scsi/.*)>@include/\1@' \
-e 's@^.*<(sound/.*)>@include/\1@' \
-e 's@^.*<(target/.*)>@include/\1@' \
-e 's@^.*<(trace/.*)>@include/\1@' \
-e 's@^.*<(uapi/.*)>@include/\1@' \
-e 's@^.*<(video/.*)>@include/\1@' \
-e 's@^.*<(xen/.*)>@include/\1@' \
-e "s@^.*<(asm/.*)>@arch/${ARCH}/include/\1 arch/${ARCH}/include/generated/\1@" \
-e "s@^.*<(mach/.*)>@arch/${ARCH}/mach-${MACH}/include/\1@" \
-e 's@(^.*/)[^/]+\.c.*\"(.*)\"@\1\2@' \
-e 's@/\*.*@@' \
-e 's@^.*\#include.*$@@' \
-e 's@^@ @' | \
sort | \
uniq | \
tr -d '\n' | \
tr -d '\r' \
)
if [ -n "${includes}" ]; then
get_includes "${includes}"
fi
echo ">${NEST_DTPTH}) : ${file}"
NEST_DTPTH=$((NEST_DTPTH-1))
done
}
# get *.c from kernel build log
SOURCE_LIST=$( \
grep -E '^\s*CC' ${FILE_IN} | \
sed -r \
-e 's/^\s*CC\s*/ /' \
-e 's/\.o/\.c/' | \
tr -d '\n' | \
tr -d '\r' \
)
echo ${SOURCE_LIST}
get_includes "${SOURCE_LIST}"
FILE_LIST=$(echo "${FILE_LIST}" | sed -r -e 's/\s/\r\n/g' )
echo "${FILE_LIST}" > ${FILE_OUT}
3内核目录下 执行命令
./sg.sh build_log.txt file_list.txt
如果报错-bash: ./xxx.sh: /bin/sh^M: bad interpreter: No such file or directory
则表示文件格式有问题
执行
sed -i -e 's/\r$//' sg.sh
4 sourceinsight中导入file_list.txt中将记录所需要的头文件
注(很重要) 将file_list.txt 放在内核根目录下
sourceinsght 工程也要建在内核根目录下
驱动的makefile通用模板
KERN_DIR = /work/system/linux-3.4.2 //内核目录
all:
make -C $(KERN_DIR) M=`pwd` modules //在当前目录下变异成模块
clean:
make -C $(KERN_DIR) M=`pwd` modules clean
rm -rf modules.order
obj-m += lcd.o
应用程序通用makefile
CROSS_COMPILE = arm-linux-
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
export AS LD CC CPP AR NM
export STRIP OBJCOPY OBJDUMP
CFLAGS := -Wall -Werror -O2 -g
CFLAGS += -I $(shell pwd)/include
LDFLAGS := -lm -ljpeg -lasound
export CFLAGS LDFLAGS
TOPDIR := $(shell pwd)
export TOPDIR
TARGET := video2lcd
obj-y += main.o
obj-y += convert/
obj-y += display/
obj-y += render/
obj-y += video/
obj-y += playwav/
all :
make -C ./ -f $(TOPDIR)/Makefile.build
$(CC) $(LDFLAGS) -o $(TARGET) built-in.o
clean:
rm -f $(shell find -name "*.o")
rm -f $(TARGET)
distclean:
rm -f $(shell find -name "*.o")
rm -f $(shell find -name "*.d")
rm -f $(TARGET)
用工具制作根文件系统
yaffs_source_util_larger_small_page_nand.tar.bz2
将该文件放在tools目录下
解压
tar -xvf yaffs_source_util_larger_small_page_nand.tar.bz2
解压后进入目录 Development_util_ok/yaffs2/utils
cd Development_util_ok/yaffs2/utils
在utils目录下编译
make
编译完成后会在该目录下生成一个mkyaffs2image
该工具就是我们需要的工具,把这个工具复制到跟目录下,同时加上可执行属性
sudo cp mkyaffs2image /usr/local/bin/
sudo chmod +x /usr/local/bin/mkyaffs2image
进入到根文件系统目录 同级 不用进入文件系统目录
cd /work/nfs_root
mkyaffs2image fs_mini_mdev_new fs_mini_mdev_new.yaffs2
fs_mini_mdev_new是根文件系统目录名
fs_mini_mdev_new.yaffs2 是映像名
使用该映像名就能烧到开发板
u-boot编译时报出警告
warning: target CPU does not support interworkin
vi cpu/arm920t/config.mk
把 PLATFORM_CPPFLAGS += -march=armv4 改成 PLATFORM_CPPFLAGS += -march=armv4t