WaferTaskManager.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. using Aitex.Core.Common;
  2. using Aitex.Core.RT.Log;
  3. using Aitex.Core.Util;
  4. using MECF.Framework.Common.Equipment;
  5. using MECF.Framework.Common.Jobs;
  6. using MECF.Framework.Common.RecipeCenter;
  7. using MECF.Framework.Common.SubstrateTrackings;
  8. using MECF.Framework.Common.WaferHolder;
  9. using CyberX8_RT.Modules.PUF;
  10. using CyberX8_RT.Modules;
  11. using CyberX8_RT.Schedulers;
  12. using System;
  13. using System.Collections.Concurrent;
  14. using System.Collections.Generic;
  15. using System.Linq;
  16. using System.Text;
  17. using System.Threading.Tasks;
  18. using System.Windows.Markup;
  19. namespace CyberX8_RT.Dispatch
  20. {
  21. public class WaferTaskManager : Singleton<WaferTaskManager>
  22. {
  23. #region 内部变量
  24. /// <summary>
  25. /// FA回复
  26. /// </summary>
  27. private SchedulerFACallback _schedulerFACallback = new SchedulerFACallback();
  28. /// <summary>
  29. /// 任务锁
  30. /// </summary>
  31. private object _taskLocker = new object();
  32. /// <summary>
  33. /// 任务集合
  34. /// </summary>
  35. private List<WaferTask> _waferTaskList = new List<WaferTask>();
  36. /// <summary>
  37. /// Wafer task字典
  38. /// </summary>
  39. private ConcurrentDictionary<string, WaferTask> _waferTasksDic = new ConcurrentDictionary<string, WaferTask>();
  40. /// <summary>
  41. /// Wafer配对字典(key-自身WaferId,value-配对WaferId)
  42. /// </summary>
  43. private ConcurrentDictionary<string, string> _waferTaskMatchDic = new ConcurrentDictionary<string, string>();
  44. /// <summary>
  45. /// Wafer--WaferHolder任务字典(key-自身WaferId,value-WaferHolder任务)
  46. /// </summary>
  47. private ConcurrentDictionary<string, WaferHolderTask> _waferWaferHolderTaskDic = new ConcurrentDictionary<string, WaferHolderTask>();
  48. #endregion
  49. /// <summary>
  50. /// 初始化Task
  51. /// </summary>
  52. /// <param name="task"></param>
  53. public void InitializeTask(WaferTask task)
  54. {
  55. _waferTasksDic[task.WaferId] = task;
  56. lock(_taskLocker)
  57. {
  58. _waferTaskList.Add(task);
  59. }
  60. }
  61. /// <summary>
  62. /// 获取WaferTask
  63. /// </summary>
  64. /// <param name="waferId"></param>
  65. /// <returns></returns>
  66. public WaferTask GetWaferTask(string waferId)
  67. {
  68. return _waferTasksDic.ContainsKey(waferId) ? _waferTasksDic[waferId] : null;
  69. }
  70. /// <summary>
  71. /// 是否包含
  72. /// </summary>
  73. /// <param name="waferId"></param>
  74. /// <returns></returns>
  75. public bool Contains(string waferId)
  76. {
  77. return _waferTasksDic.ContainsKey(waferId);
  78. }
  79. /// <summary>
  80. /// 移除任务
  81. /// </summary>
  82. /// <param name="waferId"></param>
  83. public void RemoveWaferTask(string waferId)
  84. {
  85. if(_waferTasksDic.ContainsKey(waferId))
  86. {
  87. _waferTasksDic.TryRemove(waferId, out var task);
  88. task.Dispose();
  89. task.OnTaskComplete -= WaferTask_OnTaskComplete;
  90. LOG.WriteBackgroundLog(eEvent.EV_SCHEDULER, "Scheduler", $"remove wafer {waferId} task");
  91. }
  92. if(_waferTaskMatchDic.ContainsKey(waferId))
  93. {
  94. _waferTaskMatchDic.TryRemove(waferId,out var taskMath);
  95. }
  96. lock(_taskLocker)
  97. {
  98. int index = _waferTaskList.FindIndex(O => O.WaferId == waferId);
  99. if (index >= 0)
  100. {
  101. _waferTaskList.RemoveAt(index);
  102. }
  103. }
  104. }
  105. /// <summary>
  106. /// 加载Wafer Task集合
  107. /// </summary>
  108. /// <returns></returns>
  109. public List<WaferTask> LoadWaferTaskList()
  110. {
  111. return _waferTaskList.ToList();
  112. }
  113. /// <summary>
  114. /// 创建Wafer任务
  115. /// </summary>
  116. public void CreateWaferTask(List<ProcessJobInfo> processJobInfos, WaferHolderInfo waferHolderInfo,WaferHolderTask waferHolderTask)
  117. {
  118. int count = 0;
  119. string mateWaferTask = "";
  120. List<WaferInfo> wafers = new List<WaferInfo>();
  121. for(int i=0; i<processJobInfos.Count;i++)
  122. {
  123. ProcessJobInfo processJobInfo = processJobInfos[i];
  124. for(int j=0;j< processJobInfo.SlotWafers.Count; j++)
  125. {
  126. var item = processJobInfo.SlotWafers[j];
  127. if (WaferManager.Instance.CheckHasWafer(item.Item1, item.Item2))
  128. {
  129. WaferInfo waferInfo = WaferManager.Instance.GetWafer(item.Item1, item.Item2);
  130. if (waferInfo != null && waferInfo.ProcessState == EnumWaferProcessStatus.Idle)
  131. {
  132. if (!Contains(waferInfo.WaferID))
  133. {
  134. if (count == 0)
  135. {
  136. wafers.Add(waferInfo);
  137. count++;
  138. }
  139. else
  140. {
  141. wafers.Add(waferInfo);
  142. break;
  143. }
  144. }
  145. }
  146. }
  147. }
  148. }
  149. if (wafers.Count == 1&&CheckWaferHolderHasTwoProductionWafers(waferHolderInfo))
  150. {
  151. WaferInfo waferInfo = wafers[0];
  152. ModuleName pufModuleName = ModuleName.Unknown;
  153. ModuleName dummyModuleName = ModuleName.Unknown;
  154. bool lastSingleWaferToSideB = processJobInfos[0].SequenceRecipe.LastSingleWaferToSideB;
  155. if (lastSingleWaferToSideB)
  156. {
  157. pufModuleName = ModuleName.PUF2;
  158. dummyModuleName = ModuleName.PUF1;
  159. }
  160. else
  161. {
  162. pufModuleName = ModuleName.PUF1;
  163. dummyModuleName = ModuleName.PUF2;
  164. }
  165. List<WaferInfo> dummyWafers = DummyWaferManager.Instance.LoadDummyWafersByWaferHolder(waferHolderInfo);
  166. if (dummyWafers.Count != 0)
  167. {
  168. CreateWaferTaskSchedulerSequence(waferInfo, pufModuleName, waferHolderInfo, waferInfo.ProcessJob.SequenceRecipe, "");
  169. WaferInfo dummyInfo = null;
  170. if (dummyWafers.Count > 1)
  171. {
  172. foreach (WaferInfo info in dummyWafers)
  173. {
  174. //最后一片Wafer使用B面,那么dummy片使用0 slot
  175. if (lastSingleWaferToSideB && info.OriginSlot == 0)
  176. {
  177. dummyInfo = info;
  178. break;
  179. }
  180. //最后一片Wafer使用A面,那么dummy片使用1 slot
  181. if (!lastSingleWaferToSideB && info.OriginSlot == 1)
  182. {
  183. dummyInfo = info;
  184. break;
  185. }
  186. }
  187. if (dummyInfo == null)
  188. {
  189. dummyInfo=dummyWafers[0];
  190. }
  191. }
  192. else
  193. {
  194. dummyInfo = dummyWafers[0];
  195. }
  196. CreateDummyWaferTaskSchedulerSequence(waferHolderInfo.SequenceRecipe, dummyInfo, dummyModuleName, waferInfo.WaferID);
  197. _waferTaskMatchDic[waferInfo.WaferID] = dummyWafers[0].WaferID;
  198. _waferTaskMatchDic[dummyWafers[0].WaferID] = waferInfo.WaferID;
  199. _waferWaferHolderTaskDic[waferInfo.WaferID] = waferHolderTask;
  200. _waferWaferHolderTaskDic[dummyWafers[0].WaferID] = waferHolderTask;
  201. }
  202. else
  203. {
  204. CreateWaferTaskSchedulerSequence(waferInfo, pufModuleName, waferHolderInfo, waferInfo.ProcessJob.SequenceRecipe, "");
  205. _waferWaferHolderTaskDic[waferInfo.WaferID] = waferHolderTask;
  206. }
  207. }
  208. else
  209. {
  210. for (int i = 0; i < 2; i++)
  211. {
  212. WaferInfo waferInfo = wafers[i];
  213. ModuleName pufModuleName = ModuleName.Unknown;
  214. if (i == 0)
  215. {
  216. pufModuleName = ModuleName.PUF1;
  217. mateWaferTask = wafers[0].WaferID;
  218. CreateWaferTaskSchedulerSequence(waferInfo, pufModuleName, waferHolderInfo, waferInfo.ProcessJob.SequenceRecipe, "");
  219. }
  220. else
  221. {
  222. pufModuleName = ModuleName.PUF2;
  223. CreateWaferTaskSchedulerSequence(waferInfo, pufModuleName, waferHolderInfo, waferInfo.ProcessJob.SequenceRecipe, mateWaferTask);
  224. }
  225. }
  226. _waferTaskMatchDic[wafers[0].WaferID] = wafers[1].WaferID;
  227. _waferTaskMatchDic[wafers[1].WaferID] = wafers[0].WaferID;
  228. _waferWaferHolderTaskDic[wafers[0].WaferID] = waferHolderTask;
  229. _waferWaferHolderTaskDic[wafers[1].WaferID] = waferHolderTask;
  230. }
  231. }
  232. /// <summary>
  233. /// 检验WaferHolder是否存在两片生产片
  234. /// </summary>
  235. /// <param name="waferHolderInfo"></param>
  236. /// <returns></returns>
  237. private bool CheckWaferHolderHasTwoProductionWafers(WaferHolderInfo waferHolderInfo)
  238. {
  239. int count = 0;
  240. WaferInfo waferAInfo = WaferManager.Instance.GetWaferByWaferId(waferHolderInfo.WaferAId);
  241. if (waferAInfo != null && waferAInfo.WaferType==WaferType.Production)
  242. {
  243. count++;
  244. }
  245. WaferInfo waferBInfo = WaferManager.Instance.GetWaferByWaferId(waferHolderInfo.WaferBId);
  246. if (waferBInfo != null && waferBInfo.WaferType == WaferType.Production)
  247. {
  248. count++;
  249. }
  250. return count >= 2;
  251. }
  252. /// <summary>
  253. /// 创建WaferTask SchedulerSequence
  254. /// </summary>
  255. /// <param name="waferInfo"></param>
  256. /// <param name="pufModuleName"></param>
  257. /// <param name="waferHolderInfo"></param>
  258. /// <param name="sequenceRecipe"></param>
  259. private void CreateWaferTaskSchedulerSequence(WaferInfo waferInfo, ModuleName pufModuleName, WaferHolderInfo waferHolderInfo, SequenceRecipe sequenceRecipe, string mateWafeTask)
  260. {
  261. List<SchedulerSequence> sequences = SchedulerSequenceManager.Instance.AnalyWaferAllSchedulerSequence(waferInfo, pufModuleName, waferHolderInfo, sequenceRecipe);
  262. PUFEntity pufEntity = Singleton<RouteManager>.Instance.GetModule<PUFEntity>(pufModuleName.ToString());
  263. WaferTask waferTask = new WaferTask(waferInfo, pufEntity, sequences);
  264. if (!string.IsNullOrEmpty(mateWafeTask))
  265. {
  266. waferTask.MateWaferTask = mateWafeTask;
  267. }
  268. waferTask.OnTaskComplete += WaferTask_OnTaskComplete;
  269. LOG.WriteLog(eEvent.EV_SEQUENCE, "Scheduler", $"Create wafer {waferInfo.WaferID} task");
  270. InitializeTask(waferTask);
  271. }
  272. /// <summary>
  273. /// 创建DummyWaferTask
  274. /// </summary>
  275. /// <param name="waferInfos"></param>
  276. public void CreateDummyWaferTask(List<WaferInfo> waferInfos,SequenceRecipe sequenceRecipe,WaferHolderTask waferHolderTask)
  277. {
  278. string mateWaferTask = "";
  279. for (int i = 0; i < waferInfos.Count; i++)
  280. {
  281. WaferInfo waferInfo = waferInfos[i];
  282. int orginalSlot = waferInfo.OriginSlot;
  283. ModuleName pufModuleName = orginalSlot == 0 ? ModuleName.PUF1 : ModuleName.PUF2;
  284. if (!Contains(waferInfo.WaferID))
  285. {
  286. if (i == 0)
  287. {
  288. mateWaferTask = waferInfo.WaferID;
  289. CreateDummyWaferTaskSchedulerSequence(sequenceRecipe,waferInfo, pufModuleName, "");
  290. _waferWaferHolderTaskDic[waferInfo.WaferID] = waferHolderTask;
  291. }
  292. else
  293. {
  294. CreateDummyWaferTaskSchedulerSequence(sequenceRecipe,waferInfo, pufModuleName, mateWaferTask);
  295. _waferTaskMatchDic[mateWaferTask] = waferInfo.WaferID;
  296. _waferTaskMatchDic[waferInfo.WaferID] = mateWaferTask;
  297. _waferWaferHolderTaskDic[waferInfo.WaferID]= waferHolderTask;
  298. break;
  299. }
  300. }
  301. }
  302. }
  303. /// <summary>
  304. /// 创建Dummy Wafer Task 调度工序
  305. /// </summary>
  306. /// <param name="waferInfo"></param>
  307. /// <param name="pufModuleName"></param>
  308. /// <param name="mateWaferTask"></param>
  309. private void CreateDummyWaferTaskSchedulerSequence(SequenceRecipe sequenceRecipe,WaferInfo waferInfo,ModuleName pufModuleName,string mateWaferTask)
  310. {
  311. List<SchedulerSequence> sequences = SchedulerSequenceManager.Instance.AnalyDummyWaferAllSchedulerSequence(sequenceRecipe,waferInfo, pufModuleName);
  312. PUFEntity pufEntity = Singleton<RouteManager>.Instance.GetModule<PUFEntity>(pufModuleName.ToString());
  313. WaferTask waferTask = new WaferTask(waferInfo, pufEntity,sequences);
  314. if (!string.IsNullOrEmpty(mateWaferTask))
  315. {
  316. waferTask.MateWaferTask = mateWaferTask;
  317. }
  318. LOG.WriteLog(eEvent.EV_SEQUENCE, "Scheduler", $"Create Dummy wafer {waferInfo.WaferID} task");
  319. waferTask.OnTaskStart += WaferTask_OnTaskStart;
  320. waferTask.OnTaskComplete += WaferTask_OnTaskComplete;
  321. InitializeTask(waferTask);
  322. }
  323. /// <summary>
  324. /// 任务开始
  325. /// </summary>
  326. /// <param name="id"></param>
  327. /// <exception cref="NotImplementedException"></exception>
  328. private void WaferTask_OnTaskStart(string id)
  329. {
  330. WaferInfo waferInfo = WaferManager.Instance.GetWaferByWaferId(id);
  331. if (waferInfo != null && waferInfo.WaferType == WaferType.Production)
  332. {
  333. ModuleName moduleName = (ModuleName)waferInfo.OriginStation;
  334. if (ModuleHelper.IsLoadPort(moduleName))
  335. {
  336. CycleManager.Instance.UpdateCycleWaferCount(moduleName.ToString());
  337. }
  338. _schedulerFACallback.JobWaferStart(JobProcesser.Instance.GetControlJobInfoByProcessJob(waferInfo.ProcessJob),
  339. waferInfo.SequenceName, waferInfo.OriginSlot);
  340. }
  341. }
  342. /// <summary>
  343. /// Wafer task完成事件
  344. /// </summary>
  345. /// <param name="id"></param>
  346. private void WaferTask_OnTaskComplete(string id)
  347. {
  348. WaferInfo waferInfo=WaferManager.Instance.GetWaferByWaferId(id);
  349. if (waferInfo != null&&waferInfo.WaferType==WaferType.Production)
  350. {
  351. ModuleName moduleName = (ModuleName)waferInfo.OriginStation;
  352. if (ModuleHelper.IsLoadPort(moduleName))
  353. {
  354. CycleManager.Instance.UpdateCycleWaferCount(moduleName.ToString());
  355. }
  356. _schedulerFACallback.JobWaferEnd(JobProcesser.Instance.GetControlJobInfoByProcessJob(waferInfo.ProcessJob),
  357. waferInfo.SequenceName, waferInfo.OriginSlot);
  358. }
  359. RemoveWaferTask(id);
  360. }
  361. /// <summary>
  362. /// 暂停
  363. /// </summary>
  364. public void PauseAllTask()
  365. {
  366. List<WaferTask> waferTasks = _waferTaskList.ToList();
  367. foreach(WaferTask item in waferTasks)
  368. {
  369. item.Pause();
  370. }
  371. }
  372. /// <summary>
  373. /// 恢复所有任务
  374. /// </summary>
  375. public void ResumeAllTask()
  376. {
  377. List<WaferTask> waferTasks = _waferTaskList.ToList();
  378. foreach (WaferTask item in waferTasks)
  379. {
  380. item.Resume();
  381. }
  382. }
  383. /// <summary>
  384. /// 恢复所有任务
  385. /// </summary>
  386. public void RemoveAllTask()
  387. {
  388. List<WaferTask> waferTasks = _waferTaskList.ToList();
  389. foreach (WaferTask item in waferTasks)
  390. {
  391. RemoveWaferTask(item.WaferId);
  392. }
  393. }
  394. /// <summary>
  395. /// 根据WaferId获取配对另一个WaferId
  396. /// </summary>
  397. /// <param name="waferId"></param>
  398. /// <returns></returns>
  399. public string GetMatchWaferIdByWaferId(string waferId)
  400. {
  401. return _waferTaskMatchDic.ContainsKey(waferId) ? _waferTaskMatchDic[waferId] : "";
  402. }
  403. /// <summary>
  404. /// 移除WaferId匹配WaferHolderTask字典
  405. /// </summary>
  406. /// <param name="waferId"></param>
  407. public void RemoveWaferIdMatchWaferHolderTaskDic(string waferId)
  408. {
  409. if(_waferWaferHolderTaskDic.ContainsKey(waferId))
  410. {
  411. _waferWaferHolderTaskDic.TryRemove(waferId, out var waferHolderTask);
  412. }
  413. }
  414. /// <summary>
  415. /// 获取WaferId匹配WaferHolderTask字典
  416. /// </summary>
  417. /// <param name="waferId"></param>
  418. /// <returns></returns>
  419. public WaferHolderTask GetWaferHolderTaskByWaferId(string waferId)
  420. {
  421. return _waferWaferHolderTaskDic.ContainsKey(waferId) ? _waferWaferHolderTaskDic[waferId] : null;
  422. }
  423. /// <summary>
  424. /// 获取WaferHolder Task对应的Wafer Task WaferId集合
  425. /// </summary>
  426. /// <param name="waferHolderId"></param>
  427. /// <returns></returns>
  428. public List<string> GetWaferHolderMathWaferId(string waferHolderId)
  429. {
  430. List<string> keys = _waferWaferHolderTaskDic.Keys.ToList();
  431. List<string> result = new List<string>();
  432. foreach(string item in keys)
  433. {
  434. if(_waferWaferHolderTaskDic[item].WaferHolderInfo.Id==waferHolderId)
  435. {
  436. result.Add(item);
  437. }
  438. }
  439. return result;
  440. }
  441. }
  442. }