Install Qt5.2.0 to Mac

在 Macbook Air 上安装 Qt5.2.0

从前 MBA 上安装的是 Qt4.7.4,今天下载了 5.2.0 版本,结果安装的过程竟然出了一些问题。

首先是安装过程出错,出错信息是

Command install_name_tool failed

一共出现两次,分别对应于一个 QtQuickMultimedia 和一个 QtBluetooth 的库,考虑到这两个部分可能不会用到,我选择了 Ignore 继续安装。

安装之后看起来都正常,结果 qmake 竟然也失败,说找不到 macx-clang 配置文件。使用

$ qmake -query

查询一下,发现 Qt 所默认的路径都是 /usr/local,和安装的路径选择不一致。于是在 /usr/local 下面建立了一个对于我安装目录的符号链接,具体的链接为

Qt-5.2.0 -> /Users/myuser/Qt5.2.0/5.2.0/clang_64/

Hands on mbed LPC1768

ARM 公司赠送的 mbed 开发板放在我的桌子上已经很长时间了,今天准备试试看

下载第一个程序

打开开发板的包装就可以看到一个只有 DIP40 大小的开发板,板上有一个 MiniUSB 的插头,显然这就是它的编程接口。可当我将开发板接上 USB 电缆,系统识别出来的竟然是一个 USB 存储器,这倒是一个不小的意外。通过打开存储器里面的 MBED.HTM 文件,就可以登录到 mbed 项目的官方网站,注册一个用户就可以使用在线工具编程开发了。

简单来说,使用 mbed 开发主要有三个步骤:

  1. 通过 USB 电缆连接开发板
  2. 使用在线开发环境进行编程,并最终生成二进制文件
  3. 将二进制文件放到 USB 存储器,按下板上复位按钮运行

mbed 的优点

mbed 的这种开发方式还是很新颖的,只用了几分钟的时间我就已经把第一个程序运行起来了。而作为用户,不用了解 ARM 芯片的任何知识,也不用了解编译器的相关概念,甚至在自己电脑上都不用安装任何新软件。所有的开发都可以通过浏览器完成,所有硬件的细节都被抽象成了用户 API,非常适合刚刚接触嵌入式的人士使用。

个人认为 mbed 比较适合高中生或者业余非专业人员使用,而对于专业嵌入式开发者可能会觉得它隐藏了太多的细节,更像一个玩具而不是一个开发工具。或者换句话说,专业人士如果使用 mbed,有一天碰见了一个高中生,那个高中生说:“我用的也是这个”,这或多或少会让专业人士少了些神秘感,甚至感觉有点“丢份”。就像一个 Linux Hack,要么只用 terminal,要么就使用一个平铺的窗口管理器,总之必须满屏幕是字符才会让他觉得有真正黑客的自尊。

不过 mbed 还是非常适合快速开发的。如果有一个项目工期很紧,使用 mbed 也不失好的选择。

离线开发

在线开发方式也不讨好专业人士,好在网站提供了离线的开发方法。在项目的右击菜单中有 Export Program 的选项,可以导出为 Keil,DS-5,GCC,IAR 等多种开发平台的工程,其中也包含 mbed 的链接库。因此即使使用离线开发工具,依然也可以使用 mbed 提供的 API,方便用户的开发。

离线的方式使用户可以继续使用熟悉的开发工具,而且同样可以把生成的二进制映像拷贝到 mbed 的存储器中,“自动”下载程序到处理器。

也就是说 mbed 所使用的二进制文件并没有特别的地方,那它的存储器是如何实现的呢?当它运行了我的用户程序后,存储器功能是否还存在呢?其实在 LPC1768 板子的背面还可以看到很多芯片,存储器的功能就是它们实现的。每次用户按下复位按钮的时候,这部分硬件就会把存储器里面的二进制程序通过 LPC1768 的 ISP 模式下载到芯片里面去。所以存储器的这部分功能一直是存在的,也并不是 LPC1768 这个芯片所实现。

最后要提一句的是这个板子在用了一段时间后竟然是温温的,难道主频 96M 有些高?这是我第一次使用唯一一个不太满意的地方。

Integer promotion in C

虽然使用 C 语言已经很长时间了,但对于一些 C 语言的细节一直没有特别的注意,这次就遇到了在表达式中整型精度提升的问题。

问题描述

问题的发现是在一个 C51 的单片机程序中。相关的代码如下:

P4 = ~P4 >> 4;

本来很简单的一个语句,但在 sdcc 下面编译运行后却得到了令我意外的结果。我马上又使用 Keil C 进行了测试,结果就符合我的预期。那么它们的区别到底是什么呢?假如 P4 == 0x0F,那么对于 sdcc 结果是 0xFF,对于 Keil C 的结果是 0x0F,而后者是我想要的。通过对比二者生成的汇编代码,发现 sdcc 的汇编代码很长(20行),而 Keil C 的代码只有 4 行(预料之中),我根本没有仔细分析一下 sdcc 的代码就直接到它们的网站上去提交了一份 bug report。事实证明我有些太草率了。

问题分析

通过这篇文章的标题就可以知道问题的本质是什么,如果我仔细看一下 sdcc 生成的汇编代码,或者哪怕到 sdcc 的论坛上浏览一下:上个月就有个家伙问过类似的问题(虽然是从另外的方面),并得到了很好的解释。很快我的邮箱里面也收到了 Maarten Brock 的回复:

I see nothing wrong here. C integer promotion rules require the P4 value to be upcast to an int and then have its bits inverted. And after that the resulting int is shifted down. Didn't you get a warning about the ~ operator having strange effects on operands smaller than int?

To get what you probably expected, you should either cast the ~P4 value back to unsigned char or assign it to an intermediate unsigned char variable and shift that down in a second operation.

可惜当时我仍然没有立刻领会了这段话的含义,又经过了几次实验才最终搞清楚。在进行 ~P4 » 4 这个运算的时候,由于第一个取反之后还要进行其它的运算,所以必须在运算前提高 P4 的精度,对于前面的实例,P4 的值将在运算前变成 int 类型,在 C51 的环境中就是 0x000F,然后取反再右移就得到了 0xFFFF(包含符号位扩展),重新赋值给 P4 才使得它最终成为 0xFF。而这种行为是符合 C 语言的标准的,也就是说 Keil C 的行为不符合标准。

没过几天,我正好翻看 Linden 的 Expert C Programming,结果也看到了对 integer promotion 的分析,看来我的 C 语言知识还需要再补充一些。BTW,Linden 的这本书真的是非常的精彩,信息量很大,而且讲述也很有趣,非常推荐大家阅读。

Hello Hyde

第一次尝试使用比较流行的静态网页生成工具,记录一下基本操作过程和感受。

安装

安装 hyde 还是比较容易的,首先安装 pip,好像大部分 python 用户都喜欢用这个安装工具:

# apt-get install python-pip

之后安装 hyde 就比较简单了,直接 $ pip install hyde 就可以,而且也会自动解决依赖关系。

配置

建立一个新的项目可以直接用下面的命令:

$ hyde -s myhyde create

这会使用缺省的 layout 布局页面,myhyde 就是项目的目录,里面的内容就已经是一个完整的网站源码了,之后只要在 myhyde 目录执行 $ hyde serve 就可以在 localhost:8080 上看到网站的效果了。

对网站的配置实际上就是对这个示例代码的阅读、理解和修改的过程。逐步修改配置文件 site.yaml,页面布局脚本 layout/*.j2,和最终 content 目录中的 html 文件,以使网站代码符合我的应用。我把整个过程都通过 git 版本控制系统记录了下来,成为另外一个学习笔记。

页面布局脚本是 Jinja 模板,它的网站上有详细的文档可以参考。Hyde的主页上也包含了很多有价值的配置文档。有关 Markdown 的语法结构,可以参考这个

问题

目前虽然网站已经可以上线,但还是有一些问题没有解决:

  1. css 还要继续学习,一些样式还需要调整。

  2. 代码列表和行内代码没有很好的区分,好像还需要额外的过滤器。 (Edit: 增加 Markdown 的 codehilite 扩展,就可以比较好的区分代码列表和行内代码了。)

SSH reverse tunnel

访问 NAT 内部的服务器

A 处的计算机都在防火墙的后面,IP 地址是如 10.88.32.x 的非法 IP,我在 B 处就无法访问它们。为了可以远程登录 A 处的主机,就要使用 SSH 的反向隧道功能。

首先是在A处的计算机上执行

$ ssh -N -R 10002:localhost:22 [email protected]

只要保证这条命令一直执行,就可以在 B 处的电脑上打开 10002 这样一个反向隧道,之后只要在 B 处使用

$ ssh my_a_user@localhost -p 10002

就可以连接 A 处的电脑上了。其中 my_a_user 是 A 处电脑的用户名。而我主机上的 myuser 用户还可以没有合法的登录终端,这样也很安全,万一 B 处电脑重启什么的,还可以让别人帮我运行这个命令,不用担心告诉他们密码了。

如果希望从别的主机也可以连接 B 电脑的对应端口,还需要修改 sshd 的配置选项:GatewayPorts 为 yes。