Explorar o código

Extension: Added more accessors for the Identity object's Status member

This patch should make it easier to keep the "status" member (attribute #5)
with its embedded Extended Status Field correct.
- Added the convenience functions CipIdentitySetStatusFlags() and
  CipIdentityClearStatusFlags() to set and clear single status flags in the
  Identity object's "status" member.
- Because setting a Major Fault flag in the "status" word should override the
  Extended Device Status field to kMajorFault (see Vol. 1, Table 5A-2.4)
  the Extended Device Status is saved in an extra member "ext_status". This
  makes it possible that the previous Extended Device Status reappears
  when the Major Fault condition vanishes.
  To achieve this the "status" member accessor functions SetDeviceStatus(),
  CipIdentitySetStatusFlags(), CipIdentityClearStatusFlags() and
  CipIdentitySetExtendedDeviceStatus() merge a new "status" value from the
  old "status" and the "ext_status" member.
- Added a typedef enum CipIdentityState with prepared values for the Identity
  object's "state" member. (Please don't confuse the status and state members.)
- Updated Doxygen documentation accordingly.

Signed-off-by: Stefan Mätje <stefan.maetje@esd.eu>
Stefan Mätje %!s(int64=6) %!d(string=hai) anos
pai
achega
d46c23ce63
Modificáronse 3 ficheiros con 89 adicións e 26 borrados
  1. 59 14
      source/src/cip/cipidentity.c
  2. 24 9
      source/src/cip/cipidentity.h
  3. 6 3
      source/src/opener_api.h

+ 59 - 14
source/src/cip/cipidentity.c

@@ -51,6 +51,7 @@ CipIdentityObject g_identity =
     OPENER_DEVICE_MINOR_REVISION
   },
   .status = 0, /* Attribute 5: Status */
+  .ext_status = kSelftestingUnknown,  /* Attribute 5: Extended Device Status field */
   .serial_number = 0, /* Attribute 6: Serial Number */
   .product_name = { /* Attribute 7: Product Name */
     sizeof(OPENER_DEVICE_NAME) - 1,
@@ -60,18 +61,69 @@ CipIdentityObject g_identity =
 };
 
 
-/** Private functions, sets the devices serial number
- * @param serial_number The serial number of the device
- */
+/* The Doxygen comment is with the function's prototype in opener_api.h. */
 void SetDeviceSerialNumber(const EipUint32 serial_number) {
   g_identity.serial_number = serial_number;
 }
 
-/** @brief Private function, sets the devices status
- * @param status The serial number of the device
- */
-void SetDeviceStatus(const EipUint16 status) {
+/* The Doxygen comment is with the function's prototype in opener_api.h. */
+void SetDeviceStatus(const CipWord status) {
   g_identity.status = status;
+  g_identity.ext_status = status & kExtStatusMask;
+}
+
+static inline void MergeStatusAndExtStatus(void)
+{
+  CipWord status_flags = g_identity.status & (~kExtStatusMask);
+  CipWord ext_status = g_identity.ext_status & kExtStatusMask;
+
+  /* Any major fault will override the current extended status with kMajorFault.
+    See comment on Major Fault at Vol. 1, Table 5A-2.4. */
+  if(0 != (status_flags & (kMajorRecoverableFault | kMajorUnrecoverableFault))) {
+    ext_status = kMajorFault;
+  }
+  g_identity.status = status_flags | ext_status;
+}
+
+/** @brief Set status flags of the device's Status word
+ *
+ * @param status_flags  flags to set in the Status word
+ *
+ *  This function sets status flags of the device's Status word and combines
+ *  the flag values with the internal ext_status member into a new Status
+ *  value.
+ */
+void CipIdentitySetStatusFlags(const CipWord status_flags) {
+  g_identity.status |= status_flags & (~kExtStatusMask);
+  MergeStatusAndExtStatus();
+}
+
+/** @brief Clear status flags of the device's Status word
+ *
+ * @param status_flags  flags to clear in the Status word
+ *
+ *  This function clears status flags of the device's Status word and combines
+ *  the flag values with the internal ext_status member into a new Status
+ *  value.
+ */
+void CipIdentityClearStatusFlags(const CipWord status_flags) {
+  g_identity.status &= ~(status_flags & (~kExtStatusMask));
+  MergeStatusAndExtStatus();
+}
+
+/** @brief Set the device's Extended Device Status field in the Status word
+ *
+ * @param   extended_status Extended Device Status field
+ *
+ *  This function sets the internal ext_status member of the Identity object
+ *  and combines its value depending on the other Status flags into a new
+ *  Status value.
+ */
+void CipIdentitySetExtendedDeviceStatus(
+  CipIdentityExtendedStatus extended_status) {
+  OPENER_TRACE_INFO("Setting extended status: %x\n", extended_status);
+  g_identity.ext_status = extended_status & kExtStatusMask;
+  MergeStatusAndExtStatus();
 }
 
 /** @brief Reset service
@@ -208,10 +260,3 @@ EipStatus CipIdentityInit() {
 
   return kEipStatusOk;
 }
-
-void CipIdentitySetExtendedDeviceStatus(
-  CipIdentityExtendedStatus extended_status) {
-  OPENER_TRACE_INFO("Setting extended status: %x\n", extended_status);
-  g_identity.status &= ~(0x70);
-  g_identity.status |= extended_status;
-}

+ 24 - 9
source/src/cip/cipidentity.h

@@ -33,16 +33,28 @@ typedef enum {
 
 /** @brief Constants for the extended status field in the Status word */
 typedef enum {
-  kSelftestingUnknown = 0x0000,
-  kFirmwareUpdateInProgress = 0x0010,
-  kStatusAtLeastOneFaultedIoConnection = 0x0020,
-  kNoIoConnectionsEstablished = 0x0030,
-  kNonVolatileConfigurationBad = 0x0040,
-  kMajorFault = 0x0050,
-  kAtLeastOneIoConnectionInRunMode = 0x0060,
-  kAtLeastOneIoConnectionEstablishedAllInIdleMode = 0x0070
+  kSelftestingUnknown = 0x0000U,
+  kFirmwareUpdateInProgress = 0x0010U,
+  kStatusAtLeastOneFaultedIoConnection = 0x0020U,
+  kNoIoConnectionsEstablished = 0x0030U,
+  kNonVolatileConfigurationBad = 0x0040U,
+  kMajorFault = 0x0050U,
+  kAtLeastOneIoConnectionInRunMode = 0x0060U,
+  kAtLeastOneIoConnectionEstablishedAllInIdleMode = 0x0070U,
+  kExtStatusMask = 0x00F0U
 } CipIdentityExtendedStatus;
 
+/** @brief Constants for the state member of the Identity object. */
+typedef enum {
+  kStateNonExistent = 0U,
+  kStateSelfTesting = 1U,
+  kStateStandby = 2U,
+  kStateOperational = 3U,
+  kStateMajorRecoverableFault = 4U,
+  kStateMajorUnrecoverableFault = 5U,
+  kStateDefault = 255U
+} CipIdentityState;
+
 /** @brief Declaration of the Identity object's structure type
  */
 typedef struct {
@@ -51,9 +63,10 @@ typedef struct {
   CipUint product_code; /**< Attribute 3: Product Code */
   CipRevision revision; /**< Attribute 4: Revision / CipUsint Major, CipUsint Minor */
   CipWord status; /**< Attribute 5: Status */
+  CipWord ext_status;   /**< Attribute 5: last set extended status, needed for Status handling */
   CipUdint serial_number; /**< Attribute 6: Serial Number, has to be set prior to OpENer's network initialization */
   CipShortString product_name; /**< Attribute 7: Product Name */
-  CipUsint state; /** Attribute 8: state */
+  CipUsint state; /** Attribute 8: state, this member could control the Module Status LED blink pattern */
 } CipIdentityObject;
 
 
@@ -68,6 +81,8 @@ CipIdentityObject g_identity;
  */
 EipStatus CipIdentityInit(void);
 
+void CipIdentitySetStatusFlags(const CipWord status_flags);
+void CipIdentityClearStatusFlags(const CipWord status_flags);
 void CipIdentitySetExtendedDeviceStatus(
   CipIdentityExtendedStatus extended_status);
 

+ 6 - 3
source/src/opener_api.h

@@ -85,11 +85,14 @@ void GetHostName(CipString *hostname);
 void SetDeviceSerialNumber(const EipUint32 serial_number);
 
 /** @ingroup CIP_API
- * @brief Set the current status of the device.
+ * @brief Set the device's Status word also updating the Extended Device Status
  *
- * @param status new Identity object's Status value
+ * @param status    complete Identity Object's Status word content
+ *
+ *  This function sets the status flags and the internal state of the Extended
+ *  Device Status field in Identity object's ext_status member.
  */
-void SetDeviceStatus(const EipUint16 status);
+void SetDeviceStatus(const CipWord status);
 
 /** @ingroup CIP_API
  * @brief Initialize and setup the CIP-stack