nvdata.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /*******************************************************************************
  2. * Copyright (c) 2019, Rockwell Automation, Inc.
  3. * All rights reserved.
  4. *
  5. ******************************************************************************/
  6. /** @file nvdata.c
  7. * @brief This file implements common stuff to handle Non Volatile data.
  8. *
  9. * This module implements NvdataLoad(), a function to load all NV data of
  10. * known common objects.
  11. * Also this module provides callback functions to store NV data of known
  12. * objects when called by the EIP stack.
  13. */
  14. #include "nvdata.h"
  15. #include "trace.h"
  16. /* Include headers of objects that need support for NV data here. */
  17. #include "nvqos.h"
  18. #include "nvtcpip.h"
  19. /** @brief Load NV data for all object classes
  20. *
  21. * @return kEipStatusOk on success, kEipStatusError if failure for any object occurred
  22. *
  23. * This function loads the NV data for each object class that supports NV data from
  24. * external storage. If any of the load routines fails then for that object class
  25. * the current object instance values are written as new NV data. That should be
  26. * the default data.
  27. *
  28. * The load routines should be of the form
  29. * int Nv<ObjClassName>Load(<ObjectInstanceDataType> *p_obj_instance);
  30. * and return (-1) on failure and (0) on success.
  31. */
  32. EipStatus NvdataLoad(void) {
  33. /* Load NV data for QoS object instance */
  34. EipStatus eip_status = NvQosLoad(&g_qos);
  35. if (kEipStatusError != eip_status) {
  36. eip_status =
  37. ( kEipStatusError == NvQosStore(&g_qos) ) ? kEipStatusError : eip_status;
  38. }
  39. return eip_status;
  40. }
  41. /** A PostSetCallback for QoS class to store NV attributes
  42. *
  43. * @param instance pointer to instance of QoS class
  44. * @param attribute pointer to attribute structure
  45. * @param service the CIP service code of current request
  46. *
  47. * @return kEipStatusOk: success; kEipStatusError: failure
  48. *
  49. * This function implements the PostSetCallback for the QoS class. The
  50. * purpose of this function is to save the NV attributes of the QoS
  51. * class instance to external storage.
  52. *
  53. * This application specific implementation chose to save all attributes
  54. * at once using a single NvQosStore() call.
  55. */
  56. EipStatus NvQosSetCallback(CipInstance *const instance,
  57. CipAttributeStruct *const attribute,
  58. CipByte service) {
  59. /* Suppress unused parameter compiler warning. */
  60. (void)service;
  61. EipStatus status = kEipStatusOk;
  62. if ( 0 != (kNvDataFunc & attribute->attribute_flags) ) {
  63. OPENER_TRACE_INFO("NV data update: %s, i %" PRIu32 ", a %" PRIu16 "\n",
  64. instance->cip_class->class_name,
  65. instance->instance_number,
  66. attribute->attribute_number);
  67. status = NvQosStore(&g_qos);
  68. }
  69. return status;
  70. }
  71. /** A PostSetCallback for TCP/IP class to store NV attributes
  72. *
  73. * @param instance pointer to instance of TCP/IP class
  74. * @param attribute pointer to attribute structure
  75. * @param service the CIP service code of current request
  76. *
  77. * This function implements the PostSetCallback for the TCP/IP class. The
  78. * purpose of this function is to save the NV attributes of the TCP/IP
  79. * class instance to external storage.
  80. *
  81. * This application specific implementation chose to save all attributes
  82. * at once using a single NvTcpipStore() call.
  83. */
  84. EipStatus NvTcpipSetCallback(CipInstance *const instance,
  85. CipAttributeStruct *const attribute,
  86. CipByte service) {
  87. EipStatus status = kEipStatusOk;
  88. if ( 0 != (kNvDataFunc & attribute->attribute_flags) ) {
  89. /* Workaround: Update only if service is not flagged. */
  90. if ( 0 == (0x80 & service) ) {
  91. OPENER_TRACE_INFO("NV data update: %s, i %" PRIu32 ", a %" PRIu16 "\n",
  92. instance->cip_class->class_name,
  93. instance->instance_number,
  94. attribute->attribute_number);
  95. status = NvTcpipStore(&g_tcpip);
  96. }
  97. }
  98. return status;
  99. }