打印
[STM32F1]

STM32 子程序内存分配问题

[复制链接]
4926|23
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
magic_yuan|  楼主 | 2014-4-22 16:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
各位大侠,
   看一个TFT驱动程序时遇到这样的问题。
   const unsigned char asc2_1206[95][12]----在头文件内定义了这样的一个数组。数组较大。
   这个数组在调用子程序时会用到。
    问题:这么大的一个数组会一直占用STM32的内存吗?还是用完了就释放?
               如果是用完了就释放,那调用时再载入就会消耗多余的时间?
               多谢啊!
沙发
huzi2099| | 2014-4-22 16:13 | 只看该作者
const数据类型不在内存里.
另外数组定义是不能在头文件里的,编译会出错.

使用特权

评论回复
板凳
magic_yuan|  楼主 | 2014-4-22 16:23 | 只看该作者
huzi2099 发表于 2014-4-22 16:13
const数据类型不在内存里.
另外数组定义是不能在头文件里的,编译会出错.

多谢大侠,
  CONST类型不在内存里,直接方式STM32的FLASH,和程序代码放在一起?
  我看得代码是网上流行的---原子写的,实际运行也没问题。。。。是讲这个数组在头文件里定义,然后存放字符显示的内容,用于TFT的显示调用。

使用特权

评论回复
地板
huzi2099| | 2014-4-22 17:05 | 只看该作者
头文件不能产生任何形式的存储占用,只能extern

使用特权

评论回复
5
magic_yuan|  楼主 | 2014-4-22 17:52 | 只看该作者
huzi2099 发表于 2014-4-22 17:05
头文件不能产生任何形式的存储占用,只能extern

多谢大侠啊,
只能EXTERN?这个意思是?

使用特权

评论回复
6
guet_new_man| | 2014-4-22 21:42 | 只看该作者
huzi2099 发表于 2014-4-22 17:05
头文件不能产生任何形式的存储占用,只能extern

头文件为什么不能产生存储占用? 在头文件中定义宏、接口函数等,不都占用了flash空间么?

使用特权

评论回复
7
magic_yuan|  楼主 | 2014-4-23 00:01 | 只看该作者
自己顶一下。

使用特权

评论回复
8
科技猎人| | 2014-4-23 09:04 | 只看该作者
guet_new_man 发表于 2014-4-22 21:42
头文件为什么不能产生存储占用? 在头文件中定义宏、接口函数等,不都占用了flash空间么? ...

不是不能,是最好不要这样做。不在头文件里定义变量不是C语言的语法规范,而是一种C程序员的编程规范。你要分清定义和声明的区别,声明时并不会分配内存空间。。。

使用特权

评论回复
9
huzi2099| | 2014-4-23 10:10 | 只看该作者
guet_new_man 发表于 2014-4-22 21:42
头文件为什么不能产生存储占用? 在头文件中定义宏、接口函数等,不都占用了flash空间么? ...

宏不占用存储,宏只在文本替换后才起作用,这个过程最终还是要在.C中完成的,没有替换就没有用.
接口函数是在link后才实际占用flash的,头文件里不能写实际的函数代码.

使用特权

评论回复
10
huzi2099| | 2014-4-23 10:11 | 只看该作者
科技猎人 发表于 2014-4-23 09:04
不是不能,是最好不要这样做。不在头文件里定义变量不是C语言的语法规范,而是一种C程序员的编程规范。你 ...

是不能,肯定报错

使用特权

评论回复
11
科技猎人| | 2014-4-23 10:46 | 只看该作者
huzi2099 发表于 2014-4-23 10:11
是不能,肯定报错

一般来说是肯定报错,重定义了呗。但是只有一个.c文件包含此头文件时也就没有重定义了,而且包含.c文件也是可以的。#include也只是个宏,把包含文件原地展开而已,在头文件里定义变量也好编写函数也好本身是不违背语法的,你可以看看国际C语言混乱代码大赛的作品,各种混乱但都能编译通过。但一个有条理的结构清晰的程序肯定不会这么去写,真正的工程师写代码追求的是简单明了、可靠高效、规范严谨,所以头文件里不要定义变量,这是一个合格工程师的基本要素。。。

使用特权

评论回复
12
guet_new_man| | 2014-4-23 14:55 | 只看该作者
huzi2099 发表于 2014-4-23 10:10
宏不占用存储,宏只在文本替换后才起作用,这个过程最终还是要在.C中完成的,没有替换就没有用.
接口函数是 ...

是否报错,具体要看编译器吧。

平时用IAR或者KEIL,虽然自己没在头文件中写过函数体,但像ARM提供的CMSIS的库中,就有直接在头文件中定义函数的情况,具体可以看一下core_cm3.h或core_cm4.h。

