雑記帳
ここはhideyosiの雑記帳です。テケトーに書き散らしてるだけなので間違っていたりとは普通にしてます。信用度は相当低いことをあらかじめご了承を。またご覧のようにWikiを使ってますが、hideyosi意外は書き込めません。
4: 2007-01-26 (金) 23:09:59 ソース バックアップ No.4 を復元して編集 現: 2024-01-06 (土) 22:39:13 ソース 編集
Line 33: Line 33:
-tssの作成と登録の実際 -tssの作成と登録の実際
 struct TSS32 tss_a,tss_b;  /*構造体として親切する  struct TSS32 tss_a,tss_b;  /*構造体として親切する
 + 
 tss_a.ldtr = 0;            /*ldtrとiomapはとりあえずこの数値にする。  tss_a.ldtr = 0;            /*ldtrとiomapはとりあえずこの数値にする。
 tss_a.iomap = 0x40000000;  tss_a.iomap = 0x40000000;
 tss_b.ldtr = 0;  tss_b.ldtr = 0;
 tss_b.iomap = 0x40000000;  tss_b.iomap = 0x40000000;
 + 
 /*gdtへの登録  /*gdtへの登録
 set_segmdesc(gdt + 3,103,(int) &tss_a,AR_TSS32);  /*それぞれ、GDT3番と4番に  set_segmdesc(gdt + 3,103,(int) &tss_a,AR_TSS32);  /*それぞれ、GDT3番と4番に
Line 68: Line 68:
 P296の初期設定  P296の初期設定
 tss_b.eip = (int) &task_b_main;  /* 関数task_b_mainの先頭アドレス  tss_b.eip = (int) &task_b_main;  /* 関数task_b_mainの先頭アドレス
- +  
 + 
 /* これはtask_b専用のスタックの設定。mamman_allocと使い64kbを確保。  /* これはtask_b専用のスタックの設定。mamman_allocと使い64kbを確保。
 /* 後ろの計算式はスタックの最終番地を計算したもの  /* 後ろの計算式はスタックの最終番地を計算したもの
Line 75: Line 75:
 task_b_esp = memman_alloc_4k(memman,64*1024)+64*1024;  task_b_esp = memman_alloc_4k(memman,64*1024)+64*1024;
 tss_b.esp = tssk_b_esp;  tss_b.esp = tssk_b_esp;
- +  
 + 
 tss_b.eflags = 0x00000202;   /*??? どういう意味だ?  tss_b.eflags = 0x00000202;   /*??? どういう意味だ?
 + 
 tss_b.eax = 0;   /* 通常の各レジスタの初期値。  tss_b.eax = 0;   /* 通常の各レジスタの初期値。
 tss_b.ecx = 0;  tss_b.ecx = 0;
Line 128: Line 128:
 {  {
     (中略)      (中略)
 + 
     /*タイマー timer_tsを新設。*/      /*タイマー timer_tsを新設。*/
    struct TIMER *timer, *timer2, *timer3, *timer_ts;     struct TIMER *timer, *timer2, *timer3, *timer_ts;
 + 
     (中略)      (中略)
 + 
     /*新設したタイマーを初期化*/      /*新設したタイマーを初期化*/
    timer_ts = timer_alloc();     timer_ts = timer_alloc();
    timer_init(timer_ts, &fifo, 2); /* タイムアウトしたら「2」をFIFOに送るよう設定     timer_init(timer_ts, &fifo, 2); /* タイムアウトしたら「2」をFIFOに送るよう設定
    timer_settime(timer_ts, 2); /* タイムアウト時間を0.02秒に設定     timer_settime(timer_ts, 2); /* タイムアウト時間を0.02秒に設定
 + 
     (中略)      (中略)
 + 
     /* 上記は設定。ここ以下のforループがtask_aの本質部分*/      /* 上記は設定。ここ以下のforループがtask_aの本質部分*/
    for (;;) {     for (;;) {
 + 
     (中略)      (中略)
         /* FIFOに2が来たら(timer_tsがタイムアウトしたら  */          /* FIFOに2が来たら(timer_tsがタイムアウトしたら  */
Line 150: Line 150:
     timer_settime(timer_ts, 2); /*ここに復帰した時、再度タイマーをセットする      timer_settime(timer_ts, 2); /*ここに復帰した時、再度タイマーをセットする
     } else if (256 <= i && i <= 511) { /* キーボードデータ */      } else if (256 <= i && i <= 511) { /* キーボードデータ */
 + 
     (中略)      (中略)
 + 
 }  }
- +  
 + 
 void task_b_main(void)  void task_b_main(void)
 {  {
Line 161: Line 161:
    struct TIMER *timer_ts;   /*ために必要なもの。     struct TIMER *timer_ts;   /*ために必要なもの。
    int i, fifobuf[128];     int i, fifobuf[128];
 + 
    fifo32_init(&fifo, 128, fifobuf);  /*FIFOを初期化して準備する。     fifo32_init(&fifo, 128, fifobuf);  /*FIFOを初期化して準備する。
    timer_ts = timer_alloc();      /*そうしないとタイマーが使えないから     timer_ts = timer_alloc();      /*そうしないとタイマーが使えないから
    timer_init(timer_ts, &fifo, 1);   /*タイムアウトすると1を返してくるタイマー。     timer_init(timer_ts, &fifo, 1);   /*タイムアウトすると1を返してくるタイマー。
    timer_settime(timer_ts, 2);     timer_settime(timer_ts, 2);
 + 
    for (;;) {     for (;;) {
 + 
     (中略)      (中略)
 + 
     i = fifo32_get(&fifo);        /*FIFOから一つ数値を得る。      i = fifo32_get(&fifo);        /*FIFOから一つ数値を得る。
     io_sti();                    io_sti();              
Line 176: Line 176:
     farjmp(0, 3 * 8);      farjmp(0, 3 * 8);
     timer_settime(timer_ts, 2);      timer_settime(timer_ts, 2);
 + 
     }      }
     }      }
Line 185: Line 185:
-「とにかくこの方法でsht_backの値をtask_b_mainに渡せる」と理解しておこう。(これ以上は無理) -「とにかくこの方法でsht_backの値をtask_b_mainに渡せる」と理解しておこう。(これ以上は無理)
 +--ただ、一つ解ったことがある。
 +--通常、別のタスク(task_bとか)には、それ用のtssと同時にそれ用のスタックが必要。(そらそーだ。分けないとごっちゃごちゃになっちゃう)
 +--別のタスクになにも変数を渡す必要がない場合。(たとえば void task_b_main() なんて場合)
 +-- task_b_esp = memman_alloc_4k(memman,64*1024)+64*1024;
 +--こんなことして、task_b用のスタックを確保している。おそらく、大半のタスクでもこれは必要な行為だろう。(スタックを一切使用しない動作だけのタスクとかそういう特殊なのは別ね)
 +--それに対して、今回はようするに、task_bに対して値を渡したいというだけ。
 +--で、task_bは引数を持つ関数になっている。(void task_b_main(struct SHEET *sht_back);  )
 +--普通に関数を呼ぶだけならなんの問題もない。そのまま呼べばよい。
 +--しかし、今回の相手は「別に動くタスク」だ。なので、呼び出しで引数を渡せない
 +--しかし、今回どうしても理解できなかった部分の登場となる。いまだにわからない。
 +--・・・しかし、このわからない部分は、
 +-- task_b_esp = memman_alloc_4k(memman,64*1024)+64*1024 -8;
 +--である。普通に用意するスタックから 8 を引いているだけだ。
 +--これがヒントになるかもしれない。いずれ解るかも。
 +
 +
 +
 +
Line 191: Line 209:
-タスクスイッチ専用の特殊なタイマーを1個確保したと考えればよい。 -タスクスイッチ専用の特殊なタイマーを1個確保したと考えればよい。
 +
 +
 +
 +
 +
 +
 +
 +
 +COLOR(Blue){''疑問点解決?:''タスクはかならずしもメモリを別セグメントにして動かすとは限らない(上記参照)。また、状況によってはtssを共有することすら可能。(タスクA,B,Cとあった場合、絶対tssが3個必要というわけではない。屁理屈チックだが、タスクAとタスクCが絶対同時に動かないような調整をすればtssは2個でも十分マルチタスクは可能)よってこの場合は、タスクではなく''tssはどう頑張っても8,190個以上は作れない''ということでOKのようだ。(・・・なんかあったりまえな答えになってしまったな・・・(^^;))}