📄 usertask.c
字号:
/* * dspapps/dsp/tokliBIOS/usertask.c * * OMAP DSP bridge DSP-side core library * usertask module * * Copyright (C) 2002,2003 Nokia Corporation * * Written by Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: usertask.c * $Revision: 2.0 * $Date: 2003/11/11 * */#include <std.h>#include <sem.h>#include <tsk.h>#include "omap1510.h"#include "mailbox.h"#include "tokliBIOS.h"#include "tokliBIOSlib.h"#include "toklibioscfg.h"#define N_SYSTASK 0//extern struct dsptask task_wdt;#if N_SYSTASK > 0static struct dsptask *task_system[N_SYSTASK] = {// &task_wdt};#endif /* N_SYSTASK */static struct TSK_Attrs attrs_default;#define sndtyp_acv(ttyp) ((ttyp) & MBCMD_TTYP_ASND)#define sndtyp_psv(ttyp) (!((ttyp) & MBCMD_TTYP_ASND))#define sndtyp_bk(ttyp) ((ttyp) & MBCMD_TTYP_BKDM)#define sndtyp_wd(ttyp) (!((ttyp) & MBCMD_TTYP_BKDM))#define sndtyp_pv(ttyp) ((ttyp) & MBCMD_TTYP_PVDM)#define sndtyp_gb(ttyp) (!((ttyp) & MBCMD_TTYP_PVDM))#define rcvtyp_acv(ttyp) ((ttyp) & MBCMD_TTYP_ARCV)#define rcvtyp_psv(ttyp) (!((ttyp) & MBCMD_TTYP_ARCV))#define rcvtyp_bk(ttyp) ((ttyp) & MBCMD_TTYP_BKMD)#define rcvtyp_wd(ttyp) (!((ttyp) & MBCMD_TTYP_BKMD))#define rcvtyp_pv(ttyp) ((ttyp) & MBCMD_TTYP_PVMD)#define rcvtyp_gb(ttyp) (!((ttyp) & MBCMD_TTYP_PVMD))static Void procmb(Arg tid_arg);static Void do_mbq(Uns tid, Uns cmd, Uns data);static Uns mbq_wdsnd(Uns tid, Uns data);static Uns mbq_wdreq(Uns tid);static Uns mbq_bksnd(Uns tid, Uns bid);static Uns mbq_bkreq(Uns tid, Uns cnt);static Uns mbq_bksndp(Uns tid);static Uns mbq_tctl(Uns tid, Uns ctlcmd);static Uns generic_tctl(Uns ctlcmd);static Uns mbq_tcfg(Uns tid);Void init_tasks(Void){ Uns tid; Uns i; struct task_prop *prop_buf; memset(dsptask, 0, sizeof(Void*) * N_TASK_MAX); memset(task_prop, 0, sizeof(Void*) * N_TASK_MAX); _n_task += N_SYSTASK; if(_n_task > 0) { Uns allocsz = sizeof(struct task_prop) * _n_task; // allocate all together, never be released. prop_buf = MEM_alloc(MEM->MALLOCSEG, allocsz, 2); if(prop_buf == MEM_ILLEGAL) { sys_cmderr(MBCMD_EID_NOMEM, MBCMD_TID_ANON); return; } } // TSK attrs default value attrs_default.priority = DSPTASK_DEFAULT_PRIORITY; attrs_default.stack = NULL; attrs_default.stacksize = DSPTASK_DEFAULT_STACKSIZE; // default value is 1024 attrs_default.sysstacksize = DSPTASK_DEFAULT_SYSSTACKSIZE; // default value is 256 attrs_default.stackseg = MEM->MALLOCSEG; attrs_default.environ = NULL; //attrs_default.name = ""; attrs_default.exitflag = TRUE; /* * system task initialization */ tid = 0;#if N_SYSTASK > 0 for(i=0; i<N_SYSTASK; i++, tid++) { task_config(task_system[i], &prop_buf[tid], tid); }#endif /* * user task initialization */ for(i=0; tid<_n_task; i++, tid++) { task_config(task_user[i], &prop_buf[tid], tid); } /* * anonymous task initialization */ task_anon.tid = MBCMD_TID_ANON;}Void task_config(struct dsptask *task, struct task_prop *prop, Uns tid){ struct TSK_Attrs *attrs; dsptask[tid] = task; task_prop[tid] = prop; task->tid = tid; if(task->tsk_attrs == NULL) { attrs = &attrs_default; } else { attrs = task->tsk_attrs; attrs->stackseg = MEM->MALLOCSEG; } attrs->name = task->name; prop->ipbuf_p_snd.s = MBCMD_TID_FREE; prop->ipbuf_p_req.s = MBCMD_TID_FREE; prop->tsk = TSK_create((Fxn)procmb, attrs, (Arg)tid); prop->sem = SEM_create(0, NULL); prop->stat = TASK_STAT_RUNNING; prop->mbq_wp = prop->mbq_rp = 0; if((prop->tsk == MEM_ILLEGAL) || (prop->sem == MEM_ILLEGAL)) { sys_cmderr(MBCMD_EID_NOMEM, tid); return; }}Void task_unconfig(Uns tid){ struct task_prop *prop = task_prop[tid]; TSK_delete(prop->tsk); SEM_delete(prop->sem); dsptask[tid] = NULL; task_prop[tid] = NULL;}/* * mailbox process task */static Void procmb(Arg tid_arg){ Uns tid = (Uns)ArgToInt(tid_arg); struct task_prop *prop = task_prop[tid]; struct mailboxq *mbq = prop->mbq; Uns *rp = &prop->mbq_rp;start: SEM_pend(prop->sem, SYS_FOREVER); // wait for next one do_mbq(tid, mbq[*rp].cmd_h, mbq[*rp].data); if(++*rp == MBQ_MAX) *rp = 0; goto start;}static Void do_mbq(Uns tid, Uns cmd_h, Uns data){ Uns eid; switch(cmd_h) { case MBCMD_WDSND: eid = mbq_wdsnd(tid, data); break; case MBCMD_WDREQ: eid = mbq_wdreq(tid); break; case MBCMD_BKSND: eid = mbq_bksnd(tid, data); break; case MBCMD_BKREQ: eid = mbq_bkreq(tid, data); break; case MBCMD_BKSNDP: eid = mbq_bksndp(tid); break; case MBCMD_TCTL: eid = mbq_tctl(tid, data); break; case MBCMD_TCFG: eid = mbq_tcfg(tid); break; case MBCMD_TSTOP: TSK_exit(); case MBCMD_BKREQP: default: eid = MBCMD_EID_BADCMD; } if(eid) { sys_cmderr(eid, mbcmd(cmd_h,tid)); }}static Uns mbq_wdsnd(Uns tid, Uns data){ struct dsptask *task = dsptask[tid]; Uns eid; if(!rcvtyp_wd(task->ttyp)) { /* This task doesn't use word transfer. */ return MBCMD_EID_BADTCN; } if(eid = task->rcv_snd(task, data)) { return eid; } return 0;}static Uns mbq_wdreq(Uns tid){ struct dsptask *task = dsptask[tid]; Uns eid; if(!sndtyp_wd(task->ttyp) || !sndtyp_psv(task->ttyp)) { /* This task doesn't receive WDREQ. */ return MBCMD_EID_BADTCN; } if(eid = task->rcv_req(task)) { return eid; } return 0;}static Uns mbq_bksnd(Uns tid, Uns bid){ struct dsptask *task = dsptask[tid]; Uns cnt; Uns eid; //sync_ipbuf(tid, bid); // already done in interrupt routine if(!rcvtyp_bk(task->ttyp) || !rcvtyp_gb(task->ttyp)) { /* This task doesn't use global ipbuf. */ unuse_ipbuf(task, bid); return MBCMD_EID_BADTCN; } cnt = ipbuf[bid]->c; if(eid = task->rcv_snd(task, bid, cnt)) { return eid; } return 0;}static Uns mbq_bkreq(Uns tid, Uns cnt){ struct dsptask *task = dsptask[tid]; Uns eid; if(rcvtyp_gb(task->ttyp) && (cnt > _ipbuf_sz)) { return MBCMD_EID_BADCNT; } if(!sndtyp_bk(task->ttyp) || !sndtyp_psv(task->ttyp)) { /* This task doesn't receive BKREQ. */ return MBCMD_EID_BADTCN; } if(eid = task->rcv_req(task, cnt)) { return eid; } return 0;}static Uns mbq_bksndp(Uns tid){ struct dsptask *task = dsptask[tid]; struct ipbuf_p *ipbuf_p = &task_prop[tid]->ipbuf_p_req; Uns cnt; Uns eid; if(!rcvtyp_bk(task->ttyp) || !rcvtyp_pv(task->ttyp)) { /* This task doesn't use private block transfer. */ return MBCMD_EID_BADTCN; } /* sync with ARM */ while(*(volatile Uns*)&ipbuf_p->s != tid) { busywait(10); } /* * We are not going to lock this buffer any longer. * If you need lock operation, you should use * active receiving function. (bkreqp) */ ipbuf_p->s = MBCMD_TID_FREE; cnt = ipbuf_p->c; if(eid = task->rcv_snd(task, cnt)) { return eid; } return 0;}static Uns mbq_tctl(Uns tid, Uns ctlcmd){ struct dsptask *task = dsptask[tid]; Uns eid = MBCMD_EID_BADTCTL; if(task->rcv_tctl) { eid = task->rcv_tctl(task, ctlcmd); } if(eid == MBCMD_EID_BADTCTL) { eid = generic_tctl(ctlcmd); } return eid;}static Uns generic_tctl(Uns ctlcmd){ switch(ctlcmd) { case MBCMD_TCTL_TINIT: return 0; case MBCMD_TCTL_TEN: case MBCMD_TCTL_TDIS: default: return MBCMD_EID_BADTCTL; }}static Uns mbq_tcfg(Uns tid){ struct dsptask *task = dsptask[tid]; struct task_prop *prop = task_prop[tid]; Uns ttyp = task->ttyp; LgUns adr; Int i; static struct tcfgbuf { Uns tnm[MBCMD_TNM_LEN]; Uns ttyp; Uns dmh; Uns dml; Uns mdh; Uns mdl; } tcfgbuf; tcfgbuf.ttyp = ttyp; adr = sndtyp_pv(ttyp) ? (LgUns)&prop->ipbuf_p_snd : 0; tcfgbuf.dmh = adr >> 16; tcfgbuf.dml = adr & 0xffff; adr = rcvtyp_pv(ttyp) ? (LgUns)&prop->ipbuf_p_req : 0; tcfgbuf.mdh = adr >> 16; tcfgbuf.mdl = adr & 0xffff; for(i=0; i<MBCMD_TNM_LEN; i++) { tcfgbuf.tnm[i] = task->name[i]; if(task->name[i] == '\0') break; } ipbuf_sys.c = sizeof(struct tcfgbuf); ipbuf_sys.s = tid; ipbuf_sys.ah = (LgUns)&tcfgbuf >> 16; ipbuf_sys.al = (LgUns)&tcfgbuf & 0xffff; mbsend(mbcmd(MBCMD_TCFG, tid), 0); return 0;}/* * registering command to mbq. */Int register_mbq(Uns tid, Uns cmd_h, Uns data){ struct task_prop *prop; struct mailboxq *mbq_ent; Uns wp, newwp; if((tid >= N_TASK_MAX) || (dsptask[tid] == NULL)) return MBCMD_EID_BADTID; prop = task_prop[tid]; if(prop->stat == TASK_STAT_STOP) return MBCMD_EID_TASKBSY; wp = prop->mbq_wp; mbq_ent = &prop->mbq[wp]; mbq_ent->cmd_h = cmd_h; mbq_ent->data = data; if((newwp = wp+1) == MBQ_MAX) newwp = 0; if(newwp == prop->mbq_rp) { // mbq is full! mbq_ent->cmd_h = MBCMD_TSTOP; // stop this task prop->stat = TASK_STAT_STOP; return MBCMD_EID_TASKBSY; } prop->mbq_wp = newwp; SEM_post(prop->sem); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -