天天看点

Hi3518E_V200 SDK编译笔记 第一季

第一季

1.视频压缩算法有哪些,h.264 mjpeg目前主流的是h.264,压缩就编码,编码就是压缩,3518e内部专门用一个DSP来做视频编码。

2.视频经过压缩之后变成了h.264视频流,压缩的目的就是为了好传输,可以通过有线或无线网络,USB等传输。

3.网络传输协议:http/rtsp等

4.接收端一般有两种处理方法,一种存储,例如把h.264流打包成mp4格式存储;另一种是直接显示。

5.视频回放:解码+播放 解码成原始的图像,位图的图像,播放就是直接把位图的图像丢到LCD里面去播放。

6.视频行业的商业角度分段

(1)主芯片商、sensor、镜头等分立元器件厂商。

(2)模组厂商

(3)视频服务器厂商

(4)面向解决方案的方案开发商

(5)工程商或销售商

7.视频为什么要编码和解码?

    原始视频太大,网络带宽有限,

8.主芯片3518e主要解决什么问题?

    编解码及ISP

9.视频传到传输为什么要用Linux

    Linux里面网络的协议栈是最全的,Linux里面关于网络这一块的开发是最多的。但是在ISP及编码这一段

    安霸用的是rtos,在视频的网络传输这一段用的是LINUX。海思整个过程全部用Linux。

3518e方案系统整体架构介绍

1.硬件 

(1)CPU(ARM9)+DSP+512Mb(64MB)DDR2

(2)外置SPI Flash用来存放程序(uboot、kernel、rootfs、app)

    为什么不用NOR FLASH?太贵

    为什么不用NAND FLAHS?没必要,容量用不了那么大

    为什么不用EMMC?太贵,容量太大浪费。入门级的4GB的二十多块。

    16MB的SPI两块人民币,而且程序(uboot、kernel、rootfs、app)不超过16MB

(3)SD卡扩展提供用户数据区  

    行车记录肯定要

    IPC可以不要,视频可以通过网卡或者WIFI传输

(4)sensor接口 并行接口或者串行接口(MIPI CSI 及LVDS)

(5)串口

2. 软件

(1)SPIFlash分区烧录uboot.bin、zImage、rootfs

 每一段都有预留余量空间

(2)驱动支持

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

(4)各种专业工作(例如内置DSP实现h.264编码压缩)都由海思开发好并以ko的形式提供,应用开发人员

    只要去调用API实现。

3.SDK

(1)JTAG主要用来调试非常底层的东西的,其实就是UBOOT的,但是实际工作中UBOOT不用从头开始开发。

    所有平时用不到。

(2)uClibc比较精简,它通过glibc库精简出来的,只留下了一些必要的东西,它认为用处不大的东西全部精简掉了,缺点就是功能不全,海思的

    方案SPIflash都是配的是16MB,在这种情况下,你只能用uclibc库。

     glibc比较庞杂,是gcc里面的标准库,什么功能都有,缺点就是太大了,适用于板载emmc等大容量的flash

(3)arm-hisiv300-linux基于uclibc的,编译出来的程序较小  推荐使用arm-hisiv300-linux

    arm-hisiv400-linux是基于glibc的,编译出来的程序较大

(4)把Hi3518E_SDK_V1.0.3.0.tgz复制到Samba共享目录 /opt/share/

(5) 在目录/opt/share/解压 tar xzvf Hi3518E_SDK_V1.0.3.0.tgz 

(6)在目录下/opt/share/Hi3518E_SDK_V1.0.3.0执行  source sdk.cleanup   (这里必须用source才行)

Cleanup SDK

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

cleanup drv

/opt/share/Hi3518E_SDK_V1.0.3.0 /opt/share/Hi3518E_SDK_V1.0.3.0

run_command_progress_float: 'rm drv -frv'

Initializing progress bar ...find: 'drv': No such file or directory

[    ]--------------------------------------------------|

/opt/share/Hi3518E_SDK_V1.0.3.0

cleanup mpp

/opt/share/Hi3518E_SDK_V1.0.3.0 /opt/share/Hi3518E_SDK_V1.0.3.0

run_command_progress_float: 'rm mpp* -frv'

Initializing progress bar ...find: 'mpp*': No such file or directory

[    ]--------------------------------------------------|

/opt/share/Hi3518E_SDK_V1.0.3.0

cleanup osdrv

/opt/share/Hi3518E_SDK_V1.0.3.0 /opt/share/Hi3518E_SDK_V1.0.3.0

run_command_progress_float: 'rm osdrv -frv'

Initializing progress bar ...find: 'osdrv': No such file or directory

[    ]--------------------------------------------------|

/opt/share/Hi3518E_SDK_V1.0.3.0

         注意:sdk.cleanup里面的这句注释不能去#[ x$choice != xYes ] && exit 1,注释去除后执行 source sdk.cleanup终端自动退出。

(7)source sdk.unpack

Unpacking SDK

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 !!!

unpacking osdrv

run_command_progress_float: 'tar -xvzf package/osdrv.tgz'

[100%]##################################################|

unpacking kernel

run_command_progress_float: 'tar -xvzf osdrv/opensource/kernel/linux-3.4.y.tgz -C osdrv/opensource/kernel/'

[100%]##################################################|

unpacking mpp

mkdir: created directory 'mpp'

run_command_progress_float: 'tar -xvzf package/mpp.tgz'

[100%]##################################################|

unpacking drv

mkdir: created directory 'drv'

run_command_progress_float: 'tar -xvzf package/drv.tgz'

[100%]##################################################|

4. osdrv学习

(1)进入osdrv目录,在里面搞uboot、kernel、rootfs等

(2)在osdrv目录下先make OSDRV_CROSS=arm-hisiv300-linux CHIP=hi3518ev200 distclean,把之前的所有中间文件、目录、依赖等全部清除,以防别人别人编译过留下中间文件。

(3)清理完后开始整个编译make OSDRV_CROSS=arm-hisiv300-linux CHIP=hi3518ev200 all

     注意:海思的交叉编译工具链是32位的,环境最好装Ubuntu16.04 32位系统,如果使用64位系统,则需要安装32位兼容包

(4)到/opt/share/Hi3518E_SDK_V1.0.3.0/osdrv/opensource/toolchain/arm-hisiv300-linux目录下执行./cross.install.v300

     符号链接被创建在/opt/hisi-linux/x86-arm/arm-hisiv300-linux/target/bin目录下面

     在此目录下执行arm-hisiv300-linux-gcc -v可以看到版本 

(5)把路径/opt/hisi-linux/x86-arm/arm-hisiv300-linux/target/bin添加到环境变量PATH中,具体为在~/.bashrc里最后一行添加

     export PATH=/opt/hisi-linux/x86-arm/arm-hisiv300-linux/target/bin:$PATH  然后 source ~/.bashrc使其生效

(6)继续编译make OSDRV_CROSS=arm-hisiv300-linux CHIP=hi3518ev200 all

(7)制作文件系统镜像

     SPI flash目前是使用64KB为大小来擦除的,所以下面0x40000改为0X10000 这里的单位都是B,64KB=64*1024B=65536(0x10000)

     osdrv/pub/bin/pc/mkfs.jffs2 -d osdrv/pub/rootfs_uclibc -l -e 0x40000 -o osdrv/pub/rootfs_uclibc_256k.jffs2

(8)fatal error: zlib.h: No such file or directory 报错需要安装 sudo apt-get install zlib1g-dev

(9)手工单独制作rootfs

     手动拷贝cp /osdrv/tools/pc/jffs2_tool/tmp/mtd-utils-1.5.0/mkfs.jffs2 /osdrv/pub/bin/pc

     /osdrv/pub/bin/pc下面的mkyaffs2image100可以删除,我们不需要yaffs的镜像,删除后在osdrv/pub/image_uclibc下面也不会出现yaffs的镜像

     修改osdrv/下的Makefile  

     hipctools: prepare下面值保留 

        @echo "---------task [5] build tools which run on pc"

    保存,重新编译 make OSDRV_CROSS=arm-hisiv300-linux CHIP=hi3518ev200 all

     制作参数为:osdrv/pub/bin/pc/mkfs.jffs2 -d osdrv/pub/rootfs_uclibc -l -e 0x10000 -o osdrv/pub/rootfs_uclibc_64k.jffs2

(10)编译最终完成的标准

     在/opt/share/Hi3518E_SDK_V1.0.3.0/osdrv/pub/image_uclibc目录下得到uboot、uImage和roorfs即是我们要的uboot镜像、kernel的

     uImage镜像和文件系统。u-boot-hi3518ev200.bin(268K)  uImage_hi3518ev200(2.6M)  rootfs_hi3518ev200_64k.jffs2(4.8MB)

5. 烧录

(1)各种常见flash的简单讲解

        flash存储颗粒+外部封装的控制器(决定接口类型)

(2)像EMMC、SD、MMC、SPIFLASH、NANDFLASH等差异都在于控制器,内部的存储颗粒都是NAND颗粒。NANDFLASH控制复杂,主芯片内部必须要

    集成NAND控制器,器控制器是最老的最原始的,其实NANDFLASH是即将淘汰的产品,像EMMC(板载)及SD(tf卡)这种都比NANDFLASH要更新一些,

    如果需求是512M或者1G以上的这种大容量的建议选择EMMC(板载)及SD(tf卡)。现在的手机都逐渐由外扩的SD(tf卡)转为EMMC(板载)了。原始的

    NANDFLASH现在用的越来越少了,因为NANDFLASH的兼容性不好。EMMC是无缝替换,不同容量的封装兼容,换一个容量或厂家什么都不用改。

    SPIFLASH控制简单,主芯片只要支持SPI协议即可,在8M、16M、32M、64M这个级别占优势。容量小,成本低。

    比SPIFLASH容量更小,成本更低的有EEPROM

(3)运行Hitool前先安装jre-6u45-windows-i586,一定是这个版本,因为Hitool是基于这个版本来开发的

(4)烧录uboot成功,print查看默认的环境变量

(5)因为嵌入式系统为了简化,没有使用分区表来自动管理flash,所有都是事先定死的,所以在部署一个嵌入式系统前都要人为的定下一个分区,原则为:

     每个分区要足够放镜像;尽量留一点扩展余地;在满足前面两条的情况下你随便搞。

(6)我定的分区:

     分区名              分区大小          起始地址                截止地址     

     bootloader             1M             0X00000000               0x00100000   (1024*1024)B

     kernel:                3M             0X00100000               0X00400000

     rootfs                 12M            0X00400000               0X01000000

(7)烧录kernel及rootfs

    3518EV200 DDR2地址范围为 80000000-83FFFFFF  手册上有

    在这个地址范围内挑一个大小为4.8MB的内存,因为rootfs_hi3518ev200_64k.jffs2(4.8MB)最大,官方推荐从0x82000000开始

    ==============================================================================================================================================

    tftp更新并重新烧写uboot的命令序列:

    mw.b 0x82000000 ff 0x100000           (mw.b 写内存,以字节为单位操作,0x82000000 ff内存从0x82000000开始清成全ff,0x100000为清理的大小为1MB

    tftp 0x82000000 u-boot-hi3518ev200.bin  从服务器(Ubuntu)下载文件(u-boot-hi3518ev200.bin)到内存0x82000000

    sf probe 0  先选中spiflash ,0代表第一个,板上可能有多个flash

    sf erase 0x0 0x100000

    sf write 0x82000000 0x0 0x100000

    ==============================================================================================================================================

    tftp更新并重新烧写kernel的命令序列:

    mw.b 0x82000000 ff 0x300000           (mw.b 写内存,以字节为单位操作,0x82000000 ff内存从0x82000000开始清成全ff,0x300000为清理的大小为1MB

    tftp 0x82000000   uImage_hi3518ev200 从服务器(Ubuntu)下载文件(uImage_hi3518ev200)到内存0x82000000

    sf probe 0  先选中spiflash ,0代表第一个,板上可能有多个flash

    sf erase 0x100000 0x300000

    sf write 0x82000000 0x100000 0x300000

    ==============================================================================================================================================

    tftp更新并重新烧写rootfs的命令序列:

    mw.b 0x82000000 ff 0xc00000           (mw.b 写内存,以字节为单位操作,0x82000000 ff内存从0x82000000开始清成全ff,0xa00000为清理的大小为1MB

    tftp 0x82000000 rootfs_hi3518ev200_64k.jffs2  从服务器(Ubuntu)下载文件(rootfs_hi3518ev200_64k.jffs2)到内存0x82000000

    sf probe 0  先选中spiflash ,0代表第一个,板上可能有多个flash

    sf erase 0x400000 0xc00000

    sf write 0x82000000 0x400000 0xc00000

    ==============================================================================================================================================

(8)修改uboot环境变量并烧录

printenv

    bootargs=mem=96M console=ttyAMA0,115200    

    bootcmd=bootm 0x82000000

    bootdelay=1

    baudrate=115200

    ethaddr=00:00:23:34:45:66

    ipaddr=192.168.1.10

    serverip=192.168.1.2

    netmask=255.255.255.0

    bootfile="uImage"

    stdin=serial

    stdout=serial

    stderr=serial

    verify=n

    ver=U-Boot 2010.06 (Sep 17 2018 - 20:12:12)

    serverip需要修改为服务器ubuntu的IP(192.168.1.141)修改方法为 :setenv serverip 192.168.1.141 然后保存一下 saveenv

    ping 192.168.1.141可以ping通,就可以下载kernel了

    一条一条执行kernel的命令序列:

    一条一条执行rootfs的命令序列:

    kernel和rootfs烧录完成以后,需要设置bootcmd bootargs 设置完成saveen一下,reset后系统启动成功

    附2:正确的bootcmd和bootargs对应的设置命令:

    set bootcmd 'sf probe 0;sf read 0x82000000 0x100000 0x300000;bootm 0x82000000'

    set bootargs mem=32M console=ttyAMA0,115200 root=/dev/mtdblock2 rootfstype=jffs2 mtdparts=hi_sfc:1024K(boot),3072K(kernel),12288K(rootfs)

(9)总结

    SPIFLASH擦除比较慢,读写的速度倒是挺快的。

6. rootfs启动之后做了什么

(1)挂载根文件系统后第一个启动的就是/etc/init.d/rcS文件

(2)/etc/fstab :与挂载的各种虚拟文件系统有关

(3)fs-version:版本号相关

(4)group :管理用户组的  里面的值为root::0:导致开发板登入时为root用户

(5)profile :启动的时候会默认去调用里面的东西

    与环境变量设置相关,echo &PATH   /usr/bin:/usr/sbin:/bin:/sbin

    echo "${GREEN}Welcome to HiLinux.${NORMAL}"  表示开始启动的Welcome to HiLinux.这句话用绿色打印出来

    然后再把颜色设置为NORMAL,

(6)udev目录用来做即插即用的,usb、sd卡等

(7)init.d目录 :rcS是总的纲领,rcS去调用S00devs S01udev S80network S90hibernate

    这些文件命令都是用大写的S开头就是为了能够用一个for循环去执行,后面的数字是为了

    把它们区分开的,数字后面在加这些名字是为了告诉你这些文件是干什么的,S00devs 一看

    就是和devs有关的,

#! /bin/sh

/bin/mount -a

echo "

            _ _ _ _ _ _ _ _ _ _ _ _

            \  _  _   _  _ _ ___

            / /__/ \ |_/

           / __   /  -  _ ___

          / /  / /  / /

  _ _ _ _/ /  /  \_/  \_ ______

___________\___\__________________

"

for initscript in /etc/init.d/S[0-9][0-9]*   //那几个文件都是以大S开头就是为了这里能够用for循环去执行,依次S[0][0]*  S[0][1]* ...

do

    if [ -x $initscript ] ;          //-x表示这个文件存在且可执行则为真

    then

        echo "[RCS]: $initscript"    //这个文件名打印出来

        $initscript                  //并执行这个文件

    fi

done

S00devs文件内容如下:创建设备节点

#!/bin/sh

mknod /dev/console c 5 1

mknod /dev/ttyAMA0 c 204 64

mknod /dev/ttyAMA1 c 204 65

mknod /dev/ttyS000 c 204 64

mknod /dev/null       c 1 3

注意:其实我们在做文件系统的时候已经做了console、ttyAMA0、null打印就会提示文件已经存在

mknod: /dev/console: File exists

mknod: /dev/ttyAMA0: File exists

mknod: /dev/null: File exists

S01udev文件内容如下:

#!/bin/sh

mkdir /dev/pts

mount -t devpts devpts /dev/pts

mkdir -p /dev/.udev        

udevd --daemon       #udevd是一个应用程序,--daemon 就是创建那个守护进程,进程创建后内核就可以检测

                     #即插即拔的设备

udevadm trigger

S80network文件内容如下:

#!/bin/sh

ipaddr=

bootp=

gateway=

netmask=

hostname=

netdev=

autoconf=           #定义变量

for ipinfo in `cat /proc/cmdline`     #cmdline里面内容为mem=32M console=ttyAMA0,115200 root=/dev/mtdblock2 rootfstype=jffs2 rw mtdparts=hi_sfc:1M(boot),3M(kernel),12M(rootfs)

do

        case "$ipinfo" in

        ip=*)

                for var in  ipaddr bootp gateway netmask hostname netdev autoconf

                do

                        eval read $var

                done << EOF

                `echo "$ipinfo" | sed "s/:/\n/g" | sed "s/^[    ]*$/-/g"`

EOF

                ipaddr=`echo "$ipaddr" | cut -d = -f 2`

                [ x$ipaddr == x ] && ipaddr=x

                ;;

        esac

done            #cmdline里面没有ip=*,没有case到

[ -z "$ipaddr" ] && exit 0       #-z用于测试ipaddr长度是否为0,如果ipaddr长度为0则成立,则执行exit 0退出。

echo "      IP: $ipaddr"

echo "   BOOTP: $bootp"

echo " GATEWAY: $gateway"

echo " NETMASK: $netmask"

echo "HOSTNAME: $hostname"

echo "  NETDEV: $netdev"

echo "AUTOCONF: $autoconf"       #这一堆都没有得到执行,因为前面exit 0得到执行已经退出了

if [ x$ipaddr == x- ] ; then     

        # use DHCP

        :

else

        cmd="ifconfig $netdev $ipaddr"

        [ x$netmask != x- ] && cmd="$cmd netmask $netmask"

        eval $cmd

        [ x$gateway != x- ] && route add default gw $gateway

fi                           #没有得到执行

ifconfig lo 127.0.0.1        #没有得到执行

我们可以通过ifconfig -a查看所有的网卡,发现eth0和lo两个网卡都没有打开,因为S80network文件到[ -z "$ipaddr" ] && exit 0 

这里就已经退出了,什么事也没有干,所以我们要设置网卡的时候,我们的命令语句要放在[ -z "$ipaddr" ] && exit 0 的前面

eth0      Link encap:Ethernet  HWaddr 36:9C:26:23:1C:BD  

          BROADCAST MULTICAST  MTU:1500  Metric:1

          RX packets:0 errors:0 dropped:0 overruns:0 frame:0

          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000 

          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

          Interrupt:28 

lo        Link encap:Local Loopback  

          LOOPBACK  MTU:65536  Metric:1

          RX packets:0 errors:0 dropped:0 overruns:0 frame:0

          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:0 

          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

S90hibernate文件内容如下:

#!/bin/sh

echo "/root/pm_callback" > /proc/sys/kernel/pm_notifier  #好像是与电源管理相关的,

cmdline=`cat /proc/cmdline`

hbtype=resume

for str in $cmdline

do

    case $str in 

         hbtype=*)

         hbtype=`echo "$str" | awk -F"=" '{print $2}'`

    esac

done

if [ "$hbtype"x = "snap"x ]; then

    echo "hibernate start"

    echo disk > /sys/power/state

fi          

总结:默认的根文件系统提供的这些还远远不够,还需要往里面添加东西

例如我们可以在S80network中把网卡给设置上,就可以在[ -z "$ipaddr" ] && exit 0前面把

ifconfig lo 127.0.0.1

ifconfig eth0 192.168.1.10

给加上

#!/bin/sh

ipaddr=

bootp=

gateway=

netmask=

hostname=

netdev=

autoconf=

for ipinfo in `cat /proc/cmdline`

do

    case "$ipinfo" in

    ip=*)

        for var in  ipaddr bootp gateway netmask hostname netdev autoconf

        do

            eval read $var

        done << EOF

        `echo "$ipinfo" | sed "s/:/\n/g" | sed "s/^[     ]*$/-/g"`

EOF

        ipaddr=`echo "$ipaddr" | cut -d = -f 2`

        [ x$ipaddr == x ] && ipaddr=x

        ;;

    esac

done

ifconfig lo 127.0.0.1

ifconfig eth0 192.168.1.10

[ -z "$ipaddr" ] && exit 0

echo "      IP: $ipaddr"

echo "   BOOTP: $bootp"

echo " GATEWAY: $gateway"

echo " NETMASK: $netmask"

echo "HOSTNAME: $hostname"

echo "  NETDEV: $netdev"

echo "AUTOCONF: $autoconf"

if [ x$ipaddr == x- ] ; then

    # use DHCP

    :

else

    cmd="ifconfig $netdev $ipaddr"

    [ x$netmask != x- ] && cmd="$cmd netmask $netmask"

    eval $cmd

    [ x$gateway != x- ] && route add default gw $gateway

fi

ifconfig lo 127.0.0.1

7. mpp

    \Hi3518E_SDK_V1.0.3.0\mpp\ko目录下的ko文件都是海思预先编译好的模块,用ko的形式提供主要是海思不想开源。

    一是为了版权保护;二是即使给你源码你也玩不来。所以海思预先开发好,预编译成一个库文件提供给我们,我们

    把这些库文件拿到我们的系统里面部署好,部署好之后在系统启动的时候采用insmod方式去安装这些模块,这些

    模块安装了之后呢我们的内核里面就多了这些驱动了,多了这些驱动之后呢我们就可以去调用它们来完成相应的一些

    工作。

    这些ko文件的安装不用我们自己来操作的,ko目录下面有一个load3516ev100文件,这是一个sh文件。

    用法文件的第二行有提示:

    # Useage: ./load3516ev100 [ -r|-i|-a ] [ sensor ]

