目录

python移植到arm的单板

python移植到arm的单板

注:下文的CSU是我们一个嵌入式单板的名称。

1 前言

作者的话:

本人非常喜欢 python ,一直梦想可以移植到

CSU

中。但是

python

诞生之初并没有想到要应用在嵌入式领域,因此,

python

的交叉编译比较复杂。

python

的交叉编译花费了我一些时间进行摸索,这篇文章是在查阅了

N

多资料,进行了

N

多尝试后成功的,就在想彻底放弃的时候,

NEVER GIVE UP

的信念让我进行前进,而恰恰是这前进的一步,转暗为明,相继研究出来

CSU

NFS

CSU

Python

!这是让自己非常振奋的!

2 交叉编译

这里以 python2.7.6 进行陈述。

下载 python 的

linux

版本源码包,解压到

/opt

中。

2.1 更新虚拟机上的 python 版本

为了最大的稳定性,建议更新虚拟机上的版本与交叉编译的版本一致。由于下载的源码包版本肯定是最新的,因此,顺便更新一下虚拟机的 python 版本也是一件好事。

传统三部曲。

./configure

make

make install

2.2 配置 arm 的 configure

由于源码包需要生成 pc 版的

python

arm

版的

python

,因此,需要隔离开,这个非常关键。

pc 版采用原有路径,不改变。

arm 则在源码包下

mkdir arm_build

由于 configure 会在当前目录下生成

Makefile

等文件,因此,不能在源码包下直接

configure

,必须在

arm_build

里执行。这点非常重要。

cd arm_build

由于交叉编译中,需要明确如下两个变量的值,因此,这里必须人工定义。 ptmx 就是虚拟串口的意思,由于我的单板以后要用到这个,因此,设为

yes

设为 no 一样是可以的。

echo ac_cv_file__dev_ptmx=yes > config.site

echo ac_cv_file__dev_ptc=yes » config.site

export CONFIG_SITE=config.site

建好 arm 版

python

要安装到的文件夹。

arm_install=/opt/arm_python

mkdir $arm_install

configure 如下:

../configure –host=arm-none-linux-gnueabi –build=i686-linux-gnu –target=arm-none-linux-gnueabi –disable-ipv6 –prefix=$arm_install –enable-shared –silent

其中, arm 的

gcc

采用

2011

版本;

由于 ipv6 支持有问题,因此,必须关闭;

–silent 去掉

configure

过程中的垃圾信息,只输出

warning

及以上的关键信息,我特别喜欢这个。

–build 是必须填的,怎么知道这个

build

信息呢,最简单的方法就是

gcc –v

里面会有 gcc 的

configure

信息,里面就有

–build

的信息,复制过来就万无一失。

–target 其实可以不写,系统可以猜出来的,但这里还是写上。

2.3 pgen 准备

这个非常关键。

在 configure 之后

make

make Parsr/pgen

可以在 arm_build 的

Parser

文件夹里发现

pgen

这个执行文件,它是

python

的语法分析器之类东西,但问题来了。

这个东西是不能用的,因为是交叉编译版本的 pgen ,在虚拟机下用不了。

最简单的解决方法如下:

回到源码包路径

cd ../

生成 pc 版本的

pgen

make Parser/pgen

复制到 arm_build 的

Parser

里面

cd arm_build

cp ../Parser/pgen Parser

下面这一步非常关键而且非常巧妙

touch –t 12312359 Parser/pgen

意思是:将 pgen 文件的日期改为今年的最后一分钟生成的。

为什么需要这一步?

很简单:

因为, arm 版

python

make

时,会生成它的

pgen

,就会把刚才复制过来的给替换掉了,改了未来的时间,就会忽略跳过,非常巧妙的技巧!

2.4 make && make install

现在可以 make (或

make python

)了。

我喜欢加上 –silent ,这样可以减少很多垃圾信息。

make 完成后,注意:

这里,使用 make install 一般会出错,显示缺失

_struct

的类型错误。

使用 make -i install 才能搞定。

-i 就是 ignore 错误的意思,继续前进。这里可能的问题是:前面需要某模块,但是

install

中却在后面才安装这个模块,导致了前面找不到模块的错误,其实,整个完成后,是完整的。

这一招对这种时序问题,或 install 中出现的时序问题比较难解决时,能帮上大忙。

现在,查看 /opt/arm_python 这个安装目录,可以发现已经有相关

python

文件了。

3 第三方库

python 容易使用的一大特点就是自由开放的库很多,官方不可能全部纳入自己的标准库中,因此,安装自己需要的第三方库是必要的。

举例:

这里安装第三方 xlrd 库,这个库可以非常方便的读取

excel

文件的内容,即使不在

windows

下,即使没有安装

excel

,也可以,而且速度非常的快。

下载源码包后解压, cd 到那个路径下。

python setup.py install

就可以完成第三方库的安装了。这里的 install 其实就是包括

build

install

对于虚拟机,会安装到

/usr/local/lib/python3.3/site-packages

第三方库基本默认安装在 site-packages 里。

那如何安装到我们的 arm 的

python

里呢。

很简单:

python setup.py install –prefix=/opt/arm_python

( 默认情况下,这个前缀为

/usr/local/)

如果没有正确安装,当程序需要这个库时,会报找不到模块的 error 。

4 应用

由于 python 的库文件很大,直接拷贝到

CSU

是不现实的。裁剪库也很麻烦,而且消弱了功能。因此,这里采用

NFS

python

bin

lib

等文件,以及自己编写的代码文件都放在虚拟机上。

CSU

通过

NFS

使用

python

即可。

CSU 侧:

mkdir /mnt/python

mount –o nolock 10.9.102.23:/opt/arm_python /mnt/python

在 /etc/profile 里

在 export PATH 一行后面加入

:/mnt/python/bin

在 export LD_LIBRARY_PATH 一行后面加入

:/mnt/python/lib

这样就可以使用 python 了。

python –V 就可以看到

python

的版本信息了。

python 回车后

就可以进入 python 的

shell

了,可以在命令中输入

python

语句。

由于这个 CSU 上的

python

shell

非常不好用,打错字无法修正,⊙﹏⊙

b

汗,因此,我一般都在虚拟机上写代码,

CSU

上运行就行了。(注,

python

shell

退出方式是输入

exit()

指令)

例如:

mkdir /opt/arm_python/code

在 code 写入

helloworld.py

的文件

在 CSU 中:

python /mnt/python/code/helloworld.py

就可以看到输出了。

5 python3 的移植

同 python2 。

虚拟机是支持同时安装两个版本的 python 的,它们的路径会通过版本号进行区分。

arm 版的

python

也一样,在

/opt/arm_python

会进行版本的区分。

默认 python 链接指向

python2

,如果需要更改,

rm

ln

python3

即可。

6 懒人时刻

又是将书变薄的时候了,以下是精华,即自动化交叉编译脚本。

#prepare
echo "prepare stage"
arm_install=/opt/arm_python
arm_build=`pwd`/arm_build
mkdir $arm_build
mkdir $arm_install
cd `pwd`
#arm comfigure
echo "arm confiure stage"
cd $arm_build
echo ac_cv_file__dev_ptmx=yes > config.site
echo ac_cv_file__dev_ptc=yes >> config.site
export CONFIG_SITE=config.site
../configure --host=arm-none-linux-gnueabi --build=i686-linux-gnu --target=arm-none-linux-gnueabi --disable-ipv6 --prefix=$arm_install --enable-shared --silent

#pc pgen
echo "pc pgen stage"
cd - 
./configure --silent
for args in $@
do
if [ $args = "all" ];then
make --silent && make install --silent
break
fi
done
make Parser/pgen --silent
cd -
cp ../Parser/pgen Parser
#change the pgen time,
# or else the cross compile will replace this pc version pgen. important!!
touch -t 12312359 Parser/pgen

#make
echo "make stage"
make python --silent && make -i install

#make it smaller
#arm-none-linux-gnueabi-strip -s $arm_install/bin/python3.3
exit 0

使用方法:

chmod +x arm_python

复制到源码包路径下(或 ln 到源码包路径下);

执行 ./arm_python 即可。

默认安装在 /opt/arm_python 里。

(当加入参数 all 时,脚本会顺便更新虚拟机上的

python

7 附录(性能测评)

7.1 不同 cpu 与系统的对比

执行如下测评语句:

import time

start_time=time.clock()

for i in range(1000):

print(‘good’)

end_time = time.clock()

print(’total time is ‘, end_time-start_time)

结果对比:

CPUOSTime
奔腾 E6700 (酷睿 core2 )Windows70.03s
奔腾 E6700 (酷睿 core2 )Virtual Ubuntu0.01s
AMD 炫龙双核Ubuntu0.003s
AT9260 ( Arm9 )Linux0.6s
AM335 ( A8)Linux0.18s

结果在我的预测范围里,即 CSU 的处理能力只有主流台式

2

cpu

的几百分之一,属于可以接受的范围。

(有趣的是, ubuntu 的执行速度远高于

windows

python

虽然是跨平台语言,但是在

linux

环境下,却有明显的优势)

另一个将数据字典自动转为 XML 的程序对比:

win7:0.35s

A8:8s

7.2 python 与 C 的对比

执行 1000 次相加与输出:

C 语言代码如下:

1 #include <stdio.h>

2 #include <sys/time.h>

3 void main(void){

4         struct timeval start,end;

5         gettimeofday(&start,NULL);

6         int i,sum=0;

7         for(i=0;i<1000;++i){

8                 sum+=i;

9                 printf("%d\n",sum);

10         }

11         gettimeofday(&end,NULL);

12         printf(“total time is %d\n”,1000000*(end.tv_sec-start.tv_sec)+end.tv    _usec-start.tv_usec);}

Python 代码如下:

1 import time

2 start_time = time.clock()

3 sum=0

4 for i in range(1000):

5     sum=i+sum

6     print(sum)

7 end_time = time.clock()

8 print(’time is ‘,end_time-start_time )

C 一共使用:

34

毫秒;

Python 一共使用:

180

毫秒。

Python 为

C

速度的

20%

左右,属于可以接受的范围内。