📄 systask.c
字号:
//if ( AT_BUF_readcount != AT_BUF_writecount)
// flgptn |= INTAT_FLG;
//else if (KEY_BUF_readcount != KEY_BUF_writecount)
// flgptn |= INTKEY_FLG;
//else if (PEN_BUF_readcount != PEN_BUF_writecount)
// flgptn |= INTPEN_FLG;
//
// above code replaced by following code
if ( CheckKeyIntBuf( ) != BUF_EMPTY )
flgptn |= INTKEY_FLG;
else if ( CheckPenIntBuf( ) != BUF_EMPTY )
flgptn |= INTPEN_FLG;
// yes
if( flgptn > 0x1 )
set_flg(SYS_EVENT, flgptn);
return ;
}
/*****************************************************************
* Function Name: process_msg
* Param in:
* Result code: void
* Description: process message sent from tasks
*****************************************************************/
static void process_msg()
{
MSG msgrcv;
UINT flgptn;
ID id, lastid;
SYSTCB *pHead, *curTask;
TASKDESCRIPTION *description;
//WORD *initAd;
GC *pCurGC;
VRAM *vram;
/* clear task message flag */
clr_flg(SYS_EVENT,~TASKMSG_FLG);
while(1)
{
/* get message from system task's mailbox */
if( SysRecvMessage(&msgrcv, 0) != SYS_OK )
break; /* no message, go out of loop */
/* handle messages */
/* msgrcv.wparam --> task id */
id = msgrcv.lparam;
switch(msgrcv.message)
{
/* start a Dormant task */
/* it is different from EPSON's SM_START */
/* this message is always sent from shell */
case SM_START:
/* if the task has been started, do nothing here */
if(gSysTcbTbl[id-1].status == RUNNING)
{
if( id != gLcdOwnerTskId )
{
lastid = gLcdOwnerTskId;
gLcdOwnerTskId = id;
curTask = &gSysTcbTbl[gLcdOwnerTskId-1];
pCurGC = curTask->gc;
//initAd = pCurGC->vram + pCurGC->lcd_x + pCurGC->width * pCurGC->lcd_y;
vram = pCurGC->vram;
/* refresh Lcd screen */
dbgoutput("Systask refresh lcd to current task's(%s) vram\n",findtskname(gLcdOwnerTskId));
//seWrite2LCD(0, PHY_LCD_W-1, 0, PHY_LCD_H-1, \
// (CurTask->gc->vram + CurTask->gc->lcd_y*CurTask->gc->width + CurTask->gc->lcd_x), \
// CurTask->gc->width );
//Write2LCD(0, PHY_LCD_W, 0, PHY_LCD_H, CurTask->gc->vram, PHY_LCD_W );
//Write2LCD(0, PHY_LCD_W-1, 0, PHY_LCD_H-1, initAd, pCurGC->width );
Write2LCD( 0, 0, PHY_LCD_W-1, PHY_LCD_H-1, vram );
//seWrite2LCD( vram, 0 );
}
break;
}
description = gSysTcbTbl[id-1].description->desp;
/* if the task doesn't need screen, it should not get this message.
so we do nothing here. */
if((description->scr_w==0) || (description->scr_h==0)) break;
dbgoutput("Systask is ready to start task(%s)\n",findtskname(id));
/* save current Lcd screen owner's id */
lastid = gLcdOwnerTskId;
gSysTcbTbl[id-1].gc = (GC *)SysInitGC(description->scr_w, description->scr_h);
gSysTcbTbl[id-1].atvcb = (ATVCB *)SysInitATVCB();
if(gSysTcbTbl[id-1].gc && gSysTcbTbl[id-1].atvcb)
{
/* init this task's SYSTCB */
gSysTcbTbl[id-1].status = RUNNING;
/* move to AsixTaskInit() */
//gSysTcbTbl[id-1].group = gSysTcbTbl[id-1].description->group;
//gSysTcbTbl[id-1].icon = gSysTcbTbl[id-1].description->icon;
//gSysTcbTbl[id-1].id = (DWORD)&gSysTcbTbl[id-1];
/* CurTask is used by Asixwin */
curTask = &gSysTcbTbl[id-1];
/* add CurTask to Application Task List */
if(TaskHead == NULL)
{
TaskHead = curTask;
TaskHead->next = NULL;
}else{
curTask->next = TaskHead;
TaskHead = curTask;
}
/* if the task started just now needs LCD screen,
* then switch the LCD owner */
gLcdOwnerTskId = id;
/* refresh lcd screen */
/* here, we needn't refresh screen, because it will be done
while task begins. It's users' business. */
}else{
dbgoutput("Systask failed in Lmalloc while starting task(%s)\n",findtskname(id));
SysFreeGC((DWORD)gSysTcbTbl[id-1].gc);
SysFreeATVCB(gSysTcbTbl[id-1].atvcb);
gSysTcbTbl[id-1].gc = NULL;
gSysTcbTbl[id-1].atvcb = NULL;
break;
}
gSysTcbTbl[id-1].description->taskid = id;
/* Call function after last task exits */
// dbgoutput("Systask calls last task's(%s) exitCallback\n", findtskname(lastid));
if(lastid != 0 && gSysTcbTbl[lastid-1].exitCallback != NULL)
(gSysTcbTbl[lastid-1].exitCallback)((DWORD)&gSysTcbTbl[gLcdOwnerTskId-1]);
/* Call function before task begins */
// dbgoutput("Systask calls current task's(%s) entryCallback\n", findtskname(id));
if(lastid != 0 && gSysTcbTbl[id-1].entryCallback != NULL)
(gSysTcbTbl[id-1].entryCallback)((DWORD)&gSysTcbTbl[lastid-1]);
/* it is sure that this task will be added at end of ready queue */
dbgoutput("Systask starts task: %d\n", id );
sta_tsk(id, 0);
break;
/* a task declares it ended */
/* it is different from EPSON's SM_END */
case SM_END:
/* if the task has been ended, do nothing here */
if(gSysTcbTbl[id-1].status == DORMANT) break;
description = gSysTcbTbl[id-1].description->desp;
/* if the task doesn't need screen, it should not get this message.
so we do nothing here. */
if((description->scr_w==0) || (description->scr_h==0)) break;
dbgoutput("Systask is ready to end task(%s)\n",findtskname(id));
/* save current Lcd screen owner's id */
lastid = gLcdOwnerTskId;
/* Call function after task exits */
if(gSysTcbTbl[id-1].exitCallback != NULL)
(gSysTcbTbl[id-1].exitCallback)((DWORD)&gSysTcbTbl[SHELL_ID-1]);
SysFreeGC((DWORD)gSysTcbTbl[id-1].gc);
SysFreeATVCB(gSysTcbTbl[id-1].atvcb);
if( TaskHead->id == gSysTcbTbl[id-1].id )
{
TaskHead = TaskHead->next;
}else{
pHead = TaskHead;
while( pHead != NULL && pHead->next->id != gSysTcbTbl[id-1].id)
pHead = pHead->next;
pHead->next = pHead->next->next;
}
dbgoutput("Systask ends task(%s)\n",findtskname(id));
//ter_tsk(id);
gSysTcbTbl[id-1].status = DORMANT;
gSysTcbTbl[id-1].gc = NULL;
gSysTcbTbl[id-1].atvcb = NULL;
if( id == lastid )
{
/* switch the LCD owner to shell task */
// gLcdOwnerTskId = SHELL_ID;
// curTask = &gSysTcbTbl[SHELL_ID-1];
gLcdOwnerTskId = TaskHead - gSysTcbTbl +1;
curTask = TaskHead;
pCurGC = curTask->gc;
//initAd = pCurGC->vram + pCurGC->lcd_x + pCurGC->width * pCurGC->lcd_y;
vram = pCurGC->vram;
/* Call function before task begins */
//dbgoutput("Systask calls current task's(%s) entryCallback\n", findtskname(gLcdOwnerTskId));
if(gSysTcbTbl[gLcdOwnerTskId-1].entryCallback != NULL)
(gSysTcbTbl[gLcdOwnerTskId-1].entryCallback)((DWORD)&gSysTcbTbl[lastid-1]);
/* refresh Lcd screen */
dbgoutput("Systask refresh lcd to current task's(%s) vram\n",findtskname(gLcdOwnerTskId));
//seWrite2LCD(0, PHY_LCD_W-1, 0, PHY_LCD_H-1, \
// (CurTask->gc->vram + CurTask->gc->lcd_y*CurTask->gc->width + CurTask->gc->lcd_x), \
// CurTask->gc->width );
//Write2LCD(0, PHY_LCD_W, 0, PHY_LCD_H, CurTask->gc->vram, PHY_LCD_W );
//Write2LCD(0, PHY_LCD_W-1, 0, PHY_LCD_H-1, initAd, pCurGC->width );
Write2LCD(0, 0, PHY_LCD_W-1, PHY_LCD_H-1, vram );
//seWrite2LCD( vram, 0 );
{
MSG switchmsg;
switchmsg.message = SM_SWITCH;
switchmsg.wparam = SWAP_TO_FOREGROUND;
switchmsg.lparam = gLcdOwnerTskId;
SysSendMessage( gLcdOwnerTskId, &switchmsg );
}
}
break;
/* switch task */
/* if task id == 0, then wake up task at head of suspended queue.
if task id !=0 , then switch to that task. */
case SM_SWITCH:
{
U8 en_switch = TRUE;
lastid = gLcdOwnerTskId;
switch( msgrcv.wparam )
{
case SWAP_TO_FOREGROUND: // switch the task to foreground
{
/* if the task to be switched is LcdOwner(id == gLcdOwnerTskId),
we do nothing. */
if( id == gLcdOwnerTskId )
{
en_switch = FALSE;
break;
}
dbgprintf("Systask is ready to switch task\n");
if( id == 0 )
{
/* switch the LCD owner to next task */
//gLcdOwnerTskId = SHELL_ID;
pHead = TaskHead;
TaskHead = TaskHead->next;
gLcdOwnerTskId = (ID)( TaskHead - gSysTcbTbl +1 );
//curTask = &gSysTcbTbl[gLcdOwnerTskId-1];
//if( curTask->next == NULL )
// gLcdOwnerTskId = SHELL_ID;
//else
// gLcdOwnerTskId = curTask->next - gSysTcbTbl +1;
}else{
/* switch to that task(id) */
gLcdOwnerTskId = id;
{
pHead = TaskHead;
while( pHead != NULL && pHead->next != &gSysTcbTbl[id-1] )
pHead = pHead->next;
if( pHead != NULL )
{
pHead->next = gSysTcbTbl[id-1].next;
gSysTcbTbl[id-1].next = TaskHead;
TaskHead = &gSysTcbTbl[id-1];
}
}
}
}
break;
case SWAP_TO_BACKGROUND: // switch the task to background
{
pHead = TaskHead;
if( pHead != NULL && pHead == &gSysTcbTbl[id-1] )
{
TaskHead = pHead->next;
gLcdOwnerTskId = (ID)( TaskHead - gSysTcbTbl +1 );
}
else
{
while( pHead != NULL && pHead->next != &gSysTcbTbl[id-1] )
pHead = pHead->next;
if( pHead != NULL )
pHead->next = gSysTcbTbl[id-1].next;
en_switch = FALSE;
}
}
break;
}
if( en_switch == FALSE )
break;
/* if the task doesn't need screen, it should not get this message.
so we do nothing here. */
if((gSysTcbTbl[gLcdOwnerTskId-1].description->desp->scr_w==0) || (gSysTcbTbl[gLcdOwnerTskId-1].description->desp->scr_h==0))
{
gLcdOwnerTskId = lastid;
break;
}
curTask = &gSysTcbTbl[gLcdOwnerTskId-1];
pCurGC = curTask->gc;
//initAd = pCurGC->vram + pCurGC->lcd_x + pCurGC->width * pCurGC->lcd_y;
vram = pCurGC->vram;
/* Call function after last task exits */
dbgoutput("Systask calls last task's(%s) exitCallback\n",findtskname(lastid));
if(gSysTcbTbl[lastid-1].exitCallback != NULL)
(gSysTcbTbl[lastid-1].exitCallback)((DWORD)&gSysTcbTbl[gLcdOwnerTskId-1]);
/* Call function before task begins */
dbgoutput("Systask calls current task's(%s) entryCallback\n", findtskname(gLcdOwnerTskId));
if(gSysTcbTbl[gLcdOwnerTskId-1].entryCallback != NULL)
(gSysTcbTbl[gLcdOwnerTskId-1].entryCallback)((DWORD)&gSysTcbTbl[lastid-1]);
/* refresh Lcd screen */
dbgoutput("Systask refresh lcd to current task's(%s) vram\n",findtskname(gLcdOwnerTskId));
//seWrite2LCD(0, PHY_LCD_W-1, 0, PHY_LCD_H-1, \
// (CurTask->gc->vram + CurTask->gc->lcd_y*CurTask->gc->width + CurTask->gc->lcd_x), \
// CurTask->gc->width );
//Write2LCD(0, PHY_LCD_W, 0, PHY_LCD_H, CurTask->gc->vram, PHY_LCD_W );
//Write2LCD(0, PHY_LCD_W-1, 0, PHY_LCD_H-1, initAd, pCurGC->width );
Write2LCD(0, 0, PHY_LCD_W-1, PHY_LCD_H-1, vram );
//seWrite2LCD( vram, 0 );
{
MSG switchmsg;
switchmsg.message = SM_SWITCH;
switchmsg.wparam = msgrcv.wparam;
switchmsg.lparam = gLcdOwnerTskId;
SysSendMessage( gLcdOwnerTskId, &switchmsg );
}
}
break;
case SM_OPEN:
// SysOpenDev( msgrcv.wparam, (WORD)msgrcv.lparam );
// EnableUartInt( msgrcv.lparam -1 );
break;
case SM_CLOSE:
// SysCloseDev( (WORD)msgrcv.lparam );
// DisableUartInt( msgrcv.lparam -1 );
break;
case SM_DATA_SEND:
break;
case SM_DATA_RECEIVED:
// if( CheckUartRecvBuf( (WORD)msgrcv.lparam, &msgrcv.wparam ) != BUF_EMPTY )
// set_flg(SYS_EVENT, UartEventFlag[msgrcv.lparam] );
break;
case SM_PEN_CALIBRATION:
{
lastid = gLcdOwnerTskId;
PenCalibration();
gLcdOwnerTskId = lastid;
vram = gSysTcbTbl[gLcdOwnerTskId-1].gc->vram;
Write2LCD( 0, 0, PHY_LCD_W-1, PHY_LCD_H-1, vram );
}
break;
default:
break;
}/* end of switch */
}/* end of while */
/* check if any interrupt happened while executing above code */
/* yes, setflg SYS_EVENT to avoid missing event */
/* even some event was setflg again, it is still worthy */
/* problem : how to know whether Timer Interrupt happened or not? */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -