编译Nuttx
Atmel SAM4S Xplained Pro
简介
Core
- ARM Cortex-M4 with 2 Kbytes of cache running at up to 120 MHz
- Memory Protection Unit (MPU)
- DSP Instruction Set
- Thumb ® -2 instruction set
Memories
- Up to 2048 Kbytes embedded Flash with optional dual-bank and cache memory, ECC, Security Bit and Lock Bits
- Up to 160 Kbytes embedded SRAM
- 16 Kbytes ROM with embedded boot loader routines (UART, USB) and IAP routines
- 8-bit Static Memory Controller (SMC): SRAM, PSRAM, NOR and NAND Flash support
同步
nuttx与nuttx-apps两个源代码,它们两个平级目录.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35~$ git clone https://github.com/apache/incubator-nuttx nuttx
~$ git clone https://github.com/apache/incubator-nuttx-apps.git apps
~$ cd nuttx
# 列出所有支持板子.
~$ tools/configure.sh -L | grep "sam"
~$ tools/configure.sh -l sam4s-xplained-pro:nsh
~$ cp boards/arm/sam34/sam4s-xplained-pro/configs/nsh/defconfig .config
~$ cp boards/arm/sam34/sam4s-xplained-pro/scripts/Make.defs .
# 这里使用一个 第三方的工具链(gcc-arm-none-eabi-6-2017-q2-update) arm-none-eabi- 也可以编译成功.选择 CONFIG_ARMV7M_TOOLCHAIN_GNU_EABIL=y
~$ export PATH=/fullpath/gcc-arm-none-eabi-6-2017-q2-update/bin:$PATH
~$ make CROSSDEV=arm-none-eabi-
# 查看交㕚工具链支持的CPU特性.
~$ arm-none-eabi-g++ -print-multi-lib
.;
thumb;@mthumb
fpu;@mfloat-abi=hard
armv6-m;@mthumb@march=armv6s-m
armv7-m;@mthumb@march=armv7-m
armv7e-m;@mthumb@march=armv7e-m
armv7-ar/thumb;@mthumb@march=armv7
cortex-m7;@mthumb@mcpu=cortex-m7
armv7e-m/softfp;@mthumb@march=armv7e-m@mfloat-abi=softfp@mfpu=fpv4-sp-d16
armv7e-m/fpu;@mthumb@march=armv7e-m@mfloat-abi=hard@mfpu=fpv4-sp-d16
armv7-ar/thumb/softfp;@mthumb@march=armv7@mfloat-abi=softfp@mfpu=vfpv3-d16
armv7-ar/thumb/fpu;@mthumb@march=armv7@mfloat-abi=hard@mfpu=vfpv3-d16
cortex-m7/softfp/fpv5-sp-d16;@mthumb@mcpu=cortex-m7@mfloat-abi=softfp@mfpu=fpv5-sp-d16
cortex-m7/softfp/fpv5-d16;@mthumb@mcpu=cortex-m7@mfloat-abi=softfp@mfpu=fpv5-d16
cortex-m7/fpu/fpv5-sp-d16;@mthumb@mcpu=cortex-m7@mfloat-abi=hard@mfpu=fpv5-sp-d16
cortex-m7/fpu/fpv5-d16;@mthumb@mcpu=cortex-m7@mfloat-abi=hard@mfpu=fpv5-d16下面错误,可以打开源码位置,注释掉它.
1 | arch/arm/src/imxrt/Kconfig:1114: syntax error |
使用BuildRoot构建指交叉工具链
- buildroot nuttx
- 这里是使用
NuttX提供的修改后的BuildRoot版本.通过buildroot编译出一个特殊版本的交叉工具链,再用它去编译出最终的nuttx系统镜像.buildroot的源码目录与nuttx,nuttx-apps也是平级的目录.在实践过程中开启了BR2_GCC_CORTEX_M4F_SP导致下面的DBUG里出错的原因.也就是说Atmel SAM4S Xplained Pro是cortex-m4内核,但是它不带FPU,强选FPU肯定是出错的,
1 | ~$ git clone https://bitbucket.org/nuttx/buildroot.git buildroot |
- 如果成功会生成如下的目录.注意,如果开启了
BR2_ENABLE_MULTILIB=y与BR2_SOFT_FLOAT=y生成的目标目录是build_arm_nofpu,否则生成的目录就是build_arm.
1 | ~$ tree -L 2 build_arm_hf/ |
- 测试工具链
1 | ~$ export PATH=`pwd`/build_arm_hr/staging_dir/bin:$PATH |
- 如果出现下面的错误,在
make menuconfig选择一个高版本的gdb尝试一下.1
2
3
4/fullpath/buildroot/toolchain_build_arm_hf/gdb-7.9.1/gdb/python/python.c: In function ‘_initialize_python’:
/fullpath/buildroot/toolchain_build_arm_hf/gdb-7.9.1/gdb/python/python.c:1690:3: error: too few arguments to function ‘_PyImport_FixupBuiltin’
_PyImport_FixupBuiltin (gdb_module, "_gdb"); - 如果出现
gcc编译时无法下载mpc,mpfr,gmp的依赖包时,查看一下toolchain_build_arm_hf/gcc-4.9.4/contrib/download_prerequisites.修改版本号,或者下载的地址.
gcc-4.7.4的补丁
- 在构建交㕚工具链时如果出现下面的错误
1 | In file included from .../gcc-4.7.4/gcc/cp/except.c:990:0: |
- 这里引用了cfns: fix mismatch in gnu_inline attributes的补丁.直接创建在
BuildRoot的源码里.
1 | ~$ cat > toolchain/gcc/4.7.4/gnu_inline.patch <<EOF |
GCC-4.7.4的编译错误
1 | make[4]: Entering directory '/fullpath/buildroot/toolchain_build_arm_nofpu/gcc-4.7.4-build/libiberty/testsuite' |
- 编译时出现上面的错误,这好像是这个GCC版本的问题,在
4.9.x好像没有出这样的错误,同是查看了各级的config.log与各级的Makefile也没有找出问题,后来只有进入到编译的目录内toolchain_build_arm/gcc-4.7.4-build内直接运行make,无错的话再回到buildroot内,再运行make这里就正常完成了.
配置NuttX系统
1 | ~$ tools/configure.sh -l sam4s-xplained-pro:nsh |
Nuttx的最终配置如下:
1 | ~$ grep -v '^$\|^#' .config |
- 编译时出现下面错误,这个有可能是配置时没有选择
CONFIG_ARCH_IRQPRIO=y,然后就去make后的结果.通过搜索nuttx源码时发现,getcontrol(void)是定义在arch/arm/include/armv7-m/irq.h里的内联函数.最终在arch/arm/src/chip/sam_start.c前面,添加#include <nuttx/irq.h>就可以了.
1 | /fullpath/nuttx/staging/libarch.a(sam_start.o): In function `sam_fpuconfig': |
使用OpenOCD调试
编译OpenOCD
1 | ~$ git clone http://repo.or.cz/r/openocd.git |
根据
Nuttx官方的Debugging Nuttx提示,基于某些特性调试,可能需要修改相应的openocd/src/rtos/nuttx_header.h内的宏定义如:CONFIG_DISABLE_MQUEUE=y.运行
OpenOCD服务,通过PC端的USB连接到Atmel-SAM4S_Xpained-Pro上写有DEBUG USB的接口上,注意,该USB接口是板上调试器(EDBG)的组合接口,它包含三个接口功能:DEBUG,Virtual COM Port, Data Gateway Interface(DGI).
1 | # 这里如果定义板级配置也可直接: openocd -f board/atmel_sam4s_xplained_pro.cfg -c init -c "reset halt" |
- 使用GDB桥接到
OpenOCD服务上去调试.
1 | ~$ arm-nuttx-eabi-gdb nuttx |
也可以把几个参数合在一行命令下提交,如
arm-nuttx-eabi-gdb -ex "target remote :3333" -ex "mon reset halt" nuttx关于类似
ATSAM4SD32C.cpu -- clearing lockup after double fault,参考了stackexchange处理.查看目标文件的内容.
1 | ~$ file nuttx |
GDB调试
OpenOCD服务
1 | # ~$ openocd -f board/atmel_sam4s_xplained_pro.cfg -c init -c 'reset halt' -c '$_TARGETNAME configure -rtos nuttx' |
GDB连接
- 在
nuttx的目录下运行,为了加载nuttx文件.
1 | ~ nuttx$ arm-none-eabi-gdb -ex "target remote :3333" -ex "mon reset halt" nuttx |
- 定义一些
gdb hook函数,只是为了方便一些调试,最好的方式是把这些define放在~/.gdbinit内, 但是要注意,你如果在用系统gdb去调非nuttx的程序时,
记得要删了~/.gdbinit.
1 | (gdb) define hookpost-file |
- 连接远程
openocd的端口
1 | (gdb) target extended-remote :3333 |
- 上线的
file nuttx是加载文件的symbols,因为定义了hook-file,所以会在openocd内显示,如:
1 | Error: No symbols for NuttX # 有可能会显示,如果每次都显示,是因为没有打开`CONFIG_DEBUG_SYMBOLS` |
- 查看调试线程信息.
1 | (gdb) info threads |
- 查看寄存器的信息
1 | (gdb) info registers |
设置断点
下面设置的断点是在文件的某行上面,为防止调试时程序跑飞,硬件重启后又需要重新设置断点,这里保存断点到
bp.txt文件上,下次可以使用source bp.txt加载.
1 | (gdb) b chip/sam_hsmci.c:757 |
- 查看调用栈,有时调试板子,在板子初始硬件时,串口打印还没有就绪时,此时用
backtrace查看调用栈很有用,比如:晶振不起振.
1 | (gdb) backtrace |
- 单步(s = Step into, n = Step over),单步步入(Step Into)有时会进入很深的调用栈,如果要退回可以使用
finish指令跳出.
1 | (gdb) step |
- 查看变量
1 | btle_main (argc=<error reading variable: value has been optimized out>, argv=<error reading variable: value has been optimized out>) at nrf24l01_btle.c:372 |
- hexdump 查看地址,数组
1 | (gdb) x /32bx data |
- 查看结构体的内容
1 | (gdb) set print pretty on |
烧写固件
- 烧写
flash0,地址0x00400000在链接脚本文件boards/arm/sam34/sam4s-xplained-pro/scripts/sam4s-xplained-pro.ld里有定义.
1 | ~$ openocd -f board/atmel_sam4s_xplained_pro.cfg -c init -c "reset halt" -c "flash write_image erase nuttx.bin 0x00400000" -c "reset" |
- 连接到它的
UART接口,进入系统.
1 | ~$ sudo minicom -o -b 115200 -D /dev/ttyACM0 |
NAND 移植
1 | sam_nand_initialize: CS0 |
- 读/写页(page),擦除块(block).在概念上,由大到小来说,就是:
1 | Nand Flash ⇒ Chip ⇒ Plane ⇒ Block ⇒ Page ⇒ oob |
1 | hexdump /dev/mtdblock0 count=128 |
- 格式化
nuttx代码1
git status | grep "modified:" | awk '{print $2}' | xargs tools/checkpatch.sh -f
- 内存分布
SAMA5D3 Series是参照Datasheet第5章Memories. SAM4S是SAM4S Datasheet Chapter 6 . Product Mapping
Arduino Due
- Arduino Due
- Hacking with the Arduino Due
- SAM3X-Arduino Pin Mapping
- The Arduino Due is a microcontroller board based on the Atmel SAM3X8E ARM Cortex-M3 CPU. It is the first Arduino board based on a 32-bit ARM core microcontroller. It has 54 digital input/output pins (of which 12 can be used as PWM outputs), 12 analog inputs, 4 UARTs (hardware serial ports), a 84 MHz clock, an USB OTG capable connection, 2 DAC (digital to analog), 2 TWI, a power jack, an SPI header, a JTAG header, a reset button and an erase button.
- 根据官方警示:
Arduino Due的管脚只容3.3v,高于3.3v会损坏板子.
BOSSAC烧写
- 这里将使用它官方的烧写工具
BOSSAC,它一般位于用户目录下.如:~/.arduino15/packages/arduino/tools/bossac/1.7.0-arduino3/bossac.
检测目标板子信息
1 | ~$ bossac -p ttyACM0 -U false -i |
- 需要设置正确的端口参数,如果再不行,按
reset再重试,如下:
1 | ~$ stty -F /dev/ttyACM0 speed 1200 cs8 -cstopb -parenb |
烧入nuttx.bin
1 | $ bossac -p ttyACM0 -U false -e -w -v -b nuttx.bin -R |
使用SWD烧写
- 除了使用
BOSSAC,本来想使用SWD接口与OpenOCD来烧写调试.因为Due板有一个排4针的DEBUG接口,针脚是:1:RESET,2:SWDIO,3:SWCLK,4:GND.1
2
3
4
5
6
7
8
9~$ cat > ~/sam3x8e.cfg<<EOF
source [find interface/stlink.cfg]
set CPUTAPID 0x2ba01477
source [find board/atmel_sam3x_ek.cfg]
EOF
~$ openocd -f ~/sam3x8e.cfg -c init -c halt -c "flash write_image erase nuttx.bin 0x80000" -c "at91sam3 gpnvm set 1" -c "exit"
使用板载AT16u2烧写
在网上发现可以修改
AT16u2的固件,使它成为CMSIS_DAP,从而可以支持openocd的烧写调试.
更新AT16u2的固件
烧写
AVR芯片需要一个烧写器,如:avr JATG-ICE, AVR-ISP,Atmel-ICE,USBasp.也可以把一块arduino板子变成AVR-ISP.如:Arduino Uno. 但是这里有一块NUCLEO-L152RE它有兼容arduino的接口,可以使用stm32duino把它变成AVR-ISP烧写器,烧入官方的ArduinoISP进去.打开
Arduino IDE --> File --> examples(Builtin-examples) --> 11.ArduinoISP --> ArduinoISP,烧写上传到NUCLEO-L152RE.
1 | NUCLEO-L152RE Arduino Due (ICSP) |
avrdude
下载avrdude源码,
avrdude是一个开源的AVR烧写软件,它最新地板本是avrdude-6.3,通过源码可以查看它所支持的硬件详情.下面是使用
NUCLEO-L152RE做为一个烧写器,按照上面接线,对Arduino Due板上的at16u2的固件进行更新.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81~$ cd ~/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino17/
~$ tree
.
├── bin
│ └── avrdude
└── etc
└── avrdude.conf
~$ avrdude -c arduino -P /dev/ttyACM0 -b 19200 -p atmega16u2 -vvv -U flash:w:at16u2_cmsis_dap/at16u2_cmsis_dap.elf.hex:i
avrdude: Version 6.3-20171130
Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
Copyright (c) 2007-2014 Joerg Wunsch
System wide configuration file is "/etc/avrdude.conf"
User configuration file is "/home/michael/.avrduderc"
User configuration file does not exist or is not a regular file, skipping
Using Port : /dev/ttyACM0
Using Programmer : arduino
Overriding Baud Rate : 19200
AVR Part : ATmega16U2
Chip Erase delay : 9000 us
PAGEL : PD7
BS2 : PC6
RESET disposition : possible i/o
RETRY pulse : SCK
serial program mode : yes
parallel program mode : yes
Timeout : 200
StabDelay : 100
CmdexeDelay : 25
SyncLoops : 32
ByteDelay : 0
PollIndex : 3
PollValue : 0x53
Memory Detail :
Block Poll Page Polled
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
eeprom 65 20 4 0 no 512 4 128 9000 9000 0x00 0x00
Block Poll Page Polled
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
flash 65 6 128 0 yes 16384 128 128 4500 4500 0x00 0x00
Block Poll Page Polled
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
lfuse 0 0 0 0 no 1 0 0 9000 9000 0x00 0x00
Block Poll Page Polled
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
hfuse 0 0 0 0 no 1 0 0 9000 9000 0x00 0x00
Block Poll Page Polled
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
efuse 0 0 0 0 no 1 0 0 9000 9000 0x00 0x00
Block Poll Page Polled
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
lock 0 0 0 0 no 1 0 0 9000 9000 0x00 0x00
Block Poll Page Polled
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
calibration 0 0 0 0 no 1 0 0 0 0 0x00 0x00
Block Poll Page Polled
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
signature 0 0 0 0 no 3 0 0 0 0 0x00 0x00
Programmer Type : Arduino
Description : Arduino
Hardware Version: 2
Firmware Version: 1.18
Topcard : Unknown
Vtarget : 0.0 V
Varef : 0.0 V
Oscillator : Off
SCK period : 0.1 us
跳线
- 因为
Due板上的GND,RESET已经连接到AT16u2上了,这里Due板内只需两根跳线就够了.所以此时的at16u2就是一个CMSIS-DAP的设备了.
1 | ICSP DEBUG(SWD) |
- 使用
OpenOCD烧写.
1 | ~$ openocd -f interface/cmsis-dap.cfg -f board/atmel_sam3x_ek.cfg -c init -c halt -c "flash write_image erase nuttx.bin 0x80000" -c "at91sam3 gpnvm set 1" -c "exit" |
使用UM232H(FTDI)做烧写器
- 上面的做法是使用一块
arduino板做为烧写器,这里是使用FT232H USB to SPI/I2C的小板来做为烧写器,连接板上的DEBUG(SWD).
1 | # FT232HQ minimodule channel 0 (Channel A) |
也可以使用
Due板上的标准的ARM-JTAG-10pin去调试,接线的方式如同上面,可以使用JTAG信号,也可以只接SWD信号.如果转接到一个20Pin的板上,就需要对接相应的信号线.使用
OpenOCD烧写,如果板上原来是arduino镜像,需要按下reset后,马上运行下面命令.
1 | ~$ openocd -f interface/ftdi/ft232h-module-swd.cfg -f board/atmel_sam3x_ek.cfg -c init -c halt -c "flash write_image erase nuttx.bin 0x80000" -c "at91sam3 gpnvm set 1" -c "exit" |
OpenOCD连接
其它
- Write code to FLASH don’t change boot mode and don’t reset. This lets
you examine the FLASH contents that you just loaded while the bootloader
is still active.
1 | ~$ bossac.exe --port=COM26 --usb-port=false -e -w -v --boot=0 nuttx.bin |
- Verify the FLASH contents (the bootloader must be running)
1 | ~$ bossac.exe --port=COM26 --usb-port=false -v nuttx.bin |
- Read from FLASH to a file (the bootloader must be running):
1 | ~$ bossac.exe --port=COM26 --usb-port=false --read=4096 nuttx.dump |
- Change to boot from FLASH
1 | ~$ bossac.exe --port=COM26 --usb-port=false --boot=1 |
恢复AT16u2的固件
下面是把
Arduino Due板上的AT16u2恢复它原来的固件功能,这里是使用FT232H连它的ICSP而不是用一个Arduino板来做烧写器.arduino它所有支持的固件都在它的安装包内,因为Arduino Due是SAM3X8E的芯片,这里选择查看~/.arduino15/packages/arduino/hardware/sam/目录.如下.
1 | ~$ tree ~/.arduino15/packages/arduino/hardware/sam/1.6.12/firmwares |
- 关于如何接线的问题,可以查看
/etc/avrdude.conf,根据里面的注释指导,结合自已板子接线.
1 |
|
- 烧写命令如下,如有问题可以,添加
-vvv烧写查看.
1 | ~$ avrdude -C /etc/avrdude.conf -c UM232H -P /dev/ttyUSB0 -b 19200 -p atmega16u2 -U flash:w:Arduino-DUE-usbserial-prod-firmware-2013-02-05.hex:i |
谢谢支持
- 微信二维码: