Context switchの様子

今回は、文字が少ないです。次回から解説したいと思います。

f:id:wi2y59:20190329201031j:plain

RR Scheduling

 main()は、task0()に相当

各関数内にfor()の無限ループの記述がありますが、context switchを行うことで、無限ループから抜けて、続くタスクに処理を移しています。スタックとそのポインタってこの様にも使うのだと今更目からうろこです。

かつてPICのOSを弄っていた時期もありましたが、そこまで突っ込んでいませんでした。

 

/************************************************************

* Sample program using round robin like scheduling *

* modified & written by jk1brk                                     *

* Last update 2019/3/24                                             *

***********************************************************/

#include <stdio.h>

#include <stdbool.h>

#include "myint.h"

#include "z80.h"

#include "aki80.h"

 

#include "task.h"

 

#define putchr(c) SIOB_putc(c)     

#define transmitNow(void) SIOB_transmitNow(void)

// Declare functions regarding task

extern bool init_task(uchar no,void (*func)(void));

extern unsigned int switch_reg(unsigned int reg_sp);

extern void task_switch(void);

static int gCount;                                              // Counter for showing #

 

void SIOB_putc(c)

char c;

{

              volatile unsigned char status;

              do{

                  status=inp(SIOB_CMD);              // RR0

              }while((status & 0x04)==0);              // Check send buf. empty

              outp(SIOB_DATA, c);

}

 

bool SIOB_transmitNow(void)

{

              volatile unsigned char status2;

              outp(SIOB_CMD, SIO_CMD_Null | 1);      // Select WR1

              status2=inp(SIOB_CMD);

              if(status2 & 0x01)             return 0;            // All char.s not sent yet

              else                                  return 1;            // Ready to send

}

/********************************************************

* each task                                                            *

********************************************************/

void task1(void)

{

              static unsigned char lCount_1 = 1;

              for(;;){

                            printf("task1 %d\n\r", gCount++);

                            putbyt(lCount_1++);

                            putnwl();

                            task_switch();

              // PC is for the next task after task_switch()

              }

}

 

void task2(void)

{

              static unsigned char lCount_2 = 2;

              for(;;){

                            printf("task2 %d\n\r", gCount++);

                            putbyt(lCount_2++);

                            putnwl();

                            task_switch();

              // PC is for the next task after task_switch()

              }

}

 

void task3(void)

{

              static unsigned char lCount_3 = 3;

              for(;;){

                            printf("task3 %d\n\r", gCount++);

                            putbyt(lCount_3++);

                            putnwl();

                            task_switch();

              // PC is for the next task after task_switch()

              }

}

 

/********************************************************

* main()                                                                 *

********************************************************/

main(void)

{

              unsigned char c;

              gCount = 0;        

              printf("Multi task sample program Ver. 1.4\n\r");

 

              init_task(1, task1);

              init_task(2, task2);

              init_task(3, task3);

 

              for(c = 0; c < MAX_TASK+1; c++) {

//            for(;;) {

                            printf("main %d\n\r", gCount++);

                            task_switch();

                            __EI();

              }          

              ;

              return    printf("Return to monitor\n\r");

}

/*******************************************************/

putwrd(n)

int n;

{

              char c, buf[5];

              int i;

              for(i = 3; i >= 0; i--){

                            c = n & 15;

                            n = (n >> 4 ) & 4095;

                            if(c < 10) buf[i] = c + 48;

                                 else buf[i] = c + 55;

              }

              buf[4] = 0;

              putstr(buf);

}

 

putbyt(n)

char n;

{

              char c,buf[3];

              int i;

              for(i = 1; i >= 0; i--){

                            c = n & 15;

                            n = (n >> 4 ) & 4095;

                            if(c < 10) buf[i] = c + 48;

                                 else buf[i] = c + 55;

              }

              buf[2] = 0;

              putstr(buf);

}

 

putnwl( )

{

              putstr("\15\12");

}

 

putstr(b)

char *b;

{

              while(*b)

                            putchr(*b++);

}