【问题标题】:Creating initial task on Arduino RTOS在 Arduino RTOS 上创建初始任务
【发布时间】:2011-03-29 19:30:04
【问题描述】:

我正在为学校的一门课程编写实时操作系统。我在获取初始进程的上下文切换(从操作系统到进程的切换)时遇到了很多问题,因此我简化了问题以尝试找出我在哪里犯了错误。

在下面的代码中,我试图完成的是将 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");

这是按照位于 here (pdf) 的 FreeRTOS 项目指南中的示例完成的。我在 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");
    }

【问题讨论】:

  • 什么是“__SP_L__”和“__SP_H__”?
  • 堆栈指针分别为低位和高位。
  • 不都是常量(存放栈指针的两个地址)吗,比如0x5D/0x5E?

标签: assembly operating-system real-time arduino avr


【解决方案1】:

根据AVR Freaks Forum 上的 clawson 所说,这个问题是对 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");

【讨论】:

  • 谢谢 - 甚至没有注意到,我很高兴能得到这个工作。
  • 抱歉花了这么长时间才接受您的回答 - 非常感谢!
猜你喜欢
  • 2021-04-12
  • 1970-01-01
  • 2020-04-17
  • 1970-01-01
  • 2022-09-22
  • 2022-10-20
  • 1970-01-01
  • 2016-02-18
  • 1970-01-01
相关资源
最近更新 更多