OSDN Git Service

Step 10 added.
[kozos-expbrd/kozos_expbrd.git] / firm / 02 / os / consdrv.c
1 #include "defines.h"
2 #include "kozos.h"
3 #include "intr.h"
4 #include "interrupt.h"
5 #include "serial.h"
6 #include "lib.h"
7 #include "consdrv.h"
8
9 #define CONS_BUFFER_SIZE 24
10
11 static struct consreg {
12   kz_thread_id_t id; /* ¥³¥ó¥½¡¼¥ë¤òÍøÍѤ¹¤ë¥¹¥ì¥Ã¥É */
13   int index;         /* ÍøÍѤ¹¤ë¥·¥ê¥¢¥ë¤ÎÈÖ¹æ */
14
15   char *send_buf;    /* Á÷¿®¥Ð¥Ã¥Õ¥¡ */
16   char *recv_buf;    /* ¼õ¿®¥Ð¥Ã¥Õ¥¡ */
17   int send_len;      /* Á÷¿®¥Ð¥Ã¥Õ¥¡Ãæ¤Î¥Ç¡¼¥¿¥µ¥¤¥º */
18   int recv_len;      /* ¼õ¿®¥Ð¥Ã¥Õ¥¡Ãæ¤Î¥Ç¡¼¥¿¥µ¥¤¥º */
19
20   /* kozos.c ¤Î kz_msgbox ¤ÈƱÍͤÎÍýͳ¤Ç¡¤¥À¥ß¡¼¡¦¥á¥ó¥Ð¤Ç¥µ¥¤¥ºÄ´À°¤¹¤ë */
21   long dummy[3];
22 } consreg[CONSDRV_DEVICE_NUM];
23
24 /*
25  * °Ê²¼¤Î£²¤Ä¤Î´Ø¿ô(send_char(), send_string())¤Ï³ä¹þ¤ß½èÍý¤È¥¹¥ì¥Ã¥É¤«¤é
26  * ¸Æ¤Ð¤ì¤ë¤¬Á÷¿®¥Ð¥Ã¥Õ¥¡¤òÁàºî¤·¤Æ¤ª¤êºÆÆþÉԲĤΤ¿¤á¡¤¥¹¥ì¥Ã¥É¤«¤é¸Æ¤Ó½Ð¤¹
27  * ¾ì¹ç¤ÏÇÓ¾¤Î¤¿¤á³ä¹þ¤ß¶Ø»ß¾õÂ֤ǸƤ֤³¤È¡¥
28  */
29
30 /* Á÷¿®¥Ð¥Ã¥Õ¥¡¤ÎÀèƬ£±Ê¸»ú¤òÁ÷¿®¤¹¤ë */
31 static void send_char(struct consreg *cons)
32 {
33   int i;
34   serial_send_byte(cons->index, cons->send_buf[0]);
35   cons->send_len--;
36   /* ÀèƬʸ»ú¤òÁ÷¿®¤·¤¿¤Î¤Ç¡¤£±Ê¸»ú¤Ö¤ó¤º¤é¤¹ */
37   for (i = 0; i < cons->send_len; i++)
38     cons->send_buf[i] = cons->send_buf[i + 1];
39 }
40
41 /* Ê¸»úÎó¤òÁ÷¿®¥Ð¥Ã¥Õ¥¡¤Ë½ñ¤­¹þ¤ßÁ÷¿®³«»Ï¤¹¤ë */
42 static void send_string(struct consreg *cons, char *str, int len)
43 {
44   int i;
45   for (i = 0; i < len; i++) { /* Ê¸»úÎó¤òÁ÷¿®¥Ð¥Ã¥Õ¥¡¤Ë¥³¥Ô¡¼ */
46     if (str[i] == '\n') /* \n¢ª\r\n¤ËÊÑ´¹ */
47       cons->send_buf[cons->send_len++] = '\r';
48     cons->send_buf[cons->send_len++] = str[i];
49   }
50   /*
51    * Á÷¿®³ä¹þ¤ß̵¸ú¤Ê¤é¤Ð¡¤Á÷¿®³«»Ï¤µ¤ì¤Æ¤¤¤Ê¤¤¤Î¤ÇÁ÷¿®³«»Ï¤¹¤ë¡¥
52    * Á÷¿®³ä¹þ¤ßÍ­¸ú¤Ê¤é¤ÐÁ÷¿®³«»Ï¤µ¤ì¤Æ¤ª¤ê¡¤Á÷¿®³ä¹þ¤ß¤Î±äŤÇ
53    * Á÷¿®¥Ð¥Ã¥Õ¥¡Æâ¤Î¥Ç¡¼¥¿¤¬½ç¼¡Á÷¿®¤µ¤ì¤ë¤Î¤Ç¡¤²¿¤â¤·¤Ê¤¯¤Æ¤è¤¤¡¥
54    */
55   if (cons->send_len && !serial_intr_is_send_enable(cons->index)) {
56     serial_intr_send_enable(cons->index); /* Á÷¿®³ä¹þ¤ßÍ­¸ú²½ */
57     send_char(cons); /* Á÷¿®³«»Ï */
58   }
59 }
60
61 /*
62  * °Ê²¼¤Ï³ä¹þ¤ß¥Ï¥ó¥É¥é¤«¤é¸Æ¤Ð¤ì¤ë³ä¹þ¤ß½èÍý¤Ç¤¢¤ê¡¤ÈóƱ´ü¤Ç
63  * ¸Æ¤Ð¤ì¤ë¤Î¤Ç¡¤¥é¥¤¥Ö¥é¥ê´Ø¿ô¤Ê¤É¤ò¸Æ¤Ó½Ð¤¹¾ì¹ç¤Ë¤ÏÃí°Õ¤¬É¬Íס¥
64  * ´ðËܤȤ·¤Æ¡¤°Ê²¼¤Î¤¤¤º¤ì¤«¤ËÅö¤Æ¤Ï¤Þ¤ë´Ø¿ô¤·¤«¸Æ¤Ó½Ð¤·¤Æ¤Ï¤¤¤±¤Ê¤¤¡¥
65  * ¡¦ºÆÆþ²Äǽ¤Ç¤¢¤ë¡¥
66  * ¡¦¥¹¥ì¥Ã¥É¤«¤é¸Æ¤Ð¤ì¤ë¤³¤È¤Ï̵¤¤´Ø¿ô¤Ç¤¢¤ë¡¥
67  * ¡¦¥¹¥ì¥Ã¥É¤«¤é¸Æ¤Ð¤ì¤ë¤³¤È¤¬¤¢¤ë¤¬¡¤³ä¹þ¤ß¶Ø»ß¤Ç¸Æ¤Ó½Ð¤·¤Æ¤¤¤ë¡¥
68  * ¤Þ¤¿Èó¥³¥ó¥Æ¥­¥¹¥È¾õÂ֤ǸƤФì¤ë¤¿¤á¡¤¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤ÏÍøÍѤ·¤Æ¤Ï¤¤¤±¤Ê¤¤¡¥
69  * (¥µ¡¼¥Ó¥¹¡¦¥³¡¼¥ë¤òÍøÍѤ¹¤ë¤³¤È)
70  */
71 static int consdrv_intrproc(struct consreg *cons)
72 {
73   unsigned char c;
74   char *p;
75
76   if (serial_is_recv_enable(cons->index)) { /* ¼õ¿®³ä¹þ¤ß */
77     c = serial_recv_byte(cons->index);
78     if (c == '\r') /* ²þ¹Ô¥³¡¼¥ÉÊÑ´¹(\r¢ª\n) */
79       c = '\n';
80
81     send_string(cons, &c, 1); /* ¥¨¥³¡¼¥Ð¥Ã¥¯½èÍý */
82
83     if (cons->id) {
84       if (c != '\n') {
85         /* ²þ¹Ô¤Ç¤Ê¤¤¤Ê¤é¡¤¼õ¿®¥Ð¥Ã¥Õ¥¡¤Ë¥Ð¥Ã¥Õ¥¡¥ê¥ó¥°¤¹¤ë */
86         cons->recv_buf[cons->recv_len++] = c;
87       } else {
88         /*
89          * Enter¤¬²¡¤µ¤ì¤¿¤é¡¤¥Ð¥Ã¥Õ¥¡¤ÎÆâÍƤò
90          * ¥³¥Þ¥ó¥É½èÍý¥¹¥ì¥Ã¥É¤ËÄÌÃΤ¹¤ë¡¥
91          * (³ä¹þ¤ß¥Ï¥ó¥É¥é¤Ê¤Î¤Ç¡¤¥µ¡¼¥Ó¥¹¡¦¥³¡¼¥ë¤òÍøÍѤ¹¤ë)
92          */
93         p = kx_kmalloc(CONS_BUFFER_SIZE);
94         memcpy(p, cons->recv_buf, cons->recv_len);
95         kx_send(MSGBOX_ID_CONSINPUT, cons->recv_len, p);
96         cons->recv_len = 0;
97       }
98     }
99   }
100
101   if (serial_is_send_enable(cons->index)) { /* Á÷¿®³ä¹þ¤ß */
102     if (!cons->id || !cons->send_len) {
103       /* Á÷¿®¥Ç¡¼¥¿¤¬Ìµ¤¤¤Ê¤é¤Ð¡¤Á÷¿®½èÍý½ªÎ» */
104       serial_intr_send_disable(cons->index);
105     } else {
106       /* Á÷¿®¥Ç¡¼¥¿¤¬¤¢¤ë¤Ê¤é¤Ð¡¤°ú³¤­Á÷¿®¤¹¤ë */
107       send_char(cons);
108     }
109   }
110
111   return 0;
112 }
113
114 /* ³ä¹þ¤ß¥Ï¥ó¥É¥é */
115 static void consdrv_intr(void)
116 {
117   int i;
118   struct consreg *cons;
119
120   for (i = 0; i < CONSDRV_DEVICE_NUM; i++) {
121     cons = &consreg[i];
122     if (cons->id) {
123       if (serial_is_send_enable(cons->index) ||
124           serial_is_recv_enable(cons->index))
125         /* ³ä¹þ¤ß¤¬¤¢¤ë¤Ê¤é¤Ð¡¤³ä¹þ¤ß½èÍý¤ò¸Æ¤Ó½Ð¤¹ */
126         consdrv_intrproc(cons);
127     }
128   }
129 }
130
131 static int consdrv_init(void)
132 {
133   memset(consreg, 0, sizeof(consreg));
134   return 0;
135 }
136
137 /* ¥¹¥ì¥Ã¥É¤«¤é¤ÎÍ×µá¤ò½èÍý¤¹¤ë */
138 static int consdrv_command(struct consreg *cons, kz_thread_id_t id,
139                            int index, int size, char *command)
140 {
141   switch (command[0]) {
142   case CONSDRV_CMD_USE: /* ¥³¥ó¥½¡¼¥ë¡¦¥É¥é¥¤¥Ð¤Î»ÈÍѳ«»Ï */
143     cons->id = id;
144     cons->index = command[1] - '0';
145     cons->send_buf = kz_kmalloc(CONS_BUFFER_SIZE);
146     cons->recv_buf = kz_kmalloc(CONS_BUFFER_SIZE);
147     cons->send_len = 0;
148     cons->recv_len = 0;
149     serial_init(cons->index);
150     serial_intr_recv_enable(cons->index); /* ¼õ¿®³ä¹þ¤ßÍ­¸ú²½(¼õ¿®³«»Ï) */
151     break;
152
153   case CONSDRV_CMD_WRITE: /* ¥³¥ó¥½¡¼¥ë¤Ø¤Îʸ»úÎó½ÐÎÏ */
154     /*
155      * send_string()¤Ç¤ÏÁ÷¿®¥Ð¥Ã¥Õ¥¡¤òÁàºî¤·¤Æ¤ª¤êºÆÆþÉԲĤʤΤǡ¤
156      * ÇÓ¾¤Î¤¿¤á¤Ë³ä¹þ¤ß¶Ø»ß¤Ë¤·¤Æ¸Æ¤Ó½Ð¤¹¡¥
157      */
158     INTR_DISABLE;
159     send_string(cons, command + 1, size - 1); /* Ê¸»úÎó¤ÎÁ÷¿® */
160     INTR_ENABLE;
161     break;
162
163   default:
164     break;
165   }
166
167   return 0;
168 }
169
170 int consdrv_main(int argc, char *argv[])
171 {
172   int size, index;
173   kz_thread_id_t id;
174   char *p;
175
176   consdrv_init();
177   kz_setintr(SOFTVEC_TYPE_SERINTR, consdrv_intr); /* ³ä¹þ¤ß¥Ï¥ó¥É¥éÀßÄê */
178
179   while (1) {
180     id = kz_recv(MSGBOX_ID_CONSOUTPUT, &size, &p);
181     index = p[0] - '0';
182     consdrv_command(&consreg[index], id, index, size - 1, p + 1);
183     kz_kmfree(p);
184   }
185
186   return 0;
187 }