另外,这里有一个应用程序特别的检查(在ecatappl.c里面),如果状态转换从INIT到BOOT应该被完成,如果结果是NOERROR_INWORK,从站应该停留在INIT状态直到超时或者转换应该在AL_ControlRes里面完成
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250/ /** brief 应用程序控制响应 brief 这个函数被周期性调用,如果状态转换暂停(bEcatWaitForAlControlRes == TRUE) brief 如果ESM超时,状态转换将被拒绝。否则,应用程序特殊的状态转换函数将会被调用 brief 如果暂停状态转换被应用程序触发,状态转换将被应用程序(ECAT_StateChange)中完成 * void AL_ControlRes(void) { if(bEcatWaitForAlControlRes) { UINT16 result = 0; UINT8 Status = 0; UINT16 StatusCode = 0; if(EsmTimeoutCounter == 0) { Status = (UINT8)(nEcatStateTrans >> 4); /* ESM 超时*/ switch(nEcatStateTrans) { case INIT_2_PREOP: case INIT_2_BOOT: #if MAILBOX_SUPPORTED if(!bApplEsmPending) APPL_StopMailboxHandler(); MBX_StopMailboxHandler(); #endif if(bLocalErrorFlag) { /*设置应用程序特殊的错误*/ StatusCode = u16LocalErrorCode; } else { /*设置非特殊的错误*/ StatusCode = ALSTATUSCODE_UNSPECIFIEDERROR; } break; case PREOP_2_SAFEOP: if(!bApplEsmPending) APPL_StopInputHandler(); StopInputHandler(); if(bLocalErrorFlag) { /*设置应用程序的特殊错误*/ StatusCode = u16LocalErrorCode; } else { /*设置非特殊错误*/ StatusCode = ALSTATUSCODE_UNSPECIFIEDERROR; } break; case SAFEOP_2_OP: #if DC_SUPPORTED if(bDcSyncActive) { /*SafeOP to OP 超时溢出检查,当应用状态码需要被写入*/ if(!bDcRunning) { /*没有Sync0信号被接受*/ StatusCode = ALSTATUSCODE_NOSYNCERROR; } else if(!bEcatFirstOutputsReceived) { /*没有过程数据被接受*/ StatusCode = ALSTATUSCODE_SMWATCHDOG; } else { /*Pll 没有使能*/ StatusCode = ALSTATUSCODE_DCPLLSYNCERROR; } } else #endif { #if !OP_PD_REQUIRED /*设置有效的状态转换即使超时产生*/ Status = STATE_OP; StatusCode = 0; /* 从站是在可运行状态 */ bEcatOutputUpdateRunning = TRUE; #else StatusCode = ALSTATUSCODE_SMWATCHDOG; #endif } /*停止操作在一个错误的转换*/ if(StatusCode != 0) { if(!bApplEsmPending) APPL_StopOutputHandler(); StopOutputHandler(); } break; } } //ESM timeout else { /*调用应用程序特殊的转换函数和如果完成转换的话,函数将返回0*/ switch(nEcatStateTrans) { case INIT_2_PREOP: case INIT_2_BOOT: if(bApplEsmPending) { bApplEsmPending = FALSE; #if MAILBOX_SUPPORTED /*APPL_StartMailboxHandler()需要被调用 */ result = APPL_StartMailboxHandler(); if(result == 0) { /*应用程序特殊的转换成功,设置激活的邮箱操作*/ bMbxRunning = TRUE; Status = (UINT8)(nEcatStateTrans & STATE_MASK); } else { /*应用程序特殊的转换失败。(在pending中,应用程序需要完成它的转换) */ if(result != NOERROR_INWORK) { APPL_StopMailboxHandler(); MBX_StopMailboxHandler(); } } #endif } break; case PREOP_2_SAFEOP: if(bApplEsmPending) { bApplEsmPending = FALSE; result = APPL_StartInputHandler(&u16ALEventMask); if(result == 0) { bEcatInputUpdateRunning = TRUE; Status = STATE_SAFEOP; } else { /*The application specific transition failed. (In pending case the application need to complete the transition)*/ if(result != NOERROR_INWORK) { APPL_StopInputHandler(); StopInputHandler(); } } } break; case SAFEOP_2_OP: if(bApplEsmPending) { #if DC_SUPPORTED if(bDcSyncActive) { if(i16WaitForPllRunningTimeout > 0 && i16WaitForPllRunningTimeout <= i16WaitForPllRunningCnt) { /*PLL队列的有效时间是200ms(由APPL_StartOutputHandler()函数设置) 默认状态转换到OP状态 */ i16WaitForPllRunningTimeout = 0; i16WaitForPllRunningCnt = 0; result = APPL_StartOutputHandler(); if(result == 0) { /* 从站是在OPERATIONAL的状态 */ bEcatOutputUpdateRunning = TRUE; Status = STATE_OP; } else { if(result != NOERROR_INWORK) { APPL_StopOutputHandler(); StopOutputHandler(); } } } } else #endif { #if OP_PD_REQUIRED if(nPdOutputSize == 0 || bEcatFirstOutputsReceived) #endif { result = APPL_StartOutputHandler(); if(result == 0) { /* Slave is OPERATIONAL */ bEcatOutputUpdateRunning = TRUE; Status = STATE_OP; } else { if(result != NOERROR_INWORK) { APPL_StopOutputHandler(); StopOutputHandler(); } } } } } break; }//Switch - transition } if(Status != 0) { /*暂停状态转换停止=>写入AL的状态和状态码*/ bEcatWaitForAlControlRes = FALSE; if(StatusCode != 0) Status |= STATE_CHANGE; SetALStatus(Status,StatusCode); } }// Pending state transition (bEcatWaitForAlControlRes == true) }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98/ /** param alStatus 新的AL状态(写到寄存器0x130) param alStatusCode 新的AL状态码(写到寄存器0x134) brief 这个函数改变EtherCAT ASIC芯片的状态到所求的状态 * void SetALStatus(UINT8 alStatus, UINT16 alStatusCode) { UINT16 Value = alStatusCode; /*更新所需要的全局状态变量*/ if(nAlStatus != alStatus) { nAlStatus = alStatus; } nAlStatus &= ~STATE_DEVID; if (alStatusCode != 0xFFFF) { Value = SWAPWORD(Value); HW_EscWriteWord(Value,ESC_AL_STATUS_CODE_OFFSET); } Value = nAlStatus; Value = SWAPWORD(Value); HW_EscWriteWord(Value,ESC_AL_STATUS_OFFSET); #if LEDS_SUPPORTED || ESC_SUPPORT_ECAT_LED /*The Run LED state is set in Set LED Indication, only the Error LED blink code is set here*/ /*set Error blink code*/ if(alStatusCode == 0x00 || !(alStatus & STATE_CHANGE)) { u8EcatErrorLed = LED_OFF; } else if((alStatusCode == ALSTATUSCODE_NOSYNCERROR) || (alStatusCode == ALSTATUSCODE_DCPLLSYNCERROR)) { u8EcatErrorLed = LED_SINGLEFLASH; } else if((alStatusCode == ALSTATUSCODE_SMWATCHDOG)) { /* ECATCHANGE_START(V5.01) HW3*/ u8EcatErrorLed = LED_DOUBLEFLASH; /* ECATCHANGE_END(V5.01) HW3*/ } else { u8EcatErrorLed = LED_BLINKING; } #if ESC_SUPPORT_ECAT_LED u8EcatErrorLed |= LED_OVERRIDE; #if ESC_32BIT_ACCESS || ESC_16BIT_ACCESS /*The Run LED registers are also written in 16 or 32 Bit access => calculate value*/ switch((alStatus & STATE_CHANGE)) { case STATE_INIT: u8EcatRunLed = LED_OFF; break; case STATE_PREOP: u8EcatRunLed = LED_BLINKING; break; case STATE_SAFEOP: u8EcatRunLed = LED_SINGLEFLASH; break; case STATE_OP: u8EcatRunLed = LED_ON; break; case STATE_BOOT: u8EcatRunLed = LED_FLICKERING; break; } u8EcatRunLed |= LED_OVERRIDE; #if ESC_32BIT_ACCESS { UINT32 TmpVar = 0; TmpVar = SWAPDWORD((((UINT32)u8EcatRunLed) | (((UINT32)u8EcatErrorLed)>>8))); HW_EscWriteDWord(TmpVar,ESC_RUN_LED_OVERRIDE); } #else { UINT16 TmpVar = 0; TmpVar = SWAPWORD((((UINT16)u8EcatRunLed) | (((UINT16)u8EcatErrorLed)>>8))); HW_EscWriteWord(TmpVar,ESC_RUN_LED_OVERRIDE); } #endif #else HW_EscWriteByte(u8EcatErrorLed,ESC_ERROR_LED_OVERRIDE); #endif //#if ESC_32BIT_ACCESS || ESC_16BIT_ACCESS #endif // #if ESC_SUPPORT_ECAT_LED #endif //#if LEDS_SUPPORTED || ESC_SUPPORT_ECAT_LED }
最后
以上就是风中羊最近收集整理的关于AL_ControlRes的全部内容,更多相关AL_ControlRes内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复