本文介绍如何创建和编译一个Zephyr应用,并说明如何基于qemu_cortex_m32上运行.原本该模拟运行是在qemu_cortex_m32上进行的但是gdb连接调试有问题,而主要有是用来看C代码,所以最后切成qemu_x86_nommu来测试.
更新1:已找到qemu_cortex_m32的问题为使用gdb错误,应该使用arm gdb,文章更新为qemu_cortex_m32说明
更新2:增加debug编译说明
更新3:增加测试代码路径
Zephyr Application
概述
Zephyr使用的编译系统基于Cmake,Zephyr的APP目录可以独立于Zephyr目录放到任何位置进行编译,编译app的时候同时会编译Zephyr,并将两部分编译链接为一个二机制文件。
本文Sample Code可以在https://gitee.com/lgl88911/zephyr_sample.git 下载
建立一个简单的app
目录结构
创建如下的目录,先预留空文件1
2
3
4
5~/work/project/zephyr_app/test
├── CMakeLists.txt
├── prj.conf
└── src
└── main.c
文件说明
填入文件内容
CMakeLists.txt
cmake文件主要作用是告诉build系统要编译那些app文件,将app和zephyr链接在一起1
2
3
4include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
project(NONE)
target_sources(app PRIVATE src/main.c)prj.conf
kernel配置文件,如果需要配置kernel的各种选项,一般情况下不配置就留个空文件- src/main.c
应用的源代码,实现应用功能1
2
3
4
5#include "kernel.h"
void main()
{
....
}
编译Application
设置环境变量
基于qemu来测试应用,编译时要设置如下环境变量,建立文件~/work/project/zephyr_set/qemu.sh1
export ZEPHYR_TOOLCHAIN_VARIANT=zephyr
执行脚本设置环境变量1
2source ~/work/project/zephyr_set/qemu.sh
source ~/work/project/zephyr/zephyr-env.sh
编译app for qemu
1 | cd ~/work/project/zephyr_app/test |
编译完后产生1
2
3
4
5-rwxrwxr-x 1 frank frank 245260 3月 20 21:00 zephyr.elf
-rw-rw-r-- 1 frank frank 238561 3月 20 21:00 zephyr.lst
-rw-rw-r-- 1 frank frank 128858 3月 20 21:00 zephyr.map
-rwxrwxr-x 1 frank frank 245096 3月 20 21:00 zephyr_prebuilt.elf
-rw-rw-r-- 1 frank frank 3557 3月 20 21:00 zephyr.stat
正常编译下会用-Os进行优化,在test/prj.conf中增加下面配置就会以非优化进行编译1
2CONFIG_NO_OPTIMIZATIONS=y //编译不进行优化
CONFIG_DEBUG=y //Build kernel with debugging enabled
clean
下面命令只会删除编译过程文件和结果文件,不会删除配置文件1
ninja clean
下面命令删除build下所有内容1
ninja pristine
运行和调试
运行
执行下面命令会在qemu中跑起来应用程序1
ninja run
执行后可以看见1
2
3
4
5
6
7
8
9frank@frank-ThinkPad-Edge:~/work/project/zephyr_app/test/build$ ninja run
Recompacting log...
[1/64] Generating always_rebuild
Building for board qemu_cortex_m3
[2/2] To exit from QEMU enter: 'CTRL+a, x'[QEMU] CPU: cortex-m3
***** BOOTING ZEPHYR OS v1.11.99 - BUILD: Mar 26 2018 13:25:25 *****
Zephyr Shell, Zephyr version: 1.11.99
Type 'help' for a list of available commands
shell>
退出qemu,Ctrl A, X:先按”Ctrl+a”然后再按“x”
调试
执行下面命令让qemu启动gdbserver并等待gdb链接1
ninja debugserver
执行后可以看见下面提示说明已经在等待gdb的连接了1
2
3[1/64] Generating always_rebuild
Building for board qemu_cortex_m3
[2/2] To exit from QEMU enter: 'CTRL+a, x'[QEMU] CPU: cortex-m3
启动arm gdb可以在https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads 下载1
2frank@frank-ThinkPad-Edge:~/work/project/zephyr_app/test/build$ cd zephyr/
frank@frank-ThinkPad-Edge:~/work/project/zephyr_app/test/build/zephyr$ arm-none-eabi-gdb zephyr.elf
执行命令后进入gdb1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17frank@frank-ThinkPad-Edge:~/work/project/zephyr_app/test/build/zephyr$ arm-none-eabi-gdb zephyr.elf
GNU gdb (GNU Tools for Arm Embedded Processors 7-2017-q4-major) 8.0.50.20171128-git
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-linux-gnu --target=arm-none-eabi".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from zephyr.elf...done.
(gdb)
debugserver默认在断开1234等待调试,进入gdb后执行1
(gdb) target remote 127.0.0.1:1234
看到下面提示,说明已经链接上,就可以开始用debug调试了1
2
3
4
5(gdb) target remote 127.0.0.1:1234
Remote debugging using 127.0.0.1:1234
__start () at /home/frank/work/project/zephyr/arch/arm/core/cortex_m/reset.S:64
64 movs.n r0, #_EXC_IRQ_DEFAULT_PRIO
(gdb)
参考
http://docs.zephyrproject.org/application/application.html
http://docs.zephyrproject.org/boards/arm/qemu_cortex_m3/doc/board.html
http://docs.zephyrproject.org/reference/kconfig/index.html