我有一个项目,其中ATtiny2313V正在控制7x5 LED矩阵以显示滚动文本。为了显示文本,我构建了一个字体,该字体与程序的其余部分一起存储在闪存中。
整个程序,包括整个字体,占用1106个字节。但是当我把它加载到芯片中时,它似乎没有运行;相反,它只是点亮了几个LED,就是这样。
但是,当我删除大部分字体,并仅使用字母A到J进行编译时,程序的大小为878字节,并且运行正常。
这是因为AVR闪存的某种溢出吗?
ATtiny2313V的数据表说它有2KB的闪存! 1106字节怎么能太多?
更新:为了清楚起见,我正在使用的工具链是AVR Studio(编译代码),然后AVRDude将其上传到微控制器。据我所知,AVR Studio使用avr-gcc版本来编译代码。
答案 0 :(得分:6)
我不确定您使用的是什么工具链,但在avr-gcc中,您需要使用<avr/pgmspace.h>
标题来存储&amp;在flash中访问数据 - 仅仅声明数据const
是不够的,因为它仍然在运行时加载到内存中,因此占用flash和ram中的空间(就像任何其他初始化变量一样)。
查看User Manual和Header 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)
检查你的堆栈是否溢出?这可能会产生难以察觉的崩溃。您可以在编译器/链接器设置中的某处设置堆栈大小,也可以将一些局部变量转换为全局变量。嵌入式处理器通常没有任何堆栈溢出检查,只是崩溃。