简体   繁体   English

Arduino内存类型,学术

[英]Arduino memory types, academic

Dear Stackoverflow Users, 尊敬的Stackoverflow用户,

I have an interesting question and I wish to hear your opinions out, also please correct me at any part. 我有一个有趣的问题,希望听到您的意见,也请随时纠正我。

In a normal PC the memory adresses splits into 3 parts, stack, heap, globals, (lets forget peripherials now), so if I go ahead and make a bad recursive function which fills the stack with calls, the OS will send a message of stackoverflow, also if I make an infinite loop with a new keyword in it, it'll fill the heap with junk data, and get something like segfault, but what if I make such mistakes in an arduino project? 在普通PC中,内存地址分为3个部分:堆栈,堆,全局变量(现在让我们忘记外围设备),因此,如果我继续执行一个不好的递归函数,使调用充满了堆栈,则操作系统将发送一条消息stackoverflow,如果我使用新的关键字进行无限循环,它也会用垃圾数据填充堆,并得到segfault之类的东西,但是如果我在arduino项目中犯了这样的错误怎么办?

try / catch blocks are out of the game, so I tried to make my own realization of error handling in loop(), abusing the stupidity of the preprocessor: try / catch块不在游戏之列,因此我尝试在loop()中实现错误处理的自己的实现,从而滥用了预处理器的愚蠢性:

#define THROW(errval)       \
ERROR = errval;             \
loop()

#define TRY                 \
if(ERROR == 0)

#define CATCH(err)              \
else if(err == ERROR)

#define FINALLY                 \
if(ERROR != 0)

#define OUT_OF_MEMORY 1    

int ERROR = 0;

void random_routine() {
    if(/*something goes wrong*/) {
        THROW(OUT_OF_MEMORY);
    }
}

void start() { Serial.begin(9600); }
void loop() {
    TRY {
        random_routine();
    } CATCH(OUT_OF_MEMORY) {
        Serial.println("out of memory");
    } FINALLY {
        while(true);
    }
}

Now you might not see the trick here instantly so this is what you get after the preprocessing: 现在您可能不会立即在此处看到窍门,因此这是经过预处理后得到的结果:

void random_routine() {
     if(/*something goes wrong*/) {
          ERROR = 1;
          //this call is the body of my exception handling solution
          //and the question is about this as well
          loop();
     }
}
void start() { Serial.begin(9600); }
void loop() {
     ///TRY-s macro result
     if(ERROR == 0) {
         random_routine();
     ///chainable CATCH blocks
     } else if(ERROR == 1) {
         Serial.println("Out of memory");
     }
     ///FINALLY block
     if(ERROR != 0) {
         while(true);
     }
}

So my question is, what if the memory gets full for some reason, will a function call be able to get executed? 所以我的问题是,如果由于某种原因内存已满,该函数调用将能够执行吗? Because the THROW macro will always call loop() that way my idea to 'escape' from the current context and get into an infinite loop 因为THROW宏将始终以这种方式调用loop(),所以我的想法是从当前上下文“转义”并进入无限循环

Sorry for my bad english 对不起,我的英语不好

So, if you want to exit a function and get back to where you came from, you should leave the function, not call the original function! 因此,如果您想退出某个函数并回到原来的位置,则应该离开该函数,而不要调用原始函数! Either by returning from the function, or use setjmp and longjmp . 通过从函数返回,或使用setjmplongjmp

And in all cases, you also need to worry about "how does data get cleaned up". 并且在所有情况下,您还需要担心“如何清理数据”。 In other words, if you allocate memory, then you need to free it before leaving the function, of you have opened a file, you need to close it, etc. 换句话说,如果您分配了内存,则需要在离开函数之前释放它,例如,打开了文件,需要关闭文件等。

These sort of things is where the RAII principle comes in very handy, but it assumes you leave the function under the knowledge of the compiler, and not that you just jump back to your main loop without cleaning up. RAII原理非常有用,但是它假定您将函数留在编译器的知识范围之内,而不是只是跳回主循环而不进行清理。 It will sooner or later cause problems. 迟早会引起问题。

Note also that the behaviour with stack overflow is UNDEFINED BEHAVIOUR - it MAY crash the program immediately, or it may cause the heap to be overwitten, format your harddrive/SD Card, or it may cause daemons to fly out of your nose. 还要注意,堆栈溢出的行为是未定义的行为-可能会立即使程序崩溃,或者可能导致堆被覆盖,格式化硬盘驱动器/ SD卡,或者可能导致守护程序从您的鼻子里飞出来。 Or anything else you can possibly imagine and then some. 或您可能想到的其他任何东西,然后再说一些。 It is undefined, you can't rely on it doing anything in particular - just that "you're not supposed to do that". 它是未定义的,您不能依靠它做任何特别的事情-只是“您不应该这样做”。

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

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