📄 sys_arch.c
字号:
{
/* empty the mailbox */
for(;;)
{
l = posListGet(&fmb->m.listhead, POSLIST_HEAD, 0);
if (l == NULL)
break;
m = POSLIST_ELEMENT(l, struct mail, list);
if (m->l.payload == NULL)
{
LWIP_DEBUGF(SYS_DBLVL, ("sys_arch.c: sys_mbox_free: "
"mailbox not empty!\n" ));
}
else
{
LWIP_DEBUGF(SYS_DBLVL, ("sys_arch.c: sys_mbox_free: "
"mailbox not empty, memory leaks!\n" ));
}
SCHED_LOCK();
cur_used_mails_g--;
#ifdef SYSDEBUG
m->mbox = NULL;
#endif
m->l.next = unused_mail_list_g;
unused_mail_list_g = m;
SCHED_UNLOCK();
}
/* cleanup and free the memory */
posListTerm(&fmb->m.listhead);
#if SYS_TCPIPMBOXFIX
if ((struct sys_mbox*) p_tcpipmbox_g == mbox)
{
posListTerm(&p_tcpipmbox_g->highPrioList);
SCHED_LOCK();
p_tcpipmbox_g = NULL;
}
else
#endif
{
SCHED_LOCK();
#ifdef SYSDEBUG
fmb->task = NULL;
fmb->magic = 0;
#endif
fmb->m.next = unused_mbox_list_g;
unused_mbox_list_g = fmb;
#ifdef SYSDEBUG
cur_used_mboxes_g--;
#endif
}
#if SYS_STATS
lwip_stats.sys.mbox.used--;
#endif /* SYS_STATS */
SCHED_UNLOCK();
}
}
/*-----------------------------------------------------------------------------------*/
void
sys_mbox_post(struct sys_mbox *mbox, void *msg)
{
static INT_t maxloops = 4;
INT_t loops;
struct mail *m;
if (mbox != NULL)
{
#ifdef SYSDEBUG
if (mbox->magic != MMAGIC)
{
SCHED_LOCK();
printf("sys_mbox_post: wrong magic number!\n");
for(;;);
}
if (mbox->task == NULL)
{
printf("sys_mbox_post: illegal mailbox!\n");
SCHED_LOCK();
for(;;);
}
#endif
/* allocate a new mail structure */
loops = 0;
for(;;)
{
SCHED_LOCK();
if ((cur_used_mails_g < MAIL_THRESHOLD) || (loops >= maxloops))
{
m = unused_mail_list_g;
if (m != NULL)
{
unused_mail_list_g = m->l.next;
}
else
if (max_used_mails_g < SYS_MAX_MAIL)
{
m = &mail_memory_g[max_used_mails_g];
max_used_mails_g++;
}
if (m != NULL)
{
cur_used_mails_g++;
SCHED_UNLOCK();
break;
}
}
mail_waiting_g++;
SCHED_UNLOCK();
#ifdef SYSDEBUG
printf("sys_mbox_post: waiting(%i)\n", mail_waiting_g);
#endif
if (sys_sem_wait_timeout(mail_sem_g,(loops>=maxloops)?1000:1000/HZ)==0)
{
LWIP_ASSERT("WARNING: sys_arch.c: out of message memory, "
"please increase SYS_MSG_MAX\n", loops < maxloops);
SCHED_LOCK();
if (mail_waiting_g > 0)
mail_waiting_g--;
SCHED_UNLOCK();
}
loops++;
}
/* post the mail */
#ifdef SYSDEBUG
m->mbox = mbox;
#endif
m->l.payload = msg;
#if SYS_TCPIPMBOXFIX
if (((struct sys_mbox*) p_tcpipmbox_g == mbox) &&
(((struct tcpip_msg*)msg)->type != TCPIP_MSG_INPUT))
{
SCHED_LOCK();
posListAdd(&p_tcpipmbox_g->highPrioList, POSLIST_TAIL, &m->list2);
posListAdd(&mbox->m.listhead, POSLIST_TAIL, &m->list);
SCHED_UNLOCK();
}
else
#endif
posListAdd(&mbox->m.listhead, POSLIST_TAIL, &m->list);
}
}
/*-----------------------------------------------------------------------------------*/
u32_t
sys_arch_mbox_fetch(struct sys_mbox *mbox, void **msg, u32_t timeout)
{
struct mail *m;
POSLIST_t *l;
#if SYS_TCPIPMBOXFIX
POSLIST_t *l2;
#endif
JIF_t start, stop;
u32_t w;
if (mbox == NULL)
return SYS_ARCH_TIMEOUT;
/* sample start time */
start = jiffies;
/* wait for mail */
l = posListGet(&mbox->m.listhead, POSLIST_HEAD,
(timeout == 0) ? INFINITE : (UINT_t) MS(timeout) );
#if SYS_TCPIPMBOXFIX
if ((struct sys_mbox*) p_tcpipmbox_g == mbox)
{
l2 = posListGet(&p_tcpipmbox_g->highPrioList, POSLIST_HEAD, 0);
if (l2 != NULL)
{
m = POSLIST_ELEMENT(l2, struct mail, list2);
if (&m->list != l)
{
posListAdd(&mbox->m.listhead, POSLIST_HEAD, l);
l = &m->list;
posListRemove(l);
}
}
}
#endif
if (l == NULL)
{
LWIP_ASSERT("WARNING: sys_arch.c: out of pico]OS semaphores(2), "
"please increase POSCFG_MAX_EVENTS\n", start != jiffies);
mbox->lasttime = start + (timeout / HZ);
return SYS_ARCH_TIMEOUT;
}
/* get the mail payload */
m = POSLIST_ELEMENT(l, struct mail, list);
if (msg != NULL)
*msg = m->l.payload;
/* free the mail memory */
SCHED_LOCK();
cur_used_mails_g--;
#ifdef SYSDEBUG
m->mbox = NULL;
#endif
m->l.next = unused_mail_list_g;
unused_mail_list_g = m;
if (mail_waiting_g > 0)
{
mail_waiting_g--;
SCHED_UNLOCK();
sys_sem_signal(mail_sem_g);
}
else
{
SCHED_UNLOCK();
}
/* calculate the waited time */
if (!POS_TIMEAFTER(start, mbox->lasttime+2))
start = mbox->lasttime;
stop = jiffies;
mbox->lasttime = stop;
w = (u32_t) (stop - start) * 1000;
w = w / HZ;
return (w < timeout) ? w : timeout;
}
/*-----------------------------------------------------------------------------------*/
sys_thread_t
sys_thread_new(void (*function)(void *arg), void *arg, int prio)
{
POSTASK_t th;
if ((prio < 0) || (prio >= POSCFG_MAX_PRIO_LEVEL))
prio = DEFAULT_THREAD_PRIO;
do
{
#if POSCFG_ENABLE_NANO
th = (POSTASK_t) nosTaskCreate((POSTASKFUNC_t) function, arg,
(VAR_t)prio, 0, LWIPNAME "-*");
#else
#if POSCFG_TASKSTACKTYPE == 0
MEMPTR_t stk;
th = NULL;
SCHED_LOCK();
if (no_of_tasks_g < SYS_THREAD_MAX)
{
stk = (MEMPTR_t)
&stackmem_g[ no_of_tasks_g * (SYS_STACK_SIZE / sizeof(UVAR_t)) ];
#if SYS_STACK_GROWUP == 0
stk += SYS_STACK_SIZE - sizeof(UVAR_t);
#endif
th = posTaskCreate((POSTASKFUNC_t) function, arg, prio, (void*)stk);
if (th != NULL) no_of_tasks_g++;
}
SCHED_UNLOCK();
#elif POSCFG_TASKSTACKTYPE == 1
th = posTaskCreate((POSTASKFUNC_t) function, arg,
(VAR_t) prio, SYS_STACK_SIZE);
#elif POSCFG_TASKSTACKTYPE == 2
th = posTaskCreate((POSTASKFUNC_t) function, arg, prio);
#endif /* POSCFG_TASKSTACKTYPE == 2 */
POS_SETTASKNAME(th, LWIPNAME);
#endif /* !have nano layer */
}
while ((th == NULL) && (++prio < POSCFG_MAX_PRIO_LEVEL));
if (th == NULL)
{
LWIP_DEBUGF(SYS_DBLVL, ("sys_thread_new: pico]OS task create failed, "
"function = %p, prio = %i\n", (void*)function, prio) );
return NULL;
}
return (sys_thread_t) th;
}
/*-----------------------------------------------------------------------------------*/
struct sys_timeouts *
sys_arch_timeouts(void)
{
#if POSCFG_ENABLE_NANO
return (struct sys_timeouts *) (void*)
(((MEMPTR_t) nosTaskGetUserspace()) + SYS_USRSPACE_OFS);
#else
return (struct sys_timeouts *) (void*)
(((MEMPTR_t) posTaskGetUserspace()) + SYS_USRSPACE_OFS);
#endif
}
/*-----------------------------------------------------------------------------------*/
sys_prot_t
sys_arch_protect(void)
{
#if POSCFG_FEATURE_MUTEXES
posMutexLock(sysprotMutex_g);
#else
POSTASK_t thistask = posTaskGetCurrent();
SCHED_LOCK();
if (thistask == sysprotLastTask_g)
{
sysprotLockCntr_g++;
SCHED_UNLOCK();
}
else
{
SCHED_UNLOCK();
posSemaGet(sysprotSemaphore_g);
sysprotLastTask_g = thistask;
sysprotLockCntr_g = 1;
}
#endif
return 0;
}
/*-----------------------------------------------------------------------------------*/
void
sys_arch_unprotect(sys_prot_t pval)
{
(void) pval;
#if POSCFG_FEATURE_MUTEXES
posMutexUnlock(sysprotMutex_g);
#else
SCHED_LOCK();
if (--sysprotLockCntr_g == 0)
{
sysprotLastTask_g = NULL;
SCHED_UNLOCK();
posSemaSignal(sysprotSemaphore_g);
}
else
{
SCHED_UNLOCK();
}
#endif
}
/*-----------------------------------------------------------------------------------*/
void
sys_init()
{
int i;
#if BUF_MAX_SEM > 0
semabufLast_g = 0;
for (i=0; i<BUF_MAX_SEM; i++)
semabuffer_g[i] = NULL;
#endif
#if BUF_MAX_MBOX > 0
mboxbufLast_g = 0;
for (i=0; i<BUF_MAX_MBOX; i++)
mboxbuffer_g[i] = NULL;
#endif
#if SYS_TCPIPMBOXFIX
p_tcpipmbox_g = NULL;
#endif
unused_mbox_list_g = NULL;
unused_mail_list_g = NULL;
max_used_mboxes_g = 0;
max_used_mails_g = 0;
cur_used_mails_g = 0;
#ifdef SYSDEBUG
cur_used_mboxes_g = 0;
#endif
mail_waiting_g = 0;
mail_sem_g = sys_sem_new(0);
LWIP_ASSERT("sys_arch.c: failed to create semaphore", mail_sem_g != NULL);
#if POSCFG_FEATURE_MUTEXES
sysprotMutex_g = posMutexCreate();
LWIP_ASSERT("sys_arch.c: failed to create mutex", sysprotMutex_g != NULL);
#else
sysprotLockCntr_g = 0;
sysprotLastTask_g = NULL;
sysprotSemaphore_g = posSemaCreate(1);
LWIP_ASSERT("sys_arch.c: failed to create semaphore", sysprotSemaphore_g != NULL);
#endif
/* some extra checking */
if (POSCFG_TASKCB_USERSPACE < SYS_USRSPACE_OFS+sizeof(struct sys_timeouts))
{
LWIP_DEBUGF(SYS_DBLVL, ("sys_arch.c: pico]OS task user space is "
"configured too small. Minimum size = %u bytes\n",
SYS_USRSPACE_OFS+sizeof(struct sys_timeouts) ));
LWIP_ASSERT("sys_arch.c: pico]OS task user space is configured too small.",0);
for(;;);
}
}
/*-----------------------------------------------------------------------------------*/
void
sys_thread_abord(void)
{
#if POSCFG_FEATURE_EXIT
#if POSCFG_ENABLE_NANO
nosTaskExit();
#else
posTaskExit();
#endif
#else
#if POSCFG_ENABLE_NANO
nosSemaWait(nosSemaCreate(0, 0, LWIPNAME "-abort-*"));
#else
posSemaWait(posSemaCreate(0));
#endif
for(;;)
#endif
}
/*-----------------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -