Arduino内存类型,学术

Arduino memory types, academic

本文关键字:学术 内存类型 Arduino      更新时间:2023-10-16

亲爱的Stackoverflow用户,

我有一个有趣的问题,我希望听到你的意见,也请纠正我的任何部分。

在正常的PC中,内存地址分成3部分,堆栈,堆,全局,(现在让我们忘记外设),所以如果我继续做一个坏的递归函数,用调用填充堆栈,操作系统会发送stackoverflow的消息,也如果我用一个新的关键字做一个无限循环,它会用垃圾数据填充堆,并得到类似段错误的东西,但如果我在arduino项目中犯这样的错误呢?

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);
    }
}

现在你可能不会立即看到这里的技巧所以这是你在预处理后得到的:

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);
     }
}

所以我的问题是,如果内存因为某种原因而满了,函数调用能够被执行吗?因为THROW宏总是调用loop(),所以我的想法是从当前上下文中"逃脱"并进入无限循环

对不起,我的英语不好

所以,如果你想退出一个函数并回到你来的地方,你应该离开这个函数,而不是调用原来的函数!要么从函数返回,要么使用setjmplongjmp

在所有情况下,您还需要担心"如何清理数据"。换句话说,如果你分配内存,那么你需要在离开函数之前释放它,如果你打开了一个文件,你需要关闭它,等等。

这类事情是RAII原则非常有用的地方,但它假设您将函数置于编译器的知识之下,而不是不进行清理就跳转回主循环。它迟早会引起问题。

还请注意,堆栈溢出的行为是未定义的行为-它可能会立即使程序崩溃,或者它可能会导致堆被覆盖,格式化您的硬盘/SD卡,或者它可能会导致守护进程飞出您的鼻子。或者任何你能想到的东西。它是未定义的,你不能指望它做任何特别的事情-只是"你不应该这样做"。