另外,我曾经遇到过一个特殊的掌机,用C开发应用程序时, 只能有一个文件是.c文件(原因在于,对应编译链接和打包的脚本文件中只能声明一个.c文件),其他文件都是.h,而且大部分变量和接口函数本体都是在.h中实现的,这样做是OK的。当然, 如果把那些.h文件全都改成.c文件,应该也行吧,只是#include包含的就是.c文件了。

说了这么多,只是想说明.h与.c文件,对于C语言本身来说,我个人觉得是没什么区别的。但是,就像“科技猎人”说的: 不在头文件里定义变量不是C语言的语法规范,而是一种C程序员的编程规范。

使用特权

评论回复
13
guet_new_man| | 2014-4-23 14:56 | 只看该作者
科技猎人 发表于 2014-4-23 09:04
不是不能,是最好不要这样做。不在头文件里定义变量不是C语言的语法规范,而是一种C程序员的编程规范。你 ...

了解!

使用特权

评论回复
14
guet_new_man| | 2014-4-23 15:00 | 只看该作者
科技猎人 发表于 2014-4-23 10:46
一般来说是肯定报错,重定义了呗。但是只有一个.c文件包含此头文件时也就没有重定义了,而且包含.c文件也 ...

除了第一句不敢苟同,其他讲的都很好,呵呵~

使用特权

评论回复
15
科技猎人| | 2014-4-23 16:31 | 只看该作者
guet_new_man 发表于 2014-4-23 15:00
除了第一句不敢苟同,其他讲的都很好,呵呵~

所以说是“一般来讲”。对于新手们只写一个.c文件的,或者有哪些特殊编译器的等等情况,也就不会报错。呵呵。。。

使用特权

评论回复
16
huzi2099| | 2014-4-23 17:52 | 只看该作者
本帖最后由 huzi2099 于 2014-4-23 17:57 编辑

一试便知的事情啊,各种宏和extern,typedef,struct..都不是实体.

使用特权

评论回复
17
huzi2099| | 2014-4-23 17:55 | 只看该作者
guet_new_man 发表于 2014-4-23 14:55
是否报错,具体要看编译器吧。

平时用IAR或者KEIL,虽然自己没在头文件中写过函数体,但像ARM提供的CMSI ...

#include "????.c"
和复制粘贴等同的效果

使用特权

评论回复
18
huzi2099| | 2014-4-23 18:23 | 只看该作者
guet_new_man 发表于 2014-4-23 14:55
是否报错,具体要看编译器吧。

平时用IAR或者KEIL,虽然自己没在头文件中写过函数体,但像ARM提供的CMSI ...

.c和.h的区别是编译还是扩展定义的区别,这也就是为什么.h不包含存储占用(代码或ram)的原因了.

使用特权

评论回复
19
guet_new_man| | 2014-4-23 20:50 | 只看该作者
huzi2099 发表于 2014-4-23 18:23
.c和.h的区别是编译还是扩展定义的区别,这也就是为什么.h不包含存储占用(代码或ram)的原因了. ...

仔细想了一下这个问题,总结如下,你想表达的想必也是这关观点吧 :
C编译器识别的目标文件是.c文件,而.c中又调用了.h,编译的时候,.h的东西一样会被转义到中间文件以及最终的可执行文件中。虽然.h不是面向编译器的目标文件,但它是目标文件的一部分(因为被.c文件引用了),那么它内部的一些东西同样会占用ROM或者RAM(在.h中定义函数体或变量时)。当.h中定义了函数体或者变量时,仅仅被一个.c文件调用时,编译链接都不会报错;但是,如果被多个.c文件调用,那么经过编译后产生的多个中间文件都包含了该.h中定义的函数体和变量,当链接工具进行连接时,这种情况下一般就会报错,因为链接工具认为重复定义了。

另外,再补充一点,有一类特殊的函数 - inline函数,可能平时很少用,当定义在头文件中时,最好定义成静态,这样在被多个.c文件调用时,也不会出问题。

使用特权

评论回复
20
huzi2099| | 2014-4-23 21:59 | 只看该作者
我想编译的第一步是把各种include文件中的内容按顺序和成一个文件,然后掉用编译器来解释,这个时候预编译已经处理完了,目标.c变成一个大文本,所以.h中是可以做定义的.
是我理解有偏差,刚试了一下是可以的

#include "REG52.h"                        //\Keil\C51\INC
#include "aaa.h"
int main(void) {
        aaa++;
        while(1) {
        }
}
//aaa.h
unsigned char aaa=0;

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:发到3000帖时,生活大概完成了一种转折。

359

主题

2770

帖子

7

粉丝