全面认识海思SDK及嵌入式层开发(2)

一、HI3518E方案系统整体架构介绍

1、硬件上

(1)HI3518E单芯片提供:CPU(跑控制流的代码)+DSP(进行ISP和视频编解码运算)+内置64MB DDR(高性价比,集成度高) + ETHERNET MAC

(2)外置一个使用SPI协议的 Flash(16M),用来存放程序(uboot、kernel、rootfs、app)

(3)SDcard扩展提供用户数据区,存放录取的视频,网络摄像头是不需要存储的,其录取的视频通过网线直接进行传输

(4)板载ethernet PHY 和 USB HOST扩展WIFI,提供联网能力

(5)sensor接口(并行数据通道+I2C控制通道)提供主板和sensor链接

(6)串口作为调试口和linux系统控制台

2、软件上

(1)SPIFlash分区烧录uboot.bin、zImage、rootfs,并设置合理的环境变量使系统启动。

(2)sensor、ethernet等硬件均需要驱动支持

(3)app实现视频采集、编码压缩、网络传输等核心工作

(4)各种专业工作(譬如利用内置DSP实现h.264编码压缩)都由海思开发好并以ko的形式提供,有API文档参考,app编写者在sample的帮助下逐步实现自定义的功能。华为海思对h.265编解码算法贡献是比较大的。

二、海思SDK的整体介绍

资料链接:链接:https://pan.baidu.com/s/1Dno-LTc2GIT5quIBSTiuaA
提取码:nal7
–来自百度网盘超级会员V5的分享
在这里插入图片描述
在这里插入图片描述
这两个系列的芯片共用一个SDK,因为这两个芯片整体架构设计比较相似。

该芯片产品介绍的一些资料可以看看:Hi3518E V200R001C01SPC030\00.hardware\chip\document_cn

海思官方开发板的资料:Hi3518E V200R001C01SPC030\00.hardware\board

我们需要的软件资料:Hi3518E V200R001C01SPC030\01.software\board

我们使用的开发板原理图:链接:https://pan.baidu.com/s/1iYfBovbSSjNOZUGfxdVeOw
提取码:r3u2
–来自百度网盘超级会员V5的分享

三、海思SDK包的学习和实验

1、2篇相关文档

(1) Hi3518E V200R001C01SPC030\01.software\board\document_cnHi3518EV20X/Hi3516CV200 Linux开发环境用户指南.pdf

简单浏览,了解开发环境的要求和如何解决遇到的问题。
在这里插入图片描述
(2)Hi3518E V200R001C01SPC030\01.software\board\Hi3518EV20X/Hi3516CV200 U-boot 移植应用开发指南.pdf

简单浏览。
在这里插入图片描述
生成的uboot通过HiTool工具进行烧录。

2、SDK包复制到linux原生目录中并解压

(1)通过共享文件夹或者samba服务器的方式将Hi3518E_SDK_V1.0.3.0.tgz复制到Ubuntu的原生目录中去,再进行解压

mkdir -p /home/aston/sambashare
cp /mnt/hgfs/winshare_HI3518E/Hi3518E_SDK_V1.0.3.0.tgz  /home/aston/sambashare/ -rf
tar -zxvf Hi3518E_SDK_V1.0.3.0.tgz  

在这里插入图片描述

3、SDK包操作的脚本程序研究

sdk.cleanup脚本文件,类似一个main程序,common.sh类似一个函数文件,sdk.cleanup调用了common.sh的函数,可通过source sdk.cleanup执行这个脚本文件使用清理功能。

#!/bin/sh
source scripts/common.sh #将scripts/common.sh复制到这里,类似于C语言的include包含

ECHO "Cleanup SDK" COLOR_YELLOW	#用黄色打印Cleanup SDK

ECHO ""
WARN "ALL THE SOUCE FILES WILL BE DELETED, FILES YOU MOTIFIED/ADDED WILL BE LOST !!!"
ECHO ""

#ECHO "To continue, type 'Yes' and then press ENTER ..."

#read choice
#[ x$choice != xYes ] && exit 1 #读取按键输入的结果决定此时的操作

set +e
#set -e : 执行的时候如果出现了返回值为非零,整个脚本 就会立即退出 
#set +e: 执行的时候如果出现了返回值为非零将会继续执行下面的脚本 

ECHO "cleanup drv"
pushd . #功能是创建一个目录栈,你可以把你目前常见的几个目录压入栈中
run_command_progress_float "rm drv -frv" 0 "find drv | wc -l"
popd

ECHO "cleanup mpp"
pushd .
#执行脚本函数run_command_progress_float 并传参
run_command_progress_float "rm mpp* -frv" 0 "find mpp* | wc -l" 
popd

ECHO "cleanup osdrv"
pushd .
run_command_progress_float "rm osdrv -frv" 0 "find osdrv | wc -l"
popd

Linux命令–pushd和popd:
https://blog.csdn.net/happy_dw/article/details/52081345

shell脚本函数及传参:https://blog.csdn.net/happyhorizion/article/details/80431327
https://blog.csdn.net/broadCE/article/details/80027807

sdk.unpack脚本文件,也类似一个main程序,调用common.sh中的函数,执行该脚本文件,则会解压源码包:

#!/bin/sh
source scripts/common.sh

ECHO "Unpacking SDK" COLOR_YELLOW

WARN "Be sure you have installed the cross-compiler. if not, install it first!"
WARN "ALL THE SOUCE FILES WILL BE OVERWRITED, FILES YOU MOTIFIED WILL BE LOST !!!"
ECHO ""

#ECHO "To continue, type 'Yes' and then press ENTER ..."

#read choice
#[ x$choice != xYes ] && exit 1

set +e

#ECHO "install cross toolchain"
#./tools/toolchains/cross.install

ECHO "unpacking osdrv"
mkdir -p osdrv/
run_command_progress_float "tar -xvzf package/osdrv.tgz" 0 "tar -tzf package/osdrv.tgz | wc -l"

ECHO "unpacking kernel"
mkdir -p osdrv/
run_command_progress_float "tar -xvzf osdrv/opensource/kernel/linux-3.4.y.tgz -C osdrv/opensource/kernel/" 0 "tar -tzf osdrv/opensource/kernel/linux-3.4.y.tgz | wc -l"

if [ "$SDK_CHIP" = "hi3519" ]; then
#ECHO "unpacking mpp_single"
#mkdir -pv mpp_single
#run_command_progress_float "tar -xvzf package/mpp_single.tgz" 0 "tar -tzf package/mpp_single.tgz | wc -l"

ECHO "unpacking mpp_big-little"
mkdir -pv mpp_big-little
run_command_progress_float "tar -xvzf package/mpp_big-little.tgz" 0 "tar -tzf package/mpp_big-little.tgz | wc -l"
else #我们使用的是Hi3518E,所以if不成立,我们执行的是else
ECHO "unpacking mpp"
mkdir -pv mpp
run_command_progress_float "tar -xvzf package/mpp.tgz" 0 "tar -tzf package/mpp.tgz | wc -l"
fi

ECHO "unpacking drv"
mkdir -pv drv
run_command_progress_float "tar -xvzf package/drv.tgz" 0 	"tar -tzf package/drv.tgz | wc -l"

在这里插入图片描述
之后我们要重点去学习分析:osdrv目录下的内容
在这里插入图片描述
common.sh文件,大致浏览了解一下即可,不必深究:

#!/bin/sh

#set -e

# for debug
DEBUG_LOG_FILE='&2'
DEBUG_LOG_LEVEL=0

# ANSI COLORS,定义了一些颜色
COLOR_CRE="[K"
COLOR_NORMAL="[0;39m"
COLOR_RED="[1;31m"
COLOR_GREEN="[1;32m"
COLOR_YELLOW="[1;33m"
COLOR_BLUE="[1;34m"
COLOR_MAGENTA="[1;35m"
COLOR_CYAN="[1;36m"
COLOR_WHITE="[1;37m"

# Shell command,定义了一些命令,之所以未直接使用Linux命令,可能考虑到不同系统
#平台上的开发
TAR=tar
CP=/bin/cp
RM=/bin/rm
GREP=grep
SED=sed
MKDIR=mkdir
CHMOD=chmod
MV=mv
CD=cd
LN=ln
MAKE=make
MKNOD=mknod
PUSHD=pushd 
POPD=popd 
RMDIR=rmdir
DEPMOD=/sbin/depmod
RMDIR=rmdir
MKIMG=mkimage
PATCH=patch
DIFF=diff
TOUCH=touch
CAT=cat

e_blank='[        ][      ]*'
e_year='20[0-9][0-9]'
e_month='([1-9]|0[1-9]|1[0-2])'
e_day='([1-9]|0[1-9]|[12][0-9]|3[0-1])'
e_time='([01][0-9]|2[0-3]):[0-5][0-9]'
e_employid='[a-zA-Z][a-zA-Z]*[0-9]{4,}'

#以下的内容为定义的函数

#$1: string
#$2: color
ECHO()
{
	[ -n "$2" ] && eval echo -n \"\${${2}}\";
	echo "${1}${COLOR_NORMAL}"
}

ERR()
{
	echo "${COLOR_RED} ERR: ${1}${COLOR_NORMAL}" >&2
}

WARN()
{
	echo "${COLOR_YELLOW}WARN: ${1}${COLOR_NORMAL}" >&2
}

# $1:
LOG()
{
	echo "$1"
}


#$1: string
#$2: level
DEBUG()
{
	local level=$2
	[ -z "$level" ] && { level=0; }
	[ $level -lt $DEBUG_LOG_LEVEL ] && return 0;

	echo "$COLOR_WHITE$1$COLOR_NORMAL" > $DEBUG_LOG_FILE
}

# $1: command
# $2: LR/CR steps
run_command_progress()#运行命令进行工作的过程中显示进度条
{
	local n=0
	local steps=$2
	local progress_bar=""
	local counter=0
	local files=0

	ECHO "run_command_progress: '$1'" 
	[ -z "$steps" ] && { steps=1; }

	[ -n "$3" ] && [ -d "$3" ] && { steps=`find $3 | wc -l`; steps=`expr $steps / 50`; }

	eval $1 | while read line
	do
		#((n++))
		#((files++))
		((++n))
		((++files))

		if [ $n -ge $steps ] ;
		then
			#((counter++))
			((++counter))
			if [ $counter -le 50 ] ;
			then
				progress_bar="$progress_bar#";
				printf "     --------------------------------------------------|\r[%03d]$progress_bar\r" $steps
			else
				printf "[%03d#$progress_bar|\r" `expr $files / 50`
			fi

			n=0
		fi
	done

	echo ""
}

# $1: command
# $2: total
# $3: command to calc totals
run_command_progress_float()#运行命令工作时计算完成的百分比
{
	local readonly RCP_RANGE=50
	local rcp_lines=0
	local rcp_nextpos=1
	local rcp_total=0
	local progress_bar=
	local rcp_prog=0
	local rcp_tmp=0
	local prog_bar_base=
	local rcp_percent=0

	ECHO "run_command_progress_float: '$1'" 

	if [ -n "$3" ] ;
	then
		echo -n "Initializing progress bar ..."
		rcp_total=`eval $3`;
		echo -n "\r"
		[ -z "$rcp_total" ] && rcp_total=1
	else
		[ -n "$2" ] && rcp_total=$2
	fi

	[ -z "$rcp_total" ] && rcp_total=1
	[ $rcp_total -le 0 ] && rcp_total=1

	prog_bar_base="[    ]"
	while [ $rcp_tmp -lt $RCP_RANGE ]
	do
		prog_bar_base="$prog_bar_base-"
		#((rcp_tmp++)) 
		((++rcp_tmp)) 
	done
	prog_bar_base="${prog_bar_base}|"
	printf "\r$prog_bar_base\r"

	set +e
	eval $1 | while read line
	do
		#((rcp_lines++))
		((++rcp_lines))

		if [ $rcp_lines -ge $rcp_nextpos ]
		then
			rcp_percent=`expr \( $rcp_lines \* 101 - 1 \) / $rcp_total `
			rcp_prog=`expr \( $rcp_lines \* \( $RCP_RANGE + 1 \) - 1 \) / $rcp_total `
			[ $rcp_prog -gt $RCP_RANGE ] && rcp_prog=$RCP_RANGE
			rcp_nextpos=`expr \( \( $rcp_percent + 1 \) \* $rcp_total \) / 100`
			[ $rcp_nextpos -gt $rcp_total ] && rcp_nextpos=$rcp_total

			rcp_tmp=0
			progress_bar=""
			while [ $rcp_tmp -lt $rcp_prog ]
			do
				progress_bar="$progress_bar#"
				((rcp_tmp++))
			done
			printf "\r$prog_bar_base\r[%3d%%]$progress_bar\r" $rcp_percent
		fi
	done
	set -e

	echo ""
}

#$1: path
abs_path()
{
	pushd "$1" >/dev/null
	[ $? -ne 0 ] && return 1;
	pwd
	popd >/dev/null
}

#$1: $cfg_moddir is multi
prepare_unpacking_cleanup()
{
	$CAT >> $HCM_SH_SDKINSTALL << EOF

ECHO "unpacking $cfg_moddir"
mkdir -pv $module_basedir
run_command_progress_float "tar -xvzf `sub_dir $dir_postbuild_srctarball $HCM_DESTDIR`/$module_dirname.tgz -C $module_basedir/" 0 \
	"tar -tzf `sub_dir $dir_postbuild_srctarball $HCM_DESTDIR`/$module_dirname.tgz | wc -l"
EOF

if [ -z "$1" ] ;
then
	$CAT >> $HCM_SH_SDKCLEANUP << EOF

ECHO "cleanup $cfg_moddir"
run_command_progress_float "rm $cfg_moddir -frv" 0 "find $cfg_moddir | wc -l"
EOF
else
	$CAT >> $HCM_SH_SDKCLEANUP << EOF

ECHO "cleanup $cfg_moddir"
pushd $module_basedir
run_command_progress_float "rm $cfg_moddir -frv" 0 "find $cfg_moddir | wc -l"
popd
EOF
fi

}

# $1: prefix
# $2..$n: dirs list
make_dirs()
{
	local make_dirs_count=2
	local make_dirs_dir=

	[ -z "$1" ] && { ERR "make_dirs mast have a prefix dir!"; return 1; }
	$MKDIR $1 -p

	while true
	do
		eval make_dirs_dir=\${$make_dirs_count}
		[ -z "$make_dirs_dir" ] && break;
		$MKDIR $1/$make_dirs_dir -p
		#((make_dirs_count++))
		((++make_dirs_count))
	done
}

check_dir_empty()
{
	[ -z "$1" ] && return 0;
	! [ -d $1 ] && return 0;
	[ -z "`find $1/ -maxdepth 1 -mindepth 1`" ] && return 0;

	return 1
}

# $1 - $2
# $3: frefix for '/', like "\\\\/"
sub_dir()
{
	local subdir=
	local dirA=`dirname $1/stub`
	local dirB=`dirname $2/stub`

	while [ "$dirA" != "$dirB" ] && [ "$dirA" != "." ] && [ "$dirA" != "/" ] 
	do
		if [ -z "$subdir" ] ; then
			subdir=`basename $dirA`
		else
			subdir=`basename $dirA`$3/$subdir
		fi
		dirA=`dirname $dirA`
	done

	[ -z "$subdir" ] && subdir=.

	dirname $subdir/stub
}

# $1: base dir
# $2: dest dir
# $3: frefix for '/', like "\\\\/"
base_offset_dir()
{
	local ofstdir=`sub_dir $2 $1`
	local bodofst=

	while [ "$ofstdir" != "." ] && [ "$ofstdir" != "/" ] 
	do
		if [ -z "$bodofst" ] ; then
			bodofst=..
		else
			bodofst=..$3/$bodofst
		fi
		ofstdir=`dirname $ofstdir`
	done

	dirname $bodofst/stub
}

