source: azure_iot_hub_f767zi/trunk/asp_baseplatform/lwip/contrib-2.1.0/ports/toppers/sys_arch.c@ 457

Last change on this file since 457 was 457, 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: 12.6 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) 2003-2015 by Ryosuke Takeuchi
7 * GJ Business Division RICOH COMPANY,LTD. JAPAN
8 * Copyright (C) 2017-2019 by TOPPERS PROJECT Educational Working Group.
9 *
10 * 上記著作権者は,Free Software Foundation によって公表されている
11 * GNU General Public License の Version 2 に記述されている条件か,以
12 * 下の(1)~(4)の条件を満たす場合に限り,本ソフトウェア(本ソフトウェ
13 * アを改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
14 * 利用と呼ぶ)することを無償で許諾する.
15 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
16 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
17 * スコード中に含まれていること.
18 * (2) 本ソフトウェアを再利用可能なバイナリコード(リロケータブルオブ
19 * ジェクトファイルやライブラリなど)の形で利用する場合には,利用
20 * に伴うドキュメント(利用者マニュアルなど)に,上記の著作権表示,
21 * この利用条件および下記の無保証規定を掲載すること.
22 * (3) 本ソフトウェアを再利用不可能なバイナリコードの形または機器に組
23 * み込んだ形で利用する場合には,次のいずれかの条件を満たすこと.
24 * (a) 利用に伴うドキュメント(利用者マニュアルなど)に,上記の著作
25 * 権表示,この利用条件および下記の無保証規定を掲載すること.
26 * (b) 利用の形態を,別に定める方法によって,上記著作権者に報告する
27 * こと.
28 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
29 * 害からも,上記著作権者を免責すること.
30 *
31 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者は,
32 * 本ソフトウェアに関して,その適用可能性も含めて,いかなる保証も行わ
33 * ない.また,本ソフトウェアの利用により直接的または間接的に生じたい
34 * かなる損害に関しても,その責任を負わない.
35 *
36 * @(#) $Id$
37 */
38/*
39 * lwipシステム関数
40 */
41#include "kernel_impl.h"
42#include <t_syslog.h>
43#include <t_stdlib.h>
44#include <sil.h>
45#include <string.h>
46#include <target_syssvc.h>
47#include "kernel_cfg.h"
48#include "device.h"
49#include "lwip.h"
50
51#include "lwip/opt.h"
52#include "lwip/err.h"
53#include "lwip/sys.h"
54#include "arch/sys_arch.h"
55
56/*
57 * サービスコールのエラーのログ出力
58 */
59Inline void
60svc_perror(const char *file, int_t line, const char *expr, ER ercd)
61{
62 if (ercd < 0) {
63 t_perror(LOG_ERROR, file, line, expr, ercd);
64 }
65}
66
67#define SVC_PERROR(expr) svc_perror(__FILE__, __LINE__, #expr, (expr))
68
69#define NUM_LWIP_TASK (LWIP_TASK_N - LWIP_TASK_1 + 1)
70#define NUM_LOCK (LWIP_LOCK_N - LWIP_LOCK_1 + 1)
71#define NUM_SEM0 (LWIP0_SEM_N - LWIP0_SEM_1 + 1)
72
73Inline void
74svc_perror2(const char *file, int_t line, const char *expr, ER ercd)
75{
76 if (ercd != E_OK && ercd != E_QOVR) {
77 t_perror(LOG_ERROR, file, line, expr, ercd);
78 }
79}
80
81#define SVC_PERROR2(expr) svc_perror2(__FILE__, __LINE__, #expr, (expr))
82
83struct sys_thread {
84 const char *name;
85 void (*func)(struct sys_thread *); /* エラーコールバック関数 */
86 ID threadno;
87 void *arg;
88 ID pri;
89};
90
91struct sys_sem {
92 bool_t act;
93 int count;
94 ID semid;
95};
96
97#define SYS_MBOX_SIZE 128
98
99struct sys_mbox {
100 int first, last;
101 void *msgs[SYS_MBOX_SIZE];
102 struct sys_sem *not_empty;
103 struct sys_sem *not_full;
104 struct sys_sem *mutex;
105 int wait_send;
106};
107
108static int use_task_num, lwip_count;
109static struct sys_thread *lwip_thread;
110static struct sys_thread Sys_Thread[NUM_LWIP_TASK];
111static struct sys_sem Sys_Lock[NUM_LOCK];
112static struct sys_sem Sys_Sem0[NUM_SEM0];
113
114static struct sys_thread *
115search_thread(void)
116{
117 struct sys_thread *pthread = &Sys_Thread[0];
118 ID tid = 0;
119 int i;
120
121 get_tid(&tid);
122 for(i = 0 ; i < NUM_LWIP_TASK ; i++, pthread++){
123 if(pthread->threadno == tid)
124 return pthread;
125 }
126 return NULL;
127}
128
129void abort(void)
130{
131 struct sys_thread *pthread = search_thread();
132 syslog_2(LOG_ERROR, "abort [%s] thread(%d) !", pthread->name, pthread->threadno);
133 slp_tsk();
134}
135
136void
137sys_msleep(u32_t ms)
138{
139 dly_tsk(ms);
140}
141
142void
143sys_memcpy(volatile void *d, const volatile void *s, int len)
144{
145 volatile char *src = (volatile char *)s;
146 volatile char *dst = d;
147
148 while(len > 0){
149 *dst++ = *src++;
150 len--;
151 }
152}
153
154void
155sys_memset(volatile void *d, unsigned char val, int len)
156{
157 volatile char *dst = d;
158
159 while(len > 0){
160 *dst++ = val;
161 len--;
162 }
163}
164
165u32_t
166sys_now(void)
167{
168#ifdef TOPPERS_SUPPORT_GET_UTM
169 SYSUTM utime;
170 SVC_PERROR(get_utm(&utime));
171 return utime / 1000;
172#else /* TOPPERS_SUPPORT_GET_UTM */
173 SYSTIM stime;
174 SVC_PERROR(get_tim(&stime));
175 return stime;
176#endif /* TOPPERS_SUPPORT_GET_UTM */
177}
178
179u32_t
180sys_jiffies(void)
181{
182#ifdef TOPPERS_SUPPORT_GET_UTM
183 SYSUTM utime;
184 SVC_PERROR(get_utm(&utime));
185 return utime * 1000;
186#else /* TOPPERS_SUPPORT_GET_UTM */
187 SYSTIM stime;
188 SVC_PERROR(get_tim(&stime));
189 return stime * 1000000;
190#endif /* TOPPERS_SUPPORT_GET_UTM */
191}
192
193void
194sys_init(void)
195{
196 static bool_t init = false;
197 int i;
198
199 if(!init){
200 use_task_num = 0;
201 lwip_count = 0;
202 lwip_thread = NULL;
203 for(i = 0 ; i < NUM_LWIP_TASK ; i++){
204 Sys_Thread[i].threadno = LWIP_TASK_1+i;
205 }
206 for(i = 0 ; i < NUM_LOCK ; i++){
207 Sys_Lock[i].semid = LWIP_LOCK_1+i;
208 Sys_Lock[i].act = false;
209 }
210 for(i = 0 ; i < NUM_SEM0 ; i++){
211 Sys_Sem0[i].semid = LWIP0_SEM_1+i;
212 Sys_Sem0[i].act = false;
213 }
214 init = true;
215 }
216}
217
218
219void
220lwip_task(intptr_t exinf)
221{
222 struct sys_thread *pthread = &Sys_Thread[(int)exinf];
223 ID tid;
224 get_tid(&tid);
225 syslog_4(LOG_NOTICE, "lwip_task:start lwip task(%d:%d)[%s] pri(%d) !", (int)exinf, tid, pthread->name, pthread->pri);
226 if(pthread->pri >= 128){
227 SVC_PERROR(chg_pri(pthread->threadno, LWIP_DEFAULT_PRIORITY+5));
228 dly_tsk(100);
229 }
230 pthread->func(pthread->arg);
231}
232
233sys_thread_t
234sys_thread_new(const char *name, lwip_thread_fn function, void *arg, int stacksize, int prio)
235{
236 struct sys_thread *pthread;
237 if(use_task_num >= NUM_LWIP_TASK){
238 syslog_1(LOG_ERROR, "sys_thread_new over task count(%d) !", use_task_num);
239 slp_tsk();
240 }
241 wai_sem(LWIP_THREAD);
242 pthread = &Sys_Thread[use_task_num++];
243 pthread->name = name;
244 pthread->pri = prio;
245 pthread->arg = arg;
246 pthread->func = (void (*)(struct sys_thread *))function;
247 SVC_PERROR(act_tsk(pthread->threadno));
248 sig_sem(LWIP_THREAD);
249 return pthread;
250}
251
252err_t
253sys_mbox_new(struct sys_mbox **mb, int size)
254{
255 struct sys_mbox *mbox;
256 err_t err;
257
258 mbox = (struct sys_mbox *)malloc(sizeof(struct sys_mbox));
259 if(mbox == NULL){
260 syslog_0(LOG_ERROR, "## sys_mbox_new mem error 1 ##");
261 return ERR_MEM;
262 }
263
264 mbox->first = mbox->last = 0;
265 mbox->wait_send = 0;
266 err = sys_sem_new(&mbox->not_empty, 0);
267 if(err != E_OK){
268 syslog_0(LOG_ERROR, "## sys_mbox_new sem error 1 ##");
269 free(mbox);
270 return err;
271 }
272 err = sys_sem_new(&mbox->not_full, 0);
273 if(err != E_OK){
274 syslog_0(LOG_ERROR, "## sys_mbox_new sem error 2 ##");
275 free(mbox);
276 return err;
277 }
278 err = sys_sem_new(&mbox->mutex, 1);
279 if(err != E_OK){
280 syslog_0(LOG_ERROR, "## sys_mbox_new sem error 3 ##");
281 free(mbox);
282 return err;
283 }
284
285 *mb = mbox;
286 return ERR_OK;
287}
288
289void
290sys_mbox_free(struct sys_mbox **mb)
291{
292 if ((mb != NULL) && (*mb != SYS_MBOX_NULL)) {
293 struct sys_mbox *mbox = *mb;
294// SYS_STATS_DEC(mbox.used);
295 sys_mutex_lock(&mbox->mutex);
296 sys_sem_free(&mbox->not_empty);
297 sys_sem_free(&mbox->not_full);
298 sys_mutex_unlock(&mbox->mutex);
299 sys_sem_free(&mbox->mutex);
300 mbox->not_empty = mbox->not_full = mbox->mutex = NULL;
301 free(mbox);
302 }
303}
304
305err_t
306sys_mbox_trypost(struct sys_mbox **mb, void *msg)
307{
308 u8_t first;
309 struct sys_mbox *mbox;
310
311 LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
312 mbox = *mb;
313
314 sys_arch_sem_wait(&mbox->mutex, 0);
315
316 if((mbox->last + 1) >= (mbox->first + SYS_MBOX_SIZE)) {
317 sys_sem_signal(&mbox->mutex);
318 return ERR_MEM;
319 }
320
321 mbox->msgs[mbox->last % SYS_MBOX_SIZE] = msg;
322
323 if(mbox->last == mbox->first)
324 first = 1;
325 else
326 first = 0;
327
328 mbox->last++;
329
330 if(first)
331 sys_sem_signal(&mbox->not_empty);
332 sys_sem_signal(&mbox->mutex);
333
334 return ERR_OK;
335}
336
337err_t
338sys_mbox_trypost_fromisr(sys_mbox_t *q, void *msg)
339{
340 return sys_mbox_trypost(q, msg);
341}
342
343void
344sys_mbox_post(struct sys_mbox **mb, void *msg)
345{
346 u8_t first;
347 struct sys_mbox *mbox;
348 LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
349 mbox = *mb;
350
351 sys_arch_sem_wait(&mbox->mutex, 0);
352
353 syslog_2(LOG_NOTICE, "## sys_mbox_post mbox[%08x] msg[%08x] ##", mbox, msg);
354
355 while ((mbox->last + 1) >= (mbox->first + SYS_MBOX_SIZE)) {
356 mbox->wait_send++;
357 sys_sem_signal(&mbox->mutex);
358 sys_arch_sem_wait(&mbox->not_full, 0);
359 sys_arch_sem_wait(&mbox->mutex, 0);
360 mbox->wait_send--;
361 }
362
363 mbox->msgs[mbox->last % SYS_MBOX_SIZE] = msg;
364
365 if(mbox->last == mbox->first)
366 first = 1;
367 else
368 first = 0;
369
370 mbox->last++;
371
372 if(first)
373 sys_sem_signal(&mbox->not_empty);
374
375 sys_sem_signal(&mbox->mutex);
376}
377
378u32_t
379sys_arch_mbox_fetch(struct sys_mbox **mb, void **msg, u32_t timeout)
380{
381 u32_t time_needed = 0;
382 struct sys_mbox *mbox;
383
384 if(mb == NULL && *mb == NULL){
385 ID tid;
386 get_tid(&tid);
387 syslog_1(LOG_ERROR, "sys_arch_mbox_fetch mail box error task(%d) !", tid);
388 slp_tsk();
389 }
390 mbox = *mb;
391
392 /* The mutex lock is quick so we don't bother with the timeout
393 stuff here. */
394 sys_arch_sem_wait(&mbox->mutex, 0);
395
396 while (mbox->first == mbox->last) {
397 sys_sem_signal(&mbox->mutex);
398
399 /* We block while waiting for a mail to arrive in the mailbox. We
400 must be prepared to timeout. */
401 if(timeout != 0) {
402 time_needed = sys_arch_sem_wait(&mbox->not_empty, timeout);
403 if (time_needed == SYS_ARCH_TIMEOUT) {
404 return SYS_ARCH_TIMEOUT;
405 }
406 }
407 else{
408 sys_arch_sem_wait(&mbox->not_empty, 0);
409 }
410 sys_arch_sem_wait(&mbox->mutex, 0);
411 }
412
413 if (msg != NULL)
414 *msg = mbox->msgs[mbox->first % SYS_MBOX_SIZE];
415 else
416 syslog_1(LOG_NOTICE, "sys_mbox_fetch: mbox %8x, null msg", (void *)mbox);
417
418 mbox->first++;
419
420 if (mbox->wait_send) {
421 sys_sem_signal(&mbox->not_full);
422 }
423
424 sys_sem_signal(&mbox->mutex);
425
426 return time_needed;
427}
428
429u32_t
430sys_arch_mbox_tryfetch(struct sys_mbox **mb, void **msg)
431{
432 struct sys_mbox *mbox;
433 LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
434 mbox = *mb;
435
436 sys_arch_sem_wait(&mbox->mutex, 0);
437
438 if(mbox->first == mbox->last){
439 sys_sem_signal(&mbox->mutex);
440 return SYS_MBOX_EMPTY;
441 }
442
443 if(msg != NULL)
444 *msg = mbox->msgs[mbox->first % SYS_MBOX_SIZE];
445 else
446 syslog_1(LOG_NOTICE, "sys_mbox_tryfetch: mbox %08x, null msg", (void *)mbox);
447
448 mbox->first++;
449
450 if (mbox->wait_send) {
451 sys_sem_signal(&mbox->not_full);
452 }
453
454 sys_sem_signal(&mbox->mutex);
455 return 0;
456}
457
458err_t
459sys_sem_new(struct sys_sem **sem, u8_t count)
460{
461 struct sys_sem *psem = NULL;
462 int num = 0, i;
463
464 if(count == 0){
465 psem = &Sys_Sem0[0];
466 num = NUM_SEM0;
467 }
468 else if(count == 1){
469 psem = &Sys_Lock[0];
470 num = NUM_LOCK;
471 }
472 else{
473 syslog_1(LOG_ERROR, "sys_sem_new no request count(%d) !", count);
474 slp_tsk();
475 }
476 for(i = 0 ; i < num ; i++, psem++){
477 if(!psem->act){
478 psem->count = count;
479 psem->act = true;
480 *sem = psem;
481 return ERR_OK;
482 }
483 }
484 return ERR_MEM;
485}
486
487u32_t
488sys_arch_sem_wait(struct sys_sem **s, u32_t timeout)
489{
490 struct sys_sem *psem = *s;
491 ER ercd;
492
493 if(timeout == 0)
494 ercd = wai_sem(psem->semid);
495 else
496 ercd = twai_sem(psem->semid, timeout);
497 if(ercd == E_TMOUT)
498 return SYS_ARCH_TIMEOUT;
499 else if(ercd == E_OK)
500 return 0;
501 else{
502 syslog_1(LOG_ERROR, "sys_arch_sem_wait error (%d) !", ercd);
503 slp_tsk();
504 }
505 return 0;
506}
507
508void
509sys_sem_signal(struct sys_sem **s)
510{
511 struct sys_sem *psem = *s;
512 SVC_PERROR2(sig_sem(psem->semid));
513}
514
515void
516sys_sem_free(struct sys_sem **sem)
517{
518 struct sys_sem *psem = *sem;
519 psem->act = false;
520}
521
522sys_prot_t
523sys_arch_protect(void)
524{
525 struct sys_thread *pthread = search_thread();
526
527 if(lwip_thread != pthread){
528 wai_sem(LWIP_PROTECT);
529 lwip_thread = pthread;
530 lwip_count = 1;
531 }
532 else
533 lwip_count++;
534 return (sys_prot_t)pthread;
535}
536
537void
538sys_arch_unprotect(sys_prot_t pval)
539{
540 struct sys_thread *pthread = (struct sys_thread *)pval;
541
542 if(lwip_thread == pthread){
543 if(--lwip_count == 0){
544 lwip_thread = NULL;
545 sig_sem(LWIP_PROTECT);
546 }
547 }
548}
549
550#if PPP_SUPPORT == 0
551sio_fd_t sio_open(u8_t devnum)
552{
553 return 0;
554}
555
556void sio_send( u8_t c, sio_status_t * siostat )
557{
558}
559
560u32_t sio_read(sio_status_t * siostat, u8_t *buf, u32_t size)
561{
562 return 0;
563}
564
565#endif
566
Note: See TracBrowser for help on using the repository browser.