⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usertask.c

📁 TI OMAP 1510上mcbsp的驱动程序
💻 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 + -