100428

|



ルーターテーブル続き。天板の加工。フライスの加工領域を越えて作業するの
で工夫を。まずはストレートエッジを平行になるようにクランプで固定。これ
を基準にしてちょっとづつクランプをし直して切削。



まずは10φの二枚刃で切り込み3mmで。結構辛い。無難にMDFにしておけばよかっ たかな...とも。ハンドル廻すだけで筋肉痛になりそう。

計4回のクランプが必要。

そしてもう一回戻ってφ12の4枚刃ラフィングで切り込み5mmで。これは楽。本 来10φラフィング、12φ二枚刃の方がいいのだけど、手持ちの工具の関係で。 もう一本はいきなりφ12で切り込み5mm一発でいけそう。
作業に夢中になっていて、筑波の予約忘れた...ショック。今週末のMCは練習な しでぶっつけだ...。それと正直、一度S枠走れてしまうと、A枠走る気しないん だよね...。

H8SX続きスレッドの実装。今回は例外フレーム(例外時にストアすべきCPU状 態)と、スイッチフレーム(明示的にスレッドスイッチをする時にストアすべき CPU状態)を別に実装してみることにした。具体的には呼出し元退避のER0-ER3を とっておくかおかないかの差。スレッドスイッチをする時には呼出し元退避は 既に呼出し元のスタックに入っているので、例外フレームとして全部退避する とちょっと無駄になる。
こんな感じで設定。例外フレームでレジスタの順番が3,2,1,0,6,5,4になって いるのはスイッチフレームとの関係と、ldm.l,rte/lで多重レジスタロードを 効率よく使えるように。
struct exception_frame;

struct reg
{
  struct exception_frame *ef;
//今迄の他のポートではここに直接、例外フレームが入っていたのが、
//それへのポインタになった。これはldm.l,rte/l命令を効率よく使うため。
};

// Stack frame when exception is occured.
// 割り込みモード2の例外突入時のスタックフレーム
struct exception_stack_frame
{
  uint8_t exr;		/* 0x1e/0x0e EXR */
  uint8_t reserved;	/* 0x1f/0x0f reserved */
  uint32_t ccr_pc;	/* 0x20/0x10 CCR, 0x23 PC(24bit) */
} __attribute__((packed));

// Frame must be reserved in exception
struct exception_frame
{
//このフラグはスイッチフレームと例外フレームを別にしたので、レジスタ復帰の際に
//どちらのフレームかを判別するためにつけたソフトウェア的なもの。
  uint8_t flags;// frame type (switch/exception)
//スタックは2byteアラインなのでパディング
  uint8_t pad;	// for stack alignment
  uint32_t er3;	/* 0x02 caller saved */
  uint32_t er2;	/* 0x06 caller saved */
  uint32_t er1;	/* 0x0a caller saved */
  uint32_t er0;	/* 0x0e caller saved */
  uint32_t er6;	/* 0x12 callee saved */
  uint32_t er5;	/* 0x16 callee saved */
  uint32_t er4;	/* 0x1a callee saved */
  struct exception_stack_frame stack_frame;
} __attribute__((packed));

// Frame must be reserved in explicit thread switch.
struct switch_frame
{
//スイッチフレームは呼出し元退避がないだけ。サブルーチンコールと例外で
//スタック構造が違うのはソフトウェア的に変換。
  uint8_t flags;// frame type (switch/exception)
  uint8_t pad;	// for stack alignment
  uint32_t er6;	/* 0x02 callee saved */
  uint32_t er5;	/* 0x06 callee saved */
  uint32_t er4;	/* 0x0a callee saved */
  struct exception_stack_frame stack_frame;
} __attribute__((packed));


スレッドスイッチは第一引数(ER0)に継続があるので、それをそのまま渡すよう
に。継続を共なってブロックする時はスタックを放棄できるスレッド。それは、
ここでスタックを外して、次に走る時には新しくスタックを拾ってきてこの継
続から再開する。

	.h8300sx
	.section .text
	.align 2
	/* void do_thread_switch (continuation_t) */
	/* Assume already interrupt disabled */
	/* Called from thread context */
	.global	_do_thread_switch
_do_thread_switch:
//サブルーチンコールのスタック構造を例外時の構造に変換
	stc.b	exr, r2h	// Get current EXR
	mov.w	r2,  @-sp	// Store EXR
//呼出し先退避だけ退避。
	stm.l	er4-er6, @-sp	// Store caller saved registers.
//ここでフレーム種別の領域(switch_frame.flags)を設定
	subs	#2, sp		// Software flags region.
	bclr	#0, @sp		// clear exception frame bit
//current_threadのTCBのstruct regにこのフレームポインタを設定。
	mov.l	@_current_thread, er4
	mov.l	sp, @(0, er4)	// Store current frame to TLS
	// Reschedule.
	jsr	_thread_context_switch
	// Run next thread.
//ここでcurrent_threadのTCBは変更されたかもしれないのでポインタを読み直す。
	mov.l	@_current_thread, er4
//このTCBのフレームポインタを設定
	mov.l	@(0, er4), sp
//フレームがスイッチフレームならER4-ER6だけ復帰し、例外フレームなら全復帰
	btst	#0, @sp	// If switch frame, Z = 1
	adds	#2, sp
	beq	1f	// If exception frame, restore er0-er3
	// Restore registers.
	ldm.l	@sp+, er0-er3
1:	rte/l	er4-er6

終了時にスレッドのスケジューリングをする割り込みの入口は
// 例外フレームの配置に合わせてこの順番で退避
	stm.l	er4-er6, @-sp
	stm.l	er0-er3, @-sp
// 多重割り込みの判定のために、割り込まれた時点での割り込みレベルを
// 呼出し先退避のer4にとっておく
	mov.b	@(0x1c, sp), r4l	// old EXR


終了時にスレッドのスケジューリングをする割り込みの出口は

//r4lには割り込まれた時点のEXRが入っているので、優先度を抽出。
	and.b	#7, r4l		// extract EXR.I[0-2] 0: Z=1, 1-7:Z=0
//多重割り込みなら、レジスタを復帰してそのままリターン
	bne	1f		// if (Z == 0(interrupt nested)) goto 1
	// Prepare exception frame.
//そうでないならここでスレッドスイッチできるように例外フレームを構築
	subs	#2, sp
//例外フレームであることを示すためにexception_frame.flagsをセット。
	bset	#0, @sp		// Set exception frame bit
//割り込まれたスレッドのTCBにこの状態を登録。
	mov.l	@_current_thread, er1
	mov.l	sp, @(0, er1)	// Store current frame to TLS
//割り込みハンドラでは継続はない。
	mov.l	#0, er0	// no continuation.
//以下はdo_thread_switchと同じ。
	jsr	_thread_context_switch

	mov.l	@_current_thread, er1	// Load new thread control block.
	mov.l	@(0, er1), sp	// Set new exception/switch frame.

	btst	#0, @sp		// Check frame type.
	adds	#2, sp
	beq	2f	// If switch frame, don't restore er0-er3
1:	ldm.l	@sp+, er0-er3
2:	rte/l	er4-er6


mon> l
~>Local file name? a.mot
2632 lines transferred in 11 seconds 
!
Read 59127 byte. success
Start address: 0xff3d40
stack_start: 0xffc000
RAM data: 0xff723c-0xff727c 64byte
bss: 0xff7280-0xff85dc 4956byte
VBR: 0xff2000 (0xff2000)
MCU mode: 6
DTC: short-address mode
Internal RAM: enabled
External bus: enabled
Instruction fetch: 32bit
MAC instruction: non-saturation mode
Interrput Control mode: 2
PA7 clock output: On
Input clock: 12000000Hz, MDCLK=0
System clock: x4 (48000000Hz)
Peripheral clock: x2 (24000000Hz)
External clock: x4 (48000000Hz)
thread_stack_setup: ff777c-ff7380 (400)
thread_stack_setup: ff7b7c-ff7780 (400)
thread_stack_setup: ff7f7c-ff7b80 (400)
thread_stack_setup: ff837c-ff7f80 (400)
CONTINUATION=0
thread_create_no_stack: [2]:uart recv pc=7 (no stack)
thread_start: [2]
thread_create_no_stack: [3]:uart send pc=7 (no stack)
thread_start: [3]
intc_priority: fffd56(4) 7->7
OHAYO Apr 28 2010 21:58:30 arg=1badface
peripheral_power: fffdcc (4096) ->1
intc_priority: fffd62(8) 7->7
peripheral_power: fffdc8 (256) ->1
intc_priority: fffd4e(12) 7->5
user> 
user> 
user> help
---Monitor---
W ringbuffer
        lock : 
        event: 3(uart send) 
U ringbuffer
        lock : 
        event: 
---Ready Queue---
<0>: 
<1>: 
<2>: 
<3>: 1 
---Thread Status---
id   pri(used/total)
[3] W 0 (no stack) uart send
[2] W 0 (no stack) uart recv
[1] R 3 (300/1020) root
---Stack Status---
  bottom   top     (used/total)
0 ff777c-ff7380 (4/1024) 
1 ff7b7c-ff7780 (4/1024) 
2 ff7f7c-ff7b80 (180/1024) 
3 ff837c-ff7f80 (304/1024) 
avaliable command: help reset timer interrupt test 
user> timer
old=0 new=0
timer 1
user> TMR0:EXR=5 old EXR=0
TMR0:EXR=5 old EXR=0
TMR0:EXR=5 old EXR=0
TMR0:EXR=5 old EXR=0
TMR0:EXR=5 old EXR=0
TMR0:EXR=5 old EXR=0
TMR0:EXR=5 old EXR=0
tTMR0:EXR=5 old EXR=0
eTMR0:EXR=5 old EXR=0
sTMR0:EXR=5 old EXR=0
tTMR0:EXR=5 old EXR=0

0:test
timer 0
user>