> For the complete documentation index, see [llms.txt](https://oceanaparts.gitbook.io/halnote/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://oceanaparts.gitbook.io/halnote/mo-shu-bang-she-zhi-jie-xi.md).

# 魔术棒设置解析

[Keil（MDK-ARM）系列教程（四）\_工程目标选项配置（Ⅱ） (360doc.com)](http://www.360doc.com/content/17/0825/18/18945873_682095068.shtml)

[99%开发者从未听说过的堆栈模型-电子发烧友网 (elecfans.com)](https://www.elecfans.com/d/1942690.html)

[STM32（4）：番外篇之stm32固件库工程搭建 - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/454594644#:~:text=Use,MicroLIB%E5%8B%BE%E9%80%89%E4%B8%8A%EF%BC%9BMicroLib%E6%98%AF%E4%B8%80%E4%B8%AA%E5%BE%AE%E5%9E%8B%E7%9A%84C%E5%BA%93%EF%BC%8C%E6%8F%90%E4%BE%9B%E4%BA%86%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%B8%B8%E8%A7%81%E7%9A%84c%E7%9A%84%E5%87%BD%E6%95%B0%E5%BA%93%EF%BC%8C%E4%BD%86%E6%98%AF%E5%9B%A0%E4%B8%BA%E6%98%AF%E5%AF%B9%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%87%BD%E6%95%B0%E7%9A%84%E6%94%AF%E6%8C%81%EF%BC%8C%E6%89%80%E4%BB%A5%E7%9B%B8%E6%AF%94%E4%BA%8Elinux%E7%9A%84gcclib%E5%BE%88%E4%B8%8D%E5%AE%8C%E6%95%B4%EF%BC%9B%E4%B9%8B%E6%89%80%E4%BB%A5%E9%9C%80%E8%A6%81%E5%8B%BE%E9%80%89%EF%BC%8C%E6%98%AF%E5%9B%A0%E4%B8%BA%E6%9C%89%E7%9A%84%E6%97%B6%E5%80%99%E9%9C%80%E8%A6%81%E4%BD%BF%E7%94%A8%E4%B8%80%E4%BA%9B%E8%AF%B8%E5%A6%82%E5%9C%A8%22stdio.h%22%E6%9D%A5%E5%AE%9E%E7%8E%B0printf%E7%9A%84%E6%97%B6%E5%80%99%EF%BC%8C%E6%98%AF%E9%9C%80%E8%A6%81c%E5%BA%93%E6%94%AF%E6%8C%81%E7%9A%84%EF%BC%8C%E8%BF%99%E4%BA%9B%E5%BA%95%E5%B1%82c%E5%BA%93%E7%9A%84API%E6%8E%A5%E5%8F%A3%E4%BB%A5%E5%8F%8A%E5%AE%9E%E7%8E%B0stm32%E5%9B%BA%E4%BB%B6%E5%BA%93%E6%98%AF%E4%B8%8D%E6%8F%90%E4%BE%9B%E7%9A%84%EF%BC%8C%E6%B3%A8%E6%84%8Fstm%E6%8F%90%E4%BE%9B%E6%98%AF%E5%9B%BA%E4%BB%B6%E5%BA%93%EF%BC%8C%E6%98%AF%E7%9B%B4%E6%8E%A5%E6%93%8D%E4%BD%9C%EF%BC%88%E7%A1%AC%E4%BB%B6%EF%BC%89%E5%AF%84%E5%AD%98%E5%99%A8%E7%9A%84%EF%BC%8C%E8%80%8Cc%E6%98%AF%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%B1%82%E9%9D%A2%E7%9A%84%EF%BC%8C%E5%B1%9E%E4%BA%8E%E8%BD%AF%E4%BB%B6%E5%B1%82%E9%9D%A2%E7%9A%84%EF%BC%8C%E6%89%80%E4%BB%A5%E6%9C%89%E9%9C%80%E8%A6%81%E7%9A%84%E6%97%B6%E5%80%99%E5%8B%BE%E9%80%89%E4%B8%8A%EF%BC%9B)

[(22条消息) Keil（MDK-ARM）系列教程（三）\_工程目标选项配置（Ⅰ）\_strongerHuang的博客-CSDN博客](https://blog.csdn.net/ybhuangfugui/article/details/51655502?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167776276216800184196356%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D\&request_id=167776276216800184196356\&biz_id=0\&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-51655502-null-null.blog_rank_default\&utm_term=%E5%B7%A5%E7%A8%8B%E7%9B%AE%E6%A0%87\&spm=1018.2226.3001.4450)

[(18条消息) Keil（MDK-ARM）系列教程（四）\_工程目标选项配置（Ⅱ）\_plain char is signed\_strongerHuang的博客-CSDN博客](https://strongerhuang.blog.csdn.net/article/details/53131141)

## 九、魔术板设置解析

这个面板的设置影响十分多的东西

### 9.1 关于Use MicroLIB是否勾选问题

[(22条消息) 关于Use MicroLIB是否勾选问题\_The\_General\_Reader的博客-CSDN博客](https://blog.csdn.net/weixin_40692163/article/details/106422524)

> MicroLib是一个微型的C库，提供了嵌入式常见的c的函数库，但是因为是对嵌入式函数的支持，所以相比于linux的gcclib很不完整；之所以需要勾选，是因为有的时候需要使用一些诸如在"stdio.h"来实现printf的时候，是需要c库支持的，这些底层c库的API接口以及实现stm32固件库是不提供的，注意stm提供是固件库，是直接操作（硬件）寄存器的，而c是操作系统层面的，属于软件层面的，所以有需要的时候勾选上；勾选上也会影响堆栈的初始化方式，也可能会[与C库的区别](https://blog.csdn.net/xiayufeng520/article/details/46326915)
>
> 如果勾选上的话，并且主函数名为main的话启动文件一定要有\_\_initial\_sp，\_\_heap\_base，\_\_heap\_limit三个值，否则会报以下错误
>
> ```
> .\Objects\led_c.axf: Error: L6218E: Undefined symbol __initial_sp (referred from entry2.o).
> ```
>
> 海

**可能需要用到的情况：** 1、实际需要用到串口重定向到printf时可以勾选上。2、不使用这个，浮点数运算也会出问题。3、移植ucossiii ，不选微库，开了FPU 会死机

![](https://s2.loli.net/2023/03/02/QwdPtKbWyFrlBTz.png)

#### 9.1.1    应用实例：串口

**9.1.1.1    方法1–使用微库：**

1、包含头文件:#include “stdio.h”

2、Printf重定向，修改fputc()函数的内容\~

```
int fputc(int ch, FILE *f)
{
    USART_SendData(DEBUG_USART, (unsigned char) ch);
    while (!(DEBUG_USART->SR & USART_FLAG_TXE));
    return (ch);
}
```

这里的：

```
USART_SendData(DEBUG_USART, (unsigned char) ch);
while (!(DEBUG_USART->SR & USART_FLAG_TXE));
```

就是往串口发送一个字节的代码，修改相应的串口，初始化。这样就能使用printf了\~可以一试。

**9.1.1.2    方法2–不使用微库：**

1、包含头文件#include “stdio.h”

2、重写fputc，但需要先加点东西：

（用这个方法，勾选上微库Use MicroLIB也没问题）

```
#pragma import(__use_no_semihosting)
_sys_exit(int x)
{
    x = x;
}
struct __FILE
{
    int handle;
};
FILE __stdout;
int fputc(int ch, FILE *f)
{
    USART_SendData(DEBUG_USART, (unsigned char) ch);
    while (!(DEBUG_USART->SR & USART_FLAG_TXE));
    return (ch);
}
```

**9.1.1.3     总结**

不使用微库

<img src="https://s2.loli.net/2023/03/02/UxmEy
wQGoId1hLp.png" alt="" height="60%" width="60%">

使用微库

<img src="https://s2.loli.net/2023/03/02/qcOkLof2AvC18El.png" alt="" height="60%" width="60%">

### 9.2    C/C++界面

[(22条消息) Keil（MDK-ARM）系列教程（三）\_工程目标选项配置（Ⅰ）\_strongerHuang的博客-CSDN博客](https://blog.csdn.net/ybhuangfugui/article/details/51655502?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167776276216800184196356%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D\&request_id=167776276216800184196356\&biz_id=0\&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-51655502-null-null.blog_rank_default\&utm_term=%E5%B7%A5%E7%A8%8B%E7%9B%AE%E6%A0%87\&spm=1018.2226.3001.4450)

[(18条消息) Keil（MDK-ARM）系列教程（四）\_工程目标选项配置（Ⅱ）\_plain char is signed\_strongerHuang的博客-CSDN博客](https://strongerhuang.blog.csdn.net/article/details/53131141)

<img src="https://s2.loli.net/2023/03/02/Tbh6JKpZS3uvGrH.png" alt="" height="60%" width="60%">

#### 9.2.1    Define

> 相当于添加宏定义，使工程根据Define进行编译在yiSTM32F103ZET6为例，
>
> 标准库常用 STM32F10X\_HD,USE\_STDPERIPH\_DRIVER，两个都在stm32f10x.h用到，在此处宏定义后就无须在stm32f10x.h手动增加宏定义
>
> Hal库常用 USE\_HAL\_DRIVER,STM32F103xE，前者在stm32f1xx.h，后者在system\_stm32f1xx.c与stm32f1xx.h，stm32f1xx\_hal.c，stm32f1xx\_hal\_rcc\_ex.c，stm32f1xx\_hal\_rcc\_ex.h,stm32f1xx\_hal\_flash\_ex.h,stm32f1xx\_hal\_dac\_ex.h, stm32f1xx\_hal\_dma\_ex.h，stm32f1xx\_hal\_dma\_ex.h等文件都有使用到

#### 9.2.2 Language/Code Generation

Language/code Generation语言代码生成，可以理解成编译、链接到最后生成代码。这部分功能对于代码优化比较重要，初学者可以不用过多理解，对代码大小、运行速度等性能要求较高的人就需要深入理解

* **Execute only Code:** 只生成执行代码 \[设置编译器命令行: --execute only)

&#x20;   **只生成执行代码**防止编译器生成任何数据访问代码部分

* **Enum Container always int：** 枚举总是int型

  很容易理解，我们枚举时成员变量类型为int型。
* **Optimize:** 优化选择项，

&#x20;   **有Level0 - Level3四个选项**     设置编译器命令行: -Onum)     初学者、在线调试建议使用**Level0，也就是不优化**，这样执行的效果才和代码一     样。    如果配置成Leve13，在线调试可能有些地方优化而不能打断点

* **C99 Mode**

  大大减小语法编译报错的概率；C99相比于默认的C89，不仅带来很多新特性，而且更加人性化，比如变量定义要在第一行可执行代码之前，否则编译报错：

#### 9.2.3 Include Paths

**包含路径**是使用Keil（及类似）软件必须掌握的一项。包含路径就是**指定我们工程中使用头文件所在的位置，让编译器找到相应的文件**。是初学者、高级软件工程师都必须掌握的一项。

#### 9.2.4 Misc Controls

多功能空间，可以用来忽略编译的警告或错误之类的，只需在Misc Control中添加“--diag\_suppress=”就可以了， num就是Keil中的警告代码，把警告内容贴到百度搜索一下就可以知道警告代码是多少了，比如需要忽略warning: #61-D: integeroperation result is out of range这个警告，只需添加--diag\_suppress=61

#### 9.2.5 Compiler control string

设置编译器控制字符串，前面语言代码生成Language/code Generation语言代码生成的选择就会影响这边。

### 9.3 User界面

> 主要用于编写
>
> 1、编辑前运行的脚命令
>
> 2、编译前运行的命令
>
> 3、编译后运行的命令，基本上修改的是此处，生成bin文件或dis反汇编文件
>
> 4、Run "After Build" conditionally：执行条件；Beep When Complete：编译完成发出声音；Start Debugging：启动调试程序。
>
> <img src="https://s2.loli.net/2023/03/06/lpZmR8xw1rA2IDQ.png" alt="" data-size="original">

### 9.4 生成Bin文件或Dis文件

#### 9.4.1 Bin,Hex,Axf,Dis文件的区别

> Dis文件时反汇编文件，可以查看代码段与对应地址，可以直接拖入MDK打开
>
> Bin文件是编译生成的二进制文件，是最纯粹的，烧录进单片机的就是这些数据，可以计算Program Size的 Code+ RO-data+ RW-data会发现等于bin文件的大小， 而axf文件时用于调试的（用调试器烧录使用的也是Hex,不是axf），Hex文件带有地址信息，都包括了一些其他数据，因此大小也会大于bin文件

#### 9.4.2 如何使用Keil5生成

> 编辑 User的Afer Build/Rebuild脚本可以在编译后生成对应文件，**实际上是调用MDK5安装路径下的fromelf.exe（MDK5\ARM\ARMCC\bin\fromelf.exe）**
>
> 可以定位到所在文件夹后输入以下代码获取语法
>
> ```
> .\fromelf.exe --help
> ```
>
> 下面是语法
>
> ```
> fromelf [options] input_file  (命令的格式)
>
> Options:
>        --help         display this help screen (显示帮助信息)
>        --vsn          display version information (显示版本信息)
>        --output file  the output file. (defaults to stdout for -text format) (输出文件(默认的输出为文本格式))
>        --nodebug      do not put debug areas in the output image (在生成的映象中不包含调试信息)
>        --nolinkview   do not put sections in the output image (在生成的映象中不包含段的信息)
>
> Binary Output Formats:
>        --bin          Plain Binary (生成Plain Binary格式的文件)
>        --m32          Motorola 32 bit Hex (生成Motorola 32位十六进制格式的文件)
>        --i32          Intel 32 bit Hex (生成Intel 32位十六进制格式的文件)
>        --vhx          Byte Oriented Hex format (面向字节的位十六进制格式的文件t)
>
>        --base addr    Optionally set base address for m32,i32 (设置m32，i32格式文件的基地址)
>
> Output Formats Requiring Debug Information (需要调试信息的格式)
>        --fieldoffsets Assembly Language Description of Structures/Classes (结构/类的汇编语言描述)
>        --expandarrays Arrays inside and outside structures are expanded (扩展数组内部和外部结构被扩展)
>
> Other Output Formats:
>        --elf         ELF
>        --text        Text Information (显示文本信息)
>
>                 Flags for Text Information
>                 -v          verbose (打印详细信息)
>                 -a          print data addresses (For images built with debug) (打印数据地址(针对带调试信息的映象))
>                 -c          disassemble code (打印反汇编代码)
>                 -d          print contents of data section (打印数据段的内容)
>                 -e          print exception tables (打印表达式表)
>                 -g          print debug tables (打印调试表)
>                 -r          print relocation information (打印重定位信息)
>                 -s          print symbol table (打印字符表)
>                 -t          print string table (打印字符串表)
>                 -y          print dynamic segment contents (打印动态段的内容)
>                 -z          print code and data size information (打印代码和数据大小的信息)
> ```
>
> 下面提供一个生成bin的示例，放在RUN1 RUN2皆可
>
> ```
>  fromelf.exe --bin --output ../OBJ/PWM.bin ../OBJ/PWM.axf
> ```
>
> 说明：
>
> * fromelf.exe声明了使用的exe如果找不到该文件可以尝试设置全局变量或是使用相对路径
>
>   ```
>   $K\ARM\ARMCC\bin\fromelf.exe
>   ```
> * \--bin 生成plain binary即纯二进制文件
> * \--output 后面跟上输出文件
> * ../OBJ/PWM.bin **说明输出文件与路径** 在项目文件PWM.uvprojx的上级文件夹下找到OBJ文件夹，在该文件夹下生成PWM.bin文件（PWM根据实际项目名修改，如不理解文件夹结构见下面的文件树，OBJ文件夹其实就是编译的输出文件夹，在魔术棒的 Output->Select Folder for Objects下设置）
> * ```
>   ├─CORE
>   ├─HALLIB
>   │  └─STM32F1xx_HAL_Driver
>   │      ├─Inc
>   │      │  └─Legacy
>   │      └─Src
>   │          └─Legacy
>   ├─HARDWARE
>   │  ├─KEY
>   │  ├─LED
>   │  └─TIMER
>   ├─OBJ
>   ├─SYSTEM
>   │  ├─delay
>   │  ├─sys
>   │  └─usart
>   └─USER
>       └─DebugConfig
>   ```
> * ../OBJ/PWM.axf **说明使用的文件与路径** 在项目文件PWM.uvprojx的上级文件夹下找到OBJ文件夹，在该文件夹下找到PWM.axf文件（PWM根据实际项目名修改）
>
>   下面提供一个生成dis反汇编文件的实例,注意是--text -a -c
>
>   ```
>   fromelf  --text  -a -c  --output=../OBJ/PWM.dis  ../OBJ/PWM.axf
>   ```

### 9.3 对函数使用F12 Go to Definition 不能跳转

> 勾选Output下的Browse information

<img src="https://s2.loli.net/2023/03/06/vxrtsQj1gOB2Jl8.png" alt="" height="60%" width="60%">

### 9.4 为什么没有生成Map文件

> 勾选下面这个选项
>
> <img src="https://s2.loli.net/2023/03/06/GzC8W1qNVtOd3Ss.png" alt="" data-size="original">

### 9.4 为什么通过调试器烧录程序后，还需要复位才能运行

> 在Utilities界面下选择Seeting，勾选“Reset and Run”

<img src="https://s2.loli.net/2023/03/06/PmJGCS8IgNRlWXj.png" alt="" height="60%" width="60%">

### 9.5 新建工程后选择芯片后会在魔术棒界面增加什么设置

> 只会在Target标签设置频率，这个值主要用于仿真调试用，一般我们使用硬件调试可以不用管这个值，IROM1,IRAM1，不会在C/C++界面设置宏定义，会默认勾选上C99 Mode，GNU extensions ，默认优化等级0，会勾选上use memory layout from target
