2008年11月4日星期二

在Fedora7上编译qtopia-2.2.0 x86版

1>下载gcc32编译器
http://d.download.csdn.net/down/382229/morre
compat-gcc-32-3.2.3-47.3.i386.rpm

http://d.download.csdn.net/down/382235/morre
compat-gcc-32-c++-3.2.3-47.3.i386.rpm

当时没有用rpm命令行安装,是firefox下载后点“打开”,弹出更新软件,点“应用”这样装的
应该怎么安装都行吧。安装完后,出现/usr/bin/gcc32等。有人说改Makefile或设置CC环境变量,我觉得可能会改不全,所以换gcc,下面这样改不确定对不对,不过以前gcc4.1.2编不过的现在可以编过了

//替换gcc
mv /usr/bin/gcc /usr/bin/gccbak
mv /usr/bin/gcc32 /usr/bin/gcc

//替换g++
mv /usr/bin/g++ /usr/bin/g++bak
mv /usr/bin/g++32 /usr/bin/g++

//替换libc
cp /usr/lib/gcc/i386-redhat-linux/4.1.2 /usr/lib/gcc/i386-redhat-linux/4.1.2bak -rf
cp /usr/lib/gcc-lib/i386-redhat-linux/3.2.3 /* /usr/lib/gcc/i386-redhat-linux/4.1.2/ -rf

2>下载freetype2.1.10
http://download.chinaunix.net/download.php?id=6228&ResourceID=3295
freetype-2.1.10.tar.bz2

解压后
./configure --prefix=/usr
make
make install
mv /usr/freetype2/freetype /usr/freetype2/freetypebak //不用以前的freetype 头文件
cp freetype-2.1.10/include/freetype /usr/freetype2/ -rf //既然只是新的头文件,那么是不是不用编译呢?

3>编译qtopia-2.2.0
./configure
make
make install

4>跑demo
. setQpeEnv
qtopia/bin/startdemo

2008年11月1日星期六

删除libstdc++后缺少libstdc++.so.6库导致很多命令执行不了

fedora7想把gcc4.1.2替换成gcc3.2.2, 所以下载了cpp-3.2.2-5.i386.rpm, gcc-3.2.2-5.i386.rpm等包,但在安装时提示已经有更新的版本,所以先删除新版本再装旧版本,更换cpp和gcc时未出问题,更换libstdc++出问题了
rpm -e --nodeps libstdc++-4.1.2-12
rpm: error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directory

rpm -ivh libstdc++-4.1.2-12.i386.rpm
即使再执行rpm把libstdc++安装回来也不行, 因为rpm命令本身需要libstdc++.so.6库, 我有libstdc++.so.5, ln -s不可行。yum install也不能执行了

所以我到另一台机子考了一个libstdc++.so.6过来,放到/usr/lib/下,至少rpm,yum之类的可以用了,再看怎么换gcc,那台考libstdc++.so.6的机子少另一个gcc库,进不了X,都是被我换gcc搞的

2008年10月29日星期三

解决e2fsck版本太低造成的不能启动的问题:fsck.ext3:Filesystem has unsupported feature(s)

我也遇到了这个问题,到网上搜到的下面这个帖子:

转载请注明原创出处:HateMath的网上田园(http://blog.vckbase.com/hatemath/

1. 症状

PC上已经已装有Fedora 4,出于开发需要又装Red ha t 9.
FC4(hda7) & RH9(hda6) 都是ext3 文件格式.
装好后配置启动菜单,然后重启进FC4,正常进入,再重启进RH9,也正常进入.

开始配置RH9,什么系统、网络、程序、多媒体、等等、等等 - --麻烦啊.
折腾好了后,重启,出现错误:
........
checking root filesystem
fsck.ext3:filesystem has unsupported feature(s) (/12)
e2fsck:get a newer version of e2fsck!

2. 解决方法

将Fedora4中的 /sbin/e2fsck 文件拷贝到RedHat9的/sbin/目录下,覆盖原来的(最好备份一下)e2fsck 文件.
重启,一切恢复正常。

3. 探询原因
RedHat9中的e2fsck版本较低。

4.闲聊
你 看,解决方法好简单啊。可是你知道吗,我搞了3个多小时。用关键词“fsck.ext3:Filesystem has unsupported feature(s) ”google到的70多个外文网页,找了几个没合适的,中文的没有。所以,这下你理解我为什么用它做随笔的标题了吧。希望对别人有用。

(完)

======================================

但是我的fc4不在真实物理盘里,是vmware直接打开vmx文件,我在出错后命令行里看到的sda也只看到了它自己的,在根目录下也只搜索到了/sbin/e2fsck,不知道用哪个来替换了。
所以从启动脚本开始出发。看/etc/rc.d/rc.sysinit,在busybox里init命令调用到/etc/inittab会调用到/etc/rc.d/rc.sysinit,在里面搜索fsck的命令在哪里调用,既然是e2fsck版本的问题,只是检查文件系统有没有坏,那么我不要这条了,反正如果e2fsck检查出坏了也只是提示出错,没坏检查不检查不都差不多吗,或者先去掉sysinit里fsck部分,让桌面启动起来,再下载替换掉fsck命令也应该是可以的。

所以我注释了/etc/rc.d/rc.sysinit 第387-429行,也就是执行了fsck命令,但是不处理它的返回值,问题就解决了。
修改脚本前需要把根文件系统设置为rw,不然是readonly
mount -o remount,rw /
修改完后重启

我不明白为什么非物理盘安装的ubuntu会影响到非物理盘安装的FC4
========================================
xiaoshe说看不明白我写的,所以修改一下再写到下面,上面的也不想删了,照别人的板书写

1.症状
PC上用vmware装了FC4,后来又装了一个ubuntu8.04,当我用vmware打开ubuntu以后,以后在想打开FC4就在启动时提示以下错误:
checking root filesystem
fsck.ext3:filesystem has unsupported feature(s) (/12)
e2fsck:get a newer version of e2fsck!

2.解决办法
@ 网上找的办法: HateMath的网上田园(http://blog.vckbase.com/hatemath/)
将Fedora4中的 /sbin/e2fsck 文件拷贝到RedHat9的/sbin/目录下,覆盖原来的(最好备份一下)e2fsck 文件.
重启,一切恢复正常。

@我的办法:
将根文件系统修改为可读写的
mount -o remount,rw /
注释/etc/rc.d/rc.sysinit第387-429行

3. 探询原因
@ 网上找的原因: HateMath的网上田园(http://blog.vckbase.com/hatemath/)
RedHat9中的e2fsck版本较低。
@我的原因:e2fsck如果版本低就不启动

4.思考过程
既然是e2fsck版本的问题,只是检查文件系统有没有坏,那么我不要这条了,反正如果e2fsck检查出坏了也只是提示出错启动失败,没坏检查不检查不都差不多吗,所以我注释了/etc/rc.d/rc.sysinit 第387-429行,也就是执行了fsck命令,但是不处理它的返回值,问题就解决了

2008年10月27日星期一

安装了suse-linux11.0-dvd-x86_64

dvd我以为很全呢,4.3G,结果make都找不到命令,gcc估计都没有
然后从windows用vmware启动suse,结果在找硬盘处出错,网上有类似现象,by-id找不到,修改fstab不起作用,因为在fstab前就已经出错了,/dev下无sda*设备
我就又下载了fedora9,装3系统,真废时间

suse我觉得挺漂亮的,就是不会用,比fedora难操作

2008年10月24日星期五

编译busybox1.12.1和uboot1.1.6

原本编译器是arm-linux-3.4.1

下载uboot1.1.6后编译出错,网上说因为编译器不支持softfloat
lib_arm/libarm.a(_udivsi3.o)(.text+0x8c):/home/gongh/2440/u-boot-1.1.6/lib_arm/_udivsi3.S:67: relocation truncated to fit: R_ARM_PLT32 __div0
lib_arm/libarm.a(_umodsi3.o)(.text+0xa8):/home/gongh/2440/u-boot-1.1.6/lib_arm/_umodsi3.S:79: relocation truncated to fit: R_ARM_PLT32 __div0
make: *** [u-boot] Error 1

下载busybox1.12.1后编译出错,一般我都是哪个命令出错就去掉哪个命令,有inotifyd,taskset,然后是networking/interface.c出错,网络功能不能去掉,所以这个必须要编译过,这时我脑子是呆的,把uboot的softfloat对应到了busybox编译不过,所以我打算做一个交叉编译工具
networking/interface.c:818: error: `ARPHRD_INFINIBAND' undeclared here (not in a function)
networking/interface.c:818: error: initializer element is not constant
networking/interface.c:818: error: (near initialization for `ib_hwtype.type')
networking/interface.c:818: error: `ARPHRD_INFINIBAND' undeclared here (not in a function)
networking/interface.c:818: error: initializer element is not constant
networking/interface.c:818: error: (near initialization for `ib_hwtype.type')

下载crosstool-0.43
http://kegel.com/crosstool/crosstool-0.43.tar.gz

1>用非root用户登录,如果以root登录会提示这样太危险
2>建立目录/opt/crosstool,修改属性,编译时会建立这个目录,需要有权限
sudo mkdir /opt/crosstool
sudo chown $USER /opt/crosstool
3>./demo-arm-softfloat.sh,下载需要的源码并编译,虚拟机花了100分钟

然后用新的编译器gcc-3.4.5-glibc-2.3.6编译busybox的network就通过了,uboot1.1.6也通过了

2008年10月19日星期日

周日买了一台新电脑

现在电脑便宜多了。配置我说不清
CPU : amd 64位双核5000 2.5G
DDR : 2G
硬盘 : 160G
显示屏 : 20寸
一个音箱, 一个蓝牙适配器
加一个正方形电脑桌,花了3088,很久没了解市场了,至少比我预期的便宜

2008年10月16日星期四

在这里做几道题,我觉得我思路比较窄1

大学没好好上数学建模的选修,现在想自学一下,matlab还在下载,在这里做第2章19大题

19.对下面的问题列出问题表,并试图为这些问题寻求合理的解答

(a)需要一部新的电视,是买一部好还是租好?

1)问题Q:
a买的租的质量差别是否无所谓
b总共需要用多少年

2)因素F:
a新电视的价钱 输入变量 N
b租电视一年的价钱 输入变量 O
c总共需要用多少年 输入变量 T
d租的电视质量和折旧有多少 参数 A

3)假设A:新电视和租电视到家以后不会在需要它的期间内坏

4)对问题的描述P:
新电视价钱相当于租电视多少年?比打算用的年数大还是小?
租价钱:O*T+A 买电视N,比较 O*T+A 与N的大小

5)进一步考虑:
a租电视是否会因为时间越长而年租价越低
b新电视是否有促销活动
c如果电视会坏,新电视和租电视坏的概率又有多少,及新电视和租电视保修期有多久,维修费多少

=========================

(b)为长时间保存而购买冷冻食品合不合算?

1)问题Q:
a长时间保存是为了持续长时间有食品吃,还是隔一段时间后有食品吃
b超市离家的距离,改为购买常规食品的,购买频率

2)因素F:
a冷冻食品的保质期 参数 L
b每天需要的食品量 输入参数 n
c冷冻食品的价钱 输入参数 p1
d常规食品的价钱 输入参数 p2
e常规食品每日需求量 输入参数 t1
f常规食品保质期 参数 t2
g每次购买常规食品所需额外费用 参数 x
h总共需要度过的天数 参数 d

3)假设A:为了保证每天有食品吃的情况,d天内冷冻食品不过期

4)描述P:
d天内常规食品消费:(d/t2)*x + p2*n*d
d天内冷冻食品消费:p1*n*d
比较一下费用差别

5)进一步思考:
a对冷冻食品和常规食品每日需求量是否一样

2008年10月12日星期日

patch

以前有服务器,大家修改代码就合到svn里,现在没别人管内核了,所以我打一个patch
参考网页:
http://wordpad.blog.sohu.com/50009831.html
http://linux.chinaunix.net/bbs/viewthread.php?tid=615467
http://www-128.ibm.com/developerworks/cn/linux/l-diffp/index.html

1 清空新kernel多余文件
make mrproper
2 到内核根目录上一级生成patch
[root@sherman_samba kernel]#diff -Nur linux-2.6.14.4/ /home/gongh/now/t30x/src/kernel/linux-2.6.14.4/ > /home/gongh/1404patch
3 打上patch
[root@sherman_samba kernel]# patch -p0 < /home/gongh/1404patch

记一下,以后就不到网上搜了

添加config文件

以前的项目是通过load config和save config来配置。现在想把config文件放到arch/mips/config下,我把文件t30x_gpioi2c_config放在该目录下,执行make t30x_gpioi2c_config

[root@sherman_samba linux-2.6.14.4]# make t30x_gpioi2c_config
make[1]: *** No rule to make target `t30x_gpioi2c_config'. Stop.
make: *** [t30x_gpioi2c_config] Error 2

没有这个目标,然后看根目录的Makefile,有这么一段
# Brief documentation of the typical targets used
# ---------------------------------------------------------------------------

boards := $(wildcard $(srctree)/arch/$(ARCH)/configs/*_defconfig)
boards := $(notdir $(boards))

所以它需要新的config文件是以_defconfig为结尾的,所以修改 t30x_gpioi2c_config为 t30x_gpioi2c_defconfig就可以了

2008年10月8日星期三

半透明实现

GrCopyArea nanox中很多场景都需要拷贝区域,最后一直走到memmove真实的内存拷贝
|----GdBlit
|----|----dstpsd->Blit 这里的psd根绝scr_xxx.c决定哪个SUBDRIVER
|----|----|----linear24_blit 在scr_fb.c中的fb_open函数会调用fb.c中的select_fb_subdriver,根据屏每个像素占几位来确定Blit函数,如果是24位,SUBDRIVER就是fblinear24,由此确定dstpsd->Blit函数是linear24_blit
|----|----|----|----memmove

static void
linear24_blit(PSD dstpsd, MWCOORD dstx, MWCOORD dsty, MWCOORD w, MWCOORD h, PSD srcpsd, MWCOORD srcx, MWCOORD srcy, long op)
透明处理是下面这一段
alpha = op & 0xff;

while(--h >= 0) {
for(i=0; i < w; ++i) {
unsigned long s = *src++;
unsigned long d = *dst;

*dst++ = (unsigned char)(((s - d)*alpha)>>8) + d;
s = *src++;
d = *dst;
*dst++ = (unsigned char)(((s - d)*alpha)>>8) + d;
s = *src++;
d = *dst;
*dst++ = (unsigned char)(((s - d)*alpha)>>8) + d;
}
dst += dlinelen_minus_w;
src += slinelen_minus_w;
}

既然要透明也就是要2个图片一起显示,走下来也就是2个点一起显示。
这里有src和dst点,dst是背景,src是显示在上面的图片,该Blit拷贝函数需要把src图片拷贝到dst背景上。分别用3条语句把RGB红绿蓝分开来做计算。
op是传进来的透明参数,原本应该是0-1的透明范围,为了避免浮点运算,alpha范围是0-0xff,计算后右移8位。
就看蓝色这一条:
当alpha为0xff时,显示的完全是s,也就是不透明,把src拷贝到dst了
当alpha为0时,显示的完全是d,也就是完全透明,只能看到dst背景图片
当alpha取中间值时,就是半透明了,还是蛮容易的吧。值越大越不透明

nanox GsSelect函数记一下

GsSelect 获得nanox事件
|----select 同时select 2个文件描述符(鼠标,按键)
|----if((e > 0) 如果select有数据
|----|----GsCheckMouseEvent 获得鼠标事件
|----|----|----devmouse.c GdReadMouse 配置了鼠标或触摸屏
|----|----|----|----mousedev.Read 调用鼠标驱动读函数读数据,如果是transform模式则转换为lcd点再返回,如果是raw模式则直接返回数据
|----|----|----devnomouse.c GdReadMouse 未配置鼠标,直接返回x y为0的数据
|----|----GsCheckKeyboardEvent 获得键盘事件
|----|----|----GdReadKeyboard 调用devkbd.c读取键盘消息
|----|----|----|----kbddev.Read 读取键盘消息
|----|----GsDeliverKeyboardEvent 根据键值发送pen down/up事件
|----else if (e == 0) 如果select无数据
|----|----GdTimeout timeout返回
|----else if ( e < 0 ) 如果select出错,打印错误返回


说一下GsSelect的fd与select
/* Set up the FDs for use in the main select(): */
FD_ZERO(&rfds);
if(mouse_fd >= 0) {
FD_SET(mouse_fd, &rfds);
if (mouse_fd > setsize)
setsize = mouse_fd;
}
if(keyb_fd >= 0) {
FD_SET(keyb_fd, &rfds);
if (keyb_fd > setsize)
setsize = keyb_fd;

先将rfds清零,把mouse_fd和keyb_fd设置到rfds的某一位上,原本我不知道file descriptor怎样分配了,看了一下,结果fd是一个文件描述符表的索引,所以是个很小的正整数。这样FD_SET某一位时也不会重复

select(setsize+1, &rfds, NULL, NULL, to)

select同时作用到2个fd上,setsize是mouse_fd和keyb_fd中最大的一个加1,rfds里又有mouse和key的2位置1,这样内核sys_select里实现是有个for循环,会把mouse和key的poll都调用到,而不是我以前所理解的,一个select对应一个poll,而是一对多的关系。setsize加1是因为do_select 循环里用的是i < n,所以要执行到n传进去的数要加1

要看fd可以看sys_close(unsigned int fd)
struct fdtable *fdt;
fdt->fd[fd],数组下标就是fd

struct fdtable {
unsigned int max_fds;
int max_fdset;
int next_fd;
struct file ** fd; /* current fd array */
fd_set *close_on_exec;
fd_set *open_fds;
struct rcu_head rcu;
struct files_struct *free_files;
struct fdtable *next;
};

2008年10月7日星期二

nanox注释一下srvfunc.c的window方面函数

nanox的open,close,mainloop有了,然后就是它提供的画图函数了。先只看link to app的情况,主要文件是nanox/srvfunc.c,那么注释一下该文件主要函数window方面的

GrNewWindow 新建一个window
|--GsFindWindow 根据父window id找到父window的handle
|--NewWindow 在父window上建立一个新window
|--|--malloc(sizeof(GR_WINDOW)) 分配新window结构空间
|--|--window.*=* 为新window结构体赋初值

GrNewInputWindow 新建一个input window
它与GrNewWindow的差别是
GrNewWindow :window->output = GR_TRUE
GrNewInputWindow :window->output = GR_FALSE

GrNewPixmap 新建一个pixmap,通常是为画一张图片准备的一块区域,pix就是pixel(点)
|--rootwp->psd->AllocateMemGC(rootwp->psd); 根据root window的屏设备指针分配一个新的屏设备结构 typedef struct _mwscreendevice *PSD;
|--malloc(sizeof(GR_PIXMAP)); 分配pixmap结构空间
|--GdCalcMemGCAlloc 根据要分配的pixmap宽高计算出分配的实际空间,所以需要用到屏设备的参数确定一个点要分配多少字节size
|--calloc(size, 1); 分配size的空间
|--pp->psd = psd; 把psd挂在当前pixmap下
|-- psd->MapMemGC 初始化这块mem,并把画图函数指针挂进来

GrMapWindow 显示一个window
|--GsFindWindow id转换为handle
|--GsWpRealizeWindow 让window和它的子window可视
|--|--GsDeliverUpdateEvent(wp, GR_UPDATE_MAP... 发送更新map事件
|--|--if (!wp->mapped ... 如果是unmap就返回
|--|--if (wp->output) 如果不是inputwindow就显示
|--|--|--GsDrawBorder 画window边框
|--|--|--GsWpClearWindow 刷新window内部
|--|--|--|--GsSetClipWindow 判断该window刷新的部分有没有超过父window,超过就不刷新
|--|--|--|--GsWpDrawBackgroundPixmap 如果有背景pixmap就刷新
|--|--|--|--GdFillRect 如果没有背景pixmap就刷新background color
|--|--|--|--不需要刷背景就不刷
|--|--|--|--GsDeliverExposureEvent 有必要就发送exposure刷新事件
|--|--for (wp = wp->children ... GsWpRealizeWindow 递归调用将子window也刷新

GrUnmapWindow 隐藏一个window
它与GrMapWindow的差别是
GrMapWindow:wp->mapped = GR_TRUE;
GrUnmapWindow :wp->mapped = GR_FALSE;
wp->mapped = GR_TRUE;

GrMoveWindow 移动window
|--GsFindWindow id转换为handle
|--if (wp->mapped && wp == wp->parent->children && wp->parent->id == GR_ROOT_WINDOW_ID && !wp->clipregion) 如果该window可视,父window是root window,不在刷不到的区域那么刷局部
|--|--GrNewPixmap 临时新建一个pixmap为了存放window内容
|--|--GrCopyArea 把当前window内容拷贝到pixmap里
|--|--OffsetWindow 根据offset计算出新window坐标
|--|--GrCopyArea 把存放了老window内容的pixmap拷贝到新window坐标地点
|--|--GsExposeArea 刷新新老window并集的矩形区域
|--|--GrDestroyWindow 销毁临时建立的pixmap
|--|--DeliverUpdateMoveEventAndChildren 发送更新移动事件
|--else 刷整个屏
|--|--GsWpUnrealizeWindow 隐藏该window
|--|--OffsetWindow 根据offset计算出新window坐标
|--|--GsWpRealizeWindow 显示新window
|--|--DeliverUpdateMoveEventAndChildren 发送更新移动事件

GrRaiseWindow 让当前窗口显示在最上面
|--GsFindWindow id转换为handle
|-- if (wp->parent->children == wp) 如果该窗口已经在最上面就返回,wp->parent->children存放的是父window中最上面的子window
|--GsCheckOverlap 如果该窗口还有兄弟窗口,就检查兄弟窗口是否覆盖住了该窗口
|--wp->parent->children = wp; 该窗口为父窗口最上面的window
|--if (overlap) 如果有覆盖就刷新
|--|--GsDrawBorder 画window边框
|--|--GsExposeArea 更新该window的整块区域

GrLowerWindow 让当前窗口显示在最下面
|--GsFindWindow id转换为handle
|--if (wp->siblings == NULL) 如果没有兄弟窗口,那么也就没有最上最下的说法了,返回
|--if (prevwp == wp) wp->parent->children = wp->siblings; 如果当前窗口在最上面就让它的兄弟窗口显示在最上面
|--while (expwp && (expwp != wp)) ... expwp = expwp->siblings; 循环整个兄弟窗口链表找到兄弟窗口计算重叠区域并刷新,siblings是一个兄弟窗口链表
|--|--GsCheckOverlap 计算窗口与它的下一个兄弟窗口的重叠区域
|--|--GsExposeArea 刷新当前窗口,当while循环后当前窗口为它下一个兄弟窗口时就会刷新它的兄弟窗口,所以一个个刷,第一个刷的是自己,所以自己才能是最下面一层的窗口

GrDestroyWindow 销毁一个窗口或pixmap
|--GsFindWindow id转换为handle
|--if (wp) 如果是GsFindWindow返回不为0就是window
|--|--GsWpDestroyWindow 那么销毁window
|--|--|--GsWpUnrealizeWindow 如果该window在显示,先隐藏
|--|--|--GsDeliverUpdateEvent 发送更新事件
|--|--|--while (wp->children) GsWpDestroyWindow(wp->children); 递归销毁子窗口
|--|--|--该free的free,该清零的清零
|--else 如果是GsFindWindow返回为0就是pixmap
|--|--GsFindPixmap id转换为handle
|--|-- free pixmap那块区域,free pixmap结构体,free当初建立的psd

GrKillWindow 将当前window所属的client销毁或nanox server终止
|--GsFindWindow id转换为handle
|--GsClose(wp->owner->id) 根据client id销毁当前client在server中的连接
|--|--#if NONETWORK 如果是link app
|--|--|--GsDropClient --connectcount; link app的连接就是1,减一后connectcount为0
|--|--#else 如果是C/S
|--|--|--GsDropClient 销毁client,connectcount减一
|--|--if(!persistent_mode && connectcount == 0) 如果连接数为0,终止nanox server
|--|--|--GsTerminate 终止nanox server
|--|--|--|--#if !NONETWORK 如果是C/S关闭socket
|--|--|--|--|--GsCloseSocket 关闭socket
|--|--|--|--关闭屏,鼠标,键盘
|--|--|--|--exit(0); 退出

在window刷新的时候还有鼠标cursor需要特殊处理,比如移动刷新window时不能把cursor的图片也拷进来了。这个就不写了

2008年10月6日星期一

画了一个图,觉得我蛮不会画流程图,怎么学一下呢

nanox的open,close,mainloop事件循环


2008年10月5日星期日

nanox记一下大致的东西

Grxxx函数是C/S中client端调用的函数,在nanox文件夹里,client.c, nxproto.c, srvnet.c, 如果以link app的方式编译而不是C/S,那么srvfunc.c直接取代了client.c和srvnet.c

Gdxxx函数是nanox的核心函数,在engine文件夹里,devarc.c, devclip1.c, devdraw.c, devfont.c, devpoly.c等画图,devmouse.c,devkbd.c等是设备文件的接口,font_pcf.c, font_freetype.c是描述字体的文件格式是什么,如何解析。image_gif.c, image_jpeg.c是图片decode。

Gsxxx函数graphics server,在nanox/serv.h中可看到所有Gs开头函数原型。最重要的就是GsSelect函数,当系统初始化完毕进入主循环时,通过调用GsSelect函数获得按键等外部事件。

区分C/S还是link app to server在Makefile.rules里有一句,如果没定义LINK_APP_INTO_SERVER,那么用socket进行C/S通讯。
ifeq ($(LINK_APP_INTO_SERVER), Y)
DEFINES += -DNONETWORK=1
endif

如果是C/S,那么srvmain.c的main函数是第一个函数,调用GsInitialize初始化,然后进入GsSelect主循环获得外部事件。
/* Attempt to initialise the server*/
if(GsInitialize() < 0)
exit(1);

while(1)
GsSelect(0L);

如果是link app,那么app的main函数是第一个函数。当app调用GrOpen时,就会调用到GsInitialize初始化,之后app的主循环调用GrGetNextEvent函数获得事件并处理
for (;;)
{
GrGetNextEventTimeout(&event,1);
EventProc(&event);//app的事件处理函数
}

nanox记一下目录结构

源码树文件夹注释

configs //一些默认配置选项

demos //测试nanox的应用程序,配置时可选择是否编

drivers //nanox驱动,包括screen,keypad,touchpanel。比如mou_touchscreen.c里建立一个结构体变量 MOUSEDEVICE mousedev,fb开头是怎样画点画线SUBDRIVER,kbd开头是不同键盘KBDDEVICE,mou开头是不同鼠标MOUSEDEVICE。screen开头是不同屏SCREENDEVICE,如果内核提供的接口不同,比如键盘,就建立一个kbd_xxx.c,完成KBDDEVICE结构体里的函数就可以了。
typedef struct _mousedevice {
int (*Open)(struct _mousedevice *);
void (*Close)(void);
int (*GetButtonInfo)(void);
void (*GetDefaultAccel)(int *pscale,int *pthresh);
int (*Read)(MWCOORD *dx,MWCOORD *dy,MWCOORD *dz,int *bp);
int (*Poll)(void); /* not required if have select()*/
int flags; /* raw, normal, transform flags*/
} MOUSEDEVICE;


engine //nanox驱动上面一层
比如devmouse.c调用mousedev.Open(&mousedev)打开mouse设备。以dev开头的是设备相关文件,font开头是画字体的方式,image开头是不同格式的图片

fonts //纯字体数据文件,与此联系的是engine/font_xxx.c。
比如fonts/chinese/gb2312font.c建立了一个字体数组GUO_GB2312_12X12_FONT_BITMAP[],在engine/font_dbcs.c中会调用到unsigned char *src = GUO_GB2312_12X12_FONT_BITMAP + pos + i * 3;,条件是#if HAVE_GB2312_SUPPORT

mwin //microwindows API

nanox //nanox API

[摘]学而不思则罔,思而不学则殆

语出《论语·为政》——子曰:“学而不思则罔,思而不学则殆”。 此句讲学习方法.教人学思结合.只学而不思,人会被知识的表象所蒙蔽而感到迷茫困惑,尽信书不如无书,是为不通;只思而不学,就没有知识的积累,则会因为疑惑流于空想而更加危险,是为不懂。

最近老想到这2句,抄在这里。我感觉我比较偏向于学而不思

2008年9月27日星期六

unaligned.c报错的一个原因

unsigned long val=3;
printk("*val = %x\r\n",&val);
这样就会出现unaligned报错,因为未4字节对齐

2008年9月24日星期三

通过__setup宏解析bootloader传递上来的自定义参数

bootloader参数console=ttyS0,115200 root=/dev/ram rw init=/linuxrc之类的,在此后面再加一条ts=1也就是console=ttyS0,115200 root=/dev/ram rw init=/linuxrc ts=1

在内核里添加ts=对应的handle函数及__setup宏
static int __init ts_setup(char *options)
{
printk("[ts_setup] %s\r\n",options);
return 1;
}
__setup("ts=", ts_setup);

当发现bootloader参数中含有ts=字符串时就调用ts_setup函数,=后的值就是options字符串。这样除了在menuconfig里选编译文件外还可以通过setup来选功能。让我想起了前2天老板叫我用配置文件确定gpio转i2c的io口,我之前用rootfs里的配置文件,现在可以转成用__setup来配置gpio口了。
setup在initcall之前

2008年9月23日星期二

添加自己的i2c adapter (gpio转i2c)

用的这一款CPU没有i2c host,所以gpio模拟i2c,本来一个设备不用做i2c adapter,直接模拟就是了,但是接了3个i2c设备,ts,radio,touchpad,所以要用i2c总线。driver/i2c/下已经有比较成熟的代码了,所以添加我们这款CPU的adapter,然后做设备driver。
i2c通讯方式中有包含bit方式通讯,driver/i2c/algos/i2c-algo-bit.c
需要添加的是i2c-algo-bit.c里的setsda,setscl,getsda,getscl 4个函数

/* --- setting states on the bus with the right timing: --------------- */
#define setsda(adap,val) adap->setsda(adap->data, val)
#define setscl(adap,val) adap->setscl(adap->data, val)
#define getsda(adap) adap->getsda(adap->data)
#define getscl(adap) adap->getscl(adap->data)

做adapter数据结构
struct t30x_gpio_i2c_pins
{
unsigned int scl_gpio;
unsigned int scl_inout;
unsigned int scl_altfunc;
unsigned int sda_gpio;
unsigned int sda_inout;
unsigned int sda_altfunc;
};

struct t30x_gpio_i2c_data
{
struct t30x_gpio_i2c_pins gpio_pins;
struct i2c_adapter adapter;
struct i2c_algo_bit_data algo_data;
};

static struct t30x_gpio_i2c_data t30x_gpio_i2cd =
{
.gpio_pins =
{
.scl_gpio = 0x4,
.scl_inout = 0xff,
.sda_gpio = 0x8,
.sda_inout = 0xff,
},
.adapter =
{
.name = "t302b-gpio-i2c",
.owner = THIS_MODULE,
.id = I2C_HW_B_T30XGPIO,
.retries = 2,
.class = I2C_CLASS_ALL,
},
.algo_data =
{
.setsda = t30x_gpio_bit_setsda,
.setscl = t30x_gpio_bit_setscl,
.getsda = t30x_gpio_bit_getsda,
.getscl = NULL,
.udelay = 10,
.mdelay = 10,
.timeout = 100,
},
};

完成3个函数
static void t30x_gpio_bit_setscl(void *data, int val)
{
struct t30x_gpio_i2c_pins* gdata = (struct t30x_gpio_i2c_pins*)data;
//set output
if(T30X_GPIO_OUTPUT != gdata->scl_inout)
{
writel(readl(GPIO_OE)(gdata->sda_gpio), GPIO_OE);
gdata->scl_inout = T30X_GPIO_OUTPUT;
}
if (val)
writel(gdata->scl_gpio, GPIO_SET);
else
writel(gdata->scl_gpio, GPIO_CLEAR);
}

static void t30x_gpio_bit_setsda(void *data, int val)
{
struct t30x_gpio_i2c_pins* gdata = (struct t30x_gpio_i2c_pins*)data;
//set output
if(T30X_GPIO_OUTPUT != gdata->sda_inout)
{
writel(readl(GPIO_OE)(gdata->sda_gpio), GPIO_OE);
gdata->sda_inout = T30X_GPIO_OUTPUT;
}

if (val)
writel(gdata->sda_gpio, GPIO_SET);
else
writel(gdata->sda_gpio, GPIO_CLEAR);
}

static int t30x_gpio_bit_getsda(void *data)
{
int sda;
struct t30x_gpio_i2c_pins* gdata = (struct t30x_gpio_i2c_pins*)data;
//set input
if(T30X_GPIO_INPUT != gdata->sda_inout)
{
writel(readl(GPIO_OE)&(~(gdata->sda_gpio)), GPIO_OE);
gdata->sda_inout = T30X_GPIO_INPUT;
}
sda = readl(GPIO_LEVEL)&(gdata->sda_gpio);
return sda? 1 : 0;
}

完成gpio初始化函数
static int t30x_gpio_hw_init(void *data)
{
struct t30x_gpio_i2c_pins* gdata = (struct t30x_gpio_i2c_pins*)data;
//altfunc select
writel(readl(GPIO_ALTFUNC_SEL)&(~((gdata->scl_altfunc)(gdata->sda_altfunc))), GPIO_ALTFUNC_SEL);

//disable gpio interrupt mask
writel(readl(GPIO_INT_MASK)((gdata->scl_gpio)(gdata->sda_gpio)), GPIO_INT_MASK);

//set output
writel(readl(GPIO_OE)((gdata->scl_gpio)(gdata->sda_gpio)), GPIO_OE);

//set level high
writel(((gdata->scl_gpio)(gdata->sda_gpio)), GPIO_SET);
return 0;
}

模块初始化
static int __init t30x_gpio_i2c_init(void)
{
int err;
struct t30x_gpio_i2c_data *drv_data = &t30x_gpio_i2cd;
drv_data->adapter.algo_data = &(drv_data->algo_data);

//private data = gpio pins, set sda/scl will use it
drv_data->algo_data.data = &(drv_data->gpio_pins);

//gpio config
t30x_gpio_hw_init(&(drv_data->gpio_pins));

//add to i2c bit algos
if ((err = i2c_bit_add_bus(&drv_data->adapter) != 0))
{
printk(KERN_ERR "\033[0;40;36mERROR: Could not add %s to i2c bit algos\033[0m\r\n", drv_data->adapter.name); return err;
}

printk("t30x gpio i2c bus initialized\r\n");
return 0;
}

static void __exit t30x_gpio_i2c_exit(void)
{
struct t30x_gpio_i2c_data *drv_data = &t30x_gpio_i2cd;
i2c_bit_del_bus(&drv_data->adapter);
return;
}

module_init(t30x_gpio_i2c_init);
module_exit(t30x_gpio_i2c_exit);
MODULE_DESCRIPTION("GPIO-based I2C adapter for t30x systems");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("zhourr");

2008年9月21日星期日

打算把ph701机子用上,作为mp4的功能

希望我上下班的途中能用ph701看电影。701的数据线我没从公司带出来,傻了。只好用2410开发板调,然后再看怎么办吧。我速度应该比较慢,每天晚上的杂事多,最好每天能保证1小时在这上面。