Keil使用命令行附加预定义宏编译

2023-05-16

1. 前言

很多时候,一份Keil工程代码可能需要满足多个不同的应用场景。可以通过逻辑判断,将多个不同的点集成在一份代码之中,但是嵌入式往往特别关注RAM空间,集成过多的逻辑判断,RAM空间可能就不够用了。针对这种情况Keil提供了配置Target,通过宏定义来分隔不同的功能,编译生成不同的bin文件。
在这里插入图片描述

但是有时,一个Target项目中,另外又有几个子场景,子场景也需要用预定义宏来区分开。但是Keil并没有提供这样的功能。
另外,Keil工程有非常多的Target,一次修改,必须不停选择不同Target来进行编译,这种编译方式非常不方便。

2. 方法

Keil提供了命令行,可以编译工程。另外,Keil使用的ArmCC和Armlink来编译和链接,这样的话,便可以使用makefile来编译Keil工程代码。

2.1. 命令行

2.1.1 用法

UV4 [command] [projectfile]

2.1.1.1. command

command可以是下述列表之一。如果command没有指定,则只是打开Keil工程。

  • -b, 编译指定的Keil工程默认的Target。

UV4 -b PROJECT1.uvprojx

  • -c, 清除Keil工程中所有Target的临时文件。

UV4 -c PROJECT1.uvprojx

  • -cr, 清除所有Target,然后重新编译所有Target。

UV4 -cr PROJECT1.uvprojx

  • -d, 启动Keil的调试模式。

UV4 -d PROJECT1.uvprojx

  • -f, 下载程序到flash上,下载完成之后退出。

UV4 -f PROJECT1.uvprojx -t"MCB2100 Board"

  • -r, 重新编译Keil工程的默认Target,或用-t指定Target。

UV4 -r PROJECT1.uvprojx
UV4 -r PROJECT1.uvprojx -t"Simulator"

  • -5, 转换Keil4工程为Keil5工程。

UV4 -5 myoldproject.uvproj -l log.txt

  • -et, 导出工程的Target的配置。
  • -ep, 导出工程所有Target配置。
  • -X, 生成预处理符号文件。
  • -X1, 为所有Target生成预处理符号文件。

2.1.3. Option

下面的选项是可选项。

  • -j0, 隐藏Keil的UI。
  • -i, 创建一个新的工程,或通过XML文件更新存在的工程。
  • -l logfile,保存命令生成的输出到logfile中。
  • -n device_name, 创建一个指定device_name的工程。

UV4 MyProject.uvprojx -n Device123

  • -np device_name, 如果工程不存在,则指定device_name创建工程。如果工程存在,则更新所有target的device_name。
  • -o outputfile, 指定输出的Log文件。

UV4 -r PROJECT1.uvprojx -o"output.log"

  • -q, 重新编译多工程指定的Target。
  • -t, 指定工程的target。

UV4 -r PROJECT1.uvprojx -t"MCB2100 Board"

  • -x, 配合Debug模式命令-d使用,返回完整的命令输出。
  • -y, 配合Debug模式命令-d使用,返回通用的配置。
  • -z, 重新编译工程的所有Target。

UV4 -b PROJECT1.uvproj -z

2.1.4. ERRORLEVEL

Kiel编译完成后的错误码

ERRORLEVEL描述
0无错误无敬告
1仅有敬告
2错误
3重大错误
11不能打开工程
12给定的设备不存在
13写工程文件出错
15读XML文件出错
20转换工程出错

2.1.5. 指定多预定义宏

为一个target指定多个预定义宏,此处使用shell脚本编写,需要git-bash或cygwin来编译。
添加一个define.h宏,Keil工程引用此宏达到控制一个Target中有不同的预编译宏。

# Obtain Keil project
prj_name=$(find *.uvproj)

# Obtain all target name of uvproj
mapfile -t target_array < <(cat "${prj_name}" | grep "TargetName" | awk -F '>' '{print $2}' | awk -F '<' '{print $1}')

# Macro
L85C_define=(__L85C1_ __L85C2__)

# Build all target
for name in "${target_array[@]}"; do
	if [[ "$name" == "L85C" ]]; then
		for define in "${L85C_define[@]}"; do
			echo "#define" $define>define.h
			# Code中include "define.h"
			"C:\Keil\UV4\UV4.exe" -r 5081Scan.uvproj -t"$name" -o "$name""$define""Build.txt" -j0
		done
	else
		"C:\Keil\UV4\UV4.exe" -r 5081Scan.uvproj -t"$name" -o "$name""Build.txt" -j0
	fi
	
	# If build error, stop build.
	if (( $? > 0 )); then
		echo Build error.
		break
	fi