####################MMZ config####################################   定义变量 

mem_total=64;              # 64M, total mem

mem_start=0x80000000;       # phy mem start

os_mem_size=32;             # 32M, os mem

mmz_start=0x82000000;       # mmz start addr

mmz_size=32M;              # 32M, mmz size

##################################################################

####################sensor config#################################   sensor选择

#sensor list: imx290, imx323, ov2718, ar0237, jxf22, sc2235

SNS_TYPE=imx290;            # sensor type

##################################################################

insert_ko()

{

    insert_sns

    insmod sys_config.ko vi_vpss_online=$b_arg_online

    # driver load

    insmod hi_osal.ko mmz=anonymous,0,$mmz_start,$mmz_size anony=1 || report_error

    insmod hi3516cv300_base.ko

    insmod hi3516cv300_sys.ko vi_vpss_online=$b_arg_online sensor=$SNS_TYPE mem_total=$mem_total

    insmod hi3516cv300_region.ko

    insmod hi3516cv300_vgs.ko vgs_clk_frequency=$vgs_frequency

    insmod hi3516cv300_viu.ko detect_err_frame=10 viu_clk_frequency=$viu_frequency isp_div=$isp_div input_mode=$intf_mode

    insert_isp;

    insmod hi3516cv300_vpss.ko vpss_clk_frequency=$vpss_frequency

    insmod hi3516cv300_vou.ko vou_mode=$vou_intf_mode

    #insmod hi3516cv300_vou.ko detectCycle=0 vou_mode=$vou_intf_mode #close dac detect

    #insmod hi3516cv300_vou.ko transparentTransmit=1 vou_mode=$vou_intf_mode #enable transparentTransmit

    insmod hi3516cv300_rc.ko

    insmod hi3516cv300_venc.ko

    insmod hi3516cv300_chnl.ko

    insmod hi3516cv300_vedu.ko vedu_clk_frequency=$vedu_frequency

    insmod hi3516cv300_h264e.ko

    insmod hi3516cv300_h265e.ko

    insmod hi3516cv300_jpege.ko

    insmod hi3516cv300_ive.ko save_power=1 ive_clk_frequency=$ive_frequency

    insmod hi3516cv300_sensor.ko sensor_bus_type=$bus_type sensor_clk_frequency=$sensor_clk_freq sensor_pinmux_mode=$pinmux_mode

    insmod hi3516cv300_pwm.ko

    insmod extdrv/hi_piris.ko

    insert_audio

    insmod hi_mipi.ko

    echo "==== Your input Sensor type is $SNS_TYPE ===="

}

    himm:Hisilicon memery modify 海思内存修改工具  这个工具事先已经编译到根文件系统里面去了。

    himm 0x80040000 0x123   

         寄存器地址  寄存器值

    意思就往地址0x80040000 写入值0x123 

    mmz.ko内存管理相关,3518ev200里面Linux系统和mpp内存是分开的,他们两个占用的内存要小于等于64MB

    insmod mmz.ko mmz=anonymous,0,$mmz_start,$mmz_size anony=1 || report_error 让mpp从总内存64MB分一部分。

    3518EV200 DDR2地址范围为 80000000-83FFFFFF

    mmz_start=0x82000000;       # mmz start addr   可以看出mmz的范围0x82000000-0x83FFFFFF    32MB

    mem_start=0x80000000;       # phy mem start    可以看出Linux内存的范围0x80000000-0x81FFFFFF   32MB

    各自的大小看情况定,不一定要一样大。操作系统这边我们可以决定,mpp那边是海思定的,我们可以在满足操作系统

    这边的前提下,尽量多给mmz内存。

8. 在开发板上部署ko、lib

    ./load3518e -i -sensor ar0130 -osmem 32 -total 64    注意:装载sensor是不能动态装载的,要重启

    根文件系统需要部署ko、库lib             注意:.a是静态库,.so动态库,做产品用到得留下,用不到的删除。

    挂载上之后先把ko拷贝到根目录下,个人习惯,cp ko / -rf

    lib拷贝到/usr/lib/(用户库)下面   个人习惯,  cp lib/* /usr/lib/ -f  因为/lib是系统的库,用在系统的库下面不太合适

    你也可以另外建一个文件来存放这些库,然后通过export导出

    还不如直接放在/usr/lib下面,反正这个目录已经导出了

    通过命令查询服务器nfs的共享目录:sudo showmount -e

    在/etc/profile最后一行添加

    ifconfig lo 127.0.0.1

    ifconfig eth0 192.168.10.1  这里要隔一下,等通了再挂载

    mount -t nfs -o nolock 192.168.1.101:/opt/nfs /mnt

    部署ko及lib到挂载目录

    最终在/etc/profile添加的是

    ifconfig lo 127.0.0.1

    ifconfig eth0 192.168.1.10

    cd /ko

    ./load3518e -i -sensor ar0130 -osmem 32 -total 64 

    mount -t nfs -o nolock 192.168.1.101:/opt/nfs /mnt

    cd /mnt

    至此,板上ko及lib部署完成。

9. 测试海思的sampe

    编译sampe之前要先修改/mpp/sample/Makefile.param  

    使能下面

    CHIP_ID ?= CHIP_HI3518E_V200

    SENSOR_TYPE ?= APTINA_AR0130_DC_720P_30FPS

    进入/mpp/sample/venc下面make

    在当前目录下编译得到可执行文件sample_venc 把它拷贝到挂载目录/opt/nfs在开发板上执行

    ./sampe_venc 0 选择第一种模式,

    c 选择第一种码流模式

    按两次回车,停止录像,在当前目录下得到三段h.264视频,分别对应1、2、3通道视频,内容一样,分辨率不一样。

    1920*1080*20+720*576*20=49766400    1920*1080*25=51840000算出来差不多  

    子码流的能力可以折合到主码流中

10. 制作完成的根文件系统,

    如果希望ko lib提前部署到根文件系统里面,

    (1)在osdrv/pub目录下解压rootfs_uclibc.tgz,得到目录rootfs_uclibc,进入目录rootfs_uclibc,提前把/mpp下的ko及/mpp/lib下的库复制到rootfs_uclibc及user/lib下

    (2)更改rootfs_uclibc/etc/profile,与第八点更改一致即可。

    (3)手工制作rootfs

        退到Hi3518E_SDK_V1.0.3.0目录下执行

         osdrv/pub/bin/pc/mkfs.jffs2 -d osdrv/pub/rootfs_uclibc -l -e 0x10000 -o osdrv/pub/rootfs_uclibc_64k.jffs2   注意:这里SPI block大小为64KB,block大小在uboot开始几行打印出来

        则在/osdrv/pub下生成rootfs_uclibc_64k.jffs2文件,然后烧录即可。

    注意

    (1)./load3516ev100 -i imx323  提示没有执行权限,要在拷贝到rootfs_uclibc目录下之前就把权限修改好。

    (2)==== Your input Sensor type is imx290 ====串口打印还是imx290,

    因为文件load3516ev100没有改为对应型号imx323

           ####################sensor config#################################   sensor选择

           #sensor list: imx290, imx323, ov2718, ar0237, jxf22, sc2235

           SNS_TYPE=imx290;            # sensor type

    进入目录Z:\Hi3518E_V200R001C01SPC020\Hi3518E V200R001C01SPC020\01.software\board

把Hi3518E_SDK_V1.0.2.0.tgz拷贝到自己的工作目录

解压Hi3518E_SDK_V1.0.2.0.tgz得到文件夹Hi3518E_SDK_V1.0.2.0

cd Hi3518E_SDK_V1.0.2.0 

执行source sdk.cleanup清除之前的文件,./sdk.cleanup不行。

然后执行source sdk.unpack解压文件,./sdk.unpack不行。

make OSDRV_CROSS=arm-hisiv300-linux CHIP=hi3518ev200 all  编译osdrv整个目录

报错/bin/sh: 1: popd: not found 

进入/bin目录,查看sh的链接文件,显示如下:表示sh命令链接到的是dash,而pushd命令需要在bash的环境中执行。

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

再执行make OSDRV_CROSS=arm-hisiv300-linux CHIP=hi3518ev200 all 

报错arm-hisiv300-linux-gcc: Command not found 

可能是Makefile里面arm-hisiv300-linux-gcc路径不对

cp arm-hisiv300-linux.tar.bz2 /data/Hi3518E_SDK_V1.0.2.0/osdrv 把交叉编译工具拷贝到当前目录

tar xjvf arm-hisiv300-linux.tar.bz2 解压工具链

再执行make OSDRV_CROSS=arm-hisiv300-linux CHIP=hi3518ev200 all

报错arm-hisiv300-linux-gcc: Command not found还是找不到,有两种可能一是路径还是不对,二是32位和64位的问题

看一下交叉编译工具链是32还是64位的,因为系统是64位,

其实最终是要找到osdrv/arm-hisiv300-linux/bin下面的工具链,发现下面的工具链的名称arm-hisiv300-linux-uclibcgnueabi

都是以uclibcgnueabi结尾,file arm-hisiv300-linux-uclibcgnueabi-gcc  发现工具链都是32位的,在64位的机器上是不能运行的

解决方法

(1)方法1:换32位ubuntu

(2)方法2:装32位兼容包(windows的64位是兼容32位的,但是在ubuntu里面不行,必须要安装兼容包)

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

(1)参考:http://blog.csdn.net/ma57457/article/details/68923623

或者:https://www.cnblogs.com/leaven/p/5084902.html

(2)用apt-get install lib32z1 或者apt install lib32z1安装lib32z1。如果发现装不了请用 aptitude方式安装lib32z1。原因是ubuntu太新了,里面很多库都是新版本的,但是基于这个新版本的lib32z1还没有,所以不能装。解决方案就是用aptitude工具来装。看前导课程《嵌入式linux开发环境搭建》的第6节的6.3部分。

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

./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或者sudo apt install lib32stdc++6-4.8-dbg

再次测试arm-xxx-gcc -v,终于可以运行了。

再次测试整体编译osdrv

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

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

(2)修改Makefile中OSDRV_CROSS的路径,结果不行,分析原因是:命令行传参覆盖了

(3)export导出到环境变量,参考裸机课程1.4节,格式为:

echo $PATH先导出原来的环境变量

再添加环境变量

export PATH=/data/Hi3518E_SDK_V1.0.2.0/osdrv/arm-hisiv300-linux/bin:$PATH

arm-hisiv300-linux-uclibcgnueabi-gcc -v在非arm-hisiv300-linux/bin目录下来执行成功,说明环境变量导出成功

cd ~ 切换到对应用户的家目录

vim .bashrc

export PATH=/data/Hi3518E_SDK_V1.0.2.0/osdrv/arm-hisiv300-linux/bin:$PATH 直接写入.bashrc

这样以后每次打开终端环境变量都生效

再次测试整体编译 make OSDRV_CROSS=arm-hisiv300-linux CHIP=hi3518ev200 all 

直接测试可以执行了,但是编译还是出错。分析原因:名字不对make里面是arm-hisiv300-linux但是我们直接执行的是arm-hisiv300-linux-uclibcgnueabi

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

rm -fr arm-hisiv300-linux rm -f arm-hisiv300-linux.tar.bz2 删除刚刚解压的arm-hisiv300-linux,因为在Hi3518E_SDK_V1.0.2.0/目录下执行sdk.cleanup  sdk.unpack任意一个文件,下面的所有的文件都将被清空

切换到/osdrv/opensource/toolchain/arm-hisiv300-linux目录执行./cross.v300.install 

然后到/opt/hisi-linux/x86-arm/arm-hisiv300-linux/target/bin下执行./arm-hisiv300-linux-gcc -v 执行成功后

添加环境变量到~/.bashrc中export PATH=/opt/hisi-linux/x86-arm/arm-hisiv300-linux/target/bin:$PATH

source ~/.bashrc使其生效

在非arm-hisiv300-linux/target/bin目录下执行arm-hisiv300-linux-gcc -v成功

切换回osdrv目录下执行make OSDRV_CROSS=arm-hisiv300-linux CHIP=hi3518ev200 all 再次编译

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

(1)install到/opt目录下并建立符号链接

(2)导出到PATH并测试可以执行

(3)再次编译

第一季

1.视频压缩算法有哪些,h.264 mjpeg目前主流的是h.264,压缩就编码,编码就是压缩,3518e内部专门用一个DSP来做视频编码。

2.视频经过压缩之后变成了h.264视频流,压缩的目的就是为了好传输,可以通过有线或无线网络,USB等传输。

3.网络传输协议:http/rtsp等

4.接收端一般有两种处理方法,一种存储,例如把h.264流打包成mp4格式存储;另一种是直接显示。

5.视频回放:解码+播放 解码成原始的图像,位图的图像,播放就是直接把位图的图像丢到LCD里面去播放。

6.视频行业的商业角度分段

(1)主芯片商、sensor、镜头等分立元器件厂商。

(2)模组厂商

(3)视频服务器厂商

(4)面向解决方案的方案开发商

(5)工程商或销售商

7.视频为什么要编码和解码?

    原始视频太大,网络带宽有限,

8.主芯片3518e主要解决什么问题?

    编解码及ISP

9.视频传到传输为什么要用Linux

    Linux里面网络的协议栈是最全的,Linux里面关于网络这一块的开发是最多的。但是在ISP及编码这一段

    安霸用的是rtos,在视频的网络传输这一段用的是LINUX。海思整个过程全部用Linux。

3518e方案系统整体架构介绍

1.硬件 

(1)CPU(ARM9)+DSP+512Mb(64MB)DDR2

(2)外置SPI Flash用来存放程序(uboot、kernel、rootfs、app)

    为什么不用NOR FLASH?太贵

    为什么不用NAND FLAHS?没必要,容量用不了那么大

    为什么不用EMMC?太贵,容量太大浪费。入门级的4GB的二十多块。

    16MB的SPI两块人民币,而且程序(uboot、kernel、rootfs、app)不超过16MB

(3)SD卡扩展提供用户数据区  

    行车记录肯定要

    IPC可以不要,视频可以通过网卡或者WIFI传输

(4)sensor接口 并行接口或者串行接口(MIPI CSI 及LVDS)

(5)串口

2. 软件

(1)SPIFlash分区烧录uboot.bin、zImage、rootfs

 每一段都有预留余量空间

(2)驱动支持

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

(4)各种专业工作(例如内置DSP实现h.264编码压缩)都由海思开发好并以ko的形式提供,应用开发人员

    只要去调用API实现。

3.SDK

(1)JTAG主要用来调试非常底层的东西的,其实就是UBOOT的,但是实际工作中UBOOT不用从头开始开发。

    所有平时用不到。

(2)uClibc比较精简,它通过glibc库精简出来的,只留下了一些必要的东西,它认为用处不大的东西全部精简掉了,缺点就是功能不全,海思的

    方案SPIflash都是配的是16MB,在这种情况下,你只能用uclibc库。

     glibc比较庞杂,是gcc里面的标准库,什么功能都有,缺点就是太大了,适用于板载emmc等大容量的flash

(3)arm-hisiv300-linux基于uclibc的,编译出来的程序较小  推荐使用arm-hisiv300-linux

    arm-hisiv400-linux是基于glibc的,编译出来的程序较大

(4)把Hi3518E_SDK_V1.0.3.0.tgz复制到Samba共享目录 /opt/share/

(5) 在目录/opt/share/解压 tar xzvf Hi3518E_SDK_V1.0.3.0.tgz 

(6)在目录下/opt/share/Hi3518E_SDK_V1.0.3.0执行  source sdk.cleanup   (这里必须用source才行)

Cleanup SDK

继续阅读