source: azure_iot_hub_riscv/trunk/asp_baseplatform/files/stdio.c@ 453

Last change on this file since 453 was 453, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 10.2 KB
Line 
1/*
2 * TOPPERS/ASP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
5 *
6 * Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
7 * Graduate School of Information Science, Nagoya Univ., JAPAN
8 * Copyright (C) 2015-2016 by TOPPERS PROJECT Educational Working Group.
9 *
10 * 上記著作権者は,以下の (1)~(4) の条件か,Free Software Foundation
11 * によって公表されている GNU General Public License の Version 2 に記
12 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
13 * を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
14 * 利用と呼ぶ)することを無償で許諾する.
15 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
16 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
17 * スコード中に含まれていること.
18 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
19 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
20 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
21 * の無保証規定を掲載すること.
22 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
23 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
24 * と.
25 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
26 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
27 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
28 * 報告すること.
29 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
30 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
31 *
32 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
33 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
34 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
35 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
36 *
37 * @(#) $Id$
38 */
39/*
40 * このプログラムはITRON専用のTYPE3ソフトウェアである。
41 * POSIXのファイル関数を供給する。
42 * 擬似的なストレージ関数郡であり、標準ライブラリィと分けての使用が望ましい。
43 * 1. _stdfile_init ファイルインデックスの初期化を行う
44 * 2. open ファイルのオープン(特別な専用FDを発行する)
45 * 3. close ファイルのクローズ
46 * 4. fstat ファイルのステートの取り出し
47 * 5. fseek ファイルのシーク
48 * 6. read ファイルからのデータ読み出し
49 * 7. write ファイルからのデータ書き込み
50 * 8. mmap ファイルデータのマップ化
51 * 9. munmap ファイルデータのアンマップ化
52 */
53
54#include <kernel.h>
55#include <stdio.h>
56#include <stdlib.h>
57#include "kernel_cfg.h"
58#include "fcntl.h"
59#include "storagedevice.h"
60
61#ifndef NUM_FILEIDX
62#define NUM_FILEIDX 128
63#endif
64
65
66static struct StdFileIndex stdfile[NUM_FILEIDX];
67
68
69void stdfile_init(intptr_t exinf)
70{
71 unsigned int idx;
72
73 for(idx = 0 ; idx < NUM_FILEIDX ; idx++){
74 stdfile[idx].sdmdev = 0;
75 stdfile[idx].sdmfd = -1;
76 }
77}
78
79/*
80 * FDチェック関数
81 */
82static struct StdFileIndex *fdcheck(int fd)
83{
84 struct StdFileIndex *pf;
85
86 if(fd <= 0 || fd > NUM_FILEIDX)
87 return 0;
88 pf = &stdfile[fd-1];
89 if(pf->sdmfd == -1)
90 return 0;
91 else
92 return pf;
93}
94
95/*
96 * 標準ファイルインターフェイス関数(open)
97 */
98int _open(const char *pathname, int flags)
99{
100 StorageDevice_t *psdev;
101 StorageDeviceFileFunc_t *pff;
102 int devno, id, no;
103
104 if((devno = SDMGetDeviceNo(&pathname)) < 0)
105 return -1;
106 if((psdev = SDMGetStorageDevice(devno)) == 0)
107 return -1;
108 pff = psdev->pdevff;
109 if(pff != 0 && pff->_sdevff_open == 0)
110 return -1;
111
112 wai_sem(SEM_STDFILE);
113 for(no = 0 ; no < NUM_FILEIDX ; no++){
114 if(stdfile[no].sdmfd == -1)
115 break;
116 }
117 if(no >= NUM_FILEIDX){
118 sig_sem(SEM_STDFILE);
119 return -1;
120 }
121
122 id = pff->_sdevff_open(devno, pathname, flags);
123 if(id < 0){
124 sig_sem(SEM_STDFILE);
125 return id;
126 }
127 stdfile[no].sdmfd = id;
128 stdfile[no].sdmdev = psdev;
129 sig_sem(SEM_STDFILE);
130 return no+1;
131}
132
133/*
134 * 標準ファイルインターフェイス関数(close)
135 */
136int _close(int fd)
137{
138 struct StdFileIndex *ps;
139 StorageDevice_t *psdev;
140 int result;
141
142 if((ps = fdcheck(fd)) == 0)
143 return -1;
144 wai_sem(SEM_STDFILE);
145 psdev = ps->sdmdev;
146 if(psdev->pdevff != 0 && psdev->pdevff->_sdevff_close != 0)
147 result = psdev->pdevff->_sdevff_close(ps->sdmfd);
148 else
149 result = -1;
150 ps->sdmfd = -1;
151 sig_sem(SEM_STDFILE);
152 return result;
153}
154
155/*
156 * 標準ファイルインターフェイス関数(fstat)
157 */
158int _fstat(int fd, struct stat *buf)
159{
160 struct StdFileIndex *ps;
161 StorageDevice_t *psdev;
162
163 if((ps = fdcheck(fd)) == 0)
164 return -1;
165 psdev = ps->sdmdev;
166 if(psdev->pdevff != 0 && psdev->pdevff->_sdevff_fstat != 0)
167 return psdev->pdevff->_sdevff_fstat(ps->sdmfd, buf);
168 else
169 return -1;
170}
171
172/*
173 * 標準ファイルインターフェイス関数(lseek)
174 */
175off_t _lseek(int fd, off_t offset, int whence)
176{
177 struct StdFileIndex *ps;
178 StorageDevice_t *psdev;
179 int result;
180
181 if((ps = fdcheck(fd)) == 0)
182 return -1;
183 psdev = ps->sdmdev;
184 if(psdev->pdevff != 0 && psdev->pdevff->_sdevff_lseek != 0)
185 return psdev->pdevff->_sdevff_lseek(ps->sdmfd, offset, whence, &result);
186 else
187 return -1;
188}
189
190/*
191 * 標準ファイルインターフェイス関数(read)
192 */
193long _read(int fd, void *buf, long count)
194{
195 struct StdFileIndex *ps;
196 StorageDevice_t *psdev;
197 int result;
198
199 if((ps = fdcheck(fd)) == 0)
200 return -1;
201 psdev = ps->sdmdev;
202 if(psdev->pdevff != 0 && psdev->pdevff->_sdevff_read != 0)
203 return psdev->pdevff->_sdevff_read(ps->sdmfd, buf, count, &result);
204 else
205 return 0;
206}
207
208/*
209 * 標準ファイルインターフェイス関数(write)
210 */
211long _write(int fd, const void *buf, long count)
212{
213 struct StdFileIndex *ps;
214 StorageDevice_t *psdev;
215 int result;
216
217 if((ps = fdcheck(fd)) == 0)
218 return -1;
219 psdev = ps->sdmdev;
220 if(psdev->pdevff != 0 && psdev->pdevff->_sdevff_write != 0)
221 return psdev->pdevff->_sdevff_write(ps->sdmfd, buf, count, &result);
222 else
223 return 0;
224}
225
226int _isatty(int fd)
227{
228 return 1;
229}
230
231/*
232 * ファイルマップ関数(mmap)
233 */
234void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
235{
236 struct StdFileIndex *ps;
237 StorageDevice_t *psdev;
238
239 if((ps = fdcheck(fd)) == 0)
240 return (void*)-1;
241 psdev = ps->sdmdev;
242 if(psdev->pdevff != 0 && psdev->pdevff->_sdevff_mmap != 0)
243 return psdev->pdevff->_sdevff_mmap(start, length, prot, flags, ps->sdmfd, offset);
244 else
245 return (void*)-1;
246}
247
248/*
249 * ファイルアンマップ関数(未処理)
250 */
251int munmap(void *start, size_t length)
252{
253 return 0;
254}
255
256/*
257 * 標入出力用1文字入力文
258 */
259static int local_getc(void *st)
260{
261 StorageDevice_t *psdev;
262 int result, res = 0;
263 char buf[2];
264
265 if(st == 0 && ((FILE *)st)->_file < 0)
266 return -1;
267 if((psdev = (StorageDevice_t *)((FILE*)st)->_dev) == 0)
268 return -1;
269 if(psdev->pdevff != 0 && psdev->pdevff->_sdevff_read != 0){
270 result = psdev->pdevff->_sdevff_read(((FILE *)st)->_file, buf, 1, &res);
271 if(res < 0)
272 ((FILE *)st)->_flags |= __SERR;
273 if(result == 1)
274 return buf[0];
275 else
276 return -1;
277 }
278 else
279 return -1;
280}
281
282/*
283 * 標入出力用1文字入力文
284 */
285static int local_gets(void *st, unsigned int len, char *s)
286{
287 StorageDevice_t *psdev;
288 int result, res = 0;
289
290 if(st == 0 && ((FILE *)st)->_file < 0)
291 return -1;
292 if((psdev = (StorageDevice_t *)((FILE*)st)->_dev) == 0)
293 return -1;
294 if(psdev->pdevff != 0 && psdev->pdevff->_sdevff_read != 0){
295 result = psdev->pdevff->_sdevff_read(((FILE *)st)->_file, s, len, &res);
296 if(res < 0)
297 ((FILE *)st)->_flags |= __SERR;
298 return result;
299 }
300 else
301 return 0;
302}
303
304/*
305 * 標入出力用文字出力文
306 */
307static void local_putc(void *st, int c)
308{
309 StorageDevice_t *psdev;
310 int res = 0;
311 char buf[2];
312
313 if(st == 0 && ((FILE *)st)->_file < 0)
314 return;
315 if((psdev = (StorageDevice_t *)((FILE*)st)->_dev) == 0)
316 return;
317 buf[0] = c;
318 if(psdev->pdevff != 0 && psdev->pdevff->_sdevff_write != 0){
319 psdev->pdevff->_sdevff_write(((FILE *)st)->_file, buf, 1, &res);
320 if(res < 0)
321 ((FILE *)st)->_flags |= __SERR;
322 }
323}
324
325/*
326 * 標入出力用文字列出力文
327 */
328static int local_puts(void *st, unsigned int len, char *s)
329{
330 StorageDevice_t *psdev;
331 int result, res = 0;
332
333 if(st == 0 && ((FILE *)st)->_file < 0)
334 return -1;
335 if((psdev = (StorageDevice_t *)((FILE*)st)->_dev) == 0)
336 return -1;
337 if(psdev->pdevff != 0 && psdev->pdevff->_sdevff_write != 0){
338 result = psdev->pdevff->_sdevff_write(((FILE *)st)->_file, s, len, &res);
339 if(res < 0)
340 ((FILE *)st)->_flags |= __SERR;
341 return result;
342 }
343 else
344 return 0;
345}
346
347/*
348 * 標入出力用データフラッシュ文
349 */
350static int local_flush(FILE *st)
351{
352 return 0;
353}
354
355/*
356 * 通常ファイルの設定
357 */
358int _setup_file(FILE *st, StorageDevice_t *pd, int lid)
359{
360 if(st == NULL)
361 return 0;
362 st->_file = lid;
363 st->_func_in = local_getc;
364 st->_func_ins = local_gets;
365 st->_func_out = local_putc;
366 st->_func_outs = local_puts;
367 st->_func_flush = local_flush;
368 st->_dev = pd;
369 return 1;
370}
371
372/*
373 * 標準入出力ファイルの設定
374 */
375int _setupstd_file(FILE *st, int fd)
376{
377 struct StdFileIndex *ps;
378
379 if(st == NULL)
380 return 0;
381
382 st->_func_in = local_getc;
383 st->_func_ins = local_gets;
384 st->_func_out = local_putc;
385 st->_func_outs = local_puts;
386 st->_func_flush = local_flush;
387
388 if((ps = fdcheck(fd)) == 0){
389 st->_file = -1;
390 st->_dev = 0;
391 return 0;
392 }
393 else{
394 st->_file = ps->sdmfd;
395 st->_dev = ps->sdmdev;
396 return 1;
397 }
398}
399
Note: See TracBrowser for help on using the repository browser.