done

2.2. makefile

2.2.1. Keil编译过程

Keil使用ArmCC编译源文件,使用Armlink链接目录文件生成efl文件,然后调用fromelf转换为bin文件。
那么ArmCC和Armlink如何使用呢?Keil提供一种方法来展示如何使用ArmCC和Armlink。如下图,勾选Create Batch File,会将ArmCC和Armlink编译链接的过程输出到相应的文件中。
![在这里插入图片描述](https://img-blog.csdnimg.cn/6b91db62eb83428895d169c13d3bfb9c.png
编译当前工程指定的Test,编译连接的命令过程生成在test.bat文件中,如下图:
在这里插入图片描述

  • startup_mo_ia文件主要是编译汇编文件,内容为:
    在这里插入图片描述
    实际的调用命令为:

ArmAsm --cpu Cortex-M0 -g --apcs=interwork --pd “__MICROLIB SETA 1” -I C:\Keil\ARM\RV31\INC
-I C:\Keil\ARM\CMSIS\Include --list .\list\startup_m0.lst --xref -o .\obj\startup_m0.o --depend .\obj\startup_m0.d “startup_M0.s”

  • main._ip,这个主要是生成汇编文件,一般情况可以不使用。
  • main._i文件主要是编译.c文件,内容为:
    在这里插入图片描述
    实际调用的过程为:

ArmCC -c --cpu Cortex-M0 -D__MICROLIB -g -O2 -Otime --apcs=interwork -I C:\Keil\ARM\RV31\INC -I C:\Keil\ARM\CMSIS\Include -o .\obj\main.o --omf_browse .\obj\main.crf --depend .\obj\main.d “Src\main.c”

  • scan.lnp,主要是描述连接的过程。
    在这里插入图片描述
    实际的连接过程为:

ArmLink --cpu Cortex-M0".\obj\startup_m0.o" “.\obj\scan.o” “.\obj\main.o” --library_type=microlib --strict --scatter “.\Obj\scan.sct” --summary_stderr --info summarysizes --map --xref --callgraph --symbols --info sizes --info totals --info unused --info veneers --list “.\List\scan.map” -o .\Obj\scan.axf

2.2.2. makefile内容

APP ?= .\output\scan.afx
MACRO ?=invlid_macro

OUTPUTCHAN ?= SEMIHOSTED

SHELL=$(windir)\system32\cmd.exe
RM_FILES = $(foreach file,$(1),if exist $(file) del /q $(file))
RM_DIRS = $(foreach dir,$(1),if exist $(dir) rmdir /s /q $(dir)$(EOL))

ifeq ($(QUIET),@)
PROGRESS = @echo Compiling $<...
endif

SRC_DIR = Src
ASM_DIR = .
INC_DIR = include
OBJ_DIR = obj
LINK = armlink
OUTPUT_DIR=output

INCLUDES := -I$(INC_DIR)
INCLUDES += -I C:\Keil\ARM\RV31\INC
INCLUDES += -I C:\Keil\ARM\CMSIS\Include

ARCH               := Cortex-M0
CPU                := ARM
LINK_GCC            := link.ld
GCC_LINKER_FILE       := -T link/$(LINK_GCC)

GCC_TOOLCHAIN   := C:\Keil\ARM\ARMCC\bin
ASM         := $(GCC_TOOLCHAIN)\ArmAsm
CC        := $(GCC_TOOLCHAIN)\ArmCC
LINKER_CSRC := $(GCC_TOOLCHAIN)\armlink
FROMELF := $(GCC_TOOLCHAIN)\fromelf

# GCC options
ASM_OPTS          := --cpu Cortex-M0 -g --apcs=interwork --pd "__MICROLIB SETA 1"
CC_OPTS           := --cpu Cortex-M0 -D__MICROLIB -g -O2 -Otime --apcs=interwork -D$(MACRO)
LINKER_FILE		  := --cpu Cortex-M0 --library_type=microlib --strict --scatter ".\scan.sct"  --info summarysizes 


APP_C_SRC := $(wildcard $(SRC_DIR)/*.c)
APP_S_SRC := $(wildcard $(ASM_DIR)/*.s)
OBJ_FILES := $(APP_C_SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o) 
OBJ_FILES += $(APP_S_SRC:$(ASM_DIR)/%.s=$(OBJ_DIR)/%.o)
DIRS= $(OUTPUT_DIR) $(OBJ_DIR) 

.phony: all clean

all: FORCE $(APP)

FORCE:
	@echo being

$(APP): $(DIRS) $(OBJ_FILES) 
	@echo Linking $@
	$(LINKER_CSRC) $(LINKER_FILE) $(OBJ_FILES) -o $@
	$(FROMELF) $@ --i32combined --output ".\output\scan.hex"
	$(FROMELF) $@  --bin --output ".\output\scan.bin"
	@echo Done.

clean:
	$(call RM_DIRS,$(OBJ_DIR))
	$(call RM_DIRS,$(OUTPUT_DIR))
	$(call RM_FILES,$(APP))


$(DIRS):
	mkdir $@
	@echo $(OBJ_FILES)

$(OBJ_DIR)/%.o : $(SRC_DIR)/%.c
	@echo begin to comple c source
	$(CC) -c $(CC_OPTS) -o $@ $<

$(OBJ_DIR)/%.o : $(ASM_DIR)/%.s
	@echo begin to comple asm
	$(ASM) -c $(ASM_OPTS)  -o $@ $<

# Make sure everything is rebuilt if this makefile is changed
$(OBJ_FILES) $(APP): makefile

2.2.3. 多预编译宏

利用批处理,添加MACRO参数控制预编译宏。

echo off
set list=__AAA_ __BBB__  __CCCC__ __DDDD__

for %%n in (%list%) do (
	make clean
	make MACRO=%%n ) 

3. 其他

3.1. 总结

命令行的方式使用简单,但是灵活度不够,例如一个Target不能指定宏。Makefile比较灵活,但是前期构建工程会比较复杂,但是如果makefile构建完成之后,使用也非常方便。

3.2. 参考

  1. https://developer.arm.com/documentation/101407/0537/Command-Line
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Keil使用命令行附加预定义宏编译 的相关文章

  • Keil使用命令行附加预定义宏编译

    1 前言 很多时候 xff0c 一份Keil工程代码可能需要满足多个不同的应用场景 可以通过逻辑判断 xff0c 将多个不同的点集成在一份代码之中 xff0c 但是嵌入式往往特别关注RAM空间 xff0c 集成过多的逻辑判断 xff0c R
  • Keil调试中遇到问题汇总

    1 Keil MDK中工程编译弹出提醒框 xff1a Browse information of one of more files is not available Doing a project rebuild might fix th
  • Keil调试局部变量显示"not in scope"的问题解决

    今天在调试程序的时候 xff0c 发现函数返回值赋值给变量时 xff0c 变量值总是显示 34 not in scope 34 xff0c 无法看到变量被赋的值 出现这种情况的原因是这个局部变量没被分配到内存 xff0c 或者变量被编译器优
  • keil找不到芯片型号的解决方法

    1 上官网下载对应的固件包 http www keil com dd2 Pack eula container 例如 2 点击 Pack installer 3 点击 File gt Import xff0c 选中下载的固件包 如果选择后左
  • keil的错误: Error: Encountered an improper argument 的解决方法

    将附件中的文件下载然后放到keil一下的安装目录中即可C Keil v5 UV4 xff0c 选择替换即可 文件链接 xff1a http download csdn net download ma57457 10118005 官方说的是支
  • Keil工程

    文章目录 1 Keil工程添加源文件和头文件 xff08 c和 h xff09 的方法1 方式一2 方式二 2 keil工程生成的MAP文件取消优化 1 Keil工程添加源文件和头文件 xff08 c和 h xff09 的方法 1 方式一
  • error: #40: expected an identifier

    错误指向stm32f10x h typedef enum FALSE 0 TRUE FALSE bool 原因是在其他文件中重复 define了FALSE 的值 将其注释掉即可
  • keil编译问题error C100: unprintable character... 和WARNING L16: UNCALLED SEGMENT...

    keil编译出现问题如下 问题 error C100 unprintable character 0xA3 skipped 原因 keil里面出现了中文输入法时写的标点 程序中不能出现全角的任何字符 包括空格在内的任何标点符号和空格都只能在
  • STM32CubeIDE设置Flash烧录地址和大小(告别Keil魔术棒)

    STM32CubeIDE中设置Flash烧写地址和范围 在由Keil平台转到STM32CubeIDE平台过程中 我们熟悉的点开魔术棒进行相关烧录配置的方式已经不适用了 在STM32CubeIDE平台中我们需要通过修改文件的方式来实现 稍显麻
  • 005--Keil使用--出现integer conversion resulted in truncation

    warning 69 D integer conversion resulted in truncation 问题所在 变量赋值超出了变量类型的最大值 解决方法 找到该变量 适当修改变量的类型
  • keil修改字体、文本颜色、背景颜色,global.prop使用

    keil 空乏的文本颜色和背景严重影响使用感 下面教大家如何修改仿VS的黑色主题 自定义字体颜色和背景 点击 Configuration 小扳手图标 Colors Fonts 主要修改 All Editors 和 C C Editor fi
  • 把keilC51中不使用的代码禁止分配空间,为程序瘦身!

    把target options中的device页中选上 Use LX51 然后在LX51 Misc页中的Misc Control中填入 REMOVEUNUSED 确认后重新编译即可自动去掉未调用的函数 如下图
  • keil5烧录或下载程序出现停止工作的问题

    本人在使用keil5烧录或下载程序出现停止工作的问题 开始认为是keil版本的原因 后来使用了keil4发现问题依然存在 发现因为本人使用了盗版JLINK被驱动检测出来了 由于安装的驱动版本为V6 14 新版的驱动检测到盗版JLINK 一旦
  • Keil 5使用ST-LINK调试STM32程序

    1 下载并安装STM32 ST LINK Utility 含有驱动 2 启动STM32 ST LINK Utility 点击菜单 ST LINK Firmware 更新固件 3 打开Keil工程 设置Debug 4 开始调试
  • KEIL中怎样添加STC系列单片机

    我们有时在KEIL中新建工程时需要添加STC系列单片机 但就是找不到 这是因为你安转的Keil软件中没有STC的数据库 所以需要你手动添加 这就需要在STC ISP软件 这个软件可以在STC网http www stcisp com下载或者百
  • Keil编程中Source Brower : "P17" is undefined!的问题

    博客原文 Keil编程中Source Brower P17 is undefined 的问题 在Keil新建工程中经常会遇到一个问题 去看某一个变量定义 然后跳转不过去 并提示Source Brower 某某 is undefined 在这
  • 关于KEIL MDK调试ARM程序不能仿真的问题

    在单片机程序调试过程中 由于程序量小 利用仿真器进行仿真调试方便直观 所以一般经常使用 但是keil经常会出现罢工 无法用仿真器调试的现象 如下图 解决方法也很简单 按照下图设置即可
  • keil找不到device,怎么办?

    下载好的keil 准备调试程序 却发现这个问题 找不到我需要的芯片啊啊啊 头大 后面发现是缺少相应的pack 安装keil时 好像没有自动装上STM32系列芯片 所以得需要自己安装 百度一下 找一些资源 然后 把途中红色框住的 分别放在安装
  • STM32技巧: Keil错误提示“ File Not Found”

    1 文件已添加到工程目录但提示 file not found 原因 仅添加到目录但未包含编译文件的路径 解决 Option gt C C gt Include Paths 添加提示缺失的文件所在路径 错误提示消失
  • C 易失性位域结构的复制构造函数

    Good day 我正在尝试在 C 11 项目中使用 C SD 驱动程序 文件系统库 Keil MDK 它是由 Keil MDK 5 23 中的 Pack 管理器添加的 我正在使用 ARMCC 5 06u4 进行编译 我收到警告class

随机推荐

  • VScode单步调试

    VScode配置 0 快捷键1 安装clang2 VScodeDebug3 Cmake支持gdb调试的方法 0 快捷键 稍大工程在vscode下的调试参考该博客 Ctrl 43 打开默认终端 Ctrl 43 Shift 43 新建新的终端
  • 串口通信简介

    串口通信 串口通信是一种串行异步通信 xff0c 通信双方以字符帧作为数据传输单位 xff0c 字符帧按位依次传输 xff0c 每个位占固定的时间长度 两个字符帧之间的传输时间间隔可以是任意的 xff0c 即传输完一个字符帧之后 xff0c
  • ubuntu16.0 ROS(介绍EAI的YDLIDAR-X4激光雷达在ROS下使用方法)

    YDLIDAR X4激光雷达介绍 YDLIDAR X4激光雷达是深圳越登智能科技有限公司 xff08 YDLIDAR xff0c 这家公司属于EAI xff09 研发的一款 360 度二维测距产品 xff0c 本产品基于三角测距原理 xff
  • php使用http_build_query,parse_url,parse_str创建与解析url

    1 http build query http build query 可以创建urlencode之后的请求字符串 span class hljs keyword string span http build query mixed spa
  • 无人驾驶小车调试笔记(六)-- 车轮校准

    简介 xff1a 小车的动力完全来自于两个电机带动的车轮 xff0c 在理想状态下 xff0c 给两个电机同样的驱动参数 xff0c 两个车轮会以同样的转速带动小车直线行驶 xff0c 而实际情况是每个电机可能都会有个体差异 xff0c 也
  • Nginx HTTP详解

    正文 1 Nginx启动流程 2 HTTP 初始化 新连接建立时的行为 在上次博客的最后可以看到 xff0c 在ngx event accept方法建立连接的最后一步 xff0c 将会调用ngx listening t监听结构体的handl
  • 时钟周期,机器周期,指令周期的相互关系

    1 时钟周期 61 振荡周期 xff0c 名称不同而已 xff0c 都是等于单片机晶振频率的倒数 xff0c 如常见的外接12M晶振 xff0c 那它的时钟周期 61 1 12M 2 机器周期 xff1a 8051系列单片机的机器周期 61
  • 单片机的分频是什么意思?

    分频就是单片机的时钟频率 xff08 也就是晶振的震荡频率 xff09 F经过12分频 xff0c 变换成F 12的频率 简单的来说就是以整数倍降低频率 2分频就是分频前的频率除以2 xff1b 4分频就是分频前的频率除以4 比如 xff1
  • NMOS和PMOS管

    这里我先说一下我自己分辨MOS管的方法 对于NMOS我们看下图中的箭头 xff0c 都是远离源头 对于PMOS我们看箭头 xff0c 都是指向源头 P xff1a POSITIVE积极的寻找自己的起源 N xff1a NEGTIVE消极的远
  • 基本运算放大电路

    我先说明 下面的内容应该很多人都看到过 xff0c 但是我建议还是细看 xff0c 最好自己推一下 我就是这么做的 运算放大器工作原理综述 xff1a 运算放大器组成的电路五花八门 xff0c 令人眼花瞭乱 xff0c 在分析运算放大器工作
  • PCB板框的绘制——AD19

    pcb板框的绘制当然首先要切换到keep out 层才行 找到设置 xff0c 找到keep out 假如我们要绘制一个矩形的板框 xff0c 我们选择线径就可以 手动绘制一个矩形的板框 我们需要让我们的板子边框按照我们所绘制的走线来定义
  • 零基础自学STM32-野火——GPIO复习篇——使用绝对地址操作GPIO

    今天主要是复习一下 结合野火的 零基础开发指南 名字没记住大概是这个 先放一张结构图 存储器映射 xff08 初学重点 xff09 xff1a 我们的片内外设比如 xff1a Flash Sram Fsmc 以及挂在AHB 总线上的外设 x
  • Lcd1602——斌哥51

    最新修改时间2022 7 22 LCD1602 16代表显示16个字符 xff0c 2代表总共显示两行 芯片的工作电压是4 5 5 5v 工作电流2 0ma xff08 5V xff09 模块最佳工作电压5 0v 字符尺寸 xff1a 2
  • 无人驾驶小车调试笔记(七)-- 相机校准

    简介 xff1a 在第五节的内容中 xff0c 我们学习了使用rqt工具集观看摄像头视频流的方法 xff0c 细心的同学应该会发现camera node发布的视频数据中的图像有变形现象 xff0c 图像变形会导致直线不直 xff0c 部分区
  • Python实现MySql、SqlServer增删改查操作

    span class token keyword import span pymssql span class token keyword def span span class token function connection sql
  • ds1302——斌哥51

    以下内容分别借鉴了 清翔 51 xff0c 斌哥51 xff0c 以及CSDN 普通的不普通少年 内部结构 xff1a DS1302 包括时钟 日历寄存器和 31 字节 xff08 8 位 xff09 的数据暂存寄存器 xff0c 数据通信
  • AD添加LOGO

    先上原文链接 xff1a http www allchiphome com circuit pcb logo creator http www allchiphome com circuit pcb logo creator http ww
  • 视频播放组件实战【LivePlayer H5播放器】

    在公司项目开发中 xff0c 有一个项目里面需要做一个视频播放的功能 xff0c 播放方式是调用海康平台提供的接口获取流地址来进行视频的播放并且最重要的是需要支持flash 由于前端用的Vue xff0c 对比了几个 xff0c 最后选择了
  • 如何用示波器测量串口

    如何确定时基 假如要测量的波特率为9600 则每一比特位的时间为 xff1a 1 9600 104 s xff0c 一般示波器横向上每个大格子里5个小格子 xff0c 要想看清一比特位一般需要一个小格子就够了 xff0c 则时基为 xff1
  • Keil使用命令行附加预定义宏编译

    1 前言 很多时候 xff0c 一份Keil工程代码可能需要满足多个不同的应用场景 可以通过逻辑判断 xff0c 将多个不同的点集成在一份代码之中 xff0c 但是嵌入式往往特别关注RAM空间 xff0c 集成过多的逻辑判断 xff0c R