HK32F030MF4P6的Linux GCC工具鏈開發環境

2022-09-19 06:05:55

HK32F030MF4P6簡介

航順的 HK32F030MF4P6, TSSOP20封裝, Arm Cortex M0 核心, 內建32MHz時鐘, 16K Flash, 2K RAM(實際上可用的有4K).
這個型號的目的應該是硬體替換 STM8S003, 管腳和 STM8S003 相容(和 STM32F030 相容的型號是 HK32F030F4P6). HK32F030MF4P6 可能是當前市場上最便宜的 Cortex M0 晶片了, 單價0.9元不到. 一個32位元的Arm M0晶片, 燒錄能用普通程式設計器, 引數也還可以, 常用的外設I2C, SPI, UART, PWM, ADC都有, 甚至還有I2S, 價效比相當不錯.

合宙也在放風要出1元的M0, 設定4K RAM, 256K Flash, M0這個級別很快就會進入一元的市場, 8bit系列按現在的價格, 如果不降到比M0低, 可能只剩下存量專案和教學用途了.

專案模板地址:

相關資料下載:

相關連結

HK32F030MF4P6 的外設庫

對比 HK32F030M 的外設庫和 STM32F0xx_StdPeriph_Lib_V1.5.0, 格式幾乎是照抄的, 定義前者比後者有一些縮水而已, 因為埠和功能上確實少一些. 所以熟悉 STM32F0 的人很容易上手. 相比較之前介紹的華大 HC32 系列, HC32 這個系列就有很明顯的 STC 暫存器風格, 和 STM 不是一條路線.

Linux GCC Arm Embedded 開發環境

Windows下的開發環境已經有很多資料了, 前面的資料下載裡有很詳細的檔案. 這裡主要介紹一下 Linux (再準確點, Ubuntu) 下的開發環境. 以下介紹 HK32F030MF4P6 這個晶片使用 Linux GCC Arm Embedded 工具鏈的開發環境.

硬體環境

  • 帶 HK32F030MF4P6 的開發板. 這個晶片不需要外圍元件, 直接用 TSSOP20 轉接板接出即可
  • JLink OB, 最常見最便宜的那種 JLink 燒錄器

JLink接線

## JLINK
VCC -> #9  VCC
GND -> #7  GND
CLK -> #11 
SWD -> #2

軟體環境

JLink7.70 已經內建對 HK32F030M 系列的支援, 安裝後直接可用

GCC ARM工具鏈

在GCC ARM網站下載工具連結https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads, 解壓到合適的目錄

tar xvf gcc-arm-11.2-2022.02-x86_64-arm-none-eabi.tar.xz
cd /opt/gcc-arm/
sudo mv ~/Backup/linux/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi/ .
sudo chown -R root:root gcc-arm-11.2-2022.02-x86_64-arm-none-eabi/

檢查版本

/opt/gcc-arm/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi/bin/arm-none-eabi-gcc --version
arm-none-eabi-gcc (GNU Toolchain for the Arm Architecture 11.2-2022.02 (arm-11.14)) 11.2.1 20220111
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

HK32F030M外設庫

https://bbs.21ic.com/icview-3236132-1-1.html 下載, 需要其中的外設庫.

範例專案匯出和編譯

匯出專案

git clone https://github.com/IOsetting/hk32f030m-template.git

將下載的外設庫放到 Libraries/HK32F030M_Driver 目錄下

根據自己的環境引數修改 Makefile

PROJECT     ?= app
# path to gcc arm (or should be specified in PATH)
ARM_TOOCHAIN  ?= /opt/gcc-arm/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi/bin
# path to JLinkExe (or should be specified in PATH)
JLINKEXE    ?= /opt/SEGGER/JLink/JLinkExe
# MCU type: HK32F030MD4P6, HK32F030MF4U6, HK32F030MF4P6 or HK32F030MJ4M6
DEVICE      ?= HK32F030MF4P6
# The path for generated files
BUILD_DIR     = Build

專案中帶了一個LED Blink的演示, 接線

## LED
LED1 -> #18 PD1
LED2 -> #17 PC7
LED3 -> #6  PA2

編譯

make clean
make

燒錄

make flash

專案模板目錄結構

專案模板結構

├── Build                       # 編譯結果檔案目錄
├── Examples                    # 範例程式碼
├── flash.jlink                 # JLink 下載指令碼
├── Libraries
│   ├── CMSIS
│   ├── Debug                   # SysTick 延時函數, printf 支援
│   ├── HK32F030M_Driver        # MCU 外設庫
│   └── LDScripts
├── LICENSE
├── Makefile                    # Make 設定
├── README.md
├── rules.mk                    # Makefile 預設的編譯規則
└── User                        # 使用者應用程式碼

其中並未包含外設庫, 和STM32的太像了, 放上去感覺不妥, 怕有版權問題, 還是刪掉了. 自己下載也很方便.

編譯引數

rules.mk 中, 預設的包含檔案和目錄為

# C source folders
CDIRS := User \
    Libraries/CMSIS/HK32F030M/Source \
    Libraries/HK32F030M_Driver/src \
    Libraries/Debug
# C source files (if there are any single ones)
CFILES := 

# ASM source folders
ADIRS := User
# ASM single files
AFILES  := Libraries/CMSIS/HK32F030M/Source/startup_hk32f030mf4p6.s

# Include paths
INCLUDES  := Libraries/CMSIS/CM0/Core \
      Libraries/CMSIS/HK32F030M/Include \
      Libraries/HK32F030M_Driver/inc \
      Libraries/Debug \
      User

其中 CDIRS, ADIRS, INCLUDES 對應的都是目錄, CFILES 和 AFILES 對應的是單獨的原始檔.
如果引入其它的庫或者原始檔, 對應修改這部分即可.

編譯引數如下所示

# Global compile flags
CFLAGS    = -Wall -ggdb -ffunction-sections -fdata-sections
ASFLAGS   = -g -Wa,--warn

# Arch and target specified flags
OPT     ?= -Os
CSTD    ?= -std=c99
ARCH_FLAGS  := -fno-common -mcpu=cortex-m0 -mthumb

### c flags ###
TGT_CFLAGS  += $(ARCH_FLAGS) $(addprefix -D, $(LIB_FLAGS))

### asm flags ###
TGT_ASFLAGS += $(ARCH_FLAGS)

### ld flags ###
TGT_LDFLAGS += --specs=nosys.specs -mcpu=cortex-m0 -mthumb -Wl,--gc-sections -Wl,-Map=$(BDIR)/$(PROJECT).map -Wl,--print-memory-usage
 # Use newlib-nano instead of newlib for smaller flash size
TGT_LDFLAGS += --specs=nano.specs
 # Exclude standard initialization actions, when __libc_init_array exists, this should be omit, \
   otherwise it will generate "undefined reference to `_init'" error. \
   **Remove** `bl __libc_init_array` from startup.s if you want to enable this.
# TGT_LDFLAGS += -nostartfiles

因為使用了__libc_init_array, 預設不使用-nostartfiles, 如果取消註釋, 需要到 startup_hk32f030mf4p6.s 中刪除這行, 否則會報錯.

bl __libc_init_array

Startup 和 LD 程式碼

startup_hk32f030mf4p6.s 移植自 STM32F0 的 startup 程式碼, 沒有什麼特別的, 中斷向量和手冊是一致的. LD檔案中

MEMORY
{
  RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 4K
  FLASH (rx)     : ORIGIN = 0x08000000, LENGTH = 16K
}

記憶體大小在手冊上寫的是2KB, 但是實際可用的有4KB, 這裡根據實際的記憶體大小將記憶體設成了 4K. 如果實際的規格有變化, 需要將其改回2K.

預宣告的堆疊

_Min_Heap_Size = 0x200;   /* required amount of heap: 512 bytes */
_Min_Stack_Size = 0x400;  /* required amount of stack: 1024 bytes */

...

/* User_heap_stack section, used to check that there is enough RAM left */
._user_heap_stack :
{
  . = ALIGN(8);
  PROVIDE ( end = . );
  PROVIDE ( _end = . );
  . = . + _Min_Heap_Size;
  . = . + _Min_Stack_Size;
  . = ALIGN(8);
} >RAM

這裡預宣告了 512 Byte的堆和 1024 Byte的棧, 所以編譯的結果, 顯示的記憶體佔用是一定大於1.5KB的, 如果希望增加或縮小, 在這裡調整

範例程式碼

模板中 Examples 目錄下面是一些範例程式碼

├── ADC
│     ├── ADC_Interrupt_Continous
│     └── ADC_Single
├── GPIO
│     └── LED_Blink
├── I2S
│     └── I2S_Audio_TX
├── SPI
│     └── MAX7219_8x8LED
├── TIM
│     ├── Advanced_Timer
│     ├── Basic_Timer
│     └── PWM_Complementary_Output
└── USART
    └── UART_TxRx

除了 I2S 的程式碼, 其它都移植自官方的參考範例. 使用時, 將 User 目錄下的程式碼刪除, 將範例下的程式碼複製到 User 目錄, 編譯燒錄即可.

I2S 音訊輸出演示

B站視訊"航順HK32F030MF4P6 I2S驅動MAX98357播放8k 8bit語音效果演示", 地址 https://www.bilibili.com/video/BV1AP411G7kf