Zephyr系统移植调试小结

一、    zephyr开发环境搭建

1.安装常用的开发工具,gcc gdb g++ make git-corelibncurses5-dev

$ sudo apt-get update

$ sudo apt-get install gcc gdb g++ makegit-core libncurses5-dev

说明:zephyr系统支持makemenuconfig配置,libncurses5-dev必须要安装;

2.编译zephyr工程用toolchain的下载和配置

目前由两种方法编译Zephyr工程,分别为使用官网SDK包和开源Toolchain

1)  官网SDK包的下载和安装

目前zephyr官网最新的SDK版本是0.8.2,下载地址如下:

https://nexus.zephyrproject.org/content/repositories/releases/org/zephyrproject/zephyr-sdk/0.8.2-i686/zephyr-sdk-0.8.2-i686-setup.run

安装的方法非常简单,直接运行SDK安装包即可,

$ chmod +x zephyr-sdk-0.8.2-i686-setup.run

$ sudo ./ zephyr-sdk-0.8.2-i686-setup.run

安装过程中会提示,让用户指定安装路径(/usr/zephyr_sdk),如果用户不指定,则默认安装到/opt/zephyr-sdr目录下,稍等即可安装完成;

Zephyr SDK内置的ToolChain不支持Cortex-M7处理器的编译选项,仅仅支持Cortex-M0+/Cortex-M0/Cortex-M1/Cortex-M3/Cortex-M4,

我们的ATSAMV71_XULT板卡SOCATSAMV71Q21内部CPU版本为Cortex-M7,因此暂时无法使用官网自动的SDK包,需要使用下面介绍的第二种方法;

2)开源ToolChain的下载与配置

最新版本开源ToolChain下载地址如下,该ToolChain支持Cortex-M0+/Cortex-M0/Cortex-M1/Cortex-M3/Cortex-M4/Cortex-M7/ARMv8-M等CPU的编译选项

https://launchpadlibrarian.net/287101520/gcc-arm-none-eabi-5_4-2016q3-20160926-linux.tar.bz2

下载完成后解压缩到指定目录,比如/home/user/gcc-arm-none-eabi-5_4-2016q3,后续编译zephyr代码时会用于此路径

$ tar –xvfgcc-arm-none-eabi-5_4-2016q3-20160926-linux.tar.bz2

注意:

通过验证,目前zephyr官网最新SDK开发包(zephyr-sdk-0.8.2-i686-setup.run)不支持Cortex-M7选项的编译,因此必须采用介绍的第二种方式,采用开源ToolChain进行编译

随着zephyr系统SDK版本的升级,或许不久后新的SDK支持Cortex-M7;

二、    zephyr源码的获取以及编译方法

1.  zephyr源码的获取

经过Review代码得知,zephyr 1.5.0以及以下版本的源码在代码架构上不支持Cortex-M7,目前我们使用1.6.0版本的代码(截止目前为止,最新的标签代码是1.6.0);

1.6.0版本zephyr源码包获取方法如下:

$ git clone https://gerrit.zephyrproject.org/r/zephyr && cd zephyr &&git checkout tags/v1.6.0

2. zephyr代码编译

1)使用官方SDK编译zephyr工程

虽然官网SDK目前还不支持Cortex-M7处理器的编译,但是支持Cortex-M0/Cortex-M1/Cortex-M3/Cortex-M4,因此简要说明一下使用官方SDK编译Zephyr的方法;

假设zephyr源码所在路径为/home/user/build/zephyr-1.6.0,SDK安装路径为:/user/zephyr_sdk

编译步骤导致包括,导出SDK安装路径和GCC变量,加载zephyr Env文件,执行编译;

$ export ZEPHYR_GCC_VARIANT=zephyr

$ export ZEPHYR_SDK_INSTALL_DIR=/usr/zephyr_sdk

$ cd /home/user/build/zephyr-1.6.0

$ source zephyr-env.sh

$ cd samples/helloworld/ && makeARCH=arm BOARD=samv71_xult

说明:

编译时ARCH指定编译工程使用的体系结构(比如ARM或X86),BOARD指定编译的板卡形态;

2)使用开源ToolChain编译zephyr工程

使用开源ToolChain编译zephyr与上面的步骤差不多,同样也是导出GCC变量和ToolChian路径,不同的是二者导出的ToolChain路径的变量名不一样

$ export ZEPHYR_GCC_VARIANT=gccarmemb

$ export GCCARMEMB_TOOLCHAIN_PATH="/home/user/ gcc-arm-none-eabi-5_4-2016q3"

$ cd /home/user/build/zephyr-1.6.0

$ source zephyr-env.sh

$ cd samples/helloworld/ && makeARCH=arm BOARD=samv71_xult

 

编译完成后,生成的目标文件和zephyr.bin位于hello_wolrd目录下的outdir目录下

/home/user/build/zephyr-1.6.0/samples/hello_world/outdir/samv71_xult

说明:

Ø 使用开源ToolChain编译zephyr工程,在导出变量GCCARMEMB_TOOLCHAIN_PATH时,后面的路径一定要加上“”,否则编译出错;

Ø 编译时如果想看到编译的具体过程,通过在编译时传入参数V=1可以看到具体编译选项和过程(make ARCH=armBOARD=samv71_xult V=1)

Ø  上述例子事宜编译应用hello_world为例,如果需要编译其他APP,则进入目录zephyr-1.6.0/samples下其他应用目录,执行编译命令即可;

Ø  如果用户希望通过界面对工程进行配置,可以在在编译命令后面加上 menuconfig,如下:

make ARCH=arm BOARD=samv71_xult menuconfig

配置完成保存后,会在目录zephyr-1.6.0/samples/hello_world/ourdir/samv71_xult/生成更新后的系统配置文件(.config文件)

2.  zephyr工程clean

$ cd/home/user/build/zephyr-1.6.0/samples/hello_world

$ make ARCH=arm BOARD=samv71_xultclean   清除临时文件

$ make ARCH=arm BOARD=samv71_xult distclean 清除系统配置文件

$ makepristine       清除zephyr-1.6.0/samples/hello_world/outdir目录内所有文件以及outdir目录

三、    基于zephyr工程添加开发板samv71_xult的配置

1.  添加samv71_xult板卡配置

经过确认zephyr工程代码,自带一套atmelsamv3的板卡配置,对应Board目录为arduino_due,因此我们可以参考arduino_due的板卡配置来建立我们atmel samv71_xult板卡配置;

$ cd /home/user/build/zephyr-1.6.0/

$ cd boards/arm

$ cp arduino_due samv71_xult –av

copy一份atmel sam3的板卡配置,基于sam3的板卡配置进行修改,当然如果熟悉的话,可以直接自己定义新板卡samv71_xult的具体配置;

具体需要修改的文件列表如下:

Kconfig.board: 该文件主要是对板卡名字以及界面显示的板卡信息进行配置,配置完成后的内容如下:

config BOARD_SAMV71_XULT

    bool"Samv71_xult Board"

    depends onSOC_ATMEL_SAM7X8E

Kconfig.defconfig:该文件主要是配置板卡目录名字以及I2C的信息,配置完成后的内容如下:

if BOARD_SAMV71_XULT

config BOARD

    defaultsamv71_xult

if I2C

config I2C_ATMEL_SAM7

    default y

endif # I2C

endif # BOARD_SAMV71_XULT

samv71_xult_defconfig:该文件主要是对samv71_xult板卡本身的一些信息进行配置比如SOC,BOARD, UART, CLOCK Source,GPIO等,配置完成后的内容如下:

CONFIG_ARM=y

CONFIG_SOC_ATMEL_SAM7X8E=y

CONFIG_BOARD_SAMV71_XULT=y

CONFIG_CORTEX_M_SYSTICK=y

CONFIG_CONSOLE=y

CONFIG_UART_CONSOLE=y

CONFIG_SERIAL=y

CONFIG_UART_ATMEL_SAM7=y

CONFIG_SOC_ATMEL_SAM7_EXT_MAINCK=y

CONFIG_SOC_ATMEL_SAM7_EXT_SLCK=y

CONFIG_PINMUX=y

CONFIG_GPIO=y

CONFIG_GPIO_ATMEL_SAM7=y

2.  添加atmel_sam7的SOC配置;

对于添加atmel_sam7的SOC配置,我们依旧参考既有的atmel_sam3配置,完成atmel_sam7的SOC配置

$ cd/home/user/build/zephyr-1.6.0/

$ cd arch/arm/soc

$ cp atmel_sam3/ atmel_sam7 -av

    Atmel_sam7目录下主要包含如下文件

Kconfig: 主要是根据samv71_xult定义SOC宏,定义该板卡的时钟源(比如SLCK和MAINCK),以及时钟振荡器的分频配置;

Kconfig.defconfig:主要配置SOC相关的信息,比如SRAM,FLASH的偏移地址和大小,中断的Number以及PORT信息;

Kconfig.soc:定义一些CPU类型和SOC名字,配置完成后内容参考如下:

config SOC_ATMEL_SAM7X8E

    bool "Atmel SAM7X8EProcessor"

    select CPU_CORTEX_M

    select CPU_CORTEX_M7

    select SOC_ATMEL_SAM7

    selectSYS_POWER_LOW_POWER_STATE_SUPPORTED

linker.ld:连接脚本,该文件无需修改,内部指向一固定的脚本,编译时只是把一些SRAM以及FLASH的offset和长度传进去,动态生成具体板卡的连接脚本;

linker.ld内容如下:

#include

Makefile:目录编译脚本

soc.c: 实现具体板卡的时钟配置;

soc.h和soc_registers.h:定义一些寄存器地址;

 

3.  添加samv71_xult的UART配置

$ cd/home/user/build/zephyr-1.6.0/

$ cd drivers/serial

 

添加文件列表:

参考atmel_sam3的uart配置新增如下文件:

uart_atmel_sam7.c

Kconfig.atmel_sam7

修改文件列表:

Kconfig: 添加对Kconfig.amtel_sam7的加载

Makefile: 添加对uart_atmel_sam7.c的编译;

4.  添加samv71_xult的GPIO配置

$ cd/home/user/build/zephyr-1.6.0/

$ cd drivers/gpio

 

添加文件列表:

参考atmel_sam3的gpio配置新增如下文件:

gpio_atmel_sam7.c

Kconfig.atmel_sam7

修改文件列表:

Kconfig: 添加对Kconfig.amtel_sam7的加载

Makefile: 添加对gpio_atmel_sam7.c的编译;

 

到目前为止,SAMV71_XULT板卡的框架已经添加完成,建议按照上面介绍的zephyr编译方法,对SAMV71_XULT板卡先编译一遍,确保编译没有问题的情况下,

 

参考Nuttx工程clock以及uart的配置分别修改如下文件以及对应头文件,完成zephyr上samv71_xult板卡的clock和uart的配置,实现Uart的输出;

zephyr-1.6.0\arch\arm\soc\atmel_sam7\soc.c

zephyr-1.6.0\drivers\serial\uart_atmel_sam7.c

 

四、    Zephyr level初始化简介

由于Zephyr系统是由开源Linux基金会推出的轻量级的IOT系统,因此zephyr系统的编译框架多多少少继承了一些Linux内核中的特色,就拿zephyr系统初始化来说,就是沿用的Linux内核中的level init机制;

一般开机启动时,各个模块层次之间具有一定的依赖性,比如先初始化Clock,然后其他设备才能工作,进一步初始化Nandflash才能读取存储数据,接着初始化文件系统,APP才能访问文件;

为了解决上述上述初始化依赖情况,一般根据各自的优先级,被分为几个level,具体实现是在连接脚本中规划几个section,在定义函数时,强制指定函数代码被编译到指定的section中,开机启动时,根据section的优先级

逐个调用每个section中的init function完成相关初始化;

你可能感兴趣的:(Zephyr系统相关)