Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

326 linhas
14 KiB

  1. #include "plc_device.h"
  2. #include "plsr_persistence.h"
  3. #include <inttypes.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. static unsigned int TestCount;
  7. #define TEST_CHECK(condition) \
  8. do \
  9. { \
  10. TestCount++; \
  11. if (!(condition)) \
  12. { \
  13. (void)fprintf(stderr, "FAIL line %d: %s\n", __LINE__, #condition); \
  14. exit(EXIT_FAILURE); \
  15. } \
  16. } while (0)
  17. static void TestAddressMap(void)
  18. {
  19. uint16_t eventAddress;
  20. PLC_DEVICE_EVENT_RECORD eventRecord;
  21. TEST_CHECK(PlsrAxisAddressMap[0].hsdRuntimeBase == 0U);
  22. TEST_CHECK(PlsrAxisAddressMap[3].hsdRuntimeBase == 12U);
  23. TEST_CHECK(PlsrAxisAddressMap[0].smPulseActiveAddress == 1000U);
  24. TEST_CHECK(PlsrAxisAddressMap[3].smDirectionAddress == 1061U);
  25. TEST_CHECK(PlsrAxisAddressMap[2].sdRuntimeBase == 1040U);
  26. TEST_CHECK(PlsrAxisAddressMap[3].eventBase == 6300U);
  27. TEST_CHECK(PlcDeviceGetEventAddress(0U, 1U, &eventAddress) == PLC_DEVICE_OK);
  28. TEST_CHECK(eventAddress == 6000U);
  29. TEST_CHECK(PlcDeviceGetEventAddress(3U, 100U, &eventAddress) == PLC_DEVICE_OK);
  30. TEST_CHECK(eventAddress == 6399U);
  31. TEST_CHECK(PlcDeviceGetEventAddress(4U, 1U, &eventAddress)
  32. == PLC_DEVICE_INVALID_ARGUMENT);
  33. TEST_CHECK(PlcDeviceGetEventAddress(0U, 0U, &eventAddress)
  34. == PLC_DEVICE_INVALID_ARGUMENT);
  35. TEST_CHECK(PlcDevicePublishEvent(0U, 1U, 5U) == PLC_DEVICE_OK);
  36. TEST_CHECK(PlcDevicePublishEvent(0U, 1U, 6U) == PLC_DEVICE_OK);
  37. TEST_CHECK(PlcDeviceReadEvent(6000U, &eventRecord) == PLC_DEVICE_OK);
  38. TEST_CHECK(eventRecord.count == 2UL);
  39. TEST_CHECK(eventRecord.lastReason == 6U);
  40. TEST_CHECK(eventRecord.pending == 1U);
  41. TEST_CHECK(PlcDeviceAcknowledgeEvent(6000U) == PLC_DEVICE_OK);
  42. TEST_CHECK(PlcDeviceReadEvent(6000U, &eventRecord) == PLC_DEVICE_OK);
  43. TEST_CHECK(eventRecord.count == 2UL);
  44. TEST_CHECK(eventRecord.pending == 0U);
  45. TEST_CHECK(PlcDevicePublishEvent(4U, 1U, 0U)
  46. == PLC_DEVICE_INVALID_ARGUMENT);
  47. TEST_CHECK(PlcDeviceReadEvent(5999U, &eventRecord)
  48. == PLC_DEVICE_INVALID_ADDRESS);
  49. TEST_CHECK(PlcDeviceReadEvent(6000U, NULL) == PLC_DEVICE_NULL_POINTER);
  50. }
  51. static void TestHsdAndPersistence(void)
  52. {
  53. static const uint8_t crcVector[] = "123456789";
  54. uint16_t value16;
  55. int32_t value32;
  56. const int32_t firstDword = INT32_C(0x12345678);
  57. const int32_t secondDword = -INT32_C(0x1020304);
  58. TEST_CHECK(PlsrPersistenceTestCrc32(crcVector,
  59. sizeof(crcVector) - 1UL)
  60. == 0xCBF43926UL);
  61. TEST_CHECK(PlsrPersistenceTestCrc32(NULL, 0UL) == 0UL);
  62. TEST_CHECK(PlsrPersistenceTestCrc32(NULL, 1UL) == 0UL);
  63. PlsrPersistenceTestResetStorage();
  64. TEST_CHECK(PlcDeviceInit() == PLC_DEVICE_OK);
  65. TEST_CHECK(PlcDeviceGetLastHsdLoadResult() == PLSR_PERSISTENCE_DEFAULTED);
  66. TEST_CHECK(PlcDeviceIsHsdDirty() != 0U);
  67. TEST_CHECK(PlcDeviceWriteHsdConfig(460U, 11) == PLC_DEVICE_OK);
  68. TEST_CHECK(PlcDeviceWriteHsdConfig(539U, 0xB4E2U) == PLC_DEVICE_OK);
  69. TEST_CHECK(PlcDeviceWriteHsdConfig(0U, 1) == PLC_DEVICE_READ_ONLY);
  70. TEST_CHECK(PlcDeviceWriteHsdConfig(459U, 1) == PLC_DEVICE_INVALID_ADDRESS);
  71. TEST_CHECK(PlcDeviceReadHsd(460U, &value16) == PLC_DEVICE_OK);
  72. TEST_CHECK(value16 == 11);
  73. TEST_CHECK(PlcDeviceReadHsd(539U, &value16) == PLC_DEVICE_OK);
  74. TEST_CHECK(value16 == 0xB4E2U);
  75. TEST_CHECK(PlcDeviceReadHsd(540U, &value16) == PLC_DEVICE_INVALID_ADDRESS);
  76. /* 32 位兼容布局:低地址=低16位,高地址=高16位。 */
  77. TEST_CHECK(PlcDevicePublishHsdDword(0U, firstDword) == PLC_DEVICE_OK);
  78. TEST_CHECK(PlcDeviceReadHsd(0U, &value16) == PLC_DEVICE_OK);
  79. TEST_CHECK(value16 == 0x5678U);
  80. TEST_CHECK(PlcDeviceReadHsd(1U, &value16) == PLC_DEVICE_OK);
  81. TEST_CHECK(value16 == 0x1234U);
  82. TEST_CHECK(PlcDeviceReadHsdDword(0U, &value32) == PLC_DEVICE_OK);
  83. TEST_CHECK(value32 == firstDword);
  84. TEST_CHECK(PlcDeviceReadHsdDword(1U, &value32)
  85. == PLC_DEVICE_INVALID_ADDRESS);
  86. TEST_CHECK(PlcDeviceReadHsdDword(15U, &value32)
  87. == PLC_DEVICE_INVALID_ADDRESS);
  88. TEST_CHECK(PlcDeviceCheckpointHsd() == PLC_DEVICE_OK);
  89. TEST_CHECK(PlcDeviceIsHsdDirty() == 0U);
  90. TEST_CHECK(PlcDeviceWriteHsdConfig(460U, 22) == PLC_DEVICE_OK);
  91. TEST_CHECK(PlcDevicePublishHsdDword(0U, secondDword) == PLC_DEVICE_OK);
  92. TEST_CHECK(PlcDeviceCheckpointHsd() == PLC_DEVICE_OK);
  93. PlsrPersistenceTestCorruptNewestHsd();
  94. TEST_CHECK(PlcDeviceInit() == PLC_DEVICE_OK);
  95. TEST_CHECK(PlcDeviceGetLastHsdLoadResult() == PLSR_PERSISTENCE_OK);
  96. TEST_CHECK(PlcDeviceReadHsd(460U, &value16) == PLC_DEVICE_OK);
  97. TEST_CHECK(value16 == 11);
  98. TEST_CHECK(PlcDeviceReadHsdDword(0U, &value32) == PLC_DEVICE_OK);
  99. TEST_CHECK(value32 == firstDword);
  100. }
  101. static void TestHsdDefaults(void)
  102. {
  103. uint16_t value;
  104. PlsrPersistenceTestResetStorage();
  105. TEST_CHECK(PlcDeviceInit() == PLC_DEVICE_OK);
  106. TEST_CHECK(PlcDeviceGetLastHsdLoadResult() == PLSR_PERSISTENCE_DEFAULTED);
  107. /* K0(HSD460~539)出厂默认即可直接启动。 */
  108. TEST_CHECK(PlcDeviceReadHsd(460U, &value) == PLC_DEVICE_OK);
  109. TEST_CHECK(value == 1000); /* 默认速度低16位 */
  110. TEST_CHECK(PlcDeviceReadHsd(461U, &value) == PLC_DEVICE_OK);
  111. TEST_CHECK(value == 0); /* 默认速度高16位 */
  112. TEST_CHECK(PlcDeviceReadHsd(462U, &value) == PLC_DEVICE_OK);
  113. TEST_CHECK(value == 100); /* 加速时间 ms */
  114. TEST_CHECK(PlcDeviceReadHsd(463U, &value) == PLC_DEVICE_OK);
  115. TEST_CHECK(value == 100); /* 减速时间 ms */
  116. TEST_CHECK(PlcDeviceReadHsd(466U, &value) == PLC_DEVICE_OK);
  117. TEST_CHECK(value == 0x86A0U); /* 最大速度低16位 100000 */
  118. TEST_CHECK(PlcDeviceReadHsd(467U, &value) == PLC_DEVICE_OK);
  119. TEST_CHECK(value == 1); /* 最大速度高16位 */
  120. TEST_CHECK(PlcDeviceReadHsd(472U, &value) == PLC_DEVICE_OK);
  121. TEST_CHECK(value == 50); /* FOLLOW 1~100 */
  122. TEST_CHECK(PlcDeviceReadHsd(539U, &value) == PLC_DEVICE_OK);
  123. TEST_CHECK(value == 0);
  124. }
  125. static void TestHsdMetaPersistence(void)
  126. {
  127. PlsrPersistenceTestResetStorage();
  128. TEST_CHECK(PlcDeviceInit() == PLC_DEVICE_OK);
  129. TEST_CHECK(PlcDeviceGetRestoredHsdPositionValid() == 0U);
  130. TEST_CHECK(PlcDeviceGetRestoredHsdLastBusy() == 0U);
  131. /* 正常停机保存:positionValid=1, lastBusy=0。 */
  132. TEST_CHECK(PlcDeviceSetHsdCheckpointMeta(1U, 0U) == PLC_DEVICE_OK);
  133. TEST_CHECK(PlcDeviceCheckpointHsd() == PLC_DEVICE_OK);
  134. TEST_CHECK(PlcDeviceInit() == PLC_DEVICE_OK);
  135. TEST_CHECK(PlcDeviceGetRestoredHsdPositionValid() == 1U);
  136. TEST_CHECK(PlcDeviceGetRestoredHsdLastBusy() == 0U);
  137. /* 运动中掉电保存:lastBusy=1,恢复后位置不可信。 */
  138. TEST_CHECK(PlcDeviceSetHsdCheckpointMeta(1U, 1U) == PLC_DEVICE_OK);
  139. TEST_CHECK(PlcDeviceCheckpointHsd() == PLC_DEVICE_OK);
  140. TEST_CHECK(PlcDeviceInit() == PLC_DEVICE_OK);
  141. TEST_CHECK(PlcDeviceGetRestoredHsdPositionValid() == 1U);
  142. TEST_CHECK(PlcDeviceGetRestoredHsdLastBusy() == 1U);
  143. }
  144. static void TestSfd(void)
  145. {
  146. uint16_t value;
  147. PlsrPersistenceTestResetStorage();
  148. TEST_CHECK(PlcDeviceInit() == PLC_DEVICE_OK);
  149. TEST_CHECK(PlcDeviceGetLastSfdLoadResult()
  150. == PLSR_PERSISTENCE_DEFAULTED);
  151. TEST_CHECK(PlcDeviceIsSfdDirty() != 0U);
  152. TEST_CHECK(PlcDeviceReadSfd(907U, &value) == PLC_DEVICE_OK);
  153. TEST_CHECK(value == 10);
  154. TEST_CHECK(PlcDeviceReadSfd(927U, &value) == PLC_DEVICE_OK);
  155. TEST_CHECK(value == 20);
  156. TEST_CHECK(PlcDeviceReadSfd(943U, &value) == PLC_DEVICE_OK);
  157. TEST_CHECK(value == 0x0201);
  158. TEST_CHECK(PlcDeviceReadSfd(956U, &value) == PLC_DEVICE_OK);
  159. TEST_CHECK(value == 0x86A0);
  160. TEST_CHECK(PlcDeviceReadSfd(957U, &value) == PLC_DEVICE_OK);
  161. TEST_CHECK(value == 1);
  162. /* 第1套参数出厂默认可直接启动。 */
  163. TEST_CHECK(PlcDeviceReadSfd(950U, &value) == PLC_DEVICE_OK);
  164. TEST_CHECK(value == 1000);
  165. TEST_CHECK(PlcDeviceReadSfd(951U, &value) == PLC_DEVICE_OK);
  166. TEST_CHECK(value == 0);
  167. TEST_CHECK(PlcDeviceReadSfd(952U, &value) == PLC_DEVICE_OK);
  168. TEST_CHECK(value == 100);
  169. TEST_CHECK(PlcDeviceReadSfd(962U, &value) == PLC_DEVICE_OK);
  170. TEST_CHECK(value == 50);
  171. TEST_CHECK(PlcDeviceReadSfd(1297U, &value) == PLC_DEVICE_OK);
  172. TEST_CHECK(value == 10);
  173. TEST_CHECK(PlsrPersistenceLoadSfd(NULL)
  174. == PLSR_PERSISTENCE_INVALID_ARGUMENT);
  175. TEST_CHECK(PlsrPersistenceSaveSfd(NULL)
  176. == PLSR_PERSISTENCE_INVALID_ARGUMENT);
  177. TEST_CHECK(PlcDeviceWriteSfd(900U, 123) == PLC_DEVICE_OK);
  178. TEST_CHECK(PlcDeviceWriteSfd(1419U, 0xB456U) == PLC_DEVICE_OK);
  179. TEST_CHECK(PlcDeviceReadSfd(900U, &value) == PLC_DEVICE_OK);
  180. TEST_CHECK(value == 123);
  181. TEST_CHECK(PlcDeviceReadSfd(1419U, &value) == PLC_DEVICE_OK);
  182. TEST_CHECK(value == 0xB456U);
  183. TEST_CHECK(PlcDeviceReadSfd(899U, &value) == PLC_DEVICE_INVALID_ADDRESS);
  184. TEST_CHECK(PlcDeviceReadSfd(1420U, &value) == PLC_DEVICE_INVALID_ADDRESS);
  185. TEST_CHECK(PlcDeviceIsSfdDirty() != 0U);
  186. TEST_CHECK(PlcDeviceSaveSfd() == PLC_DEVICE_OK);
  187. TEST_CHECK(PlcDeviceIsSfdDirty() == 0U);
  188. TEST_CHECK(PlcDeviceInit() == PLC_DEVICE_OK);
  189. TEST_CHECK(PlcDeviceGetLastSfdLoadResult() == PLSR_PERSISTENCE_OK);
  190. TEST_CHECK(PlcDeviceReadSfd(900U, &value) == PLC_DEVICE_OK);
  191. TEST_CHECK(value == 123);
  192. TEST_CHECK(PlcDeviceReadSfd(1419U, &value) == PLC_DEVICE_OK);
  193. TEST_CHECK(value == 0xB456U);
  194. TEST_CHECK(PlcDeviceWriteSfd(900U, 789) == PLC_DEVICE_OK);
  195. TEST_CHECK(PlcDeviceWriteSfd(1419U, 0x9876U) == PLC_DEVICE_OK);
  196. TEST_CHECK(PlcDeviceSaveSfd() == PLC_DEVICE_OK);
  197. PlsrPersistenceTestCorruptNewestSfd();
  198. TEST_CHECK(PlcDeviceInit() == PLC_DEVICE_OK);
  199. TEST_CHECK(PlcDeviceReadSfd(900U, &value) == PLC_DEVICE_OK);
  200. TEST_CHECK(value == 123);
  201. TEST_CHECK(PlcDeviceReadSfd(1419U, &value) == PLC_DEVICE_OK);
  202. TEST_CHECK(value == 0xB456U);
  203. TEST_CHECK(PlcDeviceWriteSfd(900U, 1001) == PLC_DEVICE_OK);
  204. PlsrPersistenceTestSetSfdFault(PLSR_TEST_SFD_FAULT_ERASE);
  205. TEST_CHECK(PlcDeviceSaveSfd() == PLC_DEVICE_PERSISTENCE_ERROR);
  206. TEST_CHECK(PlcDeviceIsSfdDirty() != 0U);
  207. TEST_CHECK(PlcDeviceInit() == PLC_DEVICE_OK);
  208. TEST_CHECK(PlcDeviceReadSfd(900U, &value) == PLC_DEVICE_OK);
  209. TEST_CHECK(value == 123);
  210. TEST_CHECK(PlcDeviceWriteSfd(900U, 1002) == PLC_DEVICE_OK);
  211. PlsrPersistenceTestSetSfdFault(PLSR_TEST_SFD_FAULT_PROGRAM);
  212. TEST_CHECK(PlcDeviceSaveSfd() == PLC_DEVICE_PERSISTENCE_ERROR);
  213. TEST_CHECK(PlcDeviceInit() == PLC_DEVICE_OK);
  214. TEST_CHECK(PlcDeviceReadSfd(900U, &value) == PLC_DEVICE_OK);
  215. TEST_CHECK(value == 123);
  216. TEST_CHECK(PlcDeviceWriteSfd(900U, 1003) == PLC_DEVICE_OK);
  217. PlsrPersistenceTestSetSfdFault(PLSR_TEST_SFD_FAULT_VERIFY);
  218. TEST_CHECK(PlcDeviceSaveSfd() == PLC_DEVICE_PERSISTENCE_ERROR);
  219. TEST_CHECK(PlcDeviceInit() == PLC_DEVICE_OK);
  220. TEST_CHECK(PlcDeviceReadSfd(900U, &value) == PLC_DEVICE_OK);
  221. TEST_CHECK(value == 123);
  222. TEST_CHECK(PlcDeviceWriteSfd(900U, 1004) == PLC_DEVICE_OK);
  223. PlsrPersistenceTestSetSfdFault(PLSR_TEST_SFD_FAULT_BEFORE_COMMIT);
  224. TEST_CHECK(PlcDeviceSaveSfd() == PLC_DEVICE_PERSISTENCE_ERROR);
  225. TEST_CHECK(PlcDeviceInit() == PLC_DEVICE_OK);
  226. TEST_CHECK(PlcDeviceReadSfd(900U, &value) == PLC_DEVICE_OK);
  227. TEST_CHECK(value == 123);
  228. TEST_CHECK(PlcDevicePublishSm(0U, 1U, 0U) == PLC_DEVICE_OK);
  229. TEST_CHECK(PlcDeviceWriteSfd(900U, 2000) == PLC_DEVICE_OK);
  230. TEST_CHECK(PlcDeviceSaveSfd() == PLC_DEVICE_BUSY);
  231. TEST_CHECK(PlcDeviceLoadSfd() == PLC_DEVICE_BUSY);
  232. TEST_CHECK(PlcDeviceResetSfdDefaults() == PLC_DEVICE_BUSY);
  233. TEST_CHECK(PlcDevicePublishSm(0U, 0U, 0U) == PLC_DEVICE_OK);
  234. TEST_CHECK(PlcDeviceResetSfdDefaults() == PLC_DEVICE_OK);
  235. TEST_CHECK(PlcDeviceIsSfdDirty() != 0U);
  236. TEST_CHECK(PlcDeviceReadSfd(900U, &value) == PLC_DEVICE_OK);
  237. TEST_CHECK(value == 0);
  238. TEST_CHECK(PlcDeviceInit() == PLC_DEVICE_OK);
  239. TEST_CHECK(PlcDeviceGetLastSfdLoadResult()
  240. == PLSR_PERSISTENCE_DEFAULTED);
  241. TEST_CHECK(PlcDeviceReadSfd(1419U, &value) == PLC_DEVICE_OK);
  242. TEST_CHECK(value == 0);
  243. TEST_CHECK(PlcDeviceReadSfd(1333U, &value) == PLC_DEVICE_OK);
  244. TEST_CHECK(value == 0x0201);
  245. }
  246. static void TestSmAndSd(void)
  247. {
  248. uint8_t state;
  249. int32_t value;
  250. TEST_CHECK(PlcDevicePublishSm(2U, 1U, 0U) == PLC_DEVICE_OK);
  251. TEST_CHECK(PlcDeviceReadSm(1040U, &state) == PLC_DEVICE_OK);
  252. TEST_CHECK(state == 1U);
  253. TEST_CHECK(PlcDeviceReadSm(1041U, &state) == PLC_DEVICE_OK);
  254. TEST_CHECK(state == 0U);
  255. TEST_CHECK(PlcDeviceWriteSm(1040U, 0U) == PLC_DEVICE_READ_ONLY);
  256. TEST_CHECK(PlcDeviceReadSm(1042U, &state) == PLC_DEVICE_INVALID_ADDRESS);
  257. TEST_CHECK(PlcDevicePublishSd(3U, 11U, -12345) == PLC_DEVICE_OK);
  258. TEST_CHECK(PlcDeviceReadSd(1071U, &value) == PLC_DEVICE_OK);
  259. TEST_CHECK(value == -12345);
  260. TEST_CHECK(PlcDeviceWriteSd(1071U, 0) == PLC_DEVICE_READ_ONLY);
  261. TEST_CHECK(PlcDeviceReadSd(1012U, &value) == PLC_DEVICE_INVALID_ADDRESS);
  262. TEST_CHECK(PlcDevicePublishSd(4U, 0U, 0) == PLC_DEVICE_INVALID_ARGUMENT);
  263. TEST_CHECK(PlcDevicePublishSdDword(2U, 2U, -123456)
  264. == PLC_DEVICE_OK);
  265. TEST_CHECK(PlcDeviceReadSdDword(1042U, &value) == PLC_DEVICE_OK);
  266. TEST_CHECK(value == -123456);
  267. TEST_CHECK(PlcDeviceReadSdDword(1043U, &value)
  268. == PLC_DEVICE_INVALID_ADDRESS);
  269. TEST_CHECK(PlcDevicePublishSdDword(2U, 9U, 0)
  270. == PLC_DEVICE_INVALID_ARGUMENT);
  271. TEST_CHECK(PlcDeviceReadSdDword(1070U, &value)
  272. == PLC_DEVICE_INVALID_ADDRESS);
  273. TEST_CHECK(PlcDeviceInit() == PLC_DEVICE_OK);
  274. TEST_CHECK(PlcDeviceReadSm(1040U, &state) == PLC_DEVICE_OK);
  275. TEST_CHECK(state == 0U);
  276. TEST_CHECK(PlcDeviceReadSd(1071U, &value) == PLC_DEVICE_OK);
  277. TEST_CHECK(value == 0);
  278. }
  279. int main(void)
  280. {
  281. TestAddressMap();
  282. TestHsdAndPersistence();
  283. TestHsdDefaults();
  284. TestHsdMetaPersistence();
  285. TestSfd();
  286. TestSmAndSd();
  287. (void)printf("PASS: %u checks\n", TestCount);
  288. return EXIT_SUCCESS;
  289. }