Shell脚本编译和烧录 - STM32

本文介绍了如何使用Shell脚本自动化STM32固件的编译过程,包括使用VSCode和JLink工具,设置环境变量,以及实现编译、烧录和文件转换等功能,强调了脚本在提高效率、简化操作和团队协作中的重要性。
摘要由CSDN通过智能技术生成

一.前言

Shell脚本来编译STM32固件具有一些优势:

  1. 自动化编译流程: 使用Shell脚本可以将编译过程自动化,减少手动操作。这样可以节省时间并降低出错的可能性。

  2. 简化复杂的编译命令: STM32的编译可能涉及到较长的编译命令和参数,通过Shell脚本可以将这些复杂的命令整合在一起,使编译过程更加简洁明了。

  3. 易于维护和修改: 将编译过程封装在Shell脚本中,可以更轻松地对编译过程进行修改和维护。如果需要更改编译参数或添加其他操作,只需修改Shell脚本即可,而不必修改每个编译命令。

  4. 跨平台兼容性: Shell脚本通常在各种Unix和Linux系统中都能运行,因此具有很好的跨平台兼容性。这意味着您可以在不同的开发环境中使用相同的Shell脚本来编译STM32固件。

  5. 版本控制和共享: 将编译过程封装在Shell脚本中可以更好地进行版本控制,并方便与团队共享。团队成员可以轻松地使用相同的脚本来编译项目,确保整个团队的开发环境保持一致。

总的来说,编写Shell脚本来编译STM32固件可以提高工作效率,简化编译过程,并使项目更易于维护和共享。

二.所需工具

1).Visual Studio Code(VScode)以及vscode平台下的shell脚本插件。
3).JLink_Windows_V796b.exe。
4).Jlink仿真器

1.安装Visual Studio Code

VScode下载地址:Visual Studio Code - Code Editing. Redefined。下载windows版本,直接双击即可安装。

我使用的是vscode来开发shell脚本,具体如何使用vscode开发shell,可以平台上搜,教程很多,我在这里就不赘述了。

2.安装JLink工具

打开segger官网:SEGGER - The Embedded Experts - Downloads - J-Link / J-Trace。找到J-Link Software and Documentation Pack:

点击Click for downloads, 下载windows版本。

三.移植操作

1.添加环境变量

需要添加到电脑系统环境变量 Path中的有:

1.找到JLink安装路径下JFlash.exe所处目录

2.Keil软件UV4.exe软件所处目录

四.脚本实现

1.UV4.exe命令的使用

可以从命令行(Keil的UV4.exe)调用uVision来构建项目、启动调试器或将程序下载到Flash中。该命令适用于项目和多项目文件。使用命令参考µVision User's Guide (arm.com)

2.build.sh和config.sh

创建这两个文件,移植到stm32工程中 .uvprojx文件同级目录下

shell.sh

#!/bin/bash
source config.sh

print_green() {
    echo -e "\e[32m$1\e[0m"
}

# Function to print text in red
print_red() {
    echo -e "\e[31m$1\e[0m"
}

print_yellow() {
    echo -e "\e[33m$1\e[0m"
}

print_blue() {
    echo -e "\e[34m$1\e[0m"
}

print_building_msg() {
    error_count=$(grep -i "error:" $1 | wc -l)
    warning_count=$(grep -i "warning:" $1 | wc -l)

    if [ $error_count -ne 0 ]; then
        echo ""
        grep -A 1 -B 1 -i "error:" $1 | while read -r line; do
            print_red "$line"
        done
        echo ""
        print_red "Build failed with $error_count errors."
        echo ""
    else
        warning_count=$(grep -i "warning" $1 | wc -l)
        grep -i "warning:" $1 >build_warning.log
        print_green "[Warning Statistics]"
        if [ $warning_count -ne 0 ]; then
            print_yellow "Build succeeded with $warning_count warnings. Details are saved in  build_warning.log"
        else
            print_green "0 Error(s), 0 Warning(s)"
        fi

    fi

}

while true; do
    # 显示菜单
    echo ""
    echo "[Menu]"
    echo "Please choose an option:"
    echo "1.  STM32  >> Build OR Burn"
    echo "2.   Dev   >> Hex turn to Bin"
    echo "3.   Dev   >> Erase Chip"
    echo "4.   Dev   >> Make app_combine_boot file"

    read -p "Your choice: " choice
    case $choice in
    1)
        uvprojxPath=$(pwd)

        # 将反斜杠转换为斜杠
        uvProjxDirectory=$(echo $uvprojxPath | sed 's/\\/\//g')
        # 读取uvprojx文件
        for uvProjxFile in $uvProjxDirectory/*.uvprojx; do
            if [ -f "$uvProjxFile" ]; then
                # temp_file=$(mktemp)
                uvProjxFilename=$(basename "$uvProjxFile")
                # 找到.uvprojx的文件
                uvProjxFile=".\\${uvProjxFilename%.*}.uvprojx"
                # 指定编译日志路径
                temp_file=".\temp_file.txt"

                read -p "Whether you need to >> Build << (Y/N) " inputBuild
                # 将用户输入转换为大写字母
                buildOperation=$(echo "$inputBuild" | tr '[:lower:]' '[:upper:]')
                if [ "$buildOperation" = "Y" ]; then
                    # 编译
                    cmd.exe /c "$UV -j0 -sg -b $uvProjxFile -o $temp_file"
                    # 全局编译
                    # cmd.exe /c "$UV -j0 -sg -r $uvProjxFile -o $temp_file"
                    # 打印.txt文件内容
                    cat $temp_file
                fi
                print_building_msg $temp_file
                read -p "Whether you need to >> Burn << (Y/N) " inputBurn
                # 将用户输入转换为大写字母
                burnOperation=$(echo "$inputBurn" | tr '[:lower:]' '[:upper:]')
                if [ "$burnOperation" = "Y" ]; then
                    # 烧录
                    cmd.exe /c "$UV -j0 -sg -f $uvProjxFile -o $temp_file"
                    cat $temp_file
                fi

                rm -f $temp_file

            fi
        done
        ;;
    2)
        elfprojxPath=$(pwd)
        elfProjxDirectory=$(echo $elfprojxPath | sed 's/\\/\//g')
        # 在app_debug/boot_debug文件夹下找到.elf文件
        for elfProjxFile in $elfProjxDirectory/*.elf; do
            if [ -f "$elfProjxFile" ]; then
                # .elf文件名对应 .hex 的名字
                echo "Convert to bin............"
                # .hex文件转.bin文件
                # %.*用于去除文件名中的扩展名,并将其替换为.bin
                cmd.exe /c "$hex2binPath .\\${elf_filename%.*}.hex .\\${elf_filename%.*}.bin true"
                print_green "Hex2Bin operation completed."
            fi
        done
        ;;
    3)
        cmd.exe /C "$JFlashPath $jflashDevice -connect -erasechip"
        ;;
    4)
        # 获取当前用户的用户名
        nameTemp=$(whoami)
        username=$(basename "$nameTemp")
        # # 获取桌面路径
        desktop_path="$HOME/Desktop"

        # 获取当前路径
        current_path=$(pwd)
        # 使用 basename 命令提取文件名部分
        file_name=$(basename "$current_path")

        echo "1. app area >>> *.bin file"
        echo "2. app combine boot area>>> *.hex file"
        read -p "What file you want to generate " codeFileType
        # 使用 if 语句根据用户选择进行打印操作
        if [ "$codeFileType" = "1" ]; then
            cmd.exe /C "$JFlashPath $jflashDevice -connect$Device -readrange$app_start_addr,$app_end_addr -saveasC:\\Users\\$username\\Desktop\\${file_name%.*}.bin -auto -exit"
            print_yellow "app *.bin is saved in C:\\Users\\$username\\desktop"
            # 在这里执行打印操作1
        elif [ "$codeFileType" = "2" ]; then
            cmd.exe /C "$JFlashPath $jflashDevice -connect$Device -readrange$boot_start_addr,$app_end_addr -saveasC:\\Users\\$username\\Desktop\\${file_name%.*}.hex -auto -exit"
            print_yellow "app combine boot *.bin is saved in C:\\Users\\$username\\desktop"
            # 在这里执行打印操作2
        else
            echo "Error: Invalid choice. Please enter 1 or 2."
        fi

        ;;
    *)
        echo "Invalid choice."
        ;;
    esac
done

config.sh

该文件为脚本配置文件,这里需要跟进修改相关路径和芯片相关配置信息

#!/bin/bash

# *******************tool****************************
# JLink.exe
JLinkPath="D:\SEGGER\JLink\JLink.exe"
# JFlash.exe
JFlashPath="D:\SEGGER\JLink\JFlash.exe"
# JLinkGDBServer.exe
JLinkGDBServerPath="D:\SEGGER\JLink\JLinkGDBServer.exe"
#HEX2BIN
hex2binPath="E:\MC_LOCK\hex2bin.exe"
# UV4.exe
UV="D:\keil\UV4\UV4.exe"

# ****************read flash area *******************************
# 这里需要到JFlash.exe那里创建名为STM32F103.jflash,并添加到.uvprojx文件所处路径下
jflashDevice=".\STM32F103.jflash"
Device=STM32F103
# 在这里修改需要读取芯片的flash地址,我程序里带有boot和app程序,因此拆分成了两块flash区域用作读取
boot_start_addr=0x00
boot_end_addr=0x7000
app_start_addr=0x7000
app_end_addr=0X10000

# ****************JLINK*******************************
# 将多行指令写入临时文件
cat <<EOF > jlinkTempCommands.jlink
USB
si 1
speed 1000
device $Device
r
h
erase $app_start_addr $app_end_addr
loadfile .\\${elf_filename%.*}.bin $app_start_addr
r
q
EOF

3.创建JFlash工程,

该文件放置到.uvprojx所处目录下,该文件作用是方便脚本调用JFlash.exe从芯片中读取flash,生成hex/bin文件

这里我以stm32f103c8t6芯片为例

五.调用脚本

可以使用cmd窗口方式或vscode终端调用脚本。cmd终端调用脚本,需要cd到 .uvprojx 所处目录下,输入 bash build.sh 调用指令

  • 9
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值