#$1: dir
set_drv_kbuild()
{
	local cc_file=Makefile
	local mbdir= 

	for mbdir in $1 $1/*
	do
		if [ -f $mbdir/$cc_file ] ;
		then
			local kbuild_dir_adj="`base_offset_dir $HCM_DESTDIR $mbdir "\\\\"`\\/`echo "$HCM_SDKDIR_KBUILD" | \
				sed -n "s/\//\\\\\\\\\//gp"`"

			$SED -i "s/^KERNEL_MAKE[ \t]*:=.*/KERNEL_MAKE := -C $kbuild_dir_adj/" $mbdir/$cc_file
		fi
	done	
}

#$1: name
#$2: level
write_rootfs_level()
{
	local rlevel_config=$HCM_DESTDIR/$HCM_SDKDIR_RESOURCE/rlevel.config
	$TOUCH $rlevel_config
	[ -n "`grep "^\[[0-9A-Za-z][0-9A-Za-z\-]*\]	$1$" < $rlevel_config`" ] && { \
       		WARN "$rlevel_config already have item '$1'"
		return 0;
	}
	echo "[$2]	$1" >> $rlevel_config
}

#$1: 
remove_all_cvsdir()
{
	! [ -d "$1" ] && { WARN "'$1' not found when remove 'CVS' directories."; return ; }

	ECHO "Remove: 'CVS' directories in $1"
	find $1 -type d -name "CVS" | xargs rm -fr
}

#$1: strip command
#$2: file list
strip_elf()
{
	for file in $2
	do
		[ -z "`file $file | grep "ELF .* executable, .*, not stripped"`" ] && continue

		ECHO "$1 $file"
		$1 $file
	done
}

#$1: strip command
#$2: file list
strip_lib()
{
	for file in $2
	do
		[ -z "`file $file | grep "ELF .* shared object, .*, not stripped"`" ] && continue

		ECHO "strip not really done: $file"
	done
}

# $1: rootfs base
# $2: modules list
install_extern_kmod()
{
	local iek_installed_modules=
	local iek_dest_module=
	local iek_depend_info=
	local iek_install_base=

	pushd $1 >/dev/null
	iek_install_base=$PWD
	popd >/dev/null

	for iek_extmod in `find $2`
	do
		iek_dest_module=/$HCM_INROOTFS_EXTKMOD/`basename $iek_extmod`

		[ -f $HCM_DESTDIR/$HCM_KERNEL_INSTALL_RESOURCE/$iek_dest_module ] && \
			{ WARN "Extern module $iek_extmod conflict: $iek_dest_module"; sleep 1; }

		iek_installed_modules="$iek_installed_modules $iek_dest_module"
		$CP -uf $iek_extmod $HCM_DESTDIR/$HCM_KERNEL_INSTALL_RESOURCE/$iek_dest_module
	done

	pushd $HCM_DESTDIR/$HCM_KERNEL_INSTALL_RESOURCE >/dev/null

	ECHO "Generating modules dependency ..."
	$DEPMOD -ae -b ./ -r -F $HCM_DESTDIR/$HCM_SDKDIR_KBUILD/System.map $HCM_KERNEL_RELEASE

	for iek_extmod in $iek_installed_modules
	do
		iek_depend_info=`grep "^$iek_extmod:" < $HCM_DESTDIR/$HCM_KERNEL_INSTALL_RESOURCE/$HCM_INROOTFS_DEPKMOD/modules.dep | sed "s/\://"`
		for iek_extmod in $iek_depend_info
		do
			$CP -uf --parents .$iek_extmod $iek_install_base/
			[ x$cfg_install_strip == xyes ] && $HCM_CROSS_COMPILE-strip $iek_install_base$ikm_kmod -g -S -d

		done
	done

	popd >/dev/null
}

# $1: dest rootfs based
# $2: module list
install_kernel_module()
{
	local ikm_kmod_resdir=$HCM_DESTDIR/$HCM_KERNEL_INSTALL_RESOURCE
	local ikm_install_basedir=
	local ikm_kmod=

	pushd $1 >/dev/null
	ikm_install_basedir=$PWD
	popd  >/dev/null

	pushd $ikm_kmod_resdir >/dev/null
	$DEPMOD -ae -b ./ -r -F $HCM_DESTDIR/$HCM_SDKDIR_KBUILD/System.map $HCM_KERNEL_RELEASE

	while read ikm_kmod
	do
		ikm_depend_info=`grep "^$ikm_kmod:" < $HCM_DESTDIR/$HCM_KERNEL_INSTALL_RESOURCE/$HCM_INROOTFS_DEPKMOD/modules.dep | sed "s/\://"`
		for ikm_kmod in $ikm_depend_info
		do
			$CP -uf --parents .$ikm_kmod $ikm_install_basedir
			[ x$cfg_install_strip == xyes ] && $HCM_CROSS_COMPILE-strip $ikm_install_basedir$ikm_kmod -g -S -d
		done
	done << EOF
	`pushd $HCM_INROOTFS_KERNMOD >/dev/null; \
		eval find "$2" -type f -printf \"/$HCM_INROOTFS_KERNMOD/%p\\\n\"; \
		popd >/dev/null`
EOF

	popd >/dev/null
}

string_to_varname()
{
	echo "$1" | sed 's/[^a-zA-Z0-9_]/_/g'
}

patchset_get_param()
{
	echo "$1" | cut -d')' -f1 | sed 's/[\(\|]/ /g'
}

patchset_get_name()
{
	echo "$file" | cut -d')' -f2
}

4、SDK中源码包部分的配置编译分解

阅读:osdrv/readme_cn.txt,其中讲解了该目录下各个文件、文件夹的作用,以及如何使用这些文件,如何进行配置编译等等,相当于一个说明书。

glibc库比较庞大,所比较占用存储空间,而uclibc库是glibc库精简而来的,删除了一些不必要的东西,相对来说比较小,不会占用太大的存储空间,比较方便。由于板载的flash只有16MB,所以我们选择基于uclibc库制作的交叉编译链。

四、在ubuntu16.0403X64上安装海思交叉编译工具链

1.osdrv 顶层 Makefile 使用说明
本目录下的编译脚本支持选用下文提到的两种工具链中的任何一种进行编译,因此编译时需要带上一个编译参数以指定对应的工具链 -- arm-hisiv300-linux 和 arm-hisiv400-linux。其中,arm-hisiv300-linux工具链对应uclibc库,arm-hisiv400-linux工具链对应glibc库。具体命令如下

(1)编译整个osdrv目录:
	make OSDRV_CROSS=arm-hisiv300-linux CHIP=hi3516cv200 all
	make OSDRV_CROSS=arm-hisiv300-linux CHIP=hi3518ev200 all
	make OSDRV_CROSS=arm-hisiv300-linux CHIP=hi3518ev201 all
	或者
	make OSDRV_CROSS=arm-hisiv400-linux CHIP=hi3516cv200 all
	make OSDRV_CROSS=arm-hisiv400-linux CHIP=hi3518ev200 all
	make OSDRV_CROSS=arm-hisiv400-linux CHIP=hi3518ev201 all

(2)清除整个osdrv目录的编译文件:
	make OSDRV_CROSS=arm-hisiv300-linux CHIP=hi3516cv200 clean
	make OSDRV_CROSS=arm-hisiv300-linux CHIP=hi3518ev200 clean
	make OSDRV_CROSS=arm-hisiv300-linux CHIP=hi3518ev201 clean
	或者
	make OSDRV_CROSS=arm-hisiv400-linux CHIP=hi3516cv200 clean
	make OSDRV_CROSS=arm-hisiv400-linux CHIP=hi3518ev200 clean
	make OSDRV_CROSS=arm-hisiv400-linux CHIP=hi3518ev201 clean

(3)彻底清除整个osdrv目录的编译文件,除清除编译文件外,还删除已编译好的镜像:
	make OSDRV_CROSS=arm-hisiv300-linux CHIP=hi3516cv200 distclean
	make OSDRV_CROSS=arm-hisiv300-linux CHIP=hi3518ev200 distclean
	make OSDRV_CROSS=arm-hisiv300-linux CHIP=hi3518ev201 distclean
	或者
	make OSDRV_CROSS=arm-hisiv400-linux CHIP=hi3516cv200 distclean
	make OSDRV_CROSS=arm-hisiv400-linux CHIP=hi3518ev200 distclean
	make OSDRV_CROSS=arm-hisiv400-linux CHIP=hi3518ev201 distclean
交叉编译链源码在:Hi3518E_SDK_V1.0.3.0/osdrv/opensource/toolchain/arm-hisiv300-linux/arm-hisiv300-linux.tar.bz2 

将其复制到Hi3518E_SDK_V1.0.3.0/osdrv/目录下进行安装:
cp opensource/toolchain/arm-hisiv300-linux/arm-hisiv300-linux.tar.bz2 ./

进行解压:tar -jxvf arm-hisiv300-linux.tar.bz2

之所以将交叉编译链安装到这个目录,是因为osdrv目录中的Makefile中:
在这里插入图片描述
在这里插入图片描述
  为了使得编译时可以找到交叉编译链所在,故而将其放在这个目录,当然解决方法不止这一种,你也可以通过修改Makefile进行解决。

  但是经过上面的操纵后还是找不到交叉编译链,可能是以下原因导致的,我们按照下列的步骤依次排除:

1、问题:工具链是32位的,而Ubunt系统是64位的

(1)方法1:换32位ubuntu
(2)方法2:装32位兼容包

2、给ubuntu16.0403X64安装32位兼容包

(1)参考:http://blog.csdn.net/ma57457/article/details/68923623
或者:https://www.cnblogs.com/leaven/p/5084902.html

(2)用aptitude方式安装lib32z1。使用sudo apt-get install lib32z1,发现装不了。原因是ubuntu太新了,里面很多库都是新版本的,但是基于这个新版本的lib32z1还没有,所以不能装。解决方案就是用aptitude工具来装。

sudo aptitude install lib32z1
根据打印信息的提示操作:
     Keep the following packages at their current version:
1)     lib32z1 [Not Installed]                            
2)     libc6-i386 [Not Installed]                         

Accept this solution? [Y/n/q/?] n
选择n,不保留当前版本,选择降低版本,否则无法安装32位库
之后的选择都选择Y,表示接收降低版本的操作。

执行过程中可能会出现如下错误:
Err http://us.archive.ubuntu.com/ubuntu xenial/main amd64 libc6-dev amd64 2.23-0ubuntu3   Temporary 
解决方法:
(1)sudo vim /etc/resolv.conf
(2)在最后加上 nameserver 8.8.8.8
(3)保存退出

在执行上述命令的过程中你要注意打印的信息,可能会提示你要安装其他依赖的软件包,否则最后还会有问题。若是上面提供的参考链接没有解决你的问题,请自行百度找其他方法!

(3)测试执行arm-xxx-gcc -v,提示找不到stdc++错误:

cd arm-hisiv300-linux/bin

./arm-hisiv300-linux-uclibcgnueabi-gcc -v
报错:
./arm-hisiv300-linux-uclibcgnueabi-gcc: error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directory

(4)再用aptitude方式安装lib32stdc++6-4.8-dbg

sudo aptitude install lib32stdc++6-4.8-dbg

打印信息:
     Keep the following packages at their current version:
1)     lib32stdc++6 [Not Installed]                       
2)     lib32stdc++6-4.8-dbg [Not Installed]               

Accept this solution? [Y/n/q/?] 
选择:n
之后的操作全都选择:Y

再次测试./arm-xxx-gcc -v,终于可以运行了。
在这里插入图片描述

3、再次Make测试整体编译osdrv

(1)仍然提示找不到arm-hisiv300-linux-gcc

(2)修改Makefile中OSDRV_CROSS的路径,结果不行,分析原因是:命令行传参覆盖了
在这里插入图片描述

make OSDRV_CROSS=arm-hisiv300-linux CHIP=hi3518ev200 all

(3)export导出到环境变量,格式为:

export PATH=/home/aston/sambashare/Hi3518E_SDK_V1.0.3.0/osdrv/arm-hisiv300-linux/bin:$PATH

直接测试可以执行了,但是编译还是出错。分析原因:名字不对

arm-hisiv300-linux-uclibcgnueabi-gcc -v
arm-hisiv300-linux-gcc -v

在这里插入图片描述
(4)解决方案有2个:一种是修改make时传参的名字,另一种是给安装好的交叉编译工具链创建符号链接。实际尝试后发现第一种Makefile要改的太多,所以走第2种。

4、使用install脚本安装交叉编译工具链

脚本所在路径:opensource/toolchain/arm-hisiv300-linux/cross.install.v300
在这里插入图片描述
删除之前解压的arm-hisiv300-linux.tar.bz2以及在osdrv目录下的该压缩包,使该目录恢复原样。避免其为之后的操作产生影响。
在这里插入图片描述
根据这个脚本可知,其是专门用来安装交叉编译链的,并将其放在了/opt/目录下进行安装,而且这个目录不会因为执行sdk.cleanup脚本被清楚。进入脚本所在目录,执行:

sudo ./cross.install.v300

在这里插入图片描述
(1)该脚本将会把解压后的交叉编译工具链放到/opt目录下并建立符号链接
在这里插入图片描述

cd /opt/hisi-linux/x86-arm/arm-hisiv300-linux/target/bin

(2)再次导出环境变量,之前导出的那个环境变量的目录有问题,改成如下所示:

export PATH=/opt/hisi-linux/x86-arm/arm-hisiv300-linux/target/bin:$PATH
arm-hisiv300-linux-gcc -v#再次测试

注意:export只是暂时导出环境变量,当当前终端被关闭,当前进程死掉后,下次在进入需要
再次导出环境变量,或者有个一劳永逸的办法,修改:~/.bashrc文件,在末尾加上
sudo vi ~/.bashrc
末尾添加:export PATH=/opt/hisi-linux/x86-arm/arm-hisiv300-linux/target/bin:$PATH
保存退出即可

(3)再次编译

make OSDRV_CROSS=arm-hisiv300-linux CHIP=hi3518ev200 distclean
make OSDRV_CROSS=arm-hisiv300-linux CHIP=hi3518ev200 all
注意:不要在root用户下编译,否则可能会出错表示还找不到。因为你当前导出的环境变量是在
你的用户下,root用户下并没有,当然你要在root用户下导出环境变量也可以编译,记住也不可
以使用以下命令编译,因为也是相当于root用户:
sudo make OSDRV_CROSS=arm-hisiv300-linux CHIP=hi3518ev200 all

会出现报错:
pushd /home/aston/sambashare/Hi3518E_SDK_V1.0.3.0/osdrv/opensource/uboot/u-boot-2010.06;make ARCH=arm CROSS_COMPILE=arm-hisiv300-linux- -j 20 >/dev/null;popd
/bin/sh: 1: pushd: not found
解决方法:
参考学习:https://blog.csdn.net/wangweiqiang1325/article/details/53443024

执行sudo dpkg-reconfigure dash 命令,将dash设置为No。

再接着编译,最终编译还是会出问题,但和交叉编译链没关系了,我们本篇文章主要是安装交叉编译链,至于具体的编译问题我们下篇文章继续讲述。

在这里插入图片描述
注:本资料大部分由朱老师物联网大讲堂课程笔记整理而来并且引用了部分他人博客的内容,如有侵权,联系删除!水平有限,如有错误,欢迎各位在评论区交流。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小嵌同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值