Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 
 
 

629 строки
22 KiB

  1. #include "plc_device.h"
  2. #include "plsr_core.h"
  3. #include "plsr_job.h"
  4. #include "plsr_persistence.h"
  5. #include <stdio.h>
  6. #include <string.h>
  7. #define TEST_WORD_CAPACITY (3000U)
  8. #define TEST_BIT_CAPACITY (128U)
  9. typedef struct
  10. {
  11. uint16_t words[3][TEST_WORD_CAPACITY];
  12. uint8_t bits[3][TEST_BIT_CAPACITY];
  13. } TEST_MEMORY;
  14. static int TestFailures;
  15. static int TestChecks;
  16. #define CHECK(condition) \
  17. do \
  18. { \
  19. TestChecks++; \
  20. if (!(condition)) \
  21. { \
  22. TestFailures++; \
  23. (void)printf("FAIL line %d: %s\n", __LINE__, #condition); \
  24. } \
  25. } while (0)
  26. static uint8_t TestValidateWords(void *context,
  27. PLSR_DEVICE_TYPE device,
  28. uint32_t firstAddress,
  29. uint32_t wordCount)
  30. {
  31. (void)context;
  32. if ((device > PLSR_DEVICE_FD) || (wordCount == 0UL))
  33. {
  34. return 0U;
  35. }
  36. return (((uint64_t)firstAddress + wordCount) <= TEST_WORD_CAPACITY)
  37. ? 1U
  38. : 0U;
  39. }
  40. static uint8_t TestReadWord(void *context,
  41. PLSR_DEVICE_TYPE device,
  42. uint32_t address,
  43. uint16_t *value)
  44. {
  45. TEST_MEMORY *memory = (TEST_MEMORY *)context;
  46. if ((memory == NULL) || (value == NULL) || (device > PLSR_DEVICE_FD)
  47. || (address >= TEST_WORD_CAPACITY))
  48. {
  49. return 0U;
  50. }
  51. *value = memory->words[device][address];
  52. return 1U;
  53. }
  54. static uint8_t TestReadBit(void *context,
  55. PLSR_DEVICE_TYPE device,
  56. uint32_t address,
  57. uint8_t *value)
  58. {
  59. TEST_MEMORY *memory = (TEST_MEMORY *)context;
  60. uint8_t index;
  61. if ((memory == NULL) || (value == NULL) || (device < PLSR_DEVICE_X)
  62. || (device > PLSR_DEVICE_HM) || (address >= TEST_BIT_CAPACITY))
  63. {
  64. return 0U;
  65. }
  66. index = (uint8_t)(device - PLSR_DEVICE_X);
  67. *value = memory->bits[index][address];
  68. return 1U;
  69. }
  70. static void TestWriteDword(TEST_MEMORY *memory,
  71. PLSR_DEVICE_TYPE device,
  72. uint32_t address,
  73. int32_t value)
  74. {
  75. uint32_t raw = (uint32_t)value;
  76. memory->words[device][address] = (uint16_t)(raw & 0xFFFFUL);
  77. memory->words[device][address + 1UL] = (uint16_t)(raw >> 16U);
  78. }
  79. static void TestWriteSfdDword(uint16_t address, uint32_t value)
  80. {
  81. CHECK(PlcDeviceWriteSfd(address, (int32_t)(value & 0xFFFFUL))
  82. == PLC_DEVICE_OK);
  83. CHECK(PlcDeviceWriteSfd((uint16_t)(address + 1U),
  84. (int32_t)(value >> 16U))
  85. == PLC_DEVICE_OK);
  86. }
  87. static void TestConfigureAxis0K1(void)
  88. {
  89. CHECK(PlcDeviceWriteSfd(900U, 0) == PLC_DEVICE_OK);
  90. CHECK(PlcDeviceWriteSfd(906U, 4) == PLC_DEVICE_OK);
  91. CHECK(PlcDeviceWriteSfd(907U, 10) == PLC_DEVICE_OK);
  92. CHECK(PlcDeviceWriteSfd(908U, 17) == PLC_DEVICE_OK);
  93. CHECK(PlcDeviceWriteSfd(909U, 23) == PLC_DEVICE_OK);
  94. TestWriteSfdDword(950U, 1000UL);
  95. CHECK(PlcDeviceWriteSfd(952U, 100) == PLC_DEVICE_OK);
  96. CHECK(PlcDeviceWriteSfd(953U, 120) == PLC_DEVICE_OK);
  97. CHECK(PlcDeviceWriteSfd(954U, 10) == PLC_DEVICE_OK);
  98. CHECK(PlcDeviceWriteSfd(955U, 0) == PLC_DEVICE_OK);
  99. TestWriteSfdDword(956U, 100000UL);
  100. TestWriteSfdDword(958U, 120000UL);
  101. TestWriteSfdDword(960U, 500UL);
  102. CHECK(PlcDeviceWriteSfd(962U, 50) == PLC_DEVICE_OK);
  103. CHECK(PlcDeviceWriteSfd(963U, 20) == PLC_DEVICE_OK);
  104. CHECK(PlcDeviceWriteSfd(964U, 0) == PLC_DEVICE_OK);
  105. TestWriteSfdDword(966U, 2000UL);
  106. TestWriteSfdDword(968U, 200UL);
  107. }
  108. static void TestBuildValidBlocks(TEST_MEMORY *memory)
  109. {
  110. (void)memset(memory, 0, sizeof(*memory));
  111. TestWriteDword(memory, PLSR_DEVICE_D, 100U, 2);
  112. TestWriteDword(memory, PLSR_DEVICE_D, 110U, 150000);
  113. TestWriteDword(memory, PLSR_DEVICE_D, 112U, 100);
  114. memory->words[PLSR_DEVICE_D][114U] = 0U;
  115. TestWriteDword(memory, PLSR_DEVICE_D, 115U, 0);
  116. memory->words[PLSR_DEVICE_D][117U] = 0U;
  117. TestWriteDword(memory, PLSR_DEVICE_D, 118U, 0);
  118. TestWriteDword(memory, PLSR_DEVICE_D, 120U, 0);
  119. TestWriteDword(memory, PLSR_DEVICE_D, 122U, -50);
  120. memory->words[PLSR_DEVICE_D][124U] = 0x0100U;
  121. TestWriteDword(memory, PLSR_DEVICE_D, 125U, 0);
  122. memory->words[PLSR_DEVICE_D][127U] = 0U;
  123. TestWriteDword(memory, PLSR_DEVICE_D, 128U, 2);
  124. TestWriteDword(memory, PLSR_DEVICE_D, 200U, 0);
  125. TestWriteDword(memory, PLSR_DEVICE_D, 202U, 0);
  126. TestWriteDword(memory, PLSR_DEVICE_HD, 10U, 1);
  127. }
  128. static PLSR_CALL TestMakeCall(TEST_MEMORY *memory)
  129. {
  130. PLSR_CALL call;
  131. (void)memset(&call, 0, sizeof(call));
  132. call.sequence = 77UL;
  133. call.source.context = memory;
  134. call.source.validateWords = TestValidateWords;
  135. call.source.readWord = TestReadWord;
  136. call.source.readBit = TestReadBit;
  137. call.s0.device = PLSR_DEVICE_D;
  138. call.s0.address = 100UL;
  139. call.s1.device = PLSR_DEVICE_D;
  140. call.s1.address = 200UL;
  141. call.s2.type = PLSR_OPERAND_CONSTANT;
  142. call.s2.constant = 1;
  143. call.dAxis = 0U;
  144. call.outputModeOverride = PLSR_OUTPUT_MODE_FROM_SFD;
  145. return call;
  146. }
  147. static void TestValidSnapshotAndLiveFrequency(void)
  148. {
  149. TEST_MEMORY memory;
  150. PLSR_CALL call;
  151. PLSR_PARSE_CONTEXT context;
  152. PLSR_JOB_SNAPSHOT snapshot;
  153. PLSR_PARSE_DETAIL detail;
  154. uint32_t frequency;
  155. uint8_t clamped;
  156. TestBuildValidBlocks(&memory);
  157. call = TestMakeCall(&memory);
  158. context.logicalPosition = 0;
  159. context.positionValid = 0U;
  160. CHECK(PlsrBuildJobSnapshot(&call, &context, &snapshot, &detail)
  161. == PLSR_RESULT_OK);
  162. CHECK(detail.result == PLSR_RESULT_OK);
  163. CHECK(snapshot.segmentCount == 2U);
  164. CHECK(snapshot.startSegment == 1U);
  165. CHECK(snapshot.s2Set == 1U);
  166. CHECK(snapshot.outputMode == PLSR_OUTPUT_PULSE_DIR);
  167. CHECK(snapshot.directionPoint == 4U);
  168. CHECK(snapshot.directionNegativeLogic == 0U);
  169. CHECK(snapshot.positiveBacklashPulses == 17U);
  170. CHECK(snapshot.negativeBacklashPulses == 23U);
  171. CHECK(snapshot.s2.defaultSpeed == 1000UL);
  172. CHECK(snapshot.s2.maximumSpeed == 100000UL);
  173. CHECK(snapshot.s2.startSpeed == 100000UL);
  174. CHECK(snapshot.speedClamped == 1U);
  175. CHECK(snapshot.segments[0].targetFrequency == 100000UL);
  176. CHECK((snapshot.segments[0].flags & PLSR_SEGMENT_FLAG_SPEED_CLAMPED)
  177. != 0U);
  178. CHECK(snapshot.segments[1].targetFrequency == 1000UL);
  179. CHECK((snapshot.segments[1].flags & PLSR_SEGMENT_FLAG_DEFAULT_SPEED)
  180. != 0U);
  181. CHECK((snapshot.segments[1].flags & PLSR_SEGMENT_FLAG_SELF_LOOP) != 0U);
  182. CHECK(snapshot.hasSelfLoop == 1U);
  183. CHECK(snapshot.initialDirectionPositive == 1U);
  184. CHECK(PlcDeviceWriteSfd(900U, (1U << 1U)) == PLC_DEVICE_OK);
  185. CHECK(PlsrBuildJobSnapshot(&call, &context, &snapshot, &detail)
  186. == PLSR_RESULT_OK);
  187. CHECK(snapshot.directionNegativeLogic == 1U);
  188. CHECK(snapshot.initialDirectionPositive == 1U);
  189. CHECK(PlcDeviceWriteSfd(900U, 0U) == PLC_DEVICE_OK);
  190. TestWriteDword(&memory, PLSR_DEVICE_D, 112U, 9999);
  191. CHECK(snapshot.segments[0].pulseOrTarget == 100);
  192. TestWriteDword(&memory, PLSR_DEVICE_D, 110U, 2500);
  193. CHECK(PlsrResolveLiveFrequency(&snapshot, 1U, &frequency, &clamped)
  194. == PLSR_RESULT_OK);
  195. CHECK(frequency == 2500UL);
  196. CHECK(clamped == 0U);
  197. TestWriteDword(&memory, PLSR_DEVICE_D, 110U, 200000);
  198. CHECK(PlsrResolveLiveFrequency(&snapshot, 1U, &frequency, &clamped)
  199. == PLSR_RESULT_OK);
  200. CHECK(frequency == 100000UL);
  201. CHECK(clamped == 1U);
  202. call.s2.type = PLSR_OPERAND_DATA;
  203. call.s2.data.device = PLSR_DEVICE_HD;
  204. call.s2.data.address = 10UL;
  205. CHECK(PlsrBuildJobSnapshot(&call, &context, &snapshot, &detail)
  206. == PLSR_RESULT_OK);
  207. CHECK(snapshot.s2Set == 1U);
  208. }
  209. static void TestValidationFailures(void)
  210. {
  211. TEST_MEMORY memory;
  212. PLSR_CALL call;
  213. PLSR_PARSE_CONTEXT context = {0, 0U};
  214. PLSR_JOB_SNAPSHOT snapshot;
  215. PLSR_PARSE_DETAIL detail;
  216. TestBuildValidBlocks(&memory);
  217. call = TestMakeCall(&memory);
  218. call.s1.address = 120UL;
  219. CHECK(PlsrBuildJobSnapshot(&call, &context, &snapshot, &detail)
  220. == PLSR_RESULT_BLOCK_OVERLAP);
  221. TestBuildValidBlocks(&memory);
  222. call = TestMakeCall(&memory);
  223. memory.words[PLSR_DEVICE_D][103U] = 1U;
  224. CHECK(PlsrBuildJobSnapshot(&call, &context, &snapshot, &detail)
  225. == PLSR_RESULT_RESERVED_NOT_ZERO);
  226. CHECK(detail.address == 103UL);
  227. TestBuildValidBlocks(&memory);
  228. call = TestMakeCall(&memory);
  229. TestWriteDword(&memory, PLSR_DEVICE_D, 100U, 101);
  230. CHECK(PlsrBuildJobSnapshot(&call, &context, &snapshot, &detail)
  231. == PLSR_RESULT_SEGMENT_OVERFLOW);
  232. TestBuildValidBlocks(&memory);
  233. call = TestMakeCall(&memory);
  234. TestWriteDword(&memory, PLSR_DEVICE_D, 110U, -1);
  235. CHECK(PlsrBuildJobSnapshot(&call, &context, &snapshot, &detail)
  236. == PLSR_RESULT_INVALID_FREQUENCY);
  237. CHECK(detail.segment == 1U);
  238. TestBuildValidBlocks(&memory);
  239. call = TestMakeCall(&memory);
  240. memory.words[PLSR_DEVICE_D][124U] = 0x0405U;
  241. CHECK(PlsrBuildJobSnapshot(&call, &context, &snapshot, &detail)
  242. == PLSR_RESULT_INVALID_WAIT);
  243. TestBuildValidBlocks(&memory);
  244. call = TestMakeCall(&memory);
  245. TestWriteDword(&memory, PLSR_DEVICE_D, 128U, 3);
  246. CHECK(PlsrBuildJobSnapshot(&call, &context, &snapshot, &detail)
  247. == PLSR_RESULT_INVALID_JUMP);
  248. TestBuildValidBlocks(&memory);
  249. call = TestMakeCall(&memory);
  250. TestWriteDword(&memory, PLSR_DEVICE_D, 118U, 2);
  251. TestWriteDword(&memory, PLSR_DEVICE_D, 128U, 1);
  252. CHECK(PlsrBuildJobSnapshot(&call, &context, &snapshot, &detail)
  253. == PLSR_RESULT_PATH_CYCLE);
  254. TestBuildValidBlocks(&memory);
  255. call = TestMakeCall(&memory);
  256. TestWriteDword(&memory, PLSR_DEVICE_D, 200U, 1);
  257. CHECK(PlsrBuildJobSnapshot(&call, &context, &snapshot, &detail)
  258. == PLSR_RESULT_POSITION_INVALID);
  259. TestBuildValidBlocks(&memory);
  260. call = TestMakeCall(&memory);
  261. call.s0.address = UINT32_MAX - 5UL;
  262. CHECK(PlsrBuildJobSnapshot(&call, &context, &snapshot, &detail)
  263. == PLSR_RESULT_ADDRESS_OVERFLOW);
  264. TestBuildValidBlocks(&memory);
  265. call = TestMakeCall(&memory);
  266. call.s2.constant = 5;
  267. CHECK(PlsrBuildJobSnapshot(&call, &context, &snapshot, &detail)
  268. == PLSR_RESULT_INVALID_S2);
  269. TestBuildValidBlocks(&memory);
  270. call = TestMakeCall(&memory);
  271. CHECK(PlcDeviceWriteSfd(962U, 356) == PLC_DEVICE_OK);
  272. CHECK(PlsrBuildJobSnapshot(&call, &context, &snapshot, &detail)
  273. == PLSR_RESULT_INVALID_S2);
  274. CHECK(PlcDeviceWriteSfd(962U, 50) == PLC_DEVICE_OK);
  275. CHECK(PlcDeviceWriteSfd(964U, 1) == PLC_DEVICE_OK);
  276. CHECK(PlsrBuildJobSnapshot(&call, &context, &snapshot, &detail)
  277. == PLSR_RESULT_INVALID_S2);
  278. CHECK(PlcDeviceWriteSfd(964U, 0) == PLC_DEVICE_OK);
  279. }
  280. static void TestDynamicReferences(void)
  281. {
  282. TEST_MEMORY memory;
  283. PLSR_CALL call;
  284. PLSR_PARSE_CONTEXT context = {0, 0U};
  285. PLSR_JOB_SNAPSHOT snapshot;
  286. PLSR_PARSE_DETAIL detail;
  287. TestBuildValidBlocks(&memory);
  288. call = TestMakeCall(&memory);
  289. memory.words[PLSR_DEVICE_D][124U] = 0x0101U;
  290. TestWriteDword(&memory, PLSR_DEVICE_D, 125U, 300);
  291. TestWriteDword(&memory, PLSR_DEVICE_D, 300U, 25);
  292. memory.words[PLSR_DEVICE_D][127U] = 1U;
  293. TestWriteDword(&memory, PLSR_DEVICE_D, 128U, 302);
  294. TestWriteDword(&memory, PLSR_DEVICE_D, 302U, 2);
  295. CHECK(PlsrBuildJobSnapshot(&call, &context, &snapshot, &detail)
  296. == PLSR_RESULT_OK);
  297. CHECK(snapshot.segments[1].waitSource == PLSR_VALUE_D);
  298. CHECK(snapshot.segments[1].waitValueOrAddress == 300);
  299. CHECK(snapshot.segments[1].jumpSource == PLSR_VALUE_D);
  300. CHECK(snapshot.segments[1].jumpValueOrAddress == 302);
  301. memory.words[PLSR_DEVICE_D][124U] = 0x0404U;
  302. TestWriteDword(&memory, PLSR_DEVICE_D, 125U, 7);
  303. memory.bits[0][7U] = 1U;
  304. memory.words[PLSR_DEVICE_D][127U] = 0U;
  305. TestWriteDword(&memory, PLSR_DEVICE_D, 128U, 2);
  306. CHECK(PlsrBuildJobSnapshot(&call, &context, &snapshot, &detail)
  307. == PLSR_RESULT_OK);
  308. }
  309. static void TestOutputAndDivider(void)
  310. {
  311. TEST_MEMORY memory;
  312. PLSR_CALL call;
  313. PLSR_PARSE_CONTEXT context = {0, 0U};
  314. PLSR_JOB_SNAPSHOT snapshot;
  315. PLSR_PARSE_DETAIL detail;
  316. uint16_t psc;
  317. uint16_t arr;
  318. TestBuildValidBlocks(&memory);
  319. call = TestMakeCall(&memory);
  320. CHECK(PlcDeviceWriteSfd(900U, (1U << 13U)) == PLC_DEVICE_OK);
  321. CHECK(PlsrBuildJobSnapshot(&call, &context, &snapshot, &detail)
  322. == PLSR_RESULT_OK);
  323. CHECK(snapshot.outputMode == PLSR_OUTPUT_AB);
  324. CHECK(snapshot.pairedTimerClockHz == 84000000UL);
  325. CHECK(PlsrCalculateTimerDivider(168000000UL, 1UL, &psc, &arr)
  326. == PLSR_RESULT_OK);
  327. CHECK(PlsrCalculateTimerDivider(84000000UL, 100000UL, &psc, &arr)
  328. == PLSR_RESULT_OK);
  329. CHECK(PlsrCalculateTimerDivider(84000000UL, 0UL, &psc, &arr)
  330. == PLSR_RESULT_INVALID_ARGUMENT);
  331. CHECK(PlsrCalculateTimerDivider(1UL, 100000UL, &psc, &arr)
  332. == PLSR_RESULT_DIVIDER_UNREPRESENTABLE);
  333. CHECK(PlcDeviceWriteSfd(900U, 0) == PLC_DEVICE_OK);
  334. }
  335. static void TestEquivalentSnapshot(void)
  336. {
  337. TEST_MEMORY memory;
  338. PLSR_CALL call;
  339. PLSR_PARSE_CONTEXT context = {0, 1U};
  340. PLSR_JOB_SNAPSHOT snapshot;
  341. PLSR_PARSE_DETAIL detail;
  342. uint32_t liveFrequency;
  343. uint8_t clamped;
  344. TestBuildValidBlocks(&memory);
  345. TestWriteDword(&memory, PLSR_DEVICE_D, 110U, 40000);
  346. call = TestMakeCall(&memory);
  347. CHECK(PlcDeviceWriteSfd(900U, (1U << 8U)) == PLC_DEVICE_OK);
  348. TestWriteSfdDword(902U, 3UL);
  349. TestWriteSfdDword(904U, 2UL);
  350. TestWriteSfdDword(956U, 60000UL);
  351. TestWriteSfdDword(958U, 0UL);
  352. CHECK(PlsrBuildJobSnapshot(&call, &context, &snapshot, &detail)
  353. == PLSR_RESULT_OK);
  354. CHECK(snapshot.equivalent.unitCode == 1U);
  355. CHECK(snapshot.equivalent.pulsesPerRevolution == 3UL);
  356. CHECK(snapshot.equivalent.movementPerRevolution == 2UL);
  357. CHECK(snapshot.inputDefaultSpeed == 1000UL);
  358. CHECK(snapshot.inputMaximumSpeed == 60000UL);
  359. CHECK(snapshot.s2.defaultSpeed == 1500UL);
  360. CHECK(snapshot.s2.maximumSpeed == 90000UL);
  361. CHECK(snapshot.segments[0].targetFrequency == 60000UL);
  362. CHECK(snapshot.segments[1].targetFrequency == 1500UL);
  363. TestWriteDword(&memory, PLSR_DEVICE_D, 110U, 20000);
  364. CHECK(PlsrResolveLiveFrequency(&snapshot,
  365. 1U,
  366. &liveFrequency,
  367. &clamped) == PLSR_RESULT_OK);
  368. CHECK(liveFrequency == 30000UL);
  369. CHECK(clamped == 0U);
  370. TestWriteSfdDword(902U, 0UL);
  371. CHECK(PlsrBuildJobSnapshot(&call, &context, &snapshot, &detail)
  372. == PLSR_RESULT_INVALID_S2);
  373. CHECK(detail.address == 902U);
  374. TestConfigureAxis0K1();
  375. }
  376. static void TestLimitSnapshot(void)
  377. {
  378. TEST_MEMORY memory;
  379. PLSR_CALL call;
  380. PLSR_PARSE_CONTEXT context = {0, 1U};
  381. PLSR_JOB_SNAPSHOT snapshot;
  382. PLSR_PARSE_DETAIL detail;
  383. TestBuildValidBlocks(&memory);
  384. call = TestMakeCall(&memory);
  385. CHECK(PlcDeviceWriteSfd(900U, (1U << 2U)) == PLC_DEVICE_OK);
  386. CHECK(PlcDeviceWriteSfd(912U, (1U << 2U) | (1U << 3U))
  387. == PLC_DEVICE_OK);
  388. CHECK(PlcDeviceWriteSfd(915U, 0x0703U) == PLC_DEVICE_OK);
  389. TestWriteSfdDword(930U, 100UL);
  390. TestWriteSfdDword(932U, (uint32_t)(int32_t)-100);
  391. CHECK(PlsrBuildJobSnapshot(&call, &context, &snapshot, &detail)
  392. == PLSR_RESULT_OK);
  393. CHECK(snapshot.limits.softLimitEnabled == 1U);
  394. CHECK(snapshot.limits.positiveSoftLimitPulses == 100);
  395. CHECK(snapshot.limits.negativeSoftLimitPulses == -100);
  396. CHECK(snapshot.limits.positiveInputPoint == 3U);
  397. CHECK(snapshot.limits.negativeInputPoint == 7U);
  398. CHECK(snapshot.limits.positiveInputActiveLow == 1U);
  399. CHECK(snapshot.limits.negativeInputActiveLow == 1U);
  400. TestWriteSfdDword(930U, (uint32_t)(int32_t)-100);
  401. TestWriteSfdDword(932U, 100UL);
  402. CHECK(PlsrBuildJobSnapshot(&call, &context, &snapshot, &detail)
  403. == PLSR_RESULT_INVALID_S2);
  404. CHECK(detail.address == 930U);
  405. TestConfigureAxis0K1();
  406. CHECK(PlcDeviceWriteSfd(912U, 0U) == PLC_DEVICE_OK);
  407. CHECK(PlcDeviceWriteSfd(915U, 0xFFFFU) == PLC_DEVICE_OK);
  408. TestWriteSfdDword(930U, 0UL);
  409. TestWriteSfdDword(932U, 0UL);
  410. }
  411. static void TestCompatibleParseErrors(void)
  412. {
  413. TEST_MEMORY memory;
  414. PLSR_CALL call;
  415. int32_t code;
  416. int32_t block;
  417. PlsrPersistenceTestResetStorage();
  418. CHECK(PlcDeviceInit() == PLC_DEVICE_OK);
  419. TestConfigureAxis0K1();
  420. CHECK(PlsrInit() == PLSR_RESULT_OK);
  421. TestBuildValidBlocks(&memory);
  422. call = TestMakeCall(&memory);
  423. TestWriteDword(&memory, PLSR_DEVICE_D, 110U, -1);
  424. call.sequence = 700UL;
  425. CHECK(PlsrPostCall(&call) == PLSR_RESULT_QUEUED);
  426. PlsrProcess();
  427. CHECK(PlcDeviceReadSd(1010U, &code) == PLC_DEVICE_OK);
  428. CHECK(PlcDeviceReadSd(1011U, &block) == PLC_DEVICE_OK);
  429. CHECK(code == 1);
  430. CHECK(block == 1);
  431. TestWriteDword(&memory, PLSR_DEVICE_D, 110U, 1000);
  432. call.s2.constant = 5;
  433. call.sequence = 701UL;
  434. CHECK(PlsrPostCall(&call) == PLSR_RESULT_QUEUED);
  435. PlsrProcess();
  436. CHECK(PlcDeviceReadSd(1010U, &code) == PLC_DEVICE_OK);
  437. CHECK(code == 3);
  438. call.s2.constant = 1;
  439. CHECK(PlcDeviceWriteSfd(962U, 0U) == PLC_DEVICE_OK);
  440. call.sequence = 702UL;
  441. CHECK(PlsrPostCall(&call) == PLSR_RESULT_QUEUED);
  442. PlsrProcess();
  443. CHECK(PlcDeviceReadSd(1010U, &code) == PLC_DEVICE_OK);
  444. CHECK(code == 15);
  445. CHECK(PlcDeviceWriteSfd(962U, 50U) == PLC_DEVICE_OK);
  446. CHECK(PlcDeviceWriteSfd(963U, 101U) == PLC_DEVICE_OK);
  447. call.sequence = 703UL;
  448. CHECK(PlsrPostCall(&call) == PLSR_RESULT_QUEUED);
  449. PlsrProcess();
  450. CHECK(PlcDeviceReadSd(1010U, &code) == PLC_DEVICE_OK);
  451. CHECK(code == 16);
  452. CHECK(PlcDeviceWriteSfd(963U, 0U) == PLC_DEVICE_OK);
  453. CHECK(PlcDeviceWriteSfd(900U, (1U << 2U)) == PLC_DEVICE_OK);
  454. TestWriteSfdDword(930U, 0UL);
  455. TestWriteSfdDword(932U, 0UL);
  456. call.sequence = 704UL;
  457. CHECK(PlsrPostCall(&call) == PLSR_RESULT_QUEUED);
  458. PlsrProcess();
  459. CHECK(PlcDeviceReadSd(1010U, &code) == PLC_DEVICE_OK);
  460. CHECK(code == 4);
  461. CHECK(PlcDeviceWriteSfd(900U, 0U) == PLC_DEVICE_OK);
  462. CHECK(PlcDeviceWriteSfd(906U, 0xFFU) == PLC_DEVICE_OK);
  463. call.sequence = 705UL;
  464. CHECK(PlsrPostCall(&call) == PLSR_RESULT_QUEUED);
  465. PlsrProcess();
  466. CHECK(PlcDeviceReadSd(1010U, &code) == PLC_DEVICE_OK);
  467. CHECK(code == 26);
  468. TestConfigureAxis0K1();
  469. }
  470. static void TestCoreSubmission(void)
  471. {
  472. TEST_MEMORY memory;
  473. PLSR_CALL call;
  474. PLSR_STATUS status;
  475. PLSR_PARSE_DETAIL detail;
  476. TestBuildValidBlocks(&memory);
  477. call = TestMakeCall(&memory);
  478. call.sequence = 500UL;
  479. CHECK(PlsrInit() == PLSR_RESULT_OK);
  480. CHECK(PlsrPostCall(&call) == PLSR_RESULT_QUEUED);
  481. PlsrProcess();
  482. CHECK(PlsrGetStatus(0U, &status) == PLSR_RESULT_OK);
  483. CHECK(status.lastCommandResult == PLSR_RESULT_OK);
  484. CHECK(status.state == PLSR_STATE_ACCEL);
  485. CHECK(status.jobValid == 1U);
  486. CHECK(status.segmentCount == 2U);
  487. CHECK(status.startSegment == 1U);
  488. CHECK(status.s2Set == 1U);
  489. CHECK(status.speedClamped == 1U);
  490. CHECK(PlsrGetLastParseDetail(0U, &detail) == PLSR_RESULT_OK);
  491. CHECK(detail.result == PLSR_RESULT_OK);
  492. }
  493. static void TestDefaultSfdStartable(void)
  494. {
  495. TEST_MEMORY memory;
  496. PLSR_CALL call;
  497. PLSR_STATUS status;
  498. /* 全新 Flash:默认 S2 参数(FOLLOW=50、最大速度=100000 等)应可直接启动。 */
  499. PlsrPersistenceTestResetStorage();
  500. CHECK(PlcDeviceInit() == PLC_DEVICE_OK);
  501. CHECK(PlcDeviceGetLastSfdLoadResult() == PLSR_PERSISTENCE_DEFAULTED);
  502. TestBuildValidBlocks(&memory);
  503. call = TestMakeCall(&memory);
  504. call.sequence = 600UL;
  505. /* 方向端子是接线参数,未配置(0xFF)时 PULSE/DIR 应报资源错误。 */
  506. CHECK(PlsrInit() == PLSR_RESULT_OK);
  507. CHECK(PlsrPostCall(&call) == PLSR_RESULT_QUEUED);
  508. PlsrProcess();
  509. CHECK(PlsrGetStatus(0U, &status) == PLSR_RESULT_OK);
  510. CHECK(status.lastCommandResult == PLSR_RESULT_INVALID_RESOURCE);
  511. CHECK(status.state == PLSR_STATE_IDLE);
  512. /* 用户配置方向端子后,其余出厂默认参数应能直接启动。 */
  513. CHECK(PlcDeviceWriteSfd(906U, 4) == PLC_DEVICE_OK);
  514. call.sequence = 601UL;
  515. CHECK(PlsrPostCall(&call) == PLSR_RESULT_QUEUED);
  516. PlsrProcess();
  517. CHECK(PlsrGetStatus(0U, &status) == PLSR_RESULT_OK);
  518. CHECK(status.lastCommandResult == PLSR_RESULT_OK);
  519. CHECK(status.state == PLSR_STATE_ACCEL);
  520. CHECK(status.jobValid == 1U);
  521. CHECK(status.s2Set == 1U);
  522. CHECK(status.speedClamped == 1U);
  523. CHECK(status.directionPoint == 4U);
  524. /* 回到 IDLE,避免资源泄漏影响后续。 */
  525. CHECK(PlsrPostCommand(&(PLSR_COMMAND){602U, 0U, PLSR_CMD_STOP_IMMEDIATE, 0})
  526. == PLSR_RESULT_QUEUED);
  527. PlsrProcess();
  528. CHECK(PlsrPostEvent(0U, PLSR_EVENT_STOP_IMMEDIATE_DONE)
  529. == PLSR_RESULT_OK);
  530. PlsrProcess();
  531. CHECK(PlsrGetStatus(0U, &status) == PLSR_RESULT_OK);
  532. CHECK(status.state == PLSR_STATE_STOPPED);
  533. }
  534. int main(void)
  535. {
  536. PlsrPersistenceTestResetStorage();
  537. CHECK(PlcDeviceInit() == PLC_DEVICE_OK);
  538. TestConfigureAxis0K1();
  539. TestValidSnapshotAndLiveFrequency();
  540. TestValidationFailures();
  541. TestDynamicReferences();
  542. TestOutputAndDivider();
  543. TestEquivalentSnapshot();
  544. TestLimitSnapshot();
  545. TestCompatibleParseErrors();
  546. TestDefaultSfdStartable();
  547. TestCoreSubmission();
  548. if (TestFailures != 0)
  549. {
  550. (void)printf("FAIL: %d of %d PLSR job checks failed\n",
  551. TestFailures,
  552. TestChecks);
  553. return 1;
  554. }
  555. (void)printf("PASS: %d PLSR job checks\n", TestChecks);
  556. return 0;
  557. }