关于keil卡在systeminit中,然后出现void HardFault_Handler(void)的几个问题详解

2024-08-31 09:08

本文主要是介绍关于keil卡在systeminit中,然后出现void HardFault_Handler(void)的几个问题详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

版权声明:本文为博主原创文章,未经博主允许不得转载。    https://blog.csdn.net/u013184273/article/details/83860802

相信很多程序员在用keil的时候都会遇到在仿真调试时,一直停在SystemInit()中的等待晶振中,怎么也出不来。出现HardFault时,可能不是因为内存溢出,访问越界或是堆栈溢出,有可能仅仅只是自己一些最基本的规则没弄清楚而导致,所以分享下自己一些小问题,让新手朋友们出现类似问题可以借鉴下;


STM32启动文件简单解析(V3.5.0) 以:SystemInit函数详解

具体的函数调用顺序如下:
①startup_stm32f10x_hd.s(启动文件)→②SystemInit()→③SetSysClock ()→④SetSysClockTo72()
说明:由于在上面只定义了SYSCLK_FREQ_72MHz,因而在执行SetSysClock ()函数的时候,会选择进入SetSysClockTo72()函数,以设置系统时钟为72MHz
如果还是想深究SystemInit()函数,那你就打开浏览器上百度或者谷歌进行搜索,网上自来一大堆的。。。。。。。俗话说:小孩勤,喜欢人。

话不多说,进入正题:

当我们仿真一段程序,进入仿真界面的时候,首先是一下这个图: 

这是DEBUG的程序的入口,对,就是这几个汇编的启动代码。如果想知道启动文件的详情,那就打开浏览器上百度或者谷歌进行搜索,网上自来一大堆的。。。。。。。俗话说:小孩勤,喜欢人。

接下来看到  SystemInit函数,按F12进入这个函数你会看到:

如果想知道这个函数是干什么的,那就打开浏览器上百度或者谷歌进行搜索,网上自来一大堆的。。。。。。。俗话说:小孩勤,喜欢人。

你会看到    RCC->CR |= (uint32_t)0x00000001;  这一句话代表:操作时钟控制寄存器,将内部8M高速时钟使能,从这里可以看出系统启动后是首先依靠内部时钟源而工作的。那么问题来了,所谓的一直卡在SystemInit(),其实是卡在RCC->CR |= (uint32_t)0x00000001;  这一句(不是很绝对),

要怎么解决呢?分为3种情况:

A:

1.选上”Use MicroLIB”这是KEIL自带的一个简易的库,例如你用printf函数的时候,就会从串口1 输出字符串,直接默认定向到串口1

UseMicroLib

2.microlib 是缺省 C 库的备选库。 它用于必须在极少量内存环境下运行的深层嵌入式应用程序。 这些应用程序不在操作系统中运行。microlib 不会尝试成为符合标准的 ISO C 库。 
microlib 进行了高度优化以使代码变得很小。 它的功能比缺省 C 库少,并且根本不具备某些 ISO C 特性。某些库函数的运行速度也比较慢,例如,memcpy()。 

3.

microlib 与缺省 C 库之间的主要差异是: 

microlib 不符合 ISO C 库标准。 不支持某些 ISO 特性,并且其他特性具有的功能也较少。 

microlib 不符合 IEEE 754 二进制浮点算法标准。 

microlib 进行了高度优化以使代码变得很小。 

无法对区域设置进行配置。 缺省 C 区域设置是唯一可用的区域设置。 

不能将 main() 声明为使用参数,并且不能返回内容。 

不支持 stdio,但未缓冲的 stdin、stdout 和 stderr 除外。 

microlib 对 C99 函数提供有限的支持。 

microlib 不支持操作系统函数。 

microlib 不支持与位置无关的代码。 

microlib 不提供互斥锁来防止非线程安全的代码。 

microlib 不支持宽字符或多字节字符串。 

与 stdlib 不同,microlib 不支持可选择的单或双区内存模型。 microlib 只提供双区内存模型,即单独的堆栈和堆区。 

可以合理地将 microlib 与 --fpmode=std 或 --fpmode=fast 配合使用。 
microlib 中的函数负责: 

创建一个可在其中执行 C 程序的环境。 这包括: 

创建一个堆栈 

创建一个堆(如果需要) 

初始化程序所用的库的部分组成内容。 

调用 main() 以开始执行程序。 

要使用 microlib 构建程序,必须使用命令行选项 ??library_type=microlib。 根据需要,编译器、汇编程序或链接器可使用此选项处理不同的文件。 将此选项与链接器配合使用时,将覆盖所有其他选项。

4.


//加入以下代码,支持printf函数,而不需要选择use MicroLIB 
#if 1 
#pragma import(__use_no_semihosting)              
//标准库需要的支持函数                  
struct __FILE  
{  
int handle;  

};  

FILE __stdout;        
//定义_sys_exit()以避免使用半主机模式     
_sys_exit(int x)  
{  
x = x;  
}  
//重定义fputc函数  
int fputc(int ch, FILE *f) 
{       
#ifdef COM_EX 
com_snd(COM2, 1, (unsigned char*)&ch); 
#else 
com_snd(COM1, 1, (unsigned char*)&ch); 
#endif 
return ch; 

#endif  

/*使用microLib的方法,在keil里面要勾选“Use MicroLIB”*/ 
// 以便使用 printf 函数 
// #define UTCHAR_PROTOTYPE int fputc(int ch, FILE *f) 
// UTCHAR_PROTOTYPE 
// { 
// #ifdef COM_EX 
//  com_snd(COM2, 1, (unsigned char*)&ch); 
// #else 
//  com_snd(COM1, 1, (unsigned char*)&ch); 
// #endif 
//  
//  return ch; 
// }  
我试了试确实是可以,不知道,如果不用Use MicroLIB,prinft 和sprintf  其他影响不,我去验证一下

B:

1、采用target对话框中的ROM和RAM地址

   采用此方式,需在Linker选项卡中勾选Use Memory Layout from Target Dialog选项(选中这一项实际上是默认在Target中对Flash和RAM的地址配置,编译链接时会产生一个默认的脚本文件),并且在Target中设置好RAM、ROM地址,图2所示。MDK会根据Target选项中设定的RAM和ROM地址自动加载生成一个加载文件。最后链接器会根据此文件中的信息对目标文件进行链接,生成axf镜像文件。

 

C:

选项One ELF Section per Function

选项One ELF Section per Function的主要功能是对冗余函数的优化。通过这个选项,可以在最后生成的二进制文件中将冗余函数排除掉(虽然其所在的文件已经参与了编译链接),以便最大程度地优化最后生成的二进制代码。

而该选项实现的机制是将每一个函数作为一个优化的单元,而并非整个文件作为参与优化的单元。

选项One ELF Section per Function所具有的这种优化功能特别重要,尤其是在对于生成的二进制文件大小有严格要求的场合。人们习惯将一系列接口函数放在一个文件里,然后将其整个包含在工程中,即使这个文件将只有一个函数被用到。这样,最后生成的二进制文件中就有可能包含众多的冗余函数,造成了宝贵存储空间的浪费。

选项One ELF Section per Function对于一个大工程的优化效果尤其突出,有时候甚至可以达到减半的效果。当然,对于小工程或是少有冗余函数的工程来说,其优化效果就没有那么明显了。

以上三种方法是解决系统启动卡在SystemInit的方法,有不对的地方欢迎指出,鄙人马上修正。

也许你遇不到,也许你能遇到,反正它就在那里。

就像我们做了一道算术题,很多人会想,怎么老遇到着急不会的题呢?有没有搞错啊。。。。。。

但是就有那么少些人会说:我真幸运,又遇到了一到自己不会的算术题。

态度决定高度,细节决定成败!!!


 

这篇关于关于keil卡在systeminit中,然后出现void HardFault_Handler(void)的几个问题详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1123475

相关文章

MySQL数据库双机热备的配置方法详解

《MySQL数据库双机热备的配置方法详解》在企业级应用中,数据库的高可用性和数据的安全性是至关重要的,MySQL作为最流行的开源关系型数据库管理系统之一,提供了多种方式来实现高可用性,其中双机热备(M... 目录1. 环境准备1.1 安装mysql1.2 配置MySQL1.2.1 主服务器配置1.2.2 从

Linux kill正在执行的后台任务 kill进程组使用详解

《Linuxkill正在执行的后台任务kill进程组使用详解》文章介绍了两个脚本的功能和区别,以及执行这些脚本时遇到的进程管理问题,通过查看进程树、使用`kill`命令和`lsof`命令,分析了子... 目录零. 用到的命令一. 待执行的脚本二. 执行含子进程的脚本,并kill2.1 进程查看2.2 遇到的

MyBatis常用XML语法详解

《MyBatis常用XML语法详解》文章介绍了MyBatis常用XML语法,包括结果映射、查询语句、插入语句、更新语句、删除语句、动态SQL标签以及ehcache.xml文件的使用,感兴趣的朋友跟随小... 目录1、定义结果映射2、查询语句3、插入语句4、更新语句5、删除语句6、动态 SQL 标签7、ehc

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置

从基础到高级详解Go语言中错误处理的实践指南

《从基础到高级详解Go语言中错误处理的实践指南》Go语言采用了一种独特而明确的错误处理哲学,与其他主流编程语言形成鲜明对比,本文将为大家详细介绍Go语言中错误处理详细方法,希望对大家有所帮助... 目录1 Go 错误处理哲学与核心机制1.1 错误接口设计1.2 错误与异常的区别2 错误创建与检查2.1 基础

k8s按需创建PV和使用PVC详解

《k8s按需创建PV和使用PVC详解》Kubernetes中,PV和PVC用于管理持久存储,StorageClass实现动态PV分配,PVC声明存储需求并绑定PV,通过kubectl验证状态,注意回收... 目录1.按需创建 PV(使用 StorageClass)创建 StorageClass2.创建 PV

Python版本信息获取方法详解与实战

《Python版本信息获取方法详解与实战》在Python开发中,获取Python版本号是调试、兼容性检查和版本控制的重要基础操作,本文详细介绍了如何使用sys和platform模块获取Python的主... 目录1. python版本号获取基础2. 使用sys模块获取版本信息2.1 sys模块概述2.1.1

一文详解Python如何开发游戏

《一文详解Python如何开发游戏》Python是一种非常流行的编程语言,也可以用来开发游戏模组,:本文主要介绍Python如何开发游戏的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录一、python简介二、Python 开发 2D 游戏的优劣势优势缺点三、Python 开发 3D

IDEA和GIT关于文件中LF和CRLF问题及解决

《IDEA和GIT关于文件中LF和CRLF问题及解决》文章总结:因IDEA默认使用CRLF换行符导致Shell脚本在Linux运行报错,需在编辑器和Git中统一为LF,通过调整Git的core.aut... 目录问题描述问题思考解决过程总结问题描述项目软件安装shell脚本上git仓库管理,但拉取后,上l

Redis 基本数据类型和使用详解

《Redis基本数据类型和使用详解》String是Redis最基本的数据类型,一个键对应一个值,它的功能十分强大,可以存储字符串、整数、浮点数等多种数据格式,本文给大家介绍Redis基本数据类型和... 目录一、Redis 入门介绍二、Redis 的五大基本数据类型2.1 String 类型2.2 Hash