主任务控制子任务通信流程

c++ 复制代码
#define WM_TAKE_STOCK_CMD					172				//MAIN->TAKE 任务流程
		#define TAKE_STOCK_CMD_FIND_TRAY			1			// 找托盘
#define WM_TAKE_STOCK_CMD_EXC				173				//TAKE内部使用
		#define TAKE_STOCK_EXE_OK					0
#define WM_TAKE_STOCK_TASK_MSG				174				//MAIN->TAKE 发送消息
		#define TAKE_STOCK_MSG_CAL_TRAY				1
		#define TAKE_STOCK_MSG_CLOSE				2
		#define TAKE_STOCK_MSG_CHANGE_ENDPOS		3
#define WM_TAKE_STOCK_EXC_TOMAIN			175				//TAKE->MAIN任务报警异常
		#define TAKE_STOCK_EXC_ALARM				1
#define WM_TAKE_STOCK_TASK_API				176				//TAKE任务执行结果
		#define WM_TASK_STOCK_TASK_FIND_TRAY_OK		1		//找托盘成功
		#define WM_TASK_STOCK_TASK_CLOSE_OK			2		//任务中止关闭成功
c++ 复制代码
//MIAN_TASK win_SubWalk_Pos_Main_Ctrl.c 
/**
 * @brief  窗口函数
 * @param  Type: 信息的类型
 * @param  Parameter: 数值型信息
 * @param  Info: 字符串型信息
 * @param  hSrcWin: 源窗口,消息的触发窗口
 * @param  hTagWin: 目标窗口,消息的目标窗口
 * @retval None
 * @note   具体处理接收到的信息(如按键输入等),每一个功能窗口都要有一个这样的函数
 *         这是一个内部函数,其他模块的窗口函数可以与它同名 
 */
static void WindowProc(WORD Type, WORD Parameter, BYTE *Info, WORD hSrcWin, WORD hTagWin)
{
	switch( Type )		// 根据信息类型,提取及处理相应的信息
	{					
	case WM_CLOSE:
			CloseWindow(MAIN_TASK);
		break;
	case WM_REDRAW:
			Initialize();
			OpenWindow(MAIN_TASK,&Window);
		break;
	case WM_REFRESH:
	{
		//...
		
		if(sTakeOut && sTakeOut_AlarmCode){
			win_SubWalk_Emergency_Stop(sTakeOut_AlarmCode);
			return;
		}
	}
		break;
	case WM_MOTOR_ENCODER_RESET_CMD:
			switch(Parameter)
			{
			case MOTOR_ENCODER_RESET_OK:
					//向TAKE_TASK发送指令  MAIN_TASK->TAKE_TASK
					(*ActiveWindowProc)(TAKE_TASK)(WM_TAKE_STOCK_CMD, TAKE_STOCK_CMD_FIND_TRAY, (u8*)&uExtMsg, SYS_WIN_SUBWALK_POS_MAIN_CTRL,0);
				break;
			case MOTOR_ENCODER_RESET_ERR:
				break;
			default:
					ASSERT(ERROR);
				break;
			}
		break;
	//接收TAKE_TASK返回  TAKE_TASK->MAIN_TASK
	case WM_TAKE_STOCK_TASK_API: //盘点任务结果
		switch(Parameter)
		{
		case WM_TASK_STOCK_TASK_FIND_TRAY_OK: //盘点任务成功
				; //do nothing
			break;	
		case WM_TASK_STOCK_TASK_CLOSE_OK: //盘点任务关闭
		
			break;
		default:
				ASSERT(ERROR);
			break;
		}
		break;
	//接收TAKE_TASK 报错返回 
	case WM_TAKE_STOCK_EXC_TOMAIN:
		switch(Parameter)
		{
		case TAKE_STOCK_EXC_ALARM: 
				if(Info!=NULL){
					sTakeOutWindowMsg = *(WINDOW_MSG*)Info; //变叉报警
					RT_LOG(RT_LOG_WCS,("盘点流程报警AlarmCode:0x%04X\n",sTakeOutWindowMsg.Parameter));
					
					//一定是处于激活状态,需要判断当前活动窗口是不是自身
					if(Window.Active){//当前窗口活动中 
						sTakeOut_AlarmCode = sTakeOutWindowMsg.Parameter;
						if(GetCurrentWindow(MAIN_TASK) == &Window)
						{
							win_SubWalk_Emergency_Stop(sTakeOut_AlarmCode);
							return;
						}
						else{ //等待主任务流程恢复到当前窗口后在WM_REFRESH中执行异常处理流程,保证消息能正常处理
							;
						}
					}
					else{//当前窗口已关闭 - 不处理
						;
					}
				}
			break;	
		default:
				ASSERT(ERROR);
			break;
		}
		break;
	case WM_ALARM_CODE:
			CloseWindow(MAIN_TASK);
			(*ActiveWindowProc(MAIN_TASK))(WM_ALARM_CODE,Parameter,Info,hSrcWin,hTagWin);
		break;
	default:
		break;
	}
}
c++ 复制代码
//TAKE_TASK win_TakeStock.c
/**
 * @brief  窗口函数
 * @param  Type: 信息的类型
 * @param  Parameter: 数值型信息
 * @param  Info: 字符串型信息
 * @param  hSrcWin: 源窗口,消息的触发窗口
 * @param  hTagWin: 目标窗口,消息的目标窗口
 * @retval None
 * @note   具体处理接收到的信息(如按键输入等),每一个功能窗口都要有一个这样的函数
 *         这是一个内部函数,其他模块的窗口函数可以与它同名 
 */
static void WindowProc(WORD Type, WORD Parameter, BYTE *Info, WORD hSrcWin, WORD hTagWin)
{
	int i;
	switch( Type )		// 根据信息类型,提取及处理相应的信息
	{					
	case WM_CLOSE:
			CloseWindow(TAKE_TASK);
		break;
	case WM_REDRAW:
			Initialize();
			OpenWindow(TAKE_TASK,&Window);
		break;
	case WM_REFRESH:
			if( Take_Command_Irq[0].Idle ){
				TakeStock_Start_One_Irq();
			}
		break;
	case WM_TAKE_STOCK_CMD_EXC: 	//TAKE_STOCK执行结果
			if( Take_Command_Irq[0].Idle ){
				Take_Command_Irq[0].Idle = 0;
				// 后续任务往前移位   发送命令
				for(i=0;i<(sizeof(Take_Command_Irq)/sizeof(Take_Command_Irq[0])-1);i++){	
					Take_Command_Irq[i] = Take_Command_Irq[i+1];
				}
				Take_Command_Irq[sizeof(Take_Command_Irq)/sizeof(Take_Command_Irq[0])-1].Idle = 0;
				
				if( Take_Command_Irq[0].Idle ){
					TakeStock_Start_One_Irq();
				}
			}
		break;
	case WM_TAKE_STOCK_TASK_API: //任务返回的结果
			if( Take_Command_Irq[0].Idle && sExtMsg.srcWindow!=NULL){
				(sExtMsg.srcWindow->WindowProc)(Type,Parameter,Info,hSrcWin,sUser.SrcWindows);
			}
			//发送给TAKE_TASK消息
			(*ActiveWindowProc)(TAKE_TASK)(WM_TAKE_STOCK_CMD_EXC, TAKE_STOCK_EXE_OK, 0, SYS_WIN_TAKE_STOCK, 0);
		break;
	case WM_TAKE_STOCK_CMD:	//收到一个发送请求
			TakeCommandEnQueue(Parameter,Info,hSrcWin,hTagWin);
		break;
	case WM_ALARM_CODE:
			//发给主任务处理
			if( Take_Command_Irq[0].Idle && sExtMsg.srcWindow!=NULL){
				sTaskExcMsg.Type = Type;
				sTaskExcMsg.Parameter = Parameter;
				sTaskExcMsg.Info = Info;
				sTaskExcMsg.hSrcWin = hSrcWin;
				sTaskExcMsg.hTagWin = sUser.SrcWindows;
				
				(sExtMsg.srcWindow->WindowProc)(WM_TAKE_STOCK_EXC_TOMAIN,TAKE_STOCK_EXC_ALARM,(u8*)&sTaskExcMsg,SYS_WIN_TAKE_STOCK,0);
			}
			//发送给TAKE_TASK消息
			(*ActiveWindowProc)(TAKE_TASK)(WM_TAKE_STOCK_CMD_EXC, TAKE_STOCK_EXE_OK, 0, SYS_WIN_TAKE_STOCK, 0);
		break;
	default:
		break;
	}
}

/**
 * @brief 执行Kinco电机TAKE_STOCK指令
 */
static void TakeStock_Command(u16 uCommand, TAKESTOCK_USERDATA hUser)
{
	sExtMsg = Take_Command_Irq[0].Msgs;
	
	switch(uCommand)
	{
	case TAKE_STOCK_CMD_FIND_TRAY:
			win_TakeStock_FindTray(sExtMsg.TakeOut.StartPos,sExtMsg.TakeOut.EndPos);
		break;
	default:
			ASSERT(ERROR);
		break;
	}
}

/**
 * @brief 执行TAKE_STOCK命令
 */
static void TakeStock_Start_One_Irq(void)
{
	sUser.SrcWindows = Take_Command_Irq[0].SrcWindows;

	TakeStock_Command(Take_Command_Irq[0].Command, sUser);
}
c++ 复制代码
//TAKE_TASK win_TakeStock_FindTray.c

/**
 * @brief  盘点任务找托盘
 * @param  None
 * @retval None
 * @note   窗口加载函数,在窗口集合注册当前窗口;
 *         如果要每次打开窗口时都进行初始化,则应在此加入初始化
 */
void win_TakeStock_FindTray(u16 hStartPos,u16 hEndPos)
{
	if (Window.Active)return;
	if (RegisterWindow(TAKE_TASK,&Window)){
		MyRGV_Message.Take_Sys_Win = SYS_WIN_TAKE_STOCK_FIND_TRAY;
		Initialize();
		OpenWindow(TAKE_TASK,&Window);

		//...
		if(sAlarmCode){ 
			LOG_ALARM_CODE(sAlarmCode);
			CloseWindow(TAKE_TASK);
			(*ActiveWindowProc)(TAKE_TASK)(WM_ALARM_CODE, sAlarmCode, 0, SYS_WIN_TAKE_STOCK_FIND_TRAY, 0);
			return;
		}
	}
}

/**
 * @brief  窗口函数
 * @param  Type: 信息的类型
 * @param  Parameter: 数值型信息
 * @param  Info: 字符串型信息
 * @param  hSrcWin: 源窗口,消息的触发窗口
 * @param  hTagWin: 目标窗口,消息的目标窗口
 * @retval None
 * @note   具体处理接收到的信息(如按键输入等),每一个功能窗口都要有一个这样的函数
 *         这是一个内部函数,其他模块的窗口函数可以与它同名 
 */
static void WindowProc(WORD Type, WORD Parameter, BYTE *Info, WORD hSrcWin, WORD hTagWin)
{
	switch( Type )		// 根据信息类型,提取及处理相应的信息
	{					
	case WM_CLOSE:
			CloseWindow(TAKE_TASK);
		break;
	case WM_REDRAW:
			Initialize();
			OpenWindow(TAKE_TASK,&Window);
		break;
	case WM_REFRESH:
		{
			FindTraySpace();
		}
		break;
	case WM_TAKE_STOCK_TASK_MSG: //接收MAIN_TASK的消息
		switch(Parameter)
		{
		case TAKE_STOCK_MSG_CAL_TRAY: //运动流程结束
			{
				//...
				CloseWindow(TAKE_TASK);
				(*ActiveWindowProc)(TAKE_TASK)(WM_TAKE_STOCK_TASK_API, WM_TASK_STOCK_TASK_FIND_TRAY_OK, 0, SYS_WIN_TAKE_STOCK_FIND_TRAY, 0);
			}
			break;
		case TAKE_STOCK_MSG_CHANGE_ENDPOS: //改变目标位置
				if(Info!=NULL){
					sEndPos = *(u16*)Info;
				}
			break;
		case TAKE_STOCK_MSG_CLOSE: //回收资源,在windowExit窗口调用
				CloseWindow(TAKE_TASK);
				(*ActiveWindowProc)(TAKE_TASK)(WM_TAKE_STOCK_TASK_API, WM_TASK_STOCK_TASK_CLOSE_OK, 0, SYS_WIN_TAKE_STOCK_FIND_TRAY, 0);
			break;
		default:
				ASSERT(ERROR);
			break;
		}
		break;
	case WM_TAKE_STOCK_CMD:	//收到一个发送请求
			TakeCommandEnQueue(Parameter,Info,hSrcWin,hTagWin);
		break;
	case WM_ALARM_CODE:
			CloseWindow(TAKE_TASK);
			(*ActiveWindowProc(TAKE_TASK))(WM_ALARM_CODE,Parameter,Info,hSrcWin,hTagWin);
		break;
	default:
		break;
	}
}
相关推荐
艾莉丝努力练剑3 分钟前
【C++:红黑树】深入理解红黑树的平衡之道:从原理、变色、旋转到完整实现代码
大数据·开发语言·c++·人工智能·红黑树
l1t16 分钟前
利用DeepSeek优化SQLite求解数独SQL用于DuckDB
开发语言·数据库·sql·sqlite·duckdb
_OP_CHEN18 分钟前
C++进阶:(七)红黑树深度解析与 C++ 实现
开发语言·数据结构·c++·stl·红黑树·红黑树的旋转·红黑树的平衡调整
硅农深芯32 分钟前
如何使用ptqt5实现进度条的动态显示
开发语言·python·qt
Lhan.zzZ1 小时前
Qt数据可视化实战:饼图、线图与表格的完整指南
开发语言·qt·信息可视化
Acrelhuang1 小时前
筑牢用电防线:Acrel-1000 自动化系统赋能 35kV 园区高效供电-安科瑞黄安南
java·大数据·开发语言·人工智能·物联网
小龙报1 小时前
《算法通关指南数据结构和算法篇(4)--- 队列和queue》
c语言·开发语言·数据结构·c++·创业创新·学习方法·visual studio
民乐团扒谱机1 小时前
深入浅出理解克尔效应(Kerr Effect)及 MATLAB 仿真实现
开发语言·matlab·光学·非线性光学·克尔效应·kerr effect
7澄11 小时前
深入解析 LeetCode 数组经典问题:删除每行中的最大值与找出峰值
java·开发语言·算法·leetcode·intellij idea
计算衎2 小时前
.c .o .a .elf .a2l hex map 这些后缀文件的互相之间的联系和作用
开发语言·elf·gcc·c/c++·a2l