我用一个太大的程序溢出AVR的闪存吗?

时间:2009-10-19 09:49:18

标签: avr flash-memory

我有一个项目,其中ATtiny2313V正在控制7x5 LED矩阵以显示滚动文本。为了显示文本,我构建了一个字体,该字体与程序的其余部分一起存储在闪存中。

整个程序,包括整个字体,占用1106个字节。但是当我把它加载到芯片中时,它似乎没有运行;相反,它只是点亮了几个LED,就是这样。

但是,当我删除大部分字体,并仅使用字母A到J进行编译时,程序的大小为878字节,并且运行正常。

这是因为AVR闪存的某种溢出吗?

ATtiny2313V的数据表说它有2KB的闪存! 1106字节怎么能太多?

更新:为了清楚起见,我正在使用的工具链是AVR Studio(编译代码),然后AVRDude将其上传到微控制器。据我所知,AVR Studio使用avr-gcc版本来编译代码。

3 个答案:

答案 0 :(得分:6)

我不确定您使用的是什么工具链,但在avr-gcc中,您需要使用<avr/pgmspace.h>标题来存储&amp;在flash中访问数据 - 仅仅声明数据const是不够的,因为它仍然在运行时加载到内存中,因此占用flash和ram中的空间(就像任何其他初始化变量一样)。

查看User ManualHeader Docs了解详情。使用非常简单,要在flash中声明一个char数组,请使用PROGMEM宏:

char data[] PROGMEM = {0xc4, 0x77}; // etc

然后,为了访问数据,您需要使用提供的宏

char d = pgm_read_byte(&(data[i]));

编辑:还要记住,avrdude只报告全局和静态变量等的ram(.data和.bss)的静态分配部分。你需要为堆栈留出空间 - 多少取决于你的程序(提示:递归很糟糕。)

答案 1 :(得分:2)

我发誓这里有一些神奇的东西;我已经绞尽脑汁几周了,试图解决这个问题,在这里提出问题之后 - 我终于可以看到一直盯着我看的是什么!

以下是仅使用字体中的A-J字母进行编译的内存使用情况:

AVR Memory Usage
----------------
Device: attiny2313

Program:     872 bytes (42.6% Full)
(.text + .data + .bootloader)

Data:         82 bytes (64.1% Full)
(.data + .bss + .noinit)

又来了,字母是A-Z:

AVR Memory Usage
----------------
Device: attiny2313

Program:     952 bytes (46.5% Full)
(.text + .data + .bootloader)

Data:        162 bytes (126.6% Full)
(.data + .bss + .noinit)

请参阅数据中的126.6%?哎呀!我真的溢出了!

答案 2 :(得分:1)

检查你的堆栈是否溢出?这可能会产生难以察觉的崩溃。您可以在编译器/链接器设置中的某处设置堆栈大小,也可以将一些局部变量转换为全局变量。嵌入式处理器通常没有任何堆栈溢出检查,只是崩溃。