避免在内存中创建多个代码副本

Avoid creating multiple copies of code in memory

本文关键字:代码 副本 创建 内存      更新时间:2023-10-16

我是嵌入式系统开发的新手,不习惯只有很少的程序内存(在这种情况下为16kB)可以使用。我希望能够创建全局变量,数组和函数,我可以从程序中的任何地方访问,而只存在于内存中的一个地方。我目前的方法是使用静态类成员和方法,我可以通过简单地包括头文件(例如#include "spi.h")来使用。

对于我正在尝试做的事情,什么是最好的方法?

下面是一个示例类。据我所知,变量如_callback和函数定义如。cpp中的call()只会出现在spi中。所以它们在记忆中只会出现一次,但我可能会混淆。

spi.h:

#ifndef SPI_H_
#define SPI_H_
#include "msp430g2553.h"
class SPI {
public:
    typedef void (*voidCallback)(void);
    static voidCallback _callback;
    static char largeArray[1000];
    static __interrupt void USCIA0TX_ISR();
    static void call();
    static void configure();
    static void transmitByte(unsigned char byte, voidCallback callback);
};
#endif /* SPI_H_ */

spi.cpp:

#include "spi.h"
SPI::voidCallback SPI::_callback = 0;
char SPI::largeArray[] = /* data */ ;
void SPI::configure() {
    UCA0MCTL = 0;
    UCA0CTL1 &= ~UCSWRST;                   
    IE2 |= UCA0TXIE;
}
void SPI::transmitByte(unsigned char byte, voidCallback callback) {
    _callback = callback;
    UCA0TXBUF = byte;
}
void SPI::call() {
    SPI::_callback();
}
#pragma vector=USCIAB0TX_VECTOR
__interrupt void SPI::USCIA0TX_ISR()
{
    volatile unsigned int i;
    while (UCA0STAT & UCBUSY);
    SPI::call();
}

您编写的类的数据成员和成员函数将只在内存中定义一次。如果没有被标记为static,则成员函数将仍然只在内存中定义一次。对于您创建的每个对象,将在内存中创建一次非静态数据成员,因此,如果您只创建一个SPI对象,则只获得其非静态数据成员的一个副本。简而言之:你在解决一个无关紧要的问题。

根据Pete的说法,静态不会影响代码翻倍,只会影响成员变量。在您的示例中,除了_callback变量(您将其作为错误调用)之外,静态和非静态内存使用之间没有任何区别。并且只有当类被创建了不止一次时,这个变量才会加倍。

如果您希望代码在不使用时不存在于内存中,请查看覆盖或某种动态链接过程。对于16K来说,DLL类型的代码可能会过多,但是使用压缩代码的覆盖可能会对您有所帮助。

还要注意库中的额外链接代码。仔细检查您的.map文件,看看是否因为无害的函数调用而导致代码膨胀。例如,一个单独的printf()调用将链接所有类型的变量,如果它是唯一使用它的东西。对于软件浮点数也是如此(如果默认情况下没有FP单元)