This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSP430FR4133:在汇编器中构建简单的调度程序

Guru**** 2589265 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/642414/msp430fr4133-building-a-simple-scheduler-in-assembler

部件号:MSP430FR4133

我正在尝试在MSP430的汇编器中构建一个非常简单的操作系统。 我想使用先占式调度程序,以循环方式循环处理任务。 所有任务都将无限期地执行,所以我对任何花式的优先级或等待状态都不感兴趣。

我已经在C中查看了一个实施示例,因此我很好地掌握了事情发生的顺序。 但是,我正在努力将每个任务的可用RAM分成堆栈。

在C实现中:  

stack_pointer[0]= initialize_stack (Task1,&task1ram[stack_top]);
stack_pointer[1]= initialize_stack (task2,&task2ram[stack_top]);
stack_pointer[2]= initialize_stack (task3, &task3ram[stack_top]); 

每个堆栈只是RAM的数组,因此堆栈指针设置为第一个地址。

但是在汇编程序中,我不知道我的堆栈在内存中的位置。 只为每个堆栈指针划分纸张上的RAM和硬代码地址是否是不好的做法?  

例如,我可以说:

----------------------------------
RSEG代码 ;组装到闪存
RSEG CSTACK
DC16 0x20E4
DC16 0x21E4
DC16 0x22E4
---------------------------------- 

其中,每个常量都是硬编码的内存位置,我希望我的三个堆栈都从这里开始。 然后,当我执行上下文切换时,我只想将我的栈指针设置为这些常量之一,然后使用以下命令还原上下文的其余部分:

restoreContext:Pop R15
Pop r14.
Pop R13
Pop R12
Pop r11.
Pop R10
Pop R9.
Pop R8.
Pop r7.
Pop R6.
POP R5
POP R4
印度 

因此,我的问题是:

是否有人在汇编程序中有一个简单调度程序的好例子?

将RAM分成堆栈并生成堆栈指针的推荐方法是什么?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我建议大家仔细阅读米罗·萨梅克的"SST"(或者:"Super Simple Tasker"或"Single Stack Tasker"),这是一个优先(固定)的内核,在单个堆栈上运行时开销非常低。 即使您不采用他的设计,他的原始文件也提到了您可能尚未考虑到的注意事项。

    对于定义堆栈,只需(1)将它们声明为(uint16_t)全局数组,然后让链接程序找出它们,或者(2)使用链接程序控制文件定义大小和名称。 选项(2)的优点是可以将堆栈放在.BSS之外,这样启动代码就不会浪费时间0-初始化它们。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的回复。

    当我再次访问此项目时,我将查看Miro Samek的SST。

    至于定义堆栈,我知道将它们定义为数组并让链接器找出它的含义,我已经在C中看到了这一点。但是,我不确定如何在汇编程序中处理这一问题。 到目前为止,我的方法是使用C代码调试器来找出它放置数组的位置,然后尝试在我的汇编器实现中使用这些地址。

    示例C代码使用数组声明3个堆栈:

    uINT16_t task1ram[stack_size];//Stack size = 128
    uint16_t task2ram[stack_size];
    uint16_t task3ram[stack_size]; 

    然后,它使用以下命令获取起始地址:

    stack_pointer[0]= initialize_stack (Task1,&task1ram[stack_top]);
    stack_pointer[1]= initialize_stack (task2,&task2ram[stack_top]);
    stack_pointer[2]= initialize_stack (task3, &task3ram[stack_top]); 

    此代码的结果是stack_pointer[]采用以下值:0x20E4,0x21E4,0x22E4

    与设备数据表进行交叉检查后发现,RAM中确实有三个内存块,每个内存块长度为256B,而且一个又一个。

    这正是我想在汇编程序中得到的,但我不确定如何获得和存储这三个地址。

    我应该使用RSEG并让链接器将每个块放置在它想要的位置,还是应该强制它们转到与C编译器相同的地址?

     

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我很长时间没有完成(MSP430)组装,但我认为如果您定义类似的内容

    全球积1
    .common 1256 ,4.2;256字节,16位对齐

    符号"stack1"将在模块外可见。

    有些装配体向导会给您更好的答案。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用user="Euan Andrew">这正是我想要在汇编程序中使用的内容,但我不确定如何获取和存储这三个地址。一个选项是让C编译器生成汇编列表文件,或保留生成的汇编语言文件。 您可以看到在某些示例C代码中使用的汇编器语句。

    如果您使用的是TI MSP430编译器,则在“生成”->“MSP430编译器”->“高级选项”->“汇编器选项”下的项目属性中,可以使用C编译器生成汇编列表文件或保留生成的汇编语言文件。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    感谢大家的建议。 很遗憾,我使用的是IAR的快速启动版本,因此它不允许生成汇编程序列表。

    我将仔细阅读上面的一些链接,希望在我继续学习的过程中弄清楚这些链接。