一、 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完成相关初始化;