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

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

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

问题

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

  1. boolean pSystem::isLowPower(){
  2. return LOW_POWER;
  3. }

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

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

  1. boolean pSystem::isLowPower(){
  2. xSemaphoreTake( testMutex );
  3. return LOW_POWER;
  4. xSemaphoreGive( testMutex ); // 不会释放?
  5. }

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

用例将类似于这样:

  1. void TaskOne(void* parameter){
  2. for(;;){
  3. if( Preformance.isLowPower() ){ vTaskDelay(100); return; }
  4. // 执行其他与任务相关的操作...
  5. vTaskDelay(1);
  6. }
  7. }
  8. void TaskTwo(void* parameter){
  9. for(;;){
  10. if( Preformance.isLowPower() ){ vTaskDelay(100); return; }
  11. // 执行其他与任务相关的操作...
  12. vTaskDelay(1);
  13. }
  14. }

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

  1. Guru Meditation Error: Core 0 panic'ed (IllegalInstruction). Exception was unhandled.
  2. Memory dump at 0x400f1034: 08e08096 00f01d00 257bfea1
  3. Core 0 register dump:
  4. PC : 0x400f1039 PS : 0x00060430 A0 : 0x00000000 A1 : 0x3ffd2b50
  5. A2 : 0x00000000 A3 : 0x00000000 A4 : 0x00000000 A5 : 0x00000000
  6. A6 : 0x00000000 A7 : 0x00000000 A8 : 0x800f1039 A9 : 0x3ffd2b30
  7. A10 : 0x00000064 A11 : 0x3ffbf638 A12 : 0x3ffbdd58 A13 : 0x0000000a
  8. A14 : 0x0000000a A15 : 0x80000001 SAR : 0x00000000 EXCCAUSE: 0x00000000
  9. EXCVADDR: 0x00000000 LBEG : 0x00000000 LEND : 0x00000000 LCOUNT : 0x00000000
  10. Backtrace: 0x400f1036:0x3ffd2b50
  11. #0 0x400f1036:0x3ffd2b50 in mBusLoopTask(void*) at src/utilities/modBus.cpp:1495 (discriminator 1)
  12. ELF file SHA256: 1c0b237e74fe9d04
  13. 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.

  1. boolean pSystem::isLowPower(){
  2. return LOW_POWER;
  3. }

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.

  1. boolean pSystem::isLowPower(){
  2. xSemaphoreTake( testMutex );
  3. return LOW_POWER;
  4. xSemaphoreGive( testMutex ); // Will not release?
  5. }

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

The use case would be only something like this:

  1. void TaskOne(void* parameter){
  2. for(;;){
  3. if( Preformance.isLowPower() ){ vTaskDelay(100); return; }
  4. // Do other task related stuffs...
  5. vTaskDelay(1);
  6. }
  7. }
  8. void TaskTwo(void* parameter){
  9. for(;;){
  10. if( Preformance.isLowPower() ){ vTaskDelay(100); return; }
  11. // Do other task related stuffs...
  12. vTaskDelay(1);
  13. }
  14. }

The error log i got ( from random tasks )

  1. Guru Meditation Error: Core 0 panic'ed (IllegalInstruction). Exception was unhandled.
  2. Memory dump at 0x400f1034: 08e08096 00f01d00 257bfea1
  3. Core 0 register dump:
  4. PC : 0x400f1039 PS : 0x00060430 A0 : 0x00000000 A1 : 0x3ffd2b50
  5. A2 : 0x00000000 A3 : 0x00000000 A4 : 0x00000000 A5 : 0x00000000
  6. A6 : 0x00000000 A7 : 0x00000000 A8 : 0x800f1039 A9 : 0x3ffd2b30
  7. A10 : 0x00000064 A11 : 0x3ffbf638 A12 : 0x3ffbdd58 A13 : 0x0000000a
  8. A14 : 0x0000000a A15 : 0x80000001 SAR : 0x00000000 EXCCAUSE: 0x00000000
  9. EXCVADDR: 0x00000000 LBEG : 0x00000000 LEND : 0x00000000 LCOUNT : 0x00000000
  10. Backtrace: 0x400f1036:0x3ffd2b50
  11. #0 0x400f1036:0x3ffd2b50 in mBusLoopTask(void*) at src/utilities/modBus.cpp:1495 (discriminator 1)
  12. ELF file SHA256: 1c0b237e74fe9d04
  13. 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.

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

OR

  1. void TaskTwo(void* parameter){
  2. for(;;){
  3. if( !Preformance.isLowPower() ){
  4. // Do other task-related stuff...
  5. }else{
  6. vTaskDelay(100);
  7. }
  8. vTaskDelay(1);
  9. }
  10. }
英文:

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

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

OR

  1. void TaskTwo(void* parameter){
  2. for(;;){
  3. if( !Preformance.isLowPower() ){
  4. // Do other task related stuffs...
  5. }else{
  6. vTaskDelay(100);
  7. }
  8. vTaskDelay(1);
  9. }
  10. }

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:

确定