PIC18堆栈/内存管理的最佳实践?

Nat*_*ate 6 c memory stack

预算PIC的有限堆栈大小是一个问题区域,我已调整我的代码以适应这一现实.我目前采用粗略的范例,将密切相关的函数分组到一个模块中,并在模块中声明所有变量全局静态(以减少存储在auto psect中的变量数量,并且可变性问题仅与ISR相关,我考虑.)我不这样做是因为这是一种很好的做法,但实际情况是你有足够的空间来分配整个项目中存在的所有本地函数变量.在8/16位芯片的嵌入式世界中,这是一种合适的方法,只要我确保采取必要的预防措施吗?我也为以太网分配> 256字节的RAM(我知道它应该是1500作为标准MTU,但我们有一个自定义的情况和非常有限的RAM缓冲区,并且必须通过指针访问该内存,所以我可以避免内存银行的语义.我做错了吗?我的应用程序有效,但我100%愿意接受改进建议.[C]

Fel*_*lix 4

我知道这个问题已经在 4 年前被问到了,但至今还没有得到正确的回答。我相信 OP 所要求的是他们解决 HiTech PICC18 C 编译器有效和/或最佳实践限制的方法。正如后来的评论中提到的,限制(一个相当糟糕的限制,并且 Hitech 没有很好地宣传)是“Hi-Tech 编译器最多只允许 256 字节的自动变量”。实际上这个限制比这个更严重,因为局部变量和参数总共有 256 个字节。超过此值时的链接器警告也非常神秘。如果函数位于调用树的不同分支上,则编译器可以重叠变量以重用空间。这意味着您实际上可以拥有超过 256 个字节。但请注意,中断处理程序(或处理程序,如果您使用优先级方案)有自己的调用树,共享 256 字节本地/参数块。

局部变量 减少局部变量所需空间的两种解决方案是:使局部变量全局化或使其静态。使它们成为静态可以保持作用域相同,并且如果函数不从中断调用是安全的(编译器无论如何都不允许租用)。这可能是首选。缺点是编译器无法重用这些变量的位置来减少总体内存消耗。将变量移至全局范围允许重用,但重用管理必须由程序员管理。也许最好的平衡是使简单变量静态,但使大块内存(如字符串缓冲区)全局化并小心重用它们。

初始化时要小心。

foo()
{
 int myvar = 5;
}
Run Code Online (Sandbox Code Playgroud)

必须改为

foo()
{
 static int myvar;
 myvar = 5;
}
Run Code Online (Sandbox Code Playgroud)

参数 如果您在参数中沿着调用树传递大量数据,您很快就会遇到同样的 256 字节限制。这里最好的选择可能是将指针传递给全局分配的“选项”结构。或者,您可以拥有由顶级调用者设置并由树下的被调用者读取的全局设置变量。这实际上取决于软件的设计,哪种方法更好。

我一直在努力解决与OP相同的问题,我认为从长远来看最好的选择是放弃使用Hitech编译器。编译器编写者在一个块中分配所有局部变量/参数的优化决策仅真正适合非常小的 RAM 大小的 PICS。对于大型图片,您将在达到设备的内存大小之前就用完本地/参数。然后你必须开始修改你的代码以适应编译器,这是不正当的。

总之......是的,你的方法是有效的。但如果合适的话,请考虑简单地将局部变量设为静态,因为一般来说,减小范围会使代码更安全。