我正在为学校的一门课程编写一个实时操作系统。我在获取初始进程的上下文切换(从操作系统到进程的切换)时遇到了很多问题,所以我简化了问题,试图找出我在哪里犯了错误。
在下面的代码中,我试图完成的是将 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 项目指南(pdf) 中的示例完成的。我在 Arduino IDE 中将其编写为 C 文件。非常感谢您的任何意见。
编辑:
尝试另一个更简单的例子。我正在查看 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");
}