2009年9月16日星期三
DM355的I2C调试
DaVinci I2C WARNING: i2c: NACK detected
DaVinci I2C WARNING: i2c: RAR detected
这个报错是因为从设备没有反馈导致的,
后来发现是8574的地址写错了,导致I2C控制器老出现错误中断。
改正后测试I2C的SCL线的clock为400KHz。
为了和单片机连,需要降频。
修改drivers/i2c/buses/i2c-davinci.c文件
static int __init i2c_davinci_init(void)
{
int status;
struct device *dev = NULL;
DEB0("%s %s", __TIME__, __DATE__);
DEB1("i2c_davinci_init()");
/*
* NOTE: On DaVinci EVM, the i2c bus frequency is set to 20kHz
* so that the MSP430, which is doing software i2c, has
* some extra processing time
*/
if (machine_is_davinci_evm())
i2c_davinci_busFreq = 20;
else if (i2c_davinci_busFreq > 200)
i2c_davinci_busFreq = 400; /*Fast mode */
else
i2c_davinci_busFreq = 100; /*Standard mode */
i2c_clock = clk_get (dev, "I2CCLK");
}
DM355的UART调试
board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_McBSP1, 1);
board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_SPI, 1);
/* Turn on WatchDog timer LPSC. Needed for RESET to work */
board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TIMER2, 1);
/*add uart1 by xujiaxin*/
board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_UART1,1);
/*end add*/
davinci_serial_init(&serial_device);
davinci_writel(0x56837210, DAVINCI_VPSS_REGS_BASE + 0x810);
davinci_writel(0x7b3c0004, DAVINCI_VPSS_REGS_BASE + 0x814);
/*enable uart1 by jiaxinxu*/
ptr_pgmgt = (volatile int *)IO_ADDRESS(DAVINCI_UART1_BASE+0x30);
ptr_ier = (volatile int *)IO_ADDRESS(DAVINCI_UART1_BASE+0x4);
*ptr_pgmgt=0x0;
*ptr_ier =0x0;
int del;
for(del=0;del<100000;del++)
*ptr_pgmgt=0x6001;
/*end enable*/
运行rs232程序,一开始函数在发送0x0a时老是会先发送一个0x0d,后来在程序中加入下面两句话
/*RAW格式 否则会出错*/
options.c_lflag&=~(ICANON|ECHO|ECHOE|ISIG);
options.c_oflag&=~OPOST;
就不会出错了。
board_setup_psc函数用来设置PSC模块,该模块的作用是开启某个模块的电源以及使能某个模块。
对UART2进行初始化的时候,必须注意UART2和SD1是复用的。没有改动前的内核初始化时自动的初始化SD1而不是UART2。需要进行一下几点动作才能将SD1的初始化屏蔽掉。
//choose uart2 instead of sd1 jiaxinxu
PINMUX3&=~0x0000ffff;
PINMUX3|= 0x0000a000;
将引脚功能置成UART2,
//conflict with uart2 by jiaxinxu
board_setup_psc(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_MMC_SD1, 0);
禁能PSC
#if defined(CONFIG_MMC_DAVINCI) || defined(CONFIG_MMC_DAVINCI_MODULE)
&mmc0_device,
//conflict with uart2 by jiaxinxu
//&mmc1_device,
DM355的SD卡虚拟成U盘
内核编译配置如usb. Txt内容。
在/etc/init.d/rcS中加入初始化语句。
insmod musb_hdrc.ko
insmod g_file_storage.ko file=/dev/mmcblk0p1
一开始插上USB以后老是显示无法初始化硬件,是因为USB小板上将D+和D-画反了
遇到的问题:
1.在拍照的过程中,拍摄100幅照片,第一次将USB插到主机上,会显示这100幅照片的大小都是0;但是在板子上输入ls –al /mnt/sdcard看 大小都是15.8K,是正确的。第二次插上USB以后有可能会有一些图像变正确,大小变为15.8K并且可以打开。其他的一些图像就坏掉了。
2.后来对这个问题进行进一步的研究,在不加载USB驱动的情况下拍摄100幅照片,拍摄完成后在串口终端上将SD卡上的数据拷贝到NFS上,再从Linux虚拟机下拷贝到windows上,看图片都是正确的,在串口终端上输入ls –al /mnt/sdcard看 大小都是15.8K。板子断电,拔下SD卡,通过读卡器插到pc机上,在windows下浏览,结果也都是正常。但是如果不进行上述的拷贝工作,只有一副照片m1.jpeg是正常的(随机的有可能其他几个是正常的,但不是所有的都正常),其他的都是0k。将SD卡再插回板子,上电再执行ls –al /mnt/sdcard,发现只有m1.jpeg是正常的,其他的都是0k。
解决办法:linux下,向磁盘写入数据会先将数据缓存在内存里,系统在合适的时候再将数据从内存中写到磁盘里。所以SD卡拔下之前要运行sync命令,保证内存中的数据完全写入磁盘里
DM355文件系统固化
mount –t yaffs2 /dev/mtdblock3 /mnt
然后
cp -rf /copytoflash4TECHV/* /mnt/
但是当拷贝的时候报错
status check failed: 2
status check failed: 2
nfs: server 192.168.1.147 not responding, still trying
这个问题没有解决
最后将文件系统的压缩文件考到SD卡中,将SD卡的文件考到mtd上 解压
mount -t yaffs2 /dev/mtdblock3 /mnt
mount /dev/mmcblk0p1 /tmp
cp /tmp/copyfl~1.gz /mnt/copy.tar.gz
tar xzvf copy.tar.gz
mv copyflash4TECHV/* ./
rm -rf copyflash4TECHV/
DM355的SPI调试
/dev文件夹下没有spi设备,只有一个eeprom设备,这个设备用spi接口进行控制。该设备的设备文件是/dev/mtdblock5.他的驱动程序是at25xxA_eeprom.c。为什么他的设备文件是/dev/mtdblock5呢?在at25xxA_eeprom.c中的eeprom_probe函数中,调用了
ret = add_mtd_device(mtd)将该eeprom加入了mtdblock的链表中。其源码如下:
将DEBUG(0, "mtd: Giving out device %d to %s\n",i,
mtd->name);一句打印出来是:
drivers/spi/spi.cmtd: Giving out device 5 to spi_eeprom
同样我们可以看到。
mtd: Giving out device 0 to bootloader
mtd: Giving out device 1 to params
mtd: Giving out device 2 to kernel
mtd: Giving out device 3 to filesystem1
mtd: Giving out device 4 to filesystem2
如果不需要EEPROM那么可以将这个驱动程序进行一些修改 改成SPI的驱动程序
主要的底层驱动文件有四个spi.c spi.h dm355_spi_master.h dm355_spi_master.c
spi.c 和spi.h主要进行了SPI驱动的上层封装 dm355_spi_master.h
dm355_spi_master.c则是对底层的寄存器进行访问
一开始调试的时候发现一个bug 当发送N个字节的时候老是会多发一个数
而且在最后一个数发送之前CS会有一个小毛刺。
后来去阅读代码
发现最后那个字节是作者故意加上的
为了防止这个毛刺对访问eeprom控制数据的影响。
看了DM355底层的spi寄存器,发现问题处在SPIDAT1寄存器上。
去网上查解决办法 搜到了DM355的勘误表 原来是一个芯片BUG 靠!
根据勘误表上的解决办法修改成功后的SPI
调用spi write连续写数(或spi read读数 )C S是一直使能的。
但是 先写数再读数 CS中间是有一段不使能。
进行速度测试后的结果是:
SPI 的clk是4MHz
Spi 读写速度是300000Bytes/s
linux下寄存器各字节分开访问的接口函数在include » asm-arm » arch-davinci
的io.h中
00001 /*
00002 * DaVinci IO address definitions
00003 *
00004 * Copied from include/asm/arm/arch-omap/io.h
00005 *
00006 * 2007 (c) MontaVista Software, Inc. This file is licensed under
00007 * the terms of the GNU General Public License version 2. This program
00008 * is licensed "as is" without any warranty of any kind, whether
express
00009 * or implied.
00010 */
00011 #ifndef __ASM_ARCH_IO_H
00012 #define __ASM_ARCH_IO_H
00013
00014 #define IO_SPACE_LIMIT 0xffffffff
00015
00016 /*
00017 *
----------------------------------------------------------------------------
00018 * I/O mapping
00019 *
----------------------------------------------------------------------------
00020 */
00021 #define IO_PHYS 0x01c00000
00022 #define IO_OFFSET 0xfd000000 /* Virtual IO = 0xfec00000 */
00023 #define IO_SIZE 0x00400000
00024 #define IO_VIRT (IO_PHYS + IO_OFFSET)
00025 #define io_p2v(pa) ((pa) + IO_OFFSET)
00026 #define io_v2p(va) ((va) - IO_OFFSET)
00027 #define IO_ADDRESS(x) io_p2v(x)
00028
00029 /*
00030 * We don't actually have real ISA nor PCI buses, but there is so many
00031 * drivers out there that might just work if we fake them...
00032 */
00033 #define PCIO_BASE 0
00034 #define __io(a) ((void __iomem *)(PCIO_BASE + (a)))
00035 #define __mem_pci(a) (a)
00036 #define __mem_isa(a) (a)
00037
00038 #ifndef __ASSEMBLER__
00039
00040 /*
00041 * Functions to access the DaVinci IO region
00042 *
00043 * NOTE: - Use davinci_read/write[bwl] for physical register addresses
00044 * - Use __raw_read/write[bwl]() for virtual register addresses
00045 * - Use IO_ADDRESS(phys_addr) to convert registers to virtual
addresses
00046 * - DO NOT use hardcoded virtual addresses to allow changing
the
00047 * IO address space again if needed
00048 */
00049 #define davinci_readb(a) (*(volatile unsigned char
*)IO_ADDRESS(a))
00050 #define davinci_readw(a) (*(volatile unsigned short
*)IO_ADDRESS(a))
00051 #define davinci_readl(a) (*(volatile unsigned int
*)IO_ADDRESS(a))
00052
00053 #define davinci_writeb(v,a) (*(volatile unsigned char
*)IO_ADDRESS(a) = (v))
00054 #define davinci_writew(v,a) (*(volatile unsigned short
*)IO_ADDRESS(a) = (v))
00055 #define davinci_writel(v,a) (*(volatile unsigned int
*)IO_ADDRESS(a) = (v))
00056
00057 /* 16 bit uses LDRH/STRH, base +/- offset_8 */
00058 typedef struct { volatile u16 offset[256]; } __regbase16;
00059 #define __REGV16(vaddr) ((__regbase16 *)((vaddr)&~0xff)) \
00060 ->offset[((vaddr)&0xff)>>1]
00061 #define __REG16(paddr) __REGV16(io_p2v(paddr))
00062
00063 /* 8/32 bit uses LDR/STR, base +/- offset_12 */
00064 typedef struct { volatile u8 offset[4096]; } __regbase8;
00065 #define __REGV8(vaddr) ((__regbase8 *)((vaddr)&~4095)) \
00066 ->offset[((vaddr)&4095)>>0]
00067 #define __REG8(paddr) __REGV8(io_p2v(paddr))
00068
00069 typedef struct { volatile u32 offset[4096]; } __regbase32;
00070 #define __REGV32(vaddr) ((__regbase32 *)((vaddr)&~4095)) \
00071 ->offset[((vaddr)&4095)>>2]
00072
00073 #define __REG(paddr) __REGV32(io_p2v(paddr))
00074 #else
00075
00076 #define __REG(x) (*((volatile unsigned long *)io_p2v(x)))
00077
00078
DM6446 OSD
一个特有的第二个OSD窗口(OSDWIN1)可以用来配置成属性窗口来控制视频窗口和第一个OSD窗口(OSDWIN0)的混合(如透明度)。因为"alpha"混合功能是OSDWIN1最通用的功能,所以以下就主要讨论第一个OSD窗口(OSDWIN0)用来显示OSD图片,以及第二个OSD窗口(OSDWIN1)用作属性窗口来控制混合。
OSD窗口可以配置成接收RGB565或者bitmap数据。一般情况,RGB,BITMAP和原始图像数据格式(raw
data
format)在技术行业是可以交换的。如果每个像素使用的bit数一样,那么这些格式就一样。在达芬奇处理器上却不是这种情况。它们提供了配置成RGB565
或者
bitmap的选项。当OSD窗口配置成接收bitmap数据,它就使用256条目的颜色查找表(CLUT)。这意味着最大颜色深度是8bit(4,2,1bit的也支持)。当OSD窗口配置成接收RGB565数据,CLUT就不需要的了,因为RGB数据在外部存储器中先转换成YCBCR;RGB565使用16bit/pixel,因此能接收64k颜色。两个窗口都可以同时配置成接收bitmap数据。然而,只有一个OSD窗口可以配置成接收RGB565数据二不能两个都配置。因此,如果第二个OSD窗口用作属性窗口,第一个OSD窗口最好使用RGB565模式,主要因为它可以存取16bits(64k颜色)。
Linux
有两个重要的驱动结构,块驱动和特征驱动块驱动允许无须存取并能挂载到文件系统中。包括了硬盘驱动,外部RAM,及copmpact
flash驱动。Character驱动读取作为流,以FIFO顺序(如音频视频)。所以大家会测出,OSD功能是作为character(视频驱动)驱动。
Linux的另一个的特征是character驱动能以类似的方式存取文件。这意味着你可以open,write,close这些设备跟操作文件一样。从Linux的命令提示下,你可以copy(cp),display(cat)
及pipe(>>)数据从一个文件到另一个文件中。这个强大的特征允许把数据放到OSD窗口中而不用写任何的代码。
达芬奇平台提供了访问视频硬件的两个Linux驱动,V4L2视频采集驱动(视频处理前端VPFE
--- davinci_vpfe.c)和FBDev(即Framebuffer设备)显示驱动(视频处理后端VPBE
---- davincifb.c)。
(1)Video for Linux
2(V4L2)是一个标准的,二级Linux视频输入驱动,它修正了第一版的一个bug。
(2)FBDev是一个标准的Linux视频输出驱动,用来映射显示设备帧存。如DaVinci处理器到user空间。
Linux frame buffer display device(ie. FBDev
驱动)包含了OSD特征。帧存驱动提供了显示硬件的概括。它令视频输出硬件(OSD亦如此)作为一个帧存设备。并因此允许软件访问图形硬件就像写入一个缓冲区。跟上面提到的一样,输出设备缓存存取跟访问文件一样,一般定位在
/dev 路径中。在这种情况下,这个路径我们感兴趣的是改变DaVinci OSD
是/dev/fb/0。使用这个路径,我们能修改显示,而只是通过一个定义好的接口。它的操作包括跟文件一样(如open,
read,write,close)的操作和设备指定的命令(ioctls
来查询/设置关于硬件的信息)。
我们应该熟悉下面的命令:
cp – copy (e.g. >cp osd.r16 /dev/fb/0 --copies osd.r16 file to /dev/fb/0
设备)
把以上的几点放到一起,通过写一个简单的命令(>cp osd.r16
/dev/fb/0)就可以把osd.r16的内容复制到OSD帧存中,并能显示。Osd.r16文件从哪里来呢?这个文件包含了现有显示到OSD的内容;因此通过图像编辑器(如GIMP)编辑好图像后,通过运行转换工具(tar.gz
文件中)就可以转换。但是GIMP要创建什么样格式的文件呢?推荐的格式是BMP。
步骤如下:
(1)创建OSD图像通过图像编辑器(如GIMP)并且保存为BMP文件。
(2)运行小程序来转换为RGB565格式。>.bmpToRgb16
mysod.bmp,这个命令就会产生osd.r16文件。
(3)把转换后的文件复制到OSD帧存中。>cp osd.r16 /dev/fb/0
(4)重复以上的几步,直到满意。保存osd.r16文件,它就可以被应用程序加到源代码中了。
需要指出的是属性窗口不应该设置为100%视频(所有都为0),因为这样混合水平不允许OSD图形显示。
自动切换有线、无线网络
操作系统在启动时检测计算机的网卡型号并在开机时自动加载驱动模块。默认情况下,操作系统只使用其中的一个网卡,默认情况因计算机而异。如:笔记本一般都同时有无线、有线网卡,大部门笔记本默认使用有线网卡,但也有一些笔记本默认使用无线网卡,如NEC的某些款笔记本。
如果默认使用有线网卡,而在使用过程中拔掉网线,那么操作系统不会自动切换到无线网络(假设此时无线网络可用),你所有的数据报还会阻塞在有线网卡处,进行重传直至超时出错,即:你上不去网了。
继续开头的状况:你也许希望在插入网线或无线网络可用时网络能够自动连上。
在这里你可以找到帮助你实现这个功能的一些工具。
ifplugd 守护进程根据相关的硬件有没有接入网络来激活或关闭接口。这个程序能够检测网线是否已经插入或无线网卡(Wi-Fi)是否能访问 AP(虽然 waproamd 比较适合后一种情况)。当 ifplugd 发现连接状态改变时,它能运行一个代理脚本,缺省会呼叫 ifup 或 ifdown。
在默认情况下,它会检查 eth0 设备。更改这个设置(以及更改其他设置,比如等待时间),可以编辑 /etc/ifplugd/ifplugd.conf 。
运行这个命令来启动它:
# /etc/rc.d/ifplugd start
或者将它加入/etc/rc.conf 的 DAEMONS 列表,这样它就能开机自动启动了。