简体   繁体   English

自动分配到 GCC/C 中的特定 RAM 区域

[英]Auto-Allocate to a specific RAM Area in GCC/C

Sorry for my english, its a bit hard for me to explain what exactly i would need.对不起我的英语,我很难解释我到底需要什么。 I'm making some extra code into existing binarys using the GCC compiler.我正在使用 GCC 编译器在现有的二进制文件中添加一些额外的代码。 In this case, its PowerPC, but it should not really matter.在这种情况下,它的 PowerPC,但它应该不重要。

I know, where in the existing binary i have free ram available (i dumped the full RAM to make sure) but i need to define each RAM address manually, currently i am doing it like this:我知道,在现有二进制文件中我有可用的可用内存(我转储了完整的内存以确保)但我需要手动定义每个内存地址,目前我这样做是这样的:

// #ram.h

//8bit ram
uint8_t*        xx1     = (uint8_t*)    0x807F00;
uint8_t*        xx2     = (uint8_t*)    0x807F01;
//...and so on

// 16bit ram
uint16_t*       xxx1    = (uint16_t*)   0x807F40;
uint16_t*       xxx2    = (uint16_t*)   0x807F42;
//...and so on
    
// 32bit ram
uint32_t*       xxxx1   = (uint32_t*)   0x807FA0;
uint32_t*       xxxx2   = (uint32_t*)   0x807FA4;
//...and so on

And im accessing my variables like this:我像这样访问我的变量:

void  __attribute__ ((noinline)) silly_demo_function() {
    #include "ram.h"
    
    if (*xxx2>*xx1) {
    *xxx3 = *xxx3 + *xx1; 
    }
    
return; 
}

But this gets really boring, if i want to patch my code into another existing binary, where the location of available/free/unused ram can be fully different, or if im replacing/removing some value in the middle.但这真的很无聊,如果我想将我的代码修补到另一个现有的二进制文件中,其中可用/空闲/未使用的 ram 的位置可能完全不同,或者如果我在中间替换/删除一些值。 I am using 8, 16 and 32bit variables.我正在使用 8、16 和 32 位变量。

Is there a way, i can define an area like 0x807F00 to 0x00808FFF, and allocate my variables on the fly, and the compiler will allocate it inside my specific location?有没有办法,我可以定义一个像 0x807F00 到 0x00808FFF 这样的区域,并动态分配我的变量,编译器会在我的特定位置分配它?

I suspect that the big problem here is that those addresses are memory mapped IO (devices) and not RAM;我怀疑这里的大问题是这些地址是内存映射的 IO(设备)而不是 RAM; and should not be treated as RAM.并且不应被视为 RAM。

Further, I'd say that you probably should be hiding the "devices that aren't RAM" behind an abstract layer, a little bit like a device driver;此外,我想说您可能应该将“不是 RAM 的设备”隐藏在抽象层后面,有点像设备驱动程序; partly so that you can make sure that the compiler complies with any constraints caused by it being IO and not RAM (eg treated as volatile , possibly honoring any access size restrictions, possibly taking care of any cache coherency management);部分原因是您可以确保编译器符合由它是 IO 而不是 RAM 引起的任何约束(例如,被视为volatile ,可能遵守任何访问大小限制,可能负责任何缓存一致性管理); partly so that you/programmers know what is normal/fast/cached RAM and what isn't;部分是为了让您/程序员知道什么是正常/快速/缓存的 RAM,什么不是; partly so that you can replace the "device" with fake code for testing;部分原因是您可以用假代码替换“设备”进行测试; and partly so that it's all kept in a single well defined area.部分原因是它全部保存在一个明确定义的区域中。

For example;例如; you might have a header file called "src/devices.h" that contains:您可能有一个名为“src/devices.h”的头文件,其中包含:

#define xx1_address  0x807F00

..and the wrapper code might be a file called "src/devices/xx1.c" that contains something like: ..包装器代码可能是一个名为“src/devices/xx1.c”的文件,其中包含以下内容:

#include "src/devices.h"


static volatile uint8_t * xx1  = (uint8_t*) xx1_address;


uint8_t get_xx1(void) {
    return *xx1;
}

void set_xx1(uint8_t x) {
    *xx1 = x;
}

However;然而; depending on what these devices actually are, you might need/want some higher level code.根据这些设备的实际情况,您可能需要/想要一些更高级别的代码。 For example, maybe xx1 is a temperature sensor and it doesn't make any sense to try to set it, and you want it to scale that raw value so it's "degrees celsius", and the highest bit of the raw value is used to indicate an error condition (and the actual temperature is only 7 bits), so the wrapper might be more like:例如,也许xx1是一个温度传感器,尝试设置它没有任何意义,并且您希望它缩放该原始值,使其为“摄氏度”,并且原始值的最高位用于指示错误情况(实际温度仅为 7 位),因此包装器可能更像:

#include "src/devices.h"

#define xx1_offset   -12.34
#define xx1_scale    1.234

static volatile uint8_t * xx1  = (uint8_t*) xx1_address;


float get_xx1_temperature(void) {
    uint8_t raw_temp = *xx1;

    if(raw_temp * 0x80 != 0) {
        /* Error flag set */
        return NAN;
    }
    /* No error */
    return (raw_temp + xx1_offset) * xx1_scale;
}

In the meanwhile, i figured it out.与此同时,我想通了。

Its just as easy as defining .data, .bsss and .sbss in the linker directives.它就像在链接器指令中定义 .data、.bsss 和 .sbss 一样简单。 6 Lines of code and its working like a charm. 6 行代码和它的工作就像一个魅力。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM