081202

|


DROの仕上げに、プログラムをいじってました。ガレージのマシンはWindows2000なので、そこでTcl/Tkのモニタプログラムをテストしていた。そのプログラムを
Jornada690 NetBSD/hpcshに持っていけば終了のはずだったのだけれど...



うまくいかなかった。最後に追加したH8ヘコマンドを送る部分が動かないのだ。 このテストプログラム(本来動くプログラムです)

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

int
main ()
{
  int fd;
  struct termios t;
  int i;

  fd = open ("/dev/dscif0", O_RDWR);
  assert (fd >= 0);

  if (tcgetattr (fd, &t) != 0)
    {
      perror ("tcgetattr");
      exit (1);
    }

  cfsetispeed(&t, B57600);
  cfsetospeed(&t, B57600);
  t.c_cflag &= ~(CSIZE|PARENB);
  t.c_cflag |= CS8;
  t.c_iflag &= ~(ISTRIP|ICRNL);
  t.c_oflag &= ~OPOST;
  t.c_lflag &= ~(ICANON|ISIG|IEXTEN|ECHO);
  t.c_cc[VMIN] = 1;
  t.c_cc[VTIME] = 0;

  if (tcsetattr (fd, TCSANOW, &t) != 0)
    exit (1);

  char msg[] = "ohayo\n";
  if ((i = write (fd, msg, sizeof msg)) != sizeof msg) {
    printf ("%d %d\n", i, sizeof msg);
    perror ("write");
  }

  if (tcdrain (fd) != 0)
    perror ("tcdrain");

  close (fd);

  return 0;
}

がwrite(2)でEIO。延々と調べたところ、ttwrite@sys/kern/tty.cの
	if (!CONNECTED(tp)) {
		if (ISSET(tp->t_state, TS_ISOPEN)) {
			mutex_spin_exit(&tty_lock);
			return (EIO);
この部分でEIO。CONNECTEDは
#define	CONNECTED(tp)	(ISSET(tp->t_state, TS_CARR_ON) ||	\
			 ISSET(tp->t_cflag, CLOCAL | MDMBUF))
このTS_CARR_ONが立ってない。というのはsys/arch/sh3/dev/scif.cは scif_stsoftを実装していない。これは割り込みハンドラでステータスレジスタ の変化があったら、スケジューリングしてその後のソフトウェア割リ込みでステータスの変化をtty層に送る部分。ここがないのでキャリアがない(ケーブルが繋がっ てない)としてEIOになってしまうのだ。
とりあえずscifopenの最後で
	(void) (*tp->t_linesw->l_modem)(tp, 1);//XXX -uch
してごまかしました。これでキャリアが立つので書きこめる。DROの実用的には OK。scif.c直したいけれど、ここは悩ましいんだよね。