3 w' n; W& @3 S% ?) _! k" q1、心跳帧的格式
' ]; T5 k* f) Z- a: J帧ID=0X700+NodeID 其中,数据区为1个字节的节点状态,不同的值对应的含义如下: 例如:节点5处于pre-operational模式,那么它就会定时发送:705 7F
$ D6 o) h' W' i" _$ D$ K2、对象字典的设置 - 1. /* NMT-heartbeat */\
6 O# r3 H) f9 d8 }1 f3 l - 2. & NODE_PREFIX ## _highestSubIndex_obj1016, /* ConsumerHeartbeatCount */\
& p0 z$ }* j5 m, C% r( ?/ ]" Q: ~, ]! d3 b - 3. NODE_PREFIX ## _obj1016, /* ConsumerHeartbeatEntries */\ " C3 G1 T$ G0 s/ m' l( V4 c
- 4. NODE_PREFIX ## _heartBeatTimers, /* ConsumerHeartBeatTimers */\
/ V4 q W' r; T; |2 M9 f - 5. & NODE_PREFIX ## _obj1017, /* ProducerHeartBeatTime */\
1 ^/ {" y M7 v. d - 6. TIMER_NONE, /* ProducerHeartBeatTimer */\
复制代码STM32F103作为心跳生产者(配置索引1017) STM32H7A3作为心跳消费者(配置索引1016) 3、生产者 心跳生产者发送心跳帧的周期由对象字典0x1017(ProducerHeartbeat Time)的值确定,单位为1ms。 设定发送心跳的定时器: 其中,*d->ProducerHeartBeatTime的值即对象字典0x1017的值。 每当定时器超时后,将调用ProducerHearbeatAlarm()发送心跳帧: - 1. /*! The Producer Timer Callback 9 z$ G1 n. M3 I1 u' g
- 2. **
8 F3 P8 r; b# L9 Y, @ - 3. **
* b8 r0 ]$ z' _7 { - 4. ** @param d , a5 w0 W/ ^: v; s2 ~! {0 N; ?
- 5. ** @param id
& K- X+ I; |0 X - 6. * @ingroup heartbeato
4 p6 S( J! b, m, u+ E# K" O - 7. **/
- a m {% e2 h y8 s3 n( o' g! Z - 8. void ProducerHeartbeatAlarm(CO_Data* d, UNS32 id) L' _2 r4 |" t' e' `" P
- 9. {
; j. Z% h N/ [1 p+ N# A - 10. (void)id; , {2 W$ I: o$ H: s0 \* ]# q0 Z
- 11. if(*d->ProducerHeartBeatTime) ' k. D# E( A7 P; V9 Y1 j
- 12. {
6 h; m$ I, e/ e, E- Q& A/ t, r" { - 13. Message msg;
% _ H$ `) X, i - 14. /* Time expired, the heartbeat must be sent immediately
0 b1 f) Q5 D w) ^: _0 M - 15. ** generate the correct node-id: this is done by the offset 1792 ( ?' Y6 Y$ Z4 ]
- 16. ** (decimal) and additionaly 4 W/ y3 U: `0 P! q, _- t$ Q
- 17. ** the node-id of this device.
& y# l9 ^8 F% {6 L% I - 18. */ - c$ W1 j% R* q* g0 e$ `3 ] a
- 19. UNS16 tmp = *d->bDeviceNodeId + 0x700; 7 z" m J& }3 A0 W
- 20. msg.cob_id = UNS16_LE(tmp);
3 @4 T/ M3 `6 S - 21. msg.len = (UNS8)0x01; 1 Z5 a4 G0 `7 J" n& x y+ g$ H/ z2 u
- 22. msg.rtr = 0;
" d9 k _1 Q5 |# g& j2 b - 23. msg.data[0] = d->nodeState; /* No toggle for heartbeat !*/ . N: m H/ x$ ^5 K! I) `
- 24. /* send the heartbeat */ ( d4 ?9 M* ?$ ?' Y) ~+ l3 a' m+ t
- 25. MSG_WAR(0x3130, "Producing heartbeat: ", d->nodeState);
( m4 }, d' y! p# A - 26. canSend(d->canHandle,&msg ); % ^! q. |$ `: Y3 W8 S' I
- 27.
3 i& @8 E) w6 A7 S* R3 y. h - 28. }else{ . N6 v: |0 t3 W6 I9 o5 l& e+ ^
- 29. d->ProducerHeartBeatTimer = DelAlarm(d->ProducerHeartBeatTimer);
1 ^1 u" q1 K/ I - 30. }
' N: L* j! E" @3 b$ [2 j$ A - 31. } 9 X k) v& H0 j0 F6 a5 E8 B
复制代码' j4 e7 n1 `9 p
4、消费者 心跳消费者发送心跳帧的周期由对象字典0x1016(Consumer HeartbeatTime)的值确定,单位为1ms。
! `' @# i3 b! ^+ d6 c$ ~ T" z' [ 设定接收心跳的定时器: 每当定时器超时后,将调用ConsumerHeartbeatAlarm()接收心跳帧: - 1. /*!
2 v' D2 U# Q: }$ l! T9 C$ ^ - 2. ** The Consumer Timer Callback 0 u+ b3 D6 {- a( N! Q
- 3. ** % c$ J; L* `9 u& D7 `8 L
- 4. ** @param d + v+ k# I8 s) l
- 5. ** @param id
( A: C# i8 ?6 p4 G* {% J2 ]3 v - 6. * @ingroup heartbeato : p2 _$ H9 m, q$ F
- 7. **/ $ @# ~" \% p' g
- 8. void ConsumerHeartbeatAlarm(CO_Data* d, UNS32 id) 9 o' g. {% B( T. H3 y0 s
- 9. { - Y" s( U1 ?" K" T; h# r/ F
- 10. UNS8 nodeId = (UNS8)(((d->ConsumerHeartbeatEntries[id]) & (UNS32)0x00FF0000) >> (UNS8)16);
+ R2 ?% o {& }! n5 \ - 11. /*MSG_WAR(0x00, "ConsumerHearbeatAlarm", 0x00);*/ + A, d8 z, H1 J
- 12.
. K5 {# g" K$ j! e1 Q+ U - 13. /* timer have been notified and is now free (non periodic)*/
7 P/ p( |1 }$ f( r5 A/ I1 `4 s - 14. /* -> avoid deleting re-assigned timer if message is received too late*/ w: E$ {! f; r8 w: |2 {
- 15. d->ConsumerHeartBeatTimers[id]=TIMER_NONE; 7 M i0 Y) _9 \6 {: H( Y
- 16.
" ]9 ]) ^ j5 L1 S - 17. /* set node state */ ' q! T0 r" \( b4 ^( B6 W8 r
- 18. d->NMTable[nodeId] = Disconnected; 9 h! U, @/ X" Y& Z# N- h- |
- 19. /*! call heartbeat error with NodeId */
% P J, r! ^5 [* L7 E! \ - 20. (*d->heartbeatError)(d, nodeId); & i0 R5 d3 k: n* [: E
- 21. }
" q" L9 N5 O1 S, K9 z0 \' N+ c
复制代码
( w- z- k: R* G9 ]
; r6 P1 U" @6 E; c+ @2 l1 @
* k7 y8 g1 f+ b5 d! g4 C, S8 g1 S3 k
5 R' ^& l* d P/ ?; h5、测试结果 利用PCAN监控CAN总线网络报文数据。可以看到主节点、从节点的心跳生产者报文701、704。
# d. c1 Y7 m8 p$ G) {) E
; e5 u# k/ ]5 x7 r8 V) x/ F" r
/ k: I, Z! b8 k1 R" K
9 P1 e% }# S1 R# x* G2 Y( K3 Z6 T! @
. x( T4 }5 A* U9 ?( M8 c7 c
. _# c0 `( X4 p- M
" F% _+ t( U) Y' L9 h$ o& p. e |