PT's Blog

嗷嗷嗷嗷嗷嗷嗷嗷

首先埋汰一下Ubuntu自带的gnuradio版本,就算是在最新的测试版11.10上,gnuradio的版本也还是3.2.0,太旧了,以至于无法兼容USRP上的WBX之类的射频子板,运行时会出现如下错误:

Warning: Treating daughterboard with invalid EEPROM contents as if it
were a “Basic Tx.”
Warning: This is almost certainly wrong… Use appropriate
burn-*-eeprom utility.出现这个错误的根源是因为gnuradio 3.2.0版本中射频子板数据库中并没有WBX子板的ID(这个值是存储在各块子板的eeprom中),解决的方法是更新到3.3.0版,或者直接从git源中安装gnuradio和uhd。通过Google,找到了一个安装脚本:
Build script for UHD+GnuRadio on Fedora and Ubuntu感谢原作者Marcus Leech,不过这个脚本存在一些问题,里面在对很多重要命令的执行结果进行判断的时候使用的是“grep前一个命令的输出”这样的方式,所以当这个脚本运行在非英语locale的系统上时,会出现相当多的误判。我把这些检查方式换成了判断前一个命令结果的返回值,应该能够适用于各种locale设置的Fedora、Ubuntu系统,修改后的版本在这里:gnuradio_build(放在Google doc上了),改动如下:

53,54c53,54
<     which $1 >tmp$$ 2>&1
<     if grep -q no.${1}.in tmp$$
---
>     which $1
>     if [ $? -ne 0 ]
59d58
<         rm -f tmp$$
68d66
<         rm -f tmp$$
72d69
<     rm -f tmp$$
80c77
<         if grep -q "No such" tmp$$
---
>         if [ $? -ne 0 ]
162c159
<         sudo apt-get remove 'gnuradio-*' >/dev/null 2>&1
---
>         sudo apt-get -y remove 'gnuradio-*' >/dev/null 2>&1
214c211,218
<         sudo apt-get -y install $PKGLIST >prereq.log 2>&1
---
>         sudo apt-get -y install $PKGLIST  2>&1 | tee prereq.log
>         if [ $? -ne 0 ]
>         then
>             echo Error occured during installing build dependency of gnuradio
>             echo Please check your network setting and look prereq.log for details.
>             more prereq.log
>             exit
>         fi
274c278
<     if [ ! -d gnuradio/gnuradio-core ]
---
>     if [ $? -ne 0 ]
287c291
<     if [ ! -d uhd/host ]
---
>     if [ $? -ne 0 ]

如果希望在使用Vim编辑python源码的时候能够获得自动补全功能,你并不需要安装第三方插件,从Vim 7开始,自带的’omnifunc’既可以提供这一利器。步骤:

  1. 确认你的Vim编译的时候包含了 +eval+insert_expandpython
    当然如何确定自己机器上的Vim已经在编译时打开这三个选项了呢?在命令行模式输入:version后回车即可。但是对于+python的确定要稍微麻烦一些,光看到+python还不够,应该在命令行中执行一条python语句确认一下:py print "hentai",假如执行之后没有报错,没有崩溃,并且最下一栏显示了hentai,那么恭喜你,+python特性是没有问题的;如果报错、崩溃(从Vim中退出之类的),那么可能你遇到了如下的问题(这种情况下你很可能是用的Windows,用有包管理工具的Linux很难遇到这类问题):
    a. python版本不兼容,这种情况是+python/dyn引发的,也就是说Vim中对python特性的支持是靠动态链接系统中python动态链接库来实现的,比如我装的Vim 7.3要求python 2.7.dll。不想重编译Vim的话就换匹配的python吧(这个可以在执行:py print "hentai"时看到提示的)
    b. 假如你用的是64bit的Windows系统,然后用了32bit的Vim,再用了64bit的python,肯定会出问题,解决的方法比较简单把Vim换成64bit版本吧
    c. Vim编译进了+python/dyn+python3/dyn两个选项也可能(注意:这里是可能,我只是搜索的时候看到有人提过)导致问题(官方的安装包就是这样的),重编译Vim,关掉一个选项(关掉哪个要看你系统没装哪个)

  2. 在.vimrc(用Linux的话)或者_vimrc(用Windows的话)中加入以下设置

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" For editing python
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
filetype plugin indent on
set completeopt+=longest
set completeopt+=menu
set wildmenu
autocmd FileType python set omnifunc=pythoncomplete#Complete
> 如果发现补全完毕之后提示窗口没有自动关闭,就加上下面这两行(从stackoverflow上看到的):
" If you prefer the Omni-Completion tip window to close when a selection is
" made, these lines close it on movement in insert mode or when leaving
" insert mode
autocmd CursorMovedI * if pumvisible() == 0|pclose|endif
autocmd InsertLeave * if pumvisible() == 0|pclose|endif
到这里就大功告成了,补全的按键组合是`Ctrl-X Ctrl-O`,只要系统中安装好的python库都能补全,效果如下(左侧边栏靠的taglist实现):
[![](/img/omni_small.png)](/img/omni.png)

在ubuntu下使用highlight软件可以非常简单的高亮目标代码:

  • 安装highlight:sudo apt-get install highlight
  • 假如你有一个名叫hello.c的源文件,想要在一个tex文档中高亮显示它:
    1. highlight -T -i hello.c -o hello.tex
    2. hello.c所在路径下,将出现两个文件:hello.texhighlight.sty
    3. highlight.sty拷贝到你的tex源文件所在路径,在你的tex源文件的导言部分(Preamble)加入:\input {highlight.sty},并把hello.tex中所有内容全部插入到tex文档中需要显示高亮代码的位置。

以上就是全部的步骤,下面是效果图:

[![](/img/frame_small.png)](/img/frame.png)

顾名思义,这个软件是用来对源代码高亮处理的。以前用的是source-highlight这个GNU的正室,其它都挺好,就是支持的格式少了点,连verilog都不支持。然后发现了highlight这款软件,相见恨晚,操作与source-highlight相近,支持的语言和输出格式都要多得多。

不说话,直接上效果:
`timescale      1ns/1ps  ////////////////////////////////////////////////////////////////////////////////  //      Description     -        qpsk_map:      2 bit --> complex number  //      Author  -                PT  //      Date    -                5月 21 2009  //////////////////////////////////////////////////////////////////////////////// 

module  qpsk_map(data_in, I_out, Q_out); 
        parameter       NUM_WIDTH       = 14; 
        parameter       POS_NUM         = 14’b00001011011010; 
        parameter       NEG_NUM         = 14’b11110100100110; 

        // input port
        // MSB  = data_in[0]
        // LSB  = data_in[1]
        input   [1:0]   data_in;

        // output port 
        output  [NUM_WIDTH-1:0] I_out; 
        output  [NUM_WIDTH-1:0] Q_out; 

    assign  I_out   = (data_in[1] == 1’b0) ? NEG_NUM : 
                      (data_in[1] == 1’b1) ? POS_NUM : 
                      14’b00000000000000; 

    assign  Q_out   = (data_in[0] == 1’b0) ? NEG_NUM : 
                      (data_in[0] == 1’b1) ? POS_NUM : 
                      14’b00000000000000; 
endmodule 

软件支持的输出格式有: Output formats         -H, --html                generate HTML file (default)         -A, --ansi                generate terminal output (16 colours)         -L, --latex                generate LaTeX file         -M, --xterm256                generate terminal output (256 colours)         -R, --rtf                generate RTF file         -T, --tex                generate TeX file         -X, --xhtml                generate XHTML 1.1 file         -Z, --xml                generate XML file         -G, --svg                generate SVG file (experimental)
输出的格式十分丰富,而且还有tex,事实上,我就是用这个东西来给我的tex文档插各种高亮代码的,下一篇post介绍如何往beamer中插高亮的代码。
补充一句,这个软件和``source-highlight''一样,我用的都是Linux版本的,不知道有没有Windows版本。

在Windows 7下,我是这么设置的(以下代码写在导言区):

\usepackage{xeCJK}
\setCJKmainfont[Mapping=tex-text]{Microsoft YaHei}
\setCJKmonofont[Mapping=tex-text]{SimSun}
\setmainfont[Mapping=tex-text]{TeX Gyre Pagella}
\setmonofont[Mapping=tex-text]{Courier New}
\setsansfont[Mapping=tex-text]{Trebuchet MS}
需要说明的是:
  • 假如你不喜欢这个字体配置或者你的操作系统里面么没有以上字体的话,改掉``{}’’中的字体就可以了;
  • 双引号的问题,xelatex编译beamer时不会将''自动转换为“”,这个让人很不适应,所以使用[Mapping=tex-text]‘’改回来。再来说字体大小,xelatex编译beamer的时候,里面的一些元素的字体大小十分O疼,比如图片的标题(caption)字体大小默认很大(生怕后排的人看不见…),如果你的页面需要混排公式和图片的话,这个就是一个灾难。

那么就手工改小吧,不过曾经在网上搜索到的一些方法已经失效了,没法偷懒找现成的方案就只能自己去翻《beamer user guide》,在18.3.3&nbsp;Setting Beamer’s Fonts''部分有说明,大意是可以用\setbeamerfont*{beamer-font name}{attributes}’’来设置beamer中各种元素的字体属性。以下是我的例子(同样需要添加在导言区):

\setbeamertemplate{caption}[numbered]
\setbeamerfont{caption}{size=\footnotesize}
\setbeamerfont{captionname}{size=\footnotesize}
  1. 第一行给图片标题加了编号;
  2. 第二、三行把caption''和captionname’’的字体大小改成了``\footnotesize‘’;
  3. 还可以改其它的字体属性,具体请参考用户手册。
    不过这个时候就有一个大问题,我怎么知道beamer中到底有哪些元素?很遗憾,我在《beamer user guide》中没有找到相应的描述,难道要去翻源代码不成?好在我找到了一个网页:
    里面列了一个很详细的表格,其中element那一项应该就是各种元素的名字,总之上面的caption''和captionname’’都是这么找到的…

缘由

在使用beamer制作Presentation的幻灯片页面中,导航按钮(官方名称是:navigation symbols)是非常重要的一个页面元素,在默认的情况下,每一页幻灯片都会有这些按钮:

[![](/img/frame_page_small.png)](/img/frame_page.png)
上图中各个按钮解释如下(摘自beamer user guide --> 8.2.4 The Navigation Symbols):
  1. A slide icon,点击中间的方框将弹出一个对话框,询问你想要跳转到文档的第几页,点击方框的左右两边的箭头将跳转到前一页或者后一页幻灯片;
  2. A frame icon,点击左侧箭头将跳转到当前frame的第一页幻灯片,点击右侧箭头将跳转到当前frame的最后一页幻灯片,当同一个frame中有多页幻灯片的时候(比如使用了``\pause’’之类的Overlay手段),这连个按钮是很有用的;
  3.  A subsection icon,点击左侧箭头将跳转到当前subsection的第一页幻灯片,点击右侧箭头将跳转到当前subsection的最后一页幻灯片;
  4. A section icon,点击左侧箭头将跳转到当前section的第一页幻灯片,点击右侧箭头将跳转到当前section的最后一页幻灯片;
  5. A presentation icon,点击左侧图标将跳转到第一页幻灯片,点击右侧图标将跳转到的最后一页(不包含附录)幻灯片;
  6. 左侧类似撤销箭头一般的图标表示跳转到刚刚播放过的幻灯片页面,右侧按钮效果类似,点击中间查找模样的图标,将弹出对话框(或者在屏幕上方显示工具栏),可以在其中输入关键词进行全文查找。

注意,在一些pdf浏览器中,这些按钮的部分或者全部功能是得不到支持的,比如sumatraPDF,所以在做Presentation的时候最好使用okular或者adobe reader。

正如标题中所暗示到的,使用xelatex编译的beamer的时候,这个导航按钮会失效,具体原因可以参考这个帖子:

[[幻灯片] 解决beamer在XeLaTeX中导航条按钮失效问题](http://bbs.ctex.org/forum.php?mod=viewthread&tid=64104)

上文也提到了解决方案,在导言区(Preamble)加入如下代码即可:

1
2
3
4
5
6
7
8
\makeatletter
\def\beamer@linkspace#1{%
\begin{pgfpicture}{0pt}{-1.5pt}{#1}{5.5pt}
\pgfsetfillopacity{0}
\pgftext[x=0pt,y=-1.5pt]{.}
\pgftext[x=#1,y=5.5pt]{.}
\end{pgfpicture}}
\makeatother

  1. 找到你需要的软件在launchpad.net''上的页面,比如用Google’’搜索ubunut Firefox ppa'',能找到如下页面:[firefix ppa](https://launchpad.net/%7Eubuntu-mozilla-daily/+archive/ppa)2. 在页面上寻找下图红框中所示的ppa:ubuntu-mozilla-daily/ppa‘’:

  2. 在``ubuntu’’中打开终端,并且输入如下命令:> sudo apt-add-repository ppa:ubuntu-mozilla-daily/ppa> sudo apt-get update> sudo apt-get upgrade

初学C++的同学常常会遇到这样一个问题:如何从标准输入流中输入一个带有空格的句子?通过不断的Google或者翻书,往往会发现个``getline’’这个全局函数,它可以从标准输入输出流中拿到一行,并且输入参数是string类型:

istream& getline ( istream& is, string& str, char delim );
istream& getline ( istream& is, string& str );
不过一旦动手就会遇到一个新问题:cin >>和getline混用的时候会出错,比如:

01 ...
02     int var;
03     string name;
04     ...
05     cin >> var;
06     getline(cin, name);
07 ... 
运行之后,你会发现你只能输入一次,当你输入了``var''这个变量的值之后,``getline(cin, name)''这一行会被跳过,仿佛没有执行过一般,这是怎么回事?

这里我们需要了解流提取操作符``>>’’的一些特点,这个重载过的操作符的实现的功能顾名思义就是从输入缓冲中提取一个词,再将这个词转化为它后面的变量的类型,比如:

01 #include 
02 #include 
03 #include 
04 
05 using namespace std;
06 
07 int main ( int argc, char *argv[] )
08 {
09     string str1;
10     streamsize  size;
11     // if you use Visual Studio, next line is unnecessary, comment it.
12     ios::sync_with_stdio(false);
13 
14     cout << "Input : ";
15     cin >> str1;
16 
17     streambuf *pBuf = cin.rdbuf();
18     size    = pBuf->in_avail();
19 
20     cout << "Your input is : " << str1 << endl;
21     cout << "There is still " << size << " chars in the buffer." << endl;
22 
23     return EXIT_SUCCESS;
24 }               // ----------  end of function main  ---------- 
假如你在第15行的``cin >> str1''处输入了``Hello World!'',cin第一次只读入Hello,后面8个字符仍在输入缓冲中,所以第21行会输出``There is still 8 chars in the buffer.''。换句话说,``>>''读到下一个空白字符的前一个字符,不过它将空白字符留在输入缓冲中。

也就是因为这一点,getline''和>>’’混用的时候会有小摩擦,考虑本文的第一个例子,当在cin &gt;&gt; var''中输入3然后回车之后,`3'作为数字被赋值给了var’’,但是换行符被留在了输入缓冲中,``getline(cin, name);’’在读入换行符之后就认为已经读到了一整行:

Extracts characters from is and stores them into str until a delimitation character is found.

The delimiter character is delim for the first function version, and ‘\n’ (newline character) for the second. The extraction also stops if the end of file is reached in is or if some other error occurs during the input operation.

If the delimiter is found, it is extracted and discarded, i.e. it is not stored and the next input operation will begin after it.上面这一段是cplusplus上对getline函数的说明:http://www.cplusplus.com/reference/string/getline/,大意就是说``getline''在输入缓冲读入输入的时候是从第一个字符开始,并且再读入之后,将换行符从输入缓冲中删掉(这个才是好的行为啊)

由以上两点不难理解为什么跟在&gt;&gt;''之后的getline’’会被跳掉,其实不是被跳掉,而是读了一个换行符`\n’就收工了……

那么怎么解决呢?

  1. 不要混用cin''和getline’’;
  2. 在使用cin''之后调用cin.ignore(256, ‘\n’)’’,将输入缓冲中的换行符清空掉……

多少次深夜12点戴着耳机播放岩男润子的这首歌从漆黑的文正楼五楼抹黑走进电梯,要是以前知道歌词的中文意思的话可不敢这么干

不过其实从整体上看,歌词还是很温馨的,也许冰箱门的开开关关是人家自己打开的哈

以下歌词以及翻译转自:http://blog.yam.com/misuno/article/20819760
パタパタ  (岩男潤子コンサート Kimochi)

作詞:岩男潤子
作曲:谷山浩子

パタパタ… 冷蔵庫のとびら
啪答啪答… 冰箱的門

パタパタ… あけたり閉めたり
啪答啪答… 開開關關

パタパタ… 何をしてるのわたし ここで
啪答啪答… 我到底在這裡做什麼呢

真夜中2時20分  冷たい床にすわりこんで
半夜的兩點二十分 跌坐在冰冷的地板上

あなたのことばかりずっと考えてる
腦中不斷想著你的事情

3日前に買ったリンゴ 食べかけのチーズ
三天前買的蘋果 正要吃的起司

半分に切った人参 1つのこったじゃがいも
切掉一半的紅蘿蔔 只剩一個的馬鈴薯

今どこにいるの? 誰の側にいるの?
現在在哪裡呢 在誰的身邊呢

笑ってるの? 怒ってるの?
正笑著嗎 還是生著氣呢

誰の夢 見て眠るの
是有誰入夢而睡著呢

会いたいよ とても 会いたいよ あなたに
好想見你 非常的 想要見你

胸の奥の とびらの音
胸口深處 門扉的聲音

パタパタパタ…
啪答啪答啪答…

ソワソワ… ベランダのとびら
坐立不安 陽台的門

ソワソワ… あけたり閉めたり
坐立不安 開開關關

ソワソワ… どうしたんだろうわたし ここで
坐立不安 在這裡的我到底怎麼了呢

真夜中3時50分  冷たい風を受けながら
半夜的三點五十分 迎著寒冷的夜風

あなたのことばかりずっと 考えてる
腦中不斷想著你的事情

植木バチのしおれた花 くもるガラス窓
花盆裡枯萎的花 泛著白霧的玻璃窗

星1つも見えない空  光る車のライト
一個星星都看不見的天空 發著光的車燈

今どこにいるの? 誰の側にいるの?
現在在哪裡呢 在誰的身邊呢

笑ってるの? 怒ってるの?
正笑著嗎 還是生著氣呢

誰の夢 見て眠るの
是有誰入夢而睡著呢

会いたいよ とても 会いたいよ あなたに
好想見你 非常的 想要見你

止められない とびらの音
無法停歇的 門扉的聲音

パタパタパタ…
啪答啪答啪答…

(感謝Seraph中譯)

用Python生成C/C++的数据
Python语言简洁方便易于开发,用来快速的生成和处理数据最好不过了,所以用Python为C/C++生成测试数据在好不过了。但是由于两者在内部的数据存储方面有很大的不同,比如Python的内建类型的float就比C/C++的double要精确的多,所以如果要为C/C++生成二进制的数据(比如通过socket直接发送包含double数据的帧),应该怎么做呢?

其实Python的内建模块中,就至少有这两个是与C/C++联系十分紧密的:

  • ctype[A foreign function library for Python]
  • struct[Interpret strings as packed binary data]如果仅仅是生成数据,而不是想调用C/C++的那一票函数的话(话说有Python在手,谁还想用那些难用的C/C++函数),用struct模块要更加方便一些。

下面提供一个例子,比如想要生成一个RFC 959[File Transfer Protocol]中的某帧格式如下所示的帧

Byte string:

             1       7                8                     8
            +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+     +-+-+-+-+-+-+-+-+
            |0|       n     | |    d(1)       | ... |      d(n)     |
            +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+     +-+-+-+-+-+-+-+-+
                                          ^             ^
                                          |---n bytes---|
                                              of data
01 # 用于C语言数据封装
02 from struct import *
03 ...
04 # 将要传输的数据,考虑到上面的帧格式,长度定义得比较短...
05 data = "Hello World!"
06 # 为将要传输的数据准备一个buffer
07 buff = ""
08 # 开始封装
09 buff += pack('!c', chr(len(data)))
10 buff += pack('!%ds'%len(data), data)
11 # 封装完毕,直接发出去就可以了 
在这个代码片段中,核心就是pack函数。而pack函数的核心是格式化字符串,这个东西和printf是差不多的。具体参数说明(引自[Python官方文档](http://docs.python.org/library/struct.html)):
Format C Type Python Notes
x pad byte no value
c char string of length 1
b signed char integer
B unsigned char integer
? _Bool bool (1)
h short integer
H unsigned short integer
i int integer
I unsigned int integer or long
l long integer
L unsigned long long
q long long long (2)
Q unsigned long long long (2)
f float float
d double float
s char[] string
p char[] string
P void * long
Notes:

1.The ‘?’ conversion code corresponds to the _Bool type defined by C99. If this type is not available, it is simulated using a char. In standard mode, it is always represented by one byte.

New in version 2.6.

2.The ‘q’ and ‘Q’ conversion codes are available in native mode only if the platform C compiler supports C long long, or, on Windows, __int64. They are always available in standard modes.

New in version 2.2.

貌似字符串部分是可以用p取代繁琐的ns的(n表示的是字节数量,在上文中是len(data))。

然后一个需要关心的就是网络字节序的问题,这个也就是上文中pack函数中’!’字段的作用了(引自Python官方文档):

Character Byte order Size and alignment
@ native native
= native standard
< little-endian standard
> big-endian standard
! network (= big-endian) standard
If the first character is not one of these, '@' is assumed.

当然如果仅仅是本机调试的话,要注意的问题会少很多,比如字节序的问题就可以忽略。下面再提供一个double型pack的例子:

01 # 用于C语言数据封装
02 from struct import *
03 ...
04 # 对一个时序列来一次fft
05 s = [1, 2, 3, 4, 5, 6, 7, 8]
06 so = fft(s)
07 # 为将要传输的数据准备一个buffer
08 buff = ""
09 # 开始封装
10 for d in so:
11     buff += pack('@dd', d.real, d.imag)
12 # 封装完毕,直接发出去就可以了 
很简单!
0%