【问题标题】:Delete Global Variable in C删除 C 中的全局变量
【发布时间】:2020-08-13 10:15:06
【问题描述】:

我正在我的 Cortex M3 芯片中开展一个更大的项目,但我的 RAM 不足。我提出的想法是,我需要通过删除引导加载程序代码上的全局变量来在我的 RAM 中腾出空间,以便在引导加载程序跳转到应用程序代码后清除该区域中的 RAM。我无法直接访问芯片中的引导加载程序代码,因此我必须在应用程序代码中更改这些全局变量。 如何使用 custom_delete() 函数或任何代码删除此全局变量。我使用 ARM cortex M3 (LPC1769)。

总而言之,基本上我正在运行的是:


Custom_Delete ( ? ){

??

}

int foo[1000];

int main(){

/*
 Bootloader Code
*/

Custom_Delete ( foo ) // I'm trying to remove the "foo" variable once the bootloader code is executed and the application code is run.

SCB->VTOR = (APP_START_ADDRESS) & 0x1FFFFF80  // jump to application code

}

【问题讨论】:

  • 你之前已经在这里问过这个问题:stackoverflow.com/questions/63390349/…,它似乎被删除了。
  • 你应该做的第一件事是摆脱幼稚的int 和类似的东西。用 stdint.h 中的相关固定大小变量替换它们。
  • 您可以编写自己的malloc 包,允许您将空闲内存块添加到竞技场(如free,但之前的块不必是mallocd)。完成foo 后,将其添加到malloc 竞技场。
  • 这可能对你有帮助:stackoverflow.com/questions/8832114/…

标签: c memory arm global-variables ram


【解决方案1】:

无法删除具有静态生命周期的变量。

您可以尝试重复使用该区域。

  union {
    struct { // bootcode data
      int foo[100];
    };
    struct { // application data
      int var1;
      long var2;
    };
  } data;

成员的名称在引导代码和应用程​​序之间应该是唯一的。然后,您可以使用未命名的成员并访问字段而无需额外的嵌套级别。 引导代码和应用程​​序都使用的数据必须放在该联合之外。 这种方法的缺点是您无法初始化联合中的应用程序的数据。只能初始化并集的第一个字段(即引导代码部分)。

注意:

这适用于您在同一个可执行文件中拥有引导代码和应用程​​序的情况。

如果两者都是独立创建的,那么您可以使用定制的链接描述文件将数据放置在同一位置。一旦您将控制权传递给应用程序,引导代码的内存布局就不再相关。如果在启动应用程序时运行应用程序的启动代码,这也允许初始化应用程序数据。如果您将应用程序构建为独立的二进制文件,这通常是正确的。

【讨论】:

  • 我想补充一点,在这两种方法中,确保在从引导加载程序切换到应用程序时运行应用程序变量的初始化程序代码非常重要。
  • 你是对的。跳转到固定地址似乎暗示应用程序是作为完整应用程序独立构建的。那么应该问题不大。在第一种方法中,不可能初始化联合的第二个字段。这必须手动完成
【解决方案2】:

您可以强制链接器将全局变量放入自定义部分:

__attribute__ ((__section__(".init.text"))) int my_global[128];

然后您必须编辑您的链接描述文件,以便以后可以重复使用此部分。

Linux 也这样做: What does __init mean in the Linux kernel code?

【讨论】:

    【解决方案3】:

    数组不能删除,由于是全局数组,所以是静态的,会一直存在到程序终止。

    我能看到的唯一解决方案是这样的:

    //int foo[1000];
    int *foo;
    
    int main(){
        foo = malloc(sizeof *foo * 1000);
    
    /*
     Bootloader Code
    */
    
        free(foo);
    
        SCB->VTOR = (APP_START_ADDRESS) & 0x1FFFFF80  // jump to application code
    }
    

    您可以将malloc 更改为alloca 并跳过free。但是您需要在引导加载程序代码中移动alloca 调用。 malloc 在堆上分配,alloca 在栈上分配。

    另一种选择是简单地重写代码,这样数组就不是全局的,而是在main()调用的函数中声明的。

    【讨论】:

    • 虽然这可行,但 LPC1769 只有 64 kB 的 RAM。我建议完全禁用堆,并改用 Gerhardh 答案中的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-29
    • 2015-11-24
    • 2011-12-27
    • 2014-05-04
    • 1970-01-01
    • 2015-06-12
    • 1970-01-01
    相关资源
    最近更新 更多