GTK开发之托盘与通知

在ubuntu的unity下是不显示托盘图标的,在13.04版本之前可以通过gconf-editor中开启白名单激活托盘图标,其实这个问题是由于ubuntu采用了indicator(appindicator, libappindicator)而不支持gtkstatusicon的缘故,所以应用程序要显示托盘图标的话,只需通过libappindicator即可,当然,对于老版本或者没有安装libappindicator库的情况下,还是应该采用gtkstatusicon的办法,所以,可以在安装配置中检测相应的库,而相应的选择对应的实现方式。
(注意,如果是gtk3必须用libappindicator3: sudo apt-get install libappindicator3-dev)

ubuntu的notification接口中,set_time_out接口如果设置的超时时间小于1000(毫秒),将会导致通知一直显示不消退。

另外,unity也可以开发,支持右键菜单,具体可以参看http://developer.ubuntu.com中的教程。实例代码可以参看xmradio。

gnome3的indicator程序真的很酷!

indicator开发:

需要先set_menu,然后gtk_widget_show菜单才能正确显示indicator和菜单
libido库里面包含有滑块的菜单项。

G_BEGIN_DECLS和 G_END_DECLS

这个是GLIB什么的一个宏,你可以看看glib的gmacro.h,编译时候指定

1
pkg-config   --cflags   glib-2.0

包含glib的头文件

1
2
3
4
5
6
7
  #ifdef     __cplusplus   
  #   define   G_BEGIN_DECLS     extern   "C"   {   
  #   define   G_END_DECLS         }   
  #else   
  #   define   G_BEGIN_DECLS   
  #   define   G_END_DECLS   
  #endif

GTK编程问题记录

今天发现一个问题,就是GTK的事件传值问题,如果在一个函数里面定义一个局部变量,然后将此变量指针传给GTK事件,再在GTK事件处理函数中重新取得该变量时,发现该变量值已经失效,也就是已经被释放掉了,原因是因为局部变量存储于栈空间,该栈空间的生命周期只存在于该函数内,一旦函数运行完毕,栈空间将被清空,而GTK事件显然是另一个函数,而且还必须是全局的,因此在该函数中引用一个其他函数栈空间内的变量指针显然无法得到正确的结果。实例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void btn_click (GtkButton *button, const char * user_data)
{
    printf("whywhywhy%s\n",user_data);    //这儿user_data的值是无效的!
}
void test()
{
const char str[20] = "fuckyou";
...
button = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
g_signal_connect (button, "clicked", G_CALLBACK(btn_click), (gpointer)str);
gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
}

另外,如果将str数组改为常量字符指针,即:

1
2
3
4
5
const char *str = "fuckyou";
...
g_signal_connect (button, "clicked", G_CALLBACK(btn_click), (gpointer)str);

如此,在btn_click中是能够获得str的值的,为什么呢?因为常量会放到常量存储区里,所以不会被释放掉。

那解决方法是什么呢?其实,只需要在test函数中声明一个静态局部变量或者用一个静态指针指向临时变量(C++才行),就能达到局部变量全局存储的效果,相当于扩大了生命周期,有点想lambda表达式的核心思想。

具体写法如下:

1
static char str[20] = "fuckyou";

或者(C++中才可以),比如在一个类的成员函数中:

1
2
3
string test = "great";
static string strTmp = test;                 // 用于扩大生命周期到整个对象
g_signal_connect(G_OBJECT(menuItem), "activate", G_CALLBACK(Gtk3StatusMenuView::OnJsMenuClick), (gpointer)test.c_str());

但用原始char指针在C++中也行不通:

1
2
3
4
5
char test[20]="great";
static char *strTmp = test; // 无效!
g_signal_connect(G_OBJECT(menuItem), "activate", G_CALLBACK(Gtk3StatusMenuView::OnJsMenuClick), (gpointer)test);

原因应该是strTmp仅仅扩大了test数组常量指针的生命周期,该数组元素还是被释放掉了。
真蛋疼!

Google NACL下载问题

google的nacl(native client) SDK在运行./nacl_sdk update的时候始终无法完成下载,究其原因是因为https隧道网络不稳定造成的,所以解决方法有2:

  1. 在sdk_tools/command/update.py中将_UpdateBundle函数中下载bundle的地方将档案地址打印出来,即在346行(pepper_29)加入如下语句:
1
2
# Display the url of the bundle
print 'Bundle url: %s' % (archive.url)

然后在浏览器中用http下载,最后放到sdkcache/archives/peper版本号/下,然后再执行./nacl_sdk update即可

  1. 将https协议的地址转换为http协议的地址然后再下载,即在update.py(pepper_29)的336行加入如下语句:
1
2
3
# Emit the https verification to speed and gurantee the downloaing.
if archive.url[0:8] == 'https://':
    archive.url = 'http://'+ archive.url[8:]

然后再执行./nacl_sdk update即可

CubieBoard-网络配置

有线的连接方法

如果路由器有有线网口,那就直接把板子直连到路由器上再重启网络服务即可,但我的路由器没有无线网口,于是可以通过桥接的方法,要准备一根网线,然后在笔记本上用无线连接网络,之后通过桥接将无线网络共享到网线口,然后将电脑和板子的有线口直连起来,然后在板子上配置/etc/network/interface,另外还要配置dns,在/etc/resolv.conf下,可以参考: [教程]通过网线直连,Cubieboard共享电脑的WIFI - DIY作品区 - Cubieboard中文论坛 - Powered by Discuz!

#nano /etc/network/interfaces

1
2
3
4
5
auto lo
iface lo inet loopbackiface eth0 inet static
address 192.168.1.1
gateway 192.168.1.253
netmask 255.255.255.0

#nano /etc/resolv.conf

1
2
3
4
5
nameserver 202.96.134.133
nameserver 202.96.134.33
# Google DNS
nameserver 8.8.8.8
nameserver 8.8.4.4

添加默认网关
#route add default gw 192.168.1.253
#service networking restart
#ifup eth0

无线的连接方法

如果路由器采用WEP的加密,可以直接配置,但如果采用的是WPA/WPA2的方式,就要要先安装wpa-supplicant,(cubieboard2 的ubuntu 12.10-v5上已经自带不需要再安装),再进行配置,配制方法是: CB/RPi 下安装使用USB无线网卡 - Learning Notes

#nano /etc/network/interfaces

1
2
3
4
5
6
7
8
# 加入无线配置
auto wlan0
iface wlan0 inet static
address 192.168.1.2
gateway 192.168.1.253
netmask 255.255.255.0
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

#wpa_passphrase [“SSID”] [“密码”] >> /etc/wpa_supplicant/wpa_supplicant.conf
#service networking restart

CubieBoard-服务搭建

为了一次性安装所有服务,先安装如下包:

1
2
3
apt-get update
apt-get install wpasupplicant ntfs-3g openssh-server tightvncserver git aria2 transmission-daemon samba cron minidlna mldonkey-server
apt-get install nginx php5-fpm php5-cli php5-curl php5-gd php5-mcrypt php5-mysql php5-cgi mysql-server node

遇到了情况,一次性安装所有软件失败,可能是有些位置空间不够的原因,可以分两次来安装,第一次安装之后清理缓存apt-get clean,再进行第二次安装
如果要安装开发环境的话

1
2
apt-get install pkg-config libusb-1.0
apt-get install build-essential

因为NAND空间紧张,最后清理一下缓存:

1
apt-get clean

配置无线

参考CubieBoard-网络配置

配置tightvncserver

VNC远程登录树莓派的图形界面(桌面环境)[一帖完结] - 教程发布区 - 树莓爱好者论坛 - Powered by Discuz!
完了之后再编辑/root/.vnc/xstartup
#nano /root/.vnc/xstartup
加入start lubuntu &这一句,如下:

1
2
3
4
5
6
7
8
9
10
#!/bin/sh
xrdb $HOME/.Xresources
xsetroot -solid grey
#x-terminal-emulator -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
#x-window-manager &
startlubuntu &
# Fix to make GNOME work
export XKL_XMODMAP_DISABLE=1
/etc/X11/Xsession

然后

1
2
service tightvncserver stop
service tightvncserver start

即可

配置nginx

参考CB/Pi 下安装配置优化LNMP环境 - Learning Notes

配置aria2

参考Cubieboard BT下载机 —— aria2 - CubieBoard 里程碑 - jyoryo的博客

配置transimission-daemon

参考安装 Transmission 的流水记录 - Learning Notes

但遇到了aria2和transimission的BT下载都没速度的问题,暂时现实验一下:

  1. 设定限速试下
  2. 查看配置是否有BT选项,如incomplete-dir-enabled设成false
  3. 将后台服务用前台运行查看

配置samba

参考安装 Samba 开启NAS网络邻居共享 - Learning Notes
配置过程中发现windows上无法发现设备,于是把后台服务禁掉,用前台运行:

1
2
service smbd stop
smbd -FS

一运行,发现爆了两个错误,是关于打印机的,解决方法参考

  1. 解决Samba Server Unable to connect to CUPS server localhost:631 - 连线被拒绝问题
  2. 安装 samba 记录 - CrazyWill - 博客园

安装mimidlna

参考Cubieboard通过aria2和minidlna来架设家庭媒体中心 - Q.Lee.lulu - 博客园

中文配置

安装文泉驿字体:

1
sudo apt-get install xfonts-wqy

文泉驿正黑微米黑

1
2
sudo apt-get install ttf-wqy-zenhei
sudo apt-get install ttf-wqy-microhei

或者这个通用的中文字体

1
sudo apt-get install ttf-arphic-uming

创建编码字符集

1
2
sudo locale-gen zh_CN.UTF-8
sudo dpkg-reconfigure locales

编辑~/.bashrc或者/etc/environment,加入:

1
2
LANG="zh_CN.UTF-8"
LANGUAGE="zh_CN:zh:en_US:en"

重启

1
reboot

CubieBoard问题记录-分区问题

遇到的问题:
如果将dev/nande格式化为EXT4分区,开机就会出现hotplug问题,估计是cubieboard上的分区是采用sanxi-tools的nand-pard来分的,估计它的MBR(硬盘分区表)是比较特殊的,所以如果采用fdisk和格式化命令,将会导致MBR改变,然后Magic Number也改变了,于是内核启动时就会报错,也有可能是/etc/nande中有一些配置信息,内核启动时会读取,格式化之后读取不了就会崩溃
崩溃时的启动信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/dev/nandd: clean, 57466/130304 files, 316309/524288 blocks
e2fsck 1.41.14 (22-Dec-2010)
/dev/nande: clean, 11/112224 files, 15906/448512 blocks
<6>EXT4-fs (nandd): mounted filesystem with ordered data mode. Opts: (null)
<6>EXT4-fs (nande): mounted filesystem with ordered data mode. Opts: (null)
switch_root: can't execute '/sbin/init': No such file or directory
<0>Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000100
[ 5.654144] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000100
[ 5.654154]
Backtrace: [ 5.664252] Backtrace:
[<c0012b5c>] (dump_backtrace+0x0/0x10c) from [<c05efd48>] (dump_stack+0x18/0x1c)
[ 5.674029] [<c0012b5c>] (dump_backtrace+0x0/0x10c) from [<c05efd48>] (dump_stack+0x18/0x1c)
r6:c097175c[ 5.683506] r6:c097175c r5:c097175c r5:c097175c r4:c09f93c0 r4:c09f93c0 r3:00000001 r3:00000001
[<c05efd30>] (dump_stack+0x0/0x1c) from [<c05f0124>] (panic+0x94/0x1d4)
[ 5.698880] [<c05efd30>] (dump_stack+0x0/0x1c) from [<c05f0124>] (panic+0x94/0x1d4)
[<c05f0090>] (panic+0x0/0x1d4) from [<c003b1e8>] (do_exit+0x6d4/0x7c4)
[ 5.712787] [<c05f0090>] (panic+0x0/0x1d4) from [<c003b1e8>] (do_exit+0x6d4/0x7c4)
r3:ef048000[ 5.721396] r3:ef048000 r2:00000000 r2:00000000 r1:00000100 r1:00000100 r0:c084c720 r0:c084c720
r7:ef03c000[ 5.731473] r7:ef03c000
[<c003ab14>] (do_exit+0x0/0x7c4) from [<c003b558>] (do_group_exit+0x50/0xb8)
[ 5.740973] [<c003ab14>] (do_exit+0x0/0x7c4) from [<c003b558>] (do_group_exit+0x50/0xb8)
r7:000000f8[ 5.750102] r7:000000f8
[<c003b508>] (do_group_exit+0x0/0xb8) from [<c003b5d8>] (__wake_up_parent+0x0/0x28)
[ 5.760208] [<c003b508>] (do_group_exit+0x0/0xb8) from [<c003b5d8>] (__wake_up_parent+0x0/0x28)
r7:000000f8[ 5.769944] r7:000000f8 r6:b6f3b774 r6:b6f3b774 r5:b6f3b774 r5:b6f3b774 r4:000708ee r4:000708ee
[<c003b5c0>] (sys_exit_group+0x0/0x18) from [<c000edc0>] (ret_fast_syscall+0x0/0x30)
[ 5.786445] [<c003b5c0>] (sys_exit_group+0x0/0x18) from [<c000edc0>] (ret_fast_syscall+0x0/0x30)
<2>CPU1: stopping
[ 5.796885] CPU1: stopping
Backtrace: [ 5.800553] Backtrace:
[<c0012b5c>] (dump_backtrace+0x0/0x10c) from [<c05efd48>] (dump_stack+0x18/0x1c)
[ 5.810317] [<c0012b5c>] (dump_backtrace+0x0/0x10c) from [<c05efd48>] (dump_stack+0x18/0x1c)
r6:c0954170[ 5.819794] r6:c0954170 r5:ef064000 r5:ef064000 r4:c09685f0 r4:c09685f0 r3:c0970194 r3:c0970194
[<c05efd30>] (dump_stack+0x0/0x1c) from [<c0014268>] (handle_IPI+0x194/0x1c8)
[ 5.835688] [<c05efd30>] (dump_stack+0x0/0x1c) from [<c0014268>] (handle_IPI+0x194/0x1c8)
[<c00140d4>] (handle_IPI+0x0/0x1c8) from [<c000853c>] (gic_handle_irq+0x58/0x60)
[ 5.850978] [<c00140d4>] (handle_IPI+0x0/0x1c8) from [<c000853c>] (gic_handle_irq+0x58/0x60)
[<c00084e4>] (gic_handle_irq+0x0/0x60) from [<c000e980>] (__irq_svc+0x40/0x70)
[ 5.866354] [<c00084e4>] (gic_handle_irq+0x0/0x60) from [<c000e980>] (__irq_svc+0x40/0x70)
Exception stack(0xef065f58 to 0xef065fa0)
[ 5.878346] Exception stack(0xef065f58 to 0xef065fa0)
5f40: ffffffed 00000001
[ 5.890249] 5f40: ffffffed 00000001
5f60: 0febd000 00000000 ef064000 ef064000 c09eac88 c05fba14 c096cb10 410fc074
[ 5.905278] 5f60: 0febd000 00000000 ef064000 ef064000 c09eac88 c05fba14 c096cb10 410fc074
5f80: ef064000 ef065fac ef065fb0 ef065fa0 c000f9c4 c000f9c8 60000013 ffffffff
[ 5.920307] 5f80: ef064000 ef065fac ef065fb0 ef065fa0 c000f9c4 c000f9c8 60000013 ffffffff
r6:ffffffff[ 5.929523] r6:ffffffff r5:60000013 r5:60000013 r4:c000f9c8 r4:c000f9c8 r3:c000f9c4 r3:c000f9c4
[<c000f998>] (default_idle+0x0/0x38) from [<c000fd64>] (cpu_idle+0xd8/0x11c)
[ 5.945330] [<c000f998>] (default_idle+0x0/0x38) from [<c000fd64>] (cpu_idle+0xd8/0x11c)
[<c000fc8c>] (cpu_idle+0x0/0x11c) from [<c05ece78>] (secondary_start_kernel+0xfc/0x11c)
[ 5.961143] [<c000fc8c>] (cpu_idle+0x0/0x11c) from [<c05ece78>] (secondary_start_kernel+0xfc/0x11c)
[<c05ecd7c>] (secondary_start_kernel+0x0/0x11c) from [<405ec814>] (0x405ec814)
[ 5.977126] [<c05ecd7c>] (secondary_start_kernel+0x0/0x11c) from [<405ec814>] (0x405ec814)
r6:10c0387d[ 5.986430] r6:10c0387d r5:00000015 r5:00000015 r4:6f05406a r4:6f05406a r3:c05ec7fc r3:c05ec7fc
<6>[hotplug]: cpu(0) try to kill cpu(1)
[ 5.999023] [hotplug]: cpu(0) try to kill cpu(1)
<3>[hotplug]: try to kill cpu:1 failed!
[ 7.007059] [hotplug]: try to kill cpu:1 failed!

CubieBoard-自动挂载TF卡和移动硬盘

fstab法:

先查看分区,确认TF卡和移动硬盘
cat /proc/partitions

然后编辑/etc/fstab
nano /etc/fstab

加入如下内容,其中/dev/mmcblk0p1为TF卡,/dev/sda1为移动硬盘的第一个分区,挂载到/media/TF和/media/DATA_PORT下,不需要先行建立/media/TF和/media/DATA_PORT文件夹,msdos适用于FAT系统,ntfs适用于NTFS系统,注意:这种系统要先安装ntfs-3g才行

1
2
/dev/mmcblk0p1     /media/TF msdos defaults   1    2
/dev/sda1          /media/DATA_PORT     ntfs  defaults 0 0

然后重启即可
reboot

下面得找个壳子了,用手摸板子出过两次事。当时也是自己好奇,摸摸芯片,看看温度如何。结果两次摸上去,mount的硬盘立即就没有了,不知道是不是手上有静电的原因。但立即又有了,但设备号已经从sda变成sdb。还好我在/etc/fstab中写的不是设备名,而是UUID值,这样mount -a就又全部找回来,直接mount上了,建议大家都使用UUID。侧面也说明这个板子设计还是不错的,没有死机,应该还是很稳定的。

如果出现装完NTFS-3G后硬盘无法挂载,总是报错:
FATAL:Module fuse not found.
fuse:devise not found,try ‘modprobe fuse’ first.

解决方法是先卸载掉FUSE,然后再重新装遍fuse和ntfs-3g

1
2
3
sudo apt-get remove fuse
sudo apt-get install fuse
sudo apt-get install ntfs-3g

自动挂载脚本法:

第一种是开机启动脚本:

创建shell脚本
#vi mount_tf.sh,内容如下(不包括引号)

1
2
#!/bin/sh
mount -t msdos /dev/mmcblk0p1 /mnt/usb/

保存后,添加执行权限,如下:
#chmod +x mount_tf.sh

随系统启动执行脚本
#vi /etc/rc.local
在近行尾的”exit 0”的上一行加入 mount_tf.sh文件所在的绝对路径即可。

重启系统后,用“df -h”查看是否自动挂载成功。

第二种是插上设备后自动挂载脚本:

#sudo nano /etc/udev/rules.d/10-usbstorage.rules
然后将以下脚本文件粘帖,保存退出无须重启系统即可实现。
Usb及Sata存储设备会自动挂载到/media目录下面,并且支持utf8格式文件名。

1
2
3
4
5
6
7
8
9
10
11
12
13
KERNEL!="sd*", GOTO="media_by_label_auto_mount_end"
SUBSYSTEM!="block",GOTO="media_by_label_auto_mount_end"
IMPORT{program}="/sbin/blkid -o udev -p %N"
ENV{ID_FS_TYPE}=="", GOTO="media_by_label_auto_mount_end"
ENV{ID_FS_LABEL}!="", ENV{dir_name}="%E{ID_FS_LABEL}"
ENV{ID_FS_LABEL}=="", ENV{dir_name}="Untitled-%k"
ACTION=="add", ENV{mount_options}="relatime,sync"
ACTION=="add", ENV{ID_FS_TYPE}=="vfat", ENV{mount_options}="iocharset=utf8,umask=000"
ACTION=="add", ENV{ID_FS_TYPE}=="ntfs", ENV{mount_options}="iocharset=utf8,umask=000"
ACTION=="add", RUN+="/bin/mkdir -p /media/%E{dir_name}", RUN+="/bin/mount -o $env{mount_options} /dev/%k /media/%E{dir_name}"
ACTION=="remove", ENV{dir_name}!="", RUN+="/bin/umount -l /media/%E{dir_name}", RUN+="/bin/rmdir /media/%E{dir_name}"
LABEL="media_by_label_auto_mount_end"

最好的做法:
/etc/fstab下加入TF卡的自动挂载
然后用第三种方法自动挂载移动硬盘

CubieBoard-固件烧写

固件烧写:先把串口线接上以显示调试信息,用putty接上板子串口,然后接上OTG转USB线的OTG接口那端,然后打开PhoenixSuit,选择固件镜像,然后按住OTG接口下的FEL按键不放,将OTG线的USB接口那端插入USB接口,保持FEL键不松手,等PhoenixSuit上显示烧写固件对话框问你是否要格式化时,点击“是”,然后继续保持FEL键不松手,看串口的输出情况,如下,直到看得到一定数目的调试信息时松开按住FEL键的手,固件就开始刷了。(之前试了多次都刷不成功,后来把所有的USB外设全拔掉,偶然用小Y右方的USB线来烧写,原来接的是USB HUB,终于成功了,估计是USB外设太多的原因,因为后来用左方的USB口也成功了)。

要注意的一点是:关于PhoenixSuit的安装,有一个google的驱动在win8 x64上安装不了。要关掉win8的驱动签名才行,具体参考:【分享】PhoenixSuit VPhoenixSuit V1.0.6 一键刷机工具 - 【台电平板电脑讨论区】 台电科技欢迎您!

注意:在 Windows 8 64Bit 操作系统,adb 驱动来自于 Google ,取消强制数字签名认证才能安装。操作步骤如下:win+I,选择最下方的更改电脑设置,常规——高级启动下的立即重启——疑难解答——高级选项——windows 启动设置——重启。重启的时候跳出选择界面,如果没有选择界面,请在重启时按 F8 进入选择界面。按数字“7”选择强制禁用驱动签名,然后正常安装驱动就行了。

烧写过程的串口信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
FES:
FES:Fes Ver: 098
FES:=================================================================================================
FES:=                                                                                               =
FES:=                                         EEMMMMMMLL                                            =
FES:=                                     ::MMMHOLIGANEE                                            =
FES:=                                   ::MM.                                                       =
FES:=                                   MMFF                                                        =
FES:=                                 FFMM                                                          =
FES:=                                MMMM                                                           =
FES:=                              ..MMFF                                                           =
FES:=                              EEMM.                                           FFMMMM           =
FES:=          . MMMMMMMM    MMMMMMMMMMMMMMMMMM      FFMMMMMM::      ::MMMM      BBMMMMFF           =
FES:=        ::MM  . MMMM          MMMM            MM.   MMMMMM    EE..EEMM::  EE::                 =
FES:=        MM      MMMM        ::MMLL          EEMM    MMMMFF  .       MMMM::::                   =
FES:=      MMMM    FFMMI         BBMM            MMI     MMMM            MMMMEE                     =
FES:=      MMMM  . MM::          MMMM          MMMM    BBMM              MMMM                       =
FES:=    BBMMFF::EE              MMMM          MMMM  MM::                BBMM..                     =
FES:=    MMMMEE                I MMI         I MMMM::                  ::FFMMFF                     =
FES:=    MMMM          LL      MMMM          EEMMMM        LL          BB  MMMM                     =
FES:=    MMMM      I MM        MMMM          MMMMMM      MM::        MM    MMMM                     =
FES:=    MMMMMMMMMMEE          MMMM          .GUANLI@HUANG.   BB    BB      FFMM.                   =
FES:=      MMMMMM..          I MMI             MMMMMMEE      MMMMMM          MMEE                   =
FES:=                        MMMM                                            MMMM                   =
FES:=                        MMMM                                            ::MM::                 =
FES:=                        MM                                                BBMM        MM       =
FES:=                      EEBB                                                  BBMM..  MMMM       =
FES:=                      MM                                                      ..EEMMFF         =
FES:=          MMMMMMMMMMMM                                                                         =
FES:=          MMMMMMMMI                                                                            =
FES:=                                                                                               =
FES:=================================================================================================
FES:INFO : ......1........
FES:INFO : ......2........
FES:INFO : ......3........
FES:INFO : ......5........
FES:INFO : ......6........
FES:INFO : ......7........
FES:INFO : ......8........
FES:INFO : ......9........
FES:CONFIG_USB_GADGET_DUALSPEED
FES:fes connect to host
FES:USB_MOV_DATA_BY_DMA!
FES:INFO : ......10.......
FES:jump to fes_main
FES:INFO: fes_protocol_process start
FES:[info]: set address 5
FES:write special pipe
FES:INFO: fed reg_addr = 0x4011f714
FES:fed para[0] = 0x40a00000
FES:fed para[1] = 0x40a01000
FES:fed para[2] = 0x00000000
FES:fed para[3] = 0x00000000
[Fed]:-------------------------------------------------
[Fed]:                Hello, Nand Register
[Fed]:-------------------------------------------------
[Fed]:"private" part NOT configured.
NHW : start nand scan
[NAND] nand driver(b) version: 0x2, 0x12, data: 20130325
NFC Randomizer start.
[SCAN_DBG] Nand flash chip id is:0xec 0xd7 0x94 0x7a 0x54 0x43
[SCAN_DBG] ==============Nand Architecture Parameter==============
[SCAN_DBG]    Nand Chip ID:         0x7a94d7ec 0xffffffff
[SCAN_DBG]    Nand Chip Count:      0x1
[SCAN_DBG]    Nand Chip Connect:    0x1
[SCAN_DBG]    Nand Rb Connect Mode:      0x1
[SCAN_DBG]    Sector Count Of Page: 0x10
[SCAN_DBG]    Page Count Of Block:  0x80
[SCAN_DBG]    Block Count Of Die:   0x1000
[SCAN_DBG]    Plane Count Of Die:   0x2
[SCAN_DBG]    Die Count Of Chip:    0x1
[SCAN_DBG]    Bank Count Of Chip:   0x1
[SCAN_DBG]    Optional Operation:   0x11088
[SCAN_DBG]    Access Frequence:     0x1e
[SCAN_DBG]    ECC Mode:             0x3
[SCAN_DBG]    Read Retry Type:      0x0
[SCAN_DBG]    DDR Type:             0x0
[SCAN_DBG] =======================================================
[SCAN_DBG] ==============Optional Operaion Parameter==============
[SCAN_DBG]    MultiPlaneReadCmd:      0x60, 0x60
[SCAN_DBG]    MultiPlaneWriteCmd:     0x11, 0x81
[SCAN_DBG]    MultiPlaneCopyReadCmd:  0x60, 0x60, 0x35
[SCAN_DBG]    MultiPlaneCopyWriteCmd: 0x85, 0x11, 0x81
[SCAN_DBG]    MultiPlaneStatusCmd:    0x70
[SCAN_DBG]    InterBnk0StatusCmd:     0xf1
[SCAN_DBG]    InterBnk1StatusCmd:     0xf2
[SCAN_DBG]    BadBlockFlagPosition:   0x2
[SCAN_DBG]    MultiPlaneBlockOffset:  0x1
[SCAN_DBG] =======================================================
NHW : nand hw scan ok
check nand version start.
Current nand driver version is 0x000000ff 0x00000000 0x00000002 0x00000012
Succeed in getting flash info.
Media version is valid in block 0, version info is 0x000000ff 0x00000000 0x00000002 0x00000012
nand driver version match ok in block 0.
VersionCheck end.
[Fed]:To erase boot0 blocks.
Ready to erase boot blocks.
has cleared the boot blocks.
[Fed]:L322,To erase nand.
Ready to erase chip.
nfb phy init ok.
Succeed in getting flash info.
page size:0x00002000, oob_size: 0x00000020, block size: 0x00000080, bad block position: 0x00000002.
chip_cnt = 0x00000001, chip_connect = 0x00000001, rb_cnt = 0x00000001,  rb_connect = 0x00000001,  good_block_ratio =0x000003b0
erase chip 0
[Fet]:find a bad block 16
[Fet]:find a bad block 17
[Fet]:find a bad block 4094
[Fet]:find a bad block 4095
has cleared the chip.
the nand is OK.
Ready to scan bad blocks.
nfb phy init ok.
Succeed in getting flash info.
scan CE 0
find defined bad block in chip 0, block 4.
find defined bad block in chip 0, block 5.
find defined bad block in chip 0, block 16.
find defined bad block in chip 0, block 17.
find defined bad block in chip 0, block 4094.
find defined bad block in chip 0, block 4095.
6 bad blocks in CE 0
cal bad block num is 12
cal good block num is 971
good block ratio is 944
[Fed]:get the good blk ratio after hwscan : 944
_RepairLogBlkTbl start
_RepairLogBlkTbl end
get mbr error
[Fed]:erase=1, hasPrivatePart=0.
[Fed]:nand logic size [0x00000000, 0x00760000]Sec.
[Fed]:-------------------------------------------------
[Fed]:               Byebye, Nand Register.
[Fed]:-------------------------------------------------
FES:INFO : run addr = 0x00000000 , type = 1437204482
FES:---------------------------------------------------
FES:fes_crc   = 0x00000000
FES:media_crc = 0x50753e48
FES:---------------------------------------------------
FES:---------------------------------------------------
FES:fes_crc   = 0x00000000
FES:media_crc = 0xc51b63f7
FES:---------------------------------------------------
FES:---------------------------------------------------
FES:fes_crc   = 0x00000000
FES:media_crc = 0xdab00f3b
FES:---------------------------------------------------

软件设计的一些感想

已经好久没有写博客了,不是因为没有学东西,而是因为学的东西不够系统,不够具体,没有整理起来(外加人懒),所以不想浪费笔墨。所以一直潜水。。但总会有感想的,在学习的过程中,时常会遇到一些令人惊喜的东西,令人拍案叫绝的东西,但学会之后觉得简单或者不值一提,于是没有当机立断写出一些洞见。事后用的时候倒觉得理所当然了。其实这是要不得的,学习的过程我认为不应该是纯粹的吸收,而是要有选择的过滤,留其精华,去其糟粕,如果能加入自己的总结就更好了,只可惜我在很多时候忘记了这事儿,或者在很多时候没有空下来专门做一次如此认真的总结。但在技术的层面上,一般的说法是,任何一种技术都是基于某种设计思想,而至于用什么来具体实现并不是最重要的。其实思想和设计不能用简单的一对一和一对多关系来说明。经常会有人说一种思想可以衍生多种技术,其实他只说对了一半,因为一种技术并不只是一种思想的实现,而是多种思想的交融。

拿软件设计来说,对于基于窗口的程序设计,我们有多种技术方案可以选择,在windows下有mfc,.net, wpf,在linux下有gtk, qt, wxWidgets,在mac下有cocoa, 但核心思想差不多,大多用到了mvc思想,但mvc思想本身也是一个组合思想,它组合了策略模式,观察者模式等。对于这样的一个设计思想来说,它其实是一个对设计的高度抽象。我甚至可以做这样一个奇怪的思考:如果将mvc模式套用到人身上,那么人所看到的就是view,人所想到的就是controller,人所使用的便是model了,那么针对一个人来说,他的基本动作可能如下:看到东西->产生需求->寻找工具来实现自己的需求。所以我感觉,软件设计有时更像对人的行为模拟,软件系统更像是一个虚拟的人(这个人的智商要看你给他多少知识和能力),或者说,软件设计归根到底是以人的认知来实现的,所以我们要划分模块,要理清各个模块之间的关系,要考虑它们之间的相互影响,还要考虑他们之间的交互。如果各个模块之间关系混乱不清,那么你将会的到一个很烂的系统,置于会出现什么结果,那就不得而知了。举个简单的例子:试想一下如果你吃饭咬到舌头了,却发现屁股痛,这是一件多么尴尬的事情。

所以,软件的设计实际上是一个很复杂的事情,一个高超的软件更为复杂,因为你要考虑太多的情况,一个人是极其复杂的。但正如所有的物质都是由简单的原子组成的,所有的复杂性都能划分成最简单最基本的东西。就好比操作系统这样一个常人很难企及的东西,其实最底层也就六个操作,引用linux创始人linus的话来说就是:“你在UNIX上完成的大部分任务都是通过六个基本操作完成的,它们被称作”系统呼叫”(system call)。第一个基本操作是”创建子进程”(fork),一个程序把自身完全复制出来,这样你就有了两个相同的拷贝。第二个基本操作是复制出来的程序,再用一个新项目替换自己。其他四个基本系统呼叫—打开、关闭、读和写—都是为了访问文件的。这六个系统呼叫便组成了UNIX的简单操作。然后,你只需在程序之间创造出交流渠道(pipes),就能解决复杂的问题。”,那么归结到人身上,也就是那么几种:活动(身体活动和思维活动),新陈代谢,睡觉(纯属个人想法勿喷)。

记得以前看bbc的纪录片《混沌理论》中讲到图灵的一段,图灵曾经提出一个伟大的构想:自然界由一个最简单的数学公式组成。这个理论促进了后来的“混沌理论”和“分形学”的研究和发展,包括著名的“蝴蝶效应”,也和“混沌理论”有关。我们都知道,图灵被称为“计算机之父”,而现代的软件设计方法和这种构想肯定存在千丝万缕的联系。所以,我认为,软件设计如果是一种把问题搞复杂的设计,那将是一个失败的设计。软件设计应该是将一个复杂的系统一步一步划分成“原子”的过程,而软件架构的目标应该是使每一个分块都容易理解而且容易改变(所谓的可维护性和可扩展性)。

而对于人来说,人生活在一个“实体”的世界里,如果把人类的历史看作一天,那么人拥有真正的思想是在一分钟以前,所以上帝无法阻止人类用“面向对象”的方式来进行软件设计,也无法阻止程序员用mvc的思想来实现一个软件系统,因为这一切看起来理所当然。所以,无论你的技术多么高超,我都可以想象你在面对一堆复杂的算法和一堆鲜活的对象的时候的不同感受,因为我也可以感同身受:)。所有的人都喜欢用简单的方式解决问题(如果你不是,那你也许是公务员,:)),更喜欢用简单的方式解决复杂的问题,那样会有成就感,程序员是最佳案例。为什么说一个会偷懒的程序员是一个好的程序员?那是因为程序员的偷懒是对问题的抽象和扩展,对之前冗长而繁琐的解决问题的方式建立一个更为宽泛的适用模型,从而应对类似重复的问题。而所谓的抽象,便是思维的结晶。其实,抽象在各行各业都有应用,只不过在软件开发领域,这个词被提及的非常之广范非常之响亮,以至于成了某些编程语言的关键字。其实抽象是一个很宽泛的概念,它是一种对事物本质的提取过程(《数据结构》中有这样的定义),所以我觉得在软件设计中的抽象,可以运用到其他领域,在其他领域中的抽象,也能应用到软件设计中来。所以,没必要惊讶图灵是个数学家,或者唐纳德也是数学家…,因为从本质上来说,数学这门科学就是一种抽象科学,把自然界抽象成数学模型,而计算机就是对数学抽象模型的模拟器。

胡说了一大堆,也不知从哪儿来的灵感,但作为一个软件工程师,我觉得这些东西是应该而且值得去思考的。上次看到一则博文讲到,这个世界由三种人推动:科学家,艺术家,工程师。也许这种说法并不一定正确,但至少说明了一个观点:工程师想要实现优秀的产品,必须懂得科学家和艺术家的抽象,因为那是他们的思维结晶。而一个好的工程师,从某种程度来说,也是一个科学家或者一个艺术家

多系统安装实录

对于win8,ubuntu13.04和osx10.8在小Y上的安装着实费了我好一顿功夫,最难装的当属osx了,为了它,害得我格掉两块硬盘,他喵的,还好好多重要资料存在移动硬盘上,否则真得恶心死。还是描述一下吧,做一个纪念,主要是一些遇到的问题:

首先讲一下当时我格掉两块硬盘的终极无语的神操作吧。这当然是发生在装osx的时候啦。装osx的时候,打开磁盘实用工具进行抹盘操作时,发现点击想要抹去的盘的时候,提示无法识别,是否修复,结果一修复,真的一下就修复了两块硬盘,所有的分区全部丢失,每个硬盘被生生的变成3个分区。这个惨痛的教训切记不要再犯!真准备放弃osx的安装,不过后来探索了和再次尝试了一下,总算发现问题所在。原因是,用硬盘分区助手做的osx的安装盘引导分区和osx最终安装的分区必须在同一个硬盘上,否则就会出现这个情况,因为当时将osx的安装盘放在了移动硬盘的分区上,结果能识别移动硬盘的分区,就是识别不了其他硬盘的分区,你一点就会提示修复。所以,安装osx的时候必须在将要安装osx的分区的同一块硬盘的另一个分区上制作安装盘。

再说一下osx的安装,参考了这两篇文章:http://bbs.pcbeta.com/viewthread-948500-1-1.htmlhttp://bbs.pcbeta.com/forum.php?mod=viewthread&tid=1324568,大致分为几个步骤:

1. 制作osx安装盘以及安装盘引导分区

使用原生osx安装盘做系统安装盘的话,需要替换内核和放入可引导驱动,另外,还要把某个符号链接替换成链接指向的文件夹。首先将元安装盘中的可引导的安装盘提取出来之后,用硬盘分区助手写入到一个硬盘分区中(切记,一定要和osx将要安装的分区处于同一硬盘上),然后将硬盘扩容,将内核放到根目录下,将驱动放到Extra目录下以便变色龙加载从而引导osx,再替换一些文件即可。具体操作如下:

a) 分区。

在同一块硬盘上分两个区,一个用来做osx安装引导分区,一个用来安装osx,关于硬盘扩容,必须使用Paragon PartitionManager 11以上版本,其他类似软件都TM是扯淡的,对hfs+分区不支持。但这货和win8又不兼容,草,所以最好在xp上进行。分区要注意的是,将用于osx安装的分区的前半部分先分个2G用于硬盘安装助手写入安装盘(2G以上都可以,因为2G就足够用了,我分了5G),剩余空间不分配,但要让它是未格式化的,否则会导致后面的扩容失败。至于osx将要安装的分区可以弄成未格式化的或者格式化为ntfs分区都可以。

b)osx安装盘制作。

要用到这三个玩意儿:

  1. HD_Install_Helper,硬盘安装助手,用来将镜像写到分区的东东
  2. HFSexplorer,用来打开osx安装光盘的dmg映像提取文件,以及生成可供硬盘安装助手写入分区的硬盘镜像文件
  3. MacDriver或Paragon_HFS__for_Windows,用以在windows下替换osx分区文件,主要是驱动。

做法是:

  1. 用7-Zip打开原版Lion 10.7.2 DMG文件(下载我提供的原版lion安装文件,文件名为Mac OS X Install DVD.dmg),进入\Mac OS X InstallDVD.dmg\InstallMacOSX.pkg\目录找到InstallESD.dmg点击“提取”,提取出来。得到我们要用的的第一个文件:InstallESD.dmg
  2. 用hfsexplorer打开我们上一步得到的InstallESD.dmg,提取 mach_kernal 和BaseSystem.dmg 和Package文件夹。
  3. 至此我们一共得到四个文件InstallESD.dmg 和mach_kernal 和BaseSystem.dmg 和Package文件夹。下面同样用hfsexplorer打开BaseSystem.dmg之后,点击Tools—creat disk image,以BaseSystem hfs.dmg名字保存。
  4. 至此我们得到了我们所需的全部文件包括InstallESD.dmg 和mach_kernal 和BaseSystem.dmg 和Package文件夹和BaseSystem hfs.dmg
    注意事项:ubuntu安装时选择自定义安装,然后在某个分区上安装,不要swap,但引导一定要选择到对应的那块分区上,千万别选整个硬盘,因为这将覆盖活动分区的引导,而且因为是grub,所以无法正常引导OSX。