代码之家  ›  专栏  ›  技术社区  ›  Shalom Craimer

我是不是用一个太大的程序溢出了我的AVR闪存?

  •  3
  • Shalom Craimer  · 技术社区  · 16 年前

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

    整个程序,包括整个字体,占用1106字节。但当我把它装进芯片时,它似乎不工作;相反,它只是点亮了几个LED,就这样了。

    但是,当我删除大多数字体,只使用字母a到j进行编译时,程序的大小是878字节,运行得很好。

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

    阁楼2313V的数据表显示它有2字节的闪存!1106字节怎么可能太多?

    更新 :只是要明确一点,我使用的工具链是AVR Studio(编译代码),然后AVRDUDE将其上载到微控制器。据我所知,avr studio使用avr gcc的一个版本来编译代码。

    3 回复  |  直到 16 年前
        1
  •  6
  •   Peter Gibson    16 年前

    我不确定您使用的是什么工具链,但是在AVR GCC中,您需要使用 <avr/pgmspace.h> 在闪存中存储和访问数据的头文件-仅声明数据是不够的 const 因为它在运行时仍被加载到内存中,因此会占用闪存和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),用于全局变量和静态变量等。您需要为堆栈留出空间-具体取决于您的程序(提示:递归不好)。

        2
  •  2
  •   Shalom Craimer    16 年前

    我发誓这有点不可思议;我已经绞尽脑汁好几个星期了,想弄明白这一点,在问了这个问题之后——我终于可以看到我脸上的表情了!

    以下是仅使用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% 在数据中?哎呀!我真的溢出了!

        3
  •  1
  •   Zebra North    16 年前

    检查你的堆栈是否溢出?这会导致难以检测的崩溃。您可以在编译器/链接器设置中的某处设置堆栈大小,也可以将一些局部变量转换为全局变量。嵌入式处理器通常不检查堆栈溢出,它只是崩溃。

    推荐文章