任务切换到手臂

时间:2014-09-24 10:25:28

标签: arm context-switch

我正在阅读Arm Architecture参考手册,我想我有一些理论问题。

首先,我很困惑是否通过上下文切换我们的意思是任务切换?

其次,通过体验英特尔80386的体系结构,我记得有任务描述符和其他一些机制可以自动保存任务的状态,在这里如何完成?它是否完成,让我们通过在堆栈中保存寄存器来手动"

那个ASID(应用程序空间ID)链接到我以前问过的上一个?

3 个答案:

答案 0 :(得分:0)

如果你有2个线程,每个线程有一个堆栈(寄存器值的数组),那么如果你有一个ISR保存线程的状态并切换到另一个线程,那么这就是一个上下文切换。最简单的示例是具有2个线程(1个生产者,1个消费者)的操作系统,其中交换机看起来类似于此处的代码。

/*
 * threadswitch - change thread
 * 
 * The thread stack-pointer is supplied as a parameter.
 * The old thread's stack-pointer value is saved to the array
 * os_thread_info_array, and a new thread is selected from the array.
 * The stack pointer of the new thread is returned.
 */
unsigned int os_internal_threadswitch( unsigned int old_sp )
{
  unsigned int new_sp;

  os_number_of_thread_switches += 1; /* Increase thread-switch counter. */

  /* Print line 1 of an informational message. */
  printf( "\nPerforming thread-switch number %d. The system has been running for %d ticks.\n",
          os_number_of_thread_switches,
          os_get_internal_globaltime() );

  /* Save the stack pointer of the old thread. */
  os_thread_info_array[ os_currently_running_thread ].thread_sp = old_sp;

  /* Print part 1 of a message saying which threads are involved this time. */
  printf( "Switching from thread-ID %d ",
          os_thread_info_array[ os_currently_running_thread ].thread_id );

  /* Perform the scheduling decision (round-robin). */
  os_currently_running_thread += 1;
  if( os_currently_running_thread >= os_current_thread_count )
  {
    os_currently_running_thread = 0;
  }

  /* Print part 2 of the informational message. */
  printf( "to thread-ID %d.\n",
          os_thread_info_array[ os_currently_running_thread ].thread_id );

  /* Get the stack pointer of the new thread. */
  new_sp = os_thread_info_array[ os_currently_running_thread ].thread_sp;

  /* Return. */
  return( new_sp );
}

答案 1 :(得分:0)

这是一个完全符合您要求的代码 - https://github.com/DISTORTEC/distortos/blob/master/source/architecture/ARM/ARMv6-M-ARMv7-M/ARMv6-M-ARMv7-M-PendSV_Handler.cpp。在异常输入时,一些寄存器会自动保存,因此您只需保存剩余的寄存器,切换堆栈指针并执行相反的操作 - 取消堆栈“剩余”寄存器并退出异常。如果你还需要保存FPU寄存器,这会变得有点困难,因为这些寄存器不需要每次都保存(如果线程没有进行任何FPU计算,它们就不用了。)

答案 2 :(得分:0)

" context"一般指CPU的当前状态;即寄存器的内容。每个"任务" (aka线程)有自己的任务控制块结构(TCB),它存储操作系统知道的有关任务的相关信息,例如优先级,入口点,名称,堆栈大小等。通常,当前的CPU上下文保存在每当交换任务时,运行任务的堆栈(TCB具有指向任务堆栈的指针)。然后将堆栈指针保存到已知位置(通常在TCB中),并使用来自TCB的信息和要运行的下一个任务的堆栈来恢复CPU上下文。在切换之后,堆栈指针指向新运行的任务的堆栈,并且返回返回到该任务的最后一次调用之后的下一条指令。这是一个上下文切换。

我不知道为什么人们会指出上下文切换会在ISR中。上下文切换通常在系统调用期间发生,导致正在运行的任务被阻塞,例如睡眠调用或信号量调用,但是当系统调用ISR运行并唤醒更高优先级的任务时,也可能发生上下文切换,或者确定当前任务的时间片已经过期,另一个具有相同优先级的任务已准备好运行。上下文切换只是OS调度程序调用的一个函数,它是从各种其他系统函数调用的,并且它没有意义它是一个ISR,尽管我认为它可以实现为"软件&# 34;中断呼叫,也许这就是他们想到的。

关键是上下文切换不会仅仅因为中断而发生,这是我从其他响应中获得的印象。事实上,当任务进行系统调用时,它们的发生频率更高。