(toppers-users 2329) Re: M32Cのディスパッチ処理について

Naoki Saito saito @ nmiri.city.nagoya.jp
2006年 2月 27日 (月) 12:22:52 JST


こんにちは

松井 岳章 wrote:
> 現在製品にTOPPES1.4.2を載せて動作テスト中なんですが、過負荷時
> にどうも妙な動きをするのでカーネル内部を調べたました。
> その時に疑問がわきましたので質問をします。

この「妙な動き」というのが気になります。

> M32C・M16Cは割り込み発生時はフラグレジスタをスタック領域に退避
> するため若干スタック領域に差異があります。
> この状態でスタックポインタをタスクAの領域に変更して割り込み処理
> から復帰するとプログラムカウンタの下の値をフラグレジスタに格納
> しますし、そもそもスタック領域がおかしなことになります。
> 
> 
> 上記のようなことが起こっていればタスクは暴走してもおかしくはないの
> ですが、実機の動作を見ていると、通常時は何の問題も無く動いています。

タスクAは待ち状態へ移行する前に、
cpu_support.a30 の次の部分を実行していると思います。

__kernel_dispatch:
	pushm	r0,r1,r2,r3,a0,a1,sb,fb 	; スタックへレジスタ保存
	mov.l	__kernel_runtsk, a0
	stc  	isp, TCB_sp[a0]         	; スタックポインタをTCBに保存
	mov.l	#dispatch_r, TCB_pc[a0] 	; 実行再開番地をTCBに保存
	jmp.b	dispatcher

ですので、待ちが解除された後はdispatcher
dispatcher:
	mov.l 	__kernel_schedtsk, a0	;
	mov.l 	a0, __kernel_runtsk  	; schedtsk を runtsk に
	(中略)
	jz    	dispatcher_1         	; schedtsk がなければ割込み待ち
	ldc   	TCB_sp[a0], isp      	; タスクスタックポインタを復帰
	jmpi.a	TCB_pc[a0]           	; 実行再開番地へジャンプ

を経て、dispatch_r を実行することになると思います。

dispatch_r:
	mov.b	TCB_enatex[a0], r0l
	btst 	TCB_enatex_bit, r0l     	; タスク例外処理許可?
	jz   	dispatch_r_1            	; 許可でなければ dispatch_r_1 へ
	mov.w	TCB_texptn[a0], r0      	; 保留例外要因があるか?
	jz   	dispatch_r_1            	; なければ dispatch_r_1 へ
	jsr.a	__kernel_call_texrtn    	; タスク例外ハンドラへ
dispatch_r_1:	                    	; タスク例外を実行しない場合
	popm 	r0,r1,r2,r3,a0,a1,sb,fb 	; タスクスタックからレジスタ復帰
	rts  	                        	; dispatch 呼び出し元へ戻る.

割込みの出口処理である ret_int_r が
もし実行されているとすれば仰るように問題ですが、
実行されないはずです。

ちなみに、タスクBが処理を再開するときは ret_int_r から
実行が再開されますのでたぶん、これで問題ないと思います。

-----
斉藤直希
名古屋市工業研究所