2011-03-29 51 views
2

我正在爲學校的一門課程編寫一個實時操作系統。我在初始過程的上下文切換(從操作系統切換到過程)方面遇到了很多問題,所以我簡化了這個問題,試圖找出我犯的錯誤。在Arduino RTOS上創建初始任務

在下面的代碼中,我試圖完成的是將test_func地址放在堆棧指針上,然後返回,從而將該函數的地址加載到程序計數器中。現在發生的事情是,該委員會正在重新調用Arduino setup()方法,該方法會重複整個過程。

void test_func(void) 
{ 
    while(1 == 1){ 
    digitalWrite(13,HIGH);// to let me know everything has worked 
    DEBUG("test_func"); 
    } 
} 
//... 
volatile void *programcounter; 
//... 
programcounter = (void *)(&test_func); 
asm volatile(
"lds r26, programcounter  \n\t" \ 
"lds r27, programcounter+1 \n\t" \ 
"ld r28, x+     \n\t" \ 
"out __SP_L__, r28   \n\t" \ 
"ld r29, x+     \n\t" \ 
"out __SP_H__, r29   \n\t" \ 
"ret"); 

這是根據FreeRTOS項目指南中的示例完成的,位於here(pdf)。我正在將它作爲C文件在Arduino IDE中編寫。非常感謝您提供的任何輸入。

編輯:

嘗試另一個更簡單的例子。我在看Bertos的實現:http://dev.bertos.org/wiki/ArduinoHowto。我開始了一個新的草圖:

#include <avr/interrupt.h> 
    #include <avr/io.h> 

    void test_func() 
    { 
     while(true){ 
      Serial.write("Testing ..."); 
      digitalWrite(13, HIGH); 
     } 
    } 

    volatile void (*tempcounter)(void); 
    volatile void (**programcounter)(void); 

    void setup() { 
     // put your setup code here, to run once: 
     Serial.begin(9600); 
     pinMode(13, OUTPUT); 
     digitalWrite(13, LOW); 

     tempcounter = (volatile void (*)())(&test_func); 
     programcounter = &tempcounter; 

     Serial.println("Setting up ..."); 

     asm volatile (
     "cli\n\t"\ 
    "lds r24, programcounter  \n\t" \ 
    "lds r25, programcounter+1 \n\t" \ 
    "movw r26,r24\n\t"\ 
    "ld r18,X+\n\t"\ 
    "ld r19,X\n\t"\ 
    "out __SP_L__,r18\n\t"\ 
    "out __SP_H__,r19\n\t"\ 
    "sei\n\t"\ 
    "ret"); 
     Serial.println("This should never appear"); 
    } 

    void loop() { 
     // put your main code here, to run repeatedly: 
     Serial.println("looping"); 
    } 
+0

什麼是「\ _ \ _ SP \ _L \ _ \ _」和「\ _ \ _ SP \ _H _ \ _」? – 2011-03-29 22:20:26

+0

堆棧指針分別爲低和高。 – 2011-03-29 22:39:38

+0

它們不是常量(存儲堆棧指針的兩個地址),例如0x5D/0x5E? – 2011-03-29 22:56:18

回答

2

據有關AVR Freaks Forum克勞森,問題的RET是如何工作的誤解。我現在已經開始工作了;他的執行如下所示:

asm volatile ( 
"cli\n\t"\ 
"lds r24, programcounter  \n\t" \ 
"lds r25, programcounter+1 \n\t" \ 
"ldi r18, 0x00\n\t" \ 
"ldi r19, 0x03\n\t" \ 
"out __SP_L__,r18\n\t"\ 
"out __SP_H__,r19\n\t"\ 
"push r24\n\t"\ 
"push r25\n\t"\ 
"sei\n\t"\ 
"ret\n\t"); 
+0

謝謝 - 甚至沒有注意到,我很高興得到這個工作。 – 2011-03-30 13:36:27

+0

對不起,花了這麼長的時間來接受你的答案 - 我真的很感激它! – 2011-10-07 16:03:17