python移植到arm的单板

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

前言

作者的话:

本人非常喜欢python,一直梦想可以移植到CSU中。但是python诞生之初并没有想到要应用在嵌入式领域,因此,python的交叉编译比较复杂。python的交叉编译花费了我一些时间进行摸索,这篇文章是在查阅了N多资料,进行了N多尝试后成功的,就在想彻底放弃的时候,NEVER GIVE UP的信念让我进行前进,而恰恰是这前进的一步,转暗为明,相继研究出来CSUNFSCSUPython!这是让自己非常振奋的!

交叉编译

这里以python2.7.6进行陈述。

下载pythonlinux版本源码包,解压到/opt中。

2.1 更新虚拟机上的python版本

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

传统三部曲。

./configure

make

make install

2.2 配置armconfigure

由于源码包需要生成pc版的pythonarm版的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

 

建好armpython要安装到的文件夹。

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

其中,armgcc采用2011版本;

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

--silent去掉configure过程中的垃圾信息,只输出warning及以上的关键信息,我特别喜欢这个。

--build是必须填的,怎么知道这个build信息呢,最简单的方法就是

gcc –v

里面会有gccconfigure信息,里面就有--build的信息,复制过来就万无一失。

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

2.3 pgen准备

这个非常关键。

configure之后makemake Parsr/pgen

可以在arm_buildParser文件夹里发现pgen这个执行文件,它是python的语法分析器之类东西,但问题来了。

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

最简单的解决方法如下:

回到源码包路径

cd ../

生成pc版本的pgen

make Parser/pgen

复制到arm_buildParser里面

cd arm_build

cp ../Parser/pgen Parser

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

touch –t 12312359 Parser/pgen

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

为什么需要这一步?

很简单:

因为,armpythonmake时,会生成它的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文件了。

第三方库

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

举例:

这里安装第三方xlrd库,这个库可以非常方便的读取excel文件的内容,即使不在windows下,即使没有安装excel,也可以,而且速度非常的快。

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

python setup.py install

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

对于虚拟机,会安装到

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

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

 

那如何安装到我们的armpython里呢。

很简单:

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

(默认情况下,这个前缀为/usr/local/)

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

应用

由于python的库文件很大,直接拷贝到CSU是不现实的。裁剪库也很麻烦,而且消弱了功能。因此,这里采用NFSpythonbinlib等文件,以及自己编写的代码文件都放在虚拟机上。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回车后

就可以进入pythonshell了,可以在命令中输入python语句。

由于这个CSU上的pythonshell非常不好用,打错字无法修正,⊙﹏⊙b汗,因此,我一般都在虚拟机上写代码,CSU上运行就行了。(注,pythonshell退出方式是输入exit()指令)

例如:

mkdir /opt/arm_python/code

code写入helloworld.py的文件

CSU中:

python /mnt/python/code/helloworld.py

就可以看到输出了。

python3的移植

python2

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

arm版的python也一样,在/opt/arm_python会进行版本的区分。

默认python链接指向python2,如果需要更改,rmlnpython3即可。

懒人时刻

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

#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.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)

 

结果对比:

CPU

OS

Time

奔腾E6700(酷睿core2

Windows7

0.03s

奔腾E6700(酷睿core2

Virtual Ubuntu

0.01s

AMD炫龙双核

Ubuntu

0.003s

AT9260Arm9

Linux

0.6s

AM335A8)

Linux

0.18s


结果在我的预测范围里,即CSU的处理能力只有主流台式2cpu的几百分之一,属于可以接受的范围。

(有趣的是,ubuntu的执行速度远高于windowspython虽然是跨平台语言,但是在linux环境下,却有明显的优势)

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

win7:0.35s

A8:8s

7.2 pythonC的对比

执行1000次相加与输出:

C语言代码如下:

  1 #include

  2 #include

  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毫秒。

PythonC速度的20%左右,属于可以接受的范围内。

你可能感兴趣的:(python)