OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 13518|回复: 5

mdk 4.22下,照着不完全手册建立工程时遇到的 SystemInit 的小问题及解决方案

[复制链接]

36

主题

1105

帖子

5

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2196
金钱
2196
注册时间
2012-2-8
在线时间
35 小时
发表于 2012-3-8 15:37:26 | 显示全部楼层 |阅读模式
这个问题在入门STM32的时候也遇到过,刚开始也不知怎么回事,照着手册上的建立工程做好了之后,
编译,还是会提示有个错误
Test.axf: Error: L6218E: Undefined symbol SystemInit (referred from startup_stm32f10x_md.o).

当时用关键字 SystemInit 搜了整篇文档,还是没找到
现在我也搞不清楚是什么原因,估计是MDK 4 下的启动文件和以前版本的不同,带来的问题,
所以说,软件不是越新就越好的,特别是对于初学者来说,有些问题还是没能力解决的。

解决方案一(个人推荐):
幸好了解过一点汇编,所以第一次遇到这个问题的时候,我就打开启动文件把相关的代码直接给注释了注释了也就完事了,直接和原代码兼容。见下图:


方案二:
我和想我和大部分人一样,都不喜欢看汇编代码,
所以,我就找到另一种方案,可以在任意一个.c 文件里做一个 SystemInit 函数,
(当然,考虑到模块化之类的,最好放在一个有意义的.c文件里)
然后把你的系统初始化函数如Stm32_Clock_Init等等都塞进去


但是我仿真的时候发现一个问题,那个delay_init函数不能塞到 SystemInit 函数里,
要不然仿真的时候那句 delay_ms(500) 会执行很久,多久我也不知道,原因不明, (原因见5楼)

看启动代码,不就是调用了SystemInit后就调用main了吗?有什么区别呢?希望有经验的人能帮我解答下。
这个问题也是我不推荐使用这个方案的原因。

附件里是工程文件。。。其实这么简单好像也没必要上传。。。

另外,刚刚我去对比了下例程代码里的启动文件和我的工程里面的启动文件的前面的说明:
这个是例程代码里面的软件生成的启动文件:
注意到没有版本信息。
 ;/*****************************************************************************/
;/* STM32F10x.s: Startup file for ST STM32F10x device series                  */
;/*****************************************************************************/
;/* <<< Use Configuration Wizard in Context Menu >>>                          */
;/*****************************************************************************/
;/* This file is part of the uVision/ARM development tools.                   */
;/* Copyright (c) 2005-2007 Keil Software. All rights reserved.               */
;/* This software may only be used under the terms of a valid, current,       */
;/* end user licence from KEIL for a compatible version of KEIL software      */
;/* development tools. Nothing else gives you the right to use this software. */
;/*****************************************************************************/

这个是我的工程下软件自动生成的启动文件的说明:(V3.4.0)
;******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
;* File Name          : startup_stm32f10x_md.s
;* Author             : MCD Application Team
;* Version            : V3.4.0
;* Date               : 10/15/2010
;* Description        : STM32F10x Medium Density Devices vector table for MDK-ARM
;*                      toolchain. 
;*                      This module performs:
;*                      - Set the initial SP
;*                      - Set the initial PC == Reset_Handler
;*                      - Set the vector table entries with the exceptions ISR address
;*                      - Configure the clock system
;*                      - Branches to __main in the C library (which eventually
;*                        calls main()).
;*                      After Reset the CortexM3 processor is in Thread mode,
;*                      priority is Privileged, and the Stack is set to Main.
;* <<< Use Configuration Wizard in Context Menu >>>  
;*******************************************************************************
; THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
; WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
; AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
; INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
; CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
; INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
;*******************************************************************************

STM32-ALIENTEK.zip

45.17 KB, 下载次数: 917

https://github.com/roxma
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2012-3-8 15:39:44 | 显示全部楼层
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

36

主题

1105

帖子

5

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2196
金钱
2196
注册时间
2012-2-8
在线时间
35 小时
 楼主| 发表于 2012-3-8 15:42:55 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------

哈哈,原来这个问题已经有人遇到过了啊,

不过我上面还个有问题:


但是我仿真的时候发现一个问题,那个delay_init函数不能塞到 SystemInit 函数里,
要不然仿真的时候那句 delay_ms(500) 会执行很久,多久我也不知道,原因不明,
看启动代码,不就是调用了SystemInit后就调用main了吗?有什么区别呢?希望有经验的人能帮我解答下。


麻烦帮我看一下
https://github.com/roxma
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2012-3-8 15:49:33 | 显示全部楼层
回复【3楼】Pony279:
---------------------------------
这是ST公司自认为用户需要在main初始化之前就执行一些系统初始化.实际我觉得并不是那么有用.
这个你可以不理会即可.
至于延时500ms,这个软件仿真都有这个通病,延时时间大大长于实际时间.
所以软件仿真的时候,最好不要什么延时.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

36

主题

1105

帖子

5

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2196
金钱
2196
注册时间
2012-2-8
在线时间
35 小时
 楼主| 发表于 2012-3-8 15:52:50 | 显示全部楼层
回复【4楼】正点原子:
---------------------------------
哦,原来是这样,谢谢!
软件仿真延时比较长还是可以接受的,毕竟上了ARM让电脑去实时仿真基本上是不可能的了。
不过延时功能不能实现就无法接受了,看来还是直接修改启动代码的解决方案比较好一点。
https://github.com/roxma
回复 支持 反对

使用道具 举报

36

主题

1105

帖子

5

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2196
金钱
2196
注册时间
2012-2-8
在线时间
35 小时
 楼主| 发表于 2012-6-24 14:49:49 | 显示全部楼层
"但是我仿真的时候发现一个问题,那个delay_init函数不能塞到 SystemInit 函数里, 
要不然仿真的时候那句 delay_ms(500) 会执行很久,多久我也不知道,原因不明, 
看启动代码,不就是调用了SystemInit后就调用main了吗?有什么区别呢?希望有经验的人能帮我解答下。 "

没事干突然想起以前的这个问题,现在想明白了。我还想起了在发现这个问题之前,我曾经为一个ARM9的MCU移植到一个新的开发环境熬了好几个凌晨三点,结果却很不理想,部分原因就是不知道这些基础的东西才造成的。

所有的全局变量都是在 __main(注意不是我们自己写的main函数) 中初始化的,在 __main 函数中会进行 C 语言标准库的初始化和其它一些初始化,但是具体做什么我也不清楚,只知道 __main 函数是为我们使用的 C 语言环境进行初始化的,具体可以参考 mdk 的说明文档。

而3.5版配的启动代码的开头是这样的,
     IMPORT  __main
     IMPORT  SystemInit
                 LDR     R0, =SystemInit
                 BLX     R0
                 LDR     R0, =__main
                 BX      R0
                 ENDP
也就是说,系统复位后,首先调用 SystemInit 函数,然后再调用 __main 函数(在__main函数执行完后会调用 我们自己写的 main函数),再注意到 delay_init 函数,的定义
//初始化延迟函数
void delay_init(u8 SYSCLK)
{
SysTick->CTRL&=0xfffffffb;//选择内部时钟 HCLK/8
fac_us=SYSCLK/8;    
fac_ms=(u16)fac_us*1000;
}
发现了 fac_us 和 fac_ms 两个全局变量。
现在假设我只在 SystemInit 函数里调用 delay_init 函数初始化了这两个全局变量,那么,在 SystemInit 函数执行完成后,程序跳到了 __main 里去了,在 __main 里又进行一次全局变量初始化,结果就是,SystemInit 中初始化的 fac_us 和 fac_ms 两个全局变量又被重写了,最后的结果就可想而知了。

童鞋们可以按我引用的那段文字进行软件仿真测试,看看那两个全局变量的值就会明白了。

最后总结出来的原则就是,如果要用官方带的启动代码调用 SystemInit 函数的话,(1)要么把官方库中的 system_stm32f10x.c 放到工程目录下什么也别改;(2)要么自己写一个 SystemInit 函数,但是,不可以进行任何软件层的初始化,也就是说,不可以初始化任何全局变量以及静态变量!!!

https://github.com/roxma
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-26 08:29

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表