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

📄 systask.c

📁 一个操作系统源代码 用于嵌入式设备 在Vc++环境下仿真 成功移植到多款处理器上
💻 C
📖 第 1 页 / 共 3 页
字号:
	//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 + -