如何在多核环境中从函数中返回一个变量?

huangapple go评论61阅读模式
英文:

How to return a variable from a function in a multi core environment?

问题

所以我有一个必须在系统中对其他任务可用的变量。
我有一个函数,应该返回这个变量,以便其他任务可以根据这个变量执行它们的操作。

boolean pSystem::isLowPower(){
    return LOW_POWER;
}

如果我直接使用它或通过函数使用它,那么我会从想要使用这个变量的随机任务中得到一个IllegalInstruction错误,我的ESP会崩溃。

所以如果我想用互斥锁保护这个变量,我就不能返回它。

boolean pSystem::isLowPower(){
    xSemaphoreTake( testMutex );
    return LOW_POWER;
    xSemaphoreGive( testMutex  ); // 不会释放?
}

我如何能够保护这个变量并同时返回它?

用例将类似于这样:

void TaskOne(void* parameter){
    for(;;){
        if( Preformance.isLowPower() ){ vTaskDelay(100); return; }
        // 执行其他与任务相关的操作...
        vTaskDelay(1);
    }
}

void TaskTwo(void* parameter){
    for(;;){
        if( Preformance.isLowPower() ){ vTaskDelay(100); return; }
        // 执行其他与任务相关的操作...
        vTaskDelay(1);
    }
}

我得到的错误日志(来自随机任务)

Guru Meditation Error: Core 0 panic'ed (IllegalInstruction). Exception was unhandled.
Memory dump at 0x400f1034: 08e08096 00f01d00 257bfea1
Core 0 register dump:
PC      : 0x400f1039  PS      : 0x00060430  A0      : 0x00000000  A1      : 0x3ffd2b50
A2      : 0x00000000  A3      : 0x00000000  A4      : 0x00000000  A5      : 0x00000000
A6      : 0x00000000  A7      : 0x00000000  A8      : 0x800f1039  A9      : 0x3ffd2b30
A10     : 0x00000064  A11     : 0x3ffbf638  A12     : 0x3ffbdd58  A13     : 0x0000000a
A14     : 0x0000000a  A15     : 0x80000001  SAR     : 0x00000000  EXCCAUSE: 0x00000000
EXCVADDR: 0x00000000  LBEG    : 0x00000000  LEND    : 0x00000000  LCOUNT  : 0x00000000  

Backtrace: 0x400f1036:0x3ffd2b50

  #0  0x400f1036:0x3ffd2b50 in mBusLoopTask(void*) at src/utilities/modBus.cpp:1495 (discriminator 1)

ELF file SHA256: 1c0b237e74fe9d04

Rebooting...
英文:

So i have a variable which must be available to other tasks in the system.
I have a function which should return this variable so other tasks can do their thing according to this variable.

boolean pSystem::isLowPower(){
    return LOW_POWER;
}

If i use it RAW or trought the function, I got an IllegalInstruction error from a random task that wants to use this variable and my ESP crashes.

So if i want to guard this variable with a mutex i couldn't return it.

boolean pSystem::isLowPower(){
    xSemaphoreTake( testMutex );
    return LOW_POWER;
    xSemaphoreGive( testMutex  ); // Will not release?
}

How can i guard this variable and return it at the same time?

The use case would be only something like this:

void TaskOne(void* parameter){
    for(;;){
        if( Preformance.isLowPower() ){ vTaskDelay(100); return; }
        // Do other task related stuffs...
        vTaskDelay(1);
    }
}

void TaskTwo(void* parameter){
    for(;;){
        if( Preformance.isLowPower() ){ vTaskDelay(100); return; }
        // Do other task related stuffs...
        vTaskDelay(1);
    }
}

The error log i got ( from random tasks )

Guru Meditation Error: Core  0 panic'ed (IllegalInstruction). Exception was unhandled.
Memory dump at 0x400f1034: 08e08096 00f01d00 257bfea1
Core  0 register dump:
PC      : 0x400f1039  PS      : 0x00060430  A0      : 0x00000000  A1      : 0x3ffd2b50
A2      : 0x00000000  A3      : 0x00000000  A4      : 0x00000000  A5      : 0x00000000
A6      : 0x00000000  A7      : 0x00000000  A8      : 0x800f1039  A9      : 0x3ffd2b30
A10     : 0x00000064  A11     : 0x3ffbf638  A12     : 0x3ffbdd58  A13     : 0x0000000a
A14     : 0x0000000a  A15     : 0x80000001  SAR     : 0x00000000  EXCCAUSE: 0x00000000
EXCVADDR: 0x00000000  LBEG    : 0x00000000  LEND    : 0x00000000  LCOUNT  : 0x00000000  


Backtrace: 0x400f1036:0x3ffd2b50

  #0  0x400f1036:0x3ffd2b50 in mBusLoopTask(void*) at src/utilities/modBus.cpp:1495 (discriminator 1)




ELF file SHA256: 1c0b237e74fe9d04

Rebooting...

答案1

得分: 0

The problem was that I wanted to return from the task without deleting it, and it produced the IllegalInstruction error.

The solution is to not return but continue the loop.

void TaskOne(void* parameter){
    for(;;){
        if( Preformance.isLowPower() ){ vTaskDelay(100); continue; }
        // Do other task-related stuff...
        vTaskDelay(1);
    }
}

OR

void TaskTwo(void* parameter){
    for(;;){
        if( !Preformance.isLowPower() ){
            // Do other task-related stuff...
        }else{
            vTaskDelay(100);
        }
        vTaskDelay(1);
    }
}
英文:

So the problem was that i wanted to return from the task without deleting it and it produced the IllegalInstruction error.

The solution is to not return but continue the loop

void TaskOne(void* parameter){
    for(;;){
        if( Preformance.isLowPower() ){ vTaskDelay(100); continue; }
        // Do other task related stuffs...
        vTaskDelay(1);
    }
}

OR

void TaskTwo(void* parameter){
    for(;;){
        if( !Preformance.isLowPower() ){
            // Do other task related stuffs...
        }else{
            vTaskDelay(100);
        }
        vTaskDelay(1);
    }
}

huangapple
  • 本文由 发表于 2023年7月6日 19:15:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/76628228.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定