调试与烧录
调试器
做固件开发,一个方便的调试器还是很有必要的,且烧录方面比串口烧录要方便得多。HPM5301EVKLite开发板支持标准的jtag,为成本考虑未板载一颗FT2232之类的调试器芯片,这就需要外接一个标准jtag调试器。笔者有一个ft2232芯片做的调试器所以就用它了。当然因为cherrydap开源项目的存在,我们 完全可以另外再买一块HPM5301EVKLite开发板,通过串口烧录cherrydap固件后,HPM5301EVKLite即成 为一个支持daplink协议的调试器,它支持arm swd和jtag。
调试烧录工具openocd的编译
如果只用openocd调试,linux发行版自带的openocd即可使用,但如果需要使用openocd的烧录功能,那么只有HPM官方打过补丁的openocd支持HPM系列SoC的flash烧录。
- git clone https://gitee.com/hpmicro/riscv-openocd
- cd riscv-openocd
- ./bootstrap
- ./configure --prefix ~/opt/openocd_hpm
- make
- make install
hpm_sdk的下载与编译
clone hpm_sdk代码
- git clone https://gitee.com/hpmicro/hpm_sdk.git
hpm_sdk工程组织分析
hpm官方sdk使用CMakeLists.txt组织的,理论上linux下是原生支持编译hpm_sdk的。值得一提的是hpm_sdk中toolchain的似乎假设了就那么三种来源,这和笔者习惯不太一样,笔者不喜欢给每个MCU厂家都 下载特别的toolchain,比较偏向于共享toolchain。目前linux开发环境下用于riscv baremetal的toolchain通常有发行版自带riscv64-unknown-elf-gcc或者xpack打包的xpack-riscv-none-elf-gcc,前者 不带libc,需安装或自行编译适用于riscv baremetal的libc,例如picolibc-riscv64-unknown-elf;后者默认带newlibc。那笔者先用xpack的toolchain展示下hpm_sdk的编译过程,riscv64-unknown-elf-gcc配合picolibc-riscv64-unknown-elf编译hpm_sdk以后有机会再发贴说明(注:虽然这两名字上有64位但可编译32位riscv)
给hpm_sdk打上如下补丁:
- diff --git a/cmake/application.cmake b/cmake/application.cmake
- index 813782bf..86646715 100644
- --- a/cmake/application.cmake
- +++ b/cmake/application.cmake
- @@ -68,7 +68,7 @@ if(NOT RV_ABI)
- endif()
- if(NOT RV_ARCH)
- - set(RV_ARCH "rv32imac")
- + set(RV_ARCH "rv32imac_zicsr_zifencei")
- endif()
- # add basic extentions
- diff --git a/cmake/toolchain.cmake b/cmake/toolchain.cmake
- index ca914b09..89928d1f 100644
- --- a/cmake/toolchain.cmake
- +++ b/cmake/toolchain.cmake
- @@ -85,8 +85,8 @@ elseif("${TOOLCHAIN_VARIANT}" STREQUAL "gcc")
- set(LINKER ld)
- set(BINTOOLS gnu)
- set(C++ g++)
- - set(CROSS_COMPILE_TARGET riscv32-unknown-elf)
- - set(SYSROOT_TARGET riscv32-unknown-elf)
- + set(CROSS_COMPILE_TARGET riscv-none-elf)
- + set(SYSROOT_TARGET riscv-none-elf)
- set(TOOLCHAIN_CMAKE gcc.cmake)
- elseif("${TOOLCHAIN_VARIANT}" STREQUAL "nds-llvm")
- set(COMPILER clang)
因板子自带了的固件似乎就是hello_world,改动hello_world源码以示区别
- diff --git a/samples/hello_world/src/hello_world.c b/samples/hello_world/src/hello_world.c
- index 676304c9..d742e7cd 100644
- --- a/samples/hello_world/src/hello_world.c
- +++ b/samples/hello_world/src/hello_world.c
- @@ -19,7 +19,7 @@ int main(void)
- board_timer_create(LED_FLASH_PERIOD_IN_MS, board_led_toggle);
- - printf("hello world\n");
- + printf("hello riscv\n");
- while(1)
- {
- u = getchar();
编译hello_world
- export HPM_SDK_BASE=YOUR_PATH_TO_hpm_sdk/
- export GNURISCV_TOOLCHAIN_PATH=YOUR_PATH_TO_XPACK_TOOLCHAIN/xpack-riscv-none-elf-gcc-13.2.0-2
- cd samples/hello_world
- cmake -DCMAKE_BUILD_TYPE=release -DBOARD=hpm5301evklite -B build
- cmake --build build -j8
动态加载运行
- export OPENOCD_SCRIPTS=YOUR_PATH_TO_hpm_sdk/boards/openocd
- ~/opt/openocd_hpm/bin/openocd -f probes/ft2232.cfg -f soc/hpm5300.cfg -f boards/hpm5301evklite.cfg
另起一个shell接入板子串口
- minicom -c on -w usb0
另起一个shell运行
- telnet 127.0.0.1 4444
在telnet界面中
- halt
- load_image samples/hello_world/build/output/demo.bin 0
- resume 0
此时串口终端minicom显示如图