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

📄 systask.c

📁 基于东南大学开发的SEP3203的ARM7中的所有驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
					
				default :
					break;
			}
		}
		
		PEN_BUF_readcount++;
		if (PEN_BUF_readcount >= MAX_PENBUF)
			PEN_BUF_readcount = 0;	
		clr_flg(SYS_EVENT,~INTPEN_FLG);
	}
	
	/* to add new interrupt handle code here... */
	/* ................. */
	
	/* now, we think all events except Tasks' message have been handled */
	flgptn &= 0x1;
	
	/* 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 : when PEN_BUF_readcount != PEN_BUF_writecount,
	  * KEY_BUF_readcount != KEY_BUF_writecount???	*/
////	if (KEY_BUF_readcount != KEY_BUF_writecount)
////		flgptn |= INTKEY_FLG;
	if (PEN_BUF_readcount != PEN_BUF_writecount)
		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);
////#if 0			////gfd del	
	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));
						Write2LCD( 0, 0, PHY_LCD_W-1, PHY_LCD_H-1, vram );
					}
					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 */
				dbgprintf("Systask starts a task\n");
				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));
					Write2LCD(0, 0, PHY_LCD_W-1, PHY_LCD_H-1, vram );
					{
						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:
				{
					BYTE	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));
					Write2LCD(0, 0, PHY_LCD_W-1, PHY_LCD_H-1, vram );
					{
						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:
				{
					PenCalibration();
					gLcdOwnerTskId = (ID)( TaskHead - gSysTcbTbl +1 );
					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. 
	  * if there are some more interrupts not handled, setflg SYS_EVENT 
	  * to avoid missing event.  even some event was setflg again, 
	  * it is still worthy 
	  */
	flgptn = 0;
////	if (KEY_BUF_readcount != KEY_BUF_writecount)
////		flgptn |= INTKEY_FLG;

////#endif 			////gfd del end

	if (PEN_BUF_readcount != PEN_BUF_writecount)
		flgptn |= INTPEN_FLG;
	
	if( flgptn > 0x1 )
		set_flg(SYS_EVENT, flgptn);	
		
	return ;
}

/*****************************************************************
*  Function Name: systaskinit 
*  Param in:	
*  Result code:	void							
*  Description: system task init
*****************************************************************/
static void systaskinit()
{
	SYSTIME pk_KeyScan,pk_TouchPanel;
    
#ifdef HOT_RESET_DEBUG_CODE_ENABLE
	PendownFlag=0;
	gLcdOwnerTskId=0;
	CurTask=NULL;
	TaskHead=NULL;
#endif

	/* define KeyScan Cychndr */
////	pk_KeyScan.utime = 0;
////	pk_KeyScan.ltime = 100;    //100ms
////	def_cyc(KEYSCANTIMER, KeyScanHandler, TCY_OFF, &pk_KeyScan);   

	/* define TouchPanelScan Cychndr */
	pk_TouchPanel.utime = 0;
////	pk_TouchPanel.ltime = 50;    // 200ms
	pk_TouchPanel.ltime = 5;    // 50ms
	def_cyc(TOUCHTIMER, TouchPanelHandler, TCY_OFF, &pk_TouchPanel); 

#ifdef OLD_FS			//old fs and new fs
	InitialSystem();
#else
	//(michael)GFD_InitFatFS(1);	//only new fs
	//GFD_InitFatFS(2);
	GFD_InitFatFS(0);		
#endif

	/* pen calibrated!!! */
	PenCalibration();
	
	/* init some global values for Asixwin */
	ASIXInit(); /* it should run after timer_task, so we put it into shell_task */
	/* start running rtc */
//	run_rtc();
}

void PenCalibration( void )
{
	CHAR 	PenDown=0, new_check = 1, quit=0, lefttop_pressed=0, rightbottom_pressed=0, center_pressed = 0;
	SHORT 	x1=0,y1=0,x2=0,y2=0;
	SHORT 	x3=0,y3=0;
	SHORT	last_x1,last_y1,last_x2,last_y2,last_x3,last_y3;
//	SHORT	avx1, avy1, avx2, avy2;
	static 	UINT flgptn;
	BYTE	msgtype;	/* message type */
	GC 		*pGC;
	CHAR	showCross = 1;
	ID		lastid;
	CHAR	exchange;
	SHORT	pi=0;
	DWORD	exadd;

////#define AD_WUCHA 0x30
#define AD_WUCHA 0x24		////gfd for lenth:width = 3:2
	en_disp_ad = 1;
	
	kx = 0;
	ky = 0;
	bx = 0;
	by = 0;
		
	/* Create One GC */
	dbgprintf("Init GC\n");
//	if( gSysTcbTbl[SYSTASK_ID-1].gc == NULL )
	{
		pGC = (GC *)SysInitGC(PHY_LCD_W, PHY_LCD_H);
		gSysTcbTbl[SYSTASK_ID-1].gc = pGC;
	}
	lastid = gLcdOwnerTskId;
	gLcdOwnerTskId = SYSTASK_ID;
			

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -