本文介绍了基于HPM SDK如何新建一个新的工程供用户项目开发,包括HPM SDK代码结构介绍,新BOARD适配驱动运行以及新工程的建立和注意事项。
先楫半导体面向用户同时提供HPM SDK的集成工具集sdk_env,本文的介绍基于hpm sdk版本0.14.0,基于工具集sdk_env_v0.14.0。搭配以下费教授的教程视频,体验更佳哦,赶紧来一睹为快!
【先楫“芯”教程】如何创建HPM_SDK例程
----- 以下为本指南的详细内容 -----
HPM SDK 组成结构介绍
整个SDK ENV组成结构如下图所示:
doc:主要是先楫半导体官方开发的用户指导手册,包含 HPM6750EVK和HPM6750EVK mini的用户指导手册。
hpm_sdk: HPM SDK的核心软件包。
toolchains:编译工具链,主要为rv32imadc-ilp32d-x86_64-w64-mingw32
tools:主要第三方软件和相应的处理脚本。
其他:SDK运行环境配置脚本和说明文件。
SDK核心软件包主要是支持完成应用软件开发的各种组件,包含了驱动、板级支持文件、中间件、soc定义文件、实例、处理脚本、帮助文件等。如下图所示
各个目录的主要内容:
arch: 与risc-v架构相关的操作接口。
boards: 与开发板相关的硬件定义和接口,主要为HPM6300EVK、HPM6750 EVK和HPM6750 EVK mini相关的板卡硬件信息。
cmake: 与cmake和工程管理相关配置文件。
components: 常用板载模块驱动、处理逻辑和控制接口,包括camera、codec、debug_console、enet_phy、serial_nor、touch、usb等。
doc: SDK支持文档和软件API的支持文档。
drivers: soc片上硬件模块驱动、处理逻辑和控制接口。
middleware: 常见算法库、图形库、组件库、RTOS等。
samples: 各种应用例程。
script: 与工程管理、编译相关的处理脚本。
soc: soc片上资源寄存器定义。
utils: 其他通用处理组件。
其他:处理脚步和说明文件。
新 board 添加适配
集成工具集sdk_env压缩包解压目录下的start_cmd.cmd脚本可以启动命令行环境sdk prompt, 可通过命令generate_project -list 查看当前支持的boards,可以查询到当前支持的boards如下:
hpm6300evk
hpm6750evk
hpm6750evk2
hpm6750evkmini
在目录hpm_sdk/boards下添加新board目录,例如名称:hpm6750demo,如下:
参考官方board添加新board的适配code,代码介绍如下:
注:建议按照官方代码结构添加。
board.c: 新board硬件初始化,包括clock/console/pmp/ahb等以新board实际硬件添加相关code。
pinmux.c:新board硬件pin脚复用选择,以新board实际外设功能添加相关code(可使用HPM pinmux tool 泡泡龙工具自动生成)。
CMakeList.txt: cmake构建脚本文件,必须添加。
hpm6750evk.yaml: yaml配置文件, 名称同新board名称一致。文件中包含了board的相关信息,包括openocd 仿真器的相关信息。
*openocd目录下同步添加board cfg文件:
board硬件初始化核心内容详解:
注意:新board以实际功能添加、删减、修改。
(1).flash配置信息:在区域.nor_cfg_option存放flash的配置信息,包括:flash类型、频率、电压、片选等。
注:当新board外挂的flash和官方的型号参数不一致时,注意修改此配置。
#if defined(FLASH_XIP) && FLASH_XIP__attribute__ ((section(".nor_cfg_option"))) const uint32_t option[4] = {0xfcf90001, 0x00000007, 0x0, 0x0};#endif
(2).UF2固件头部的签名信息:当固件是UF2类型,签名存放在空间.uf2_signature区域。
if defined(FLASH_UF2) && FLASH_UF2ATTR_PLACE_AT(".uf2_signature") const uint32_t uf2_signature = BOARD_UF2_SIGNATURE;#endif
(3).终端初始化:串口终端初始化。
void board_init_console(void)
(4).时钟初始化:系统时钟及各个外设IP时钟组选择初始化。
void board_init_clock(void)
(5).外设初始化及外设时钟源配置:各个外设的初始化,包括PINMUX及功能配置。
//外设初始化void board_init_uart(UART_Type *ptr) //UART 串口初始化void board_init_ahb(void) //AHB总线初始化void board_init_sdram_pins(void) //SDRAM PIN初始化void board_init_lcd(void) //LCD初始化void board_init_i2c(I2C_Type *ptr) //I2C初始化void board_init_cap_touch(void) //TOUCH触摸屏初始化void board_init_gpio_pins(void) //GPIO PIN初始化void board_init_spi_pins(SPI_Type *ptr) //SPI PIN初始化void board_init_led_pins(void) //LED PIN初始化void board_init_cam_pins(void) //CAM PIN初始化void board_init_can(CAN_Type *ptr) //CAN 初始化void board_init_sd_pins(SDXC_Type *ptr) //SD PIN初始化void board_init_usb_pins(void) //USB PIN初始化void board_init_pmp(void) //PMP 初始化void board_init_adc12_pins(void) //ADC12 PIN初始化
void board_init_adc16_pins(void) //ADC16 PIN初始化hpm_stat_t board_init_enet_pins(ENET_Type *ptr) //ENEN PIN初始化//外设时钟源配置uint32_t board_init_spi_clock(SPI_Type *ptr) //SPI CLOCK配置uint32_t board_init_uart_clock(UART_Type *ptr) //UART CLOCK配置uint32_t board_init_dram_clock(void) //DRAM CLOCK配置uint32_t board_init_lcd_clock(void) //LCD CLOCK 配置uint32_t board_init_cam_clock(CAM_Type *ptr) //CAM CLOCK配置uint32_t board_init_adc12_clock(ADC12_Type *ptr) //ADC12 CLOCK配置uint32_t board_init_dao_clock(void) //DAO CLOCK配置uint32_t board_init_pdm_clock(void) //PDM CLOCK配置uint32_t board_init_i2s_clock(I2S_Type *ptr) //I2S CLOCK 配置uint32_t board_init_adc16_clock(ADC16_Type *ptr) //ADC16 CLOCK配置uint32_t board_init_can_clock(CAN_Type *ptr) //CAN CLOCK配置uint32_t board_sd_configure_clock(SDXC_Type *ptr, uint32_t freq) //SD CLOCK配置hpm_stat_t board_init_enet_ptp_clock(ENET_Type *ptr) //ENET PTP CLOCK配置hpm_stat_t board_init_enet_rmii_reference_clock(ENET_Type *ptr, bool internal) //ENET RMII CLOCK配置hpm_stat_t board_init_enet_rgmii_clock_delay(ENET_Type *ptr) //ENET RGMII delay CLOCK配置
(6). 外部SDRAM初始化:外部SDRAM初始化。
注意:当初始数据有放到外部SDRAM,必须要定义宏:INIT_EXT_RAM_FOR_DATA。(此函数在启动start.s中被调用)
#ifdef INIT_EXT_RAM_FOR_DATA/* * this function will be called during startup to initialize external memory for data use */void _init_ext_ram(void)
通过命令generate_project -list 查看当前支持的boards:
新 工 程 创 建
在目录hpm_sdk/samples 下包含了官方的所有参考用例。参考官方用例来创建新的工程,新的工程路径原则上是任意的,建议用户放到hpm_sdk之外的目录,方便用户后续更新hpm_sdk而不影响用户工程。例如创建两个工程demo1,demo2,路径和hpm_sdk在同一个目录下:
新工程组成介绍:
CMakeList.txt: cmake构建脚本文件,必须添加。
Linkers:当前工程使用的linker文件。当然也可以通过-t 使用官方的linker文件。
inc: 工程头文件。
src: 工程源文件。
CMakeList.txt脚本文件内容介绍:
cmake_minimum_required(xxx):cmake最低版本要求,使用默认3.13即可。
set(xxx):设置要使用到的中间件、组件或linker文件。例如:set(CONFIG_LVGL 1)使能中间件LVGL(middleware/littlevgl)。set(CUSTOM_GCC_LINKER_FILE xxx)设置工程使用的linker文件。
set_compile_definitions(xxx):设置编译器选项及宏定义。例如:set_compile_definitions(-DFLASH_XIP=1):宏定义 FLASH_XIP=1
注意:如果是FLASH_XIP的方式,一定要宏定义FLASH_XIP=1;如果初始数据使用了外部SDRAM,一定要宏定义INIT_EXT_RAM_FOR_DATA=1;或通过构建命令-t 指定。当-t指定工程类型,则当前cmakelist.txtset(CUSTOM_GCC_LINKER_FILE)指定的linker文件无效;
project(xxx): 工程名称xxx。例如:project(demo1),demo1工程。
sdk_inc(xxx):工程头文件路径。
sdk_app_src(xxx):工程源文件添加,也可使用sdk_ses_src(xxx)或sdk_gcc_src(xxx)来指定为SES工程文件还是GCC工程文件。
generate_ses_project(): 构建为ses工程。
通过命令:generate_project -b hpm6750demo -f 构建生成SES工程。
注意:如果cmakelist.txt中指定了linker文件及工程类型,无需-t指定。
双击工程xxx_build/segger_embedded_studio/xxx.emProject文件,打开SES工程编译调试。
至此新建工程已完成。本文主要介绍了基于sdk_env_v0.14.0如何新建一个工程。详细介绍了新BOARD适配驱动运行以及新工程建立的注意事项。HPM SDK基于CMAKE工具来为Segger构建工程,同时用户也可通过添加修改cmake脚本来快速新建工程,为用户省去了繁琐的工程配置及编译调试环境配置,大大提升了用户的开发效率。(欲了解参考文献,可点击“阅读原文”获取)
本期的内容就分享到这儿,如果有其他感兴趣的内容,欢迎随时留言给小编,先楫芯上人会在接下来的分享中陆续为大家呈现~
全部0条评论
快来发表一下你的评论吧 !