You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

388 regels
8.9 KiB

  1. #include <assert.h>
  2. #include <stdint.h>
  3. #include <string.h>
  4. #define main AppFirmwareMain
  5. #define static
  6. #include "../Core/Src/main.c"
  7. #undef static
  8. #undef main
  9. #include "../Core/Src/stm32f4xx_it.c"
  10. TIM_TypeDef TestTim5;
  11. GPIO_TypeDef TestGpioE;
  12. GPIO_TypeDef TestGpioF;
  13. GPIO_TypeDef TestGpioI;
  14. USART_TypeDef TestUsart1;
  15. OS_EVENT TestFrameSem;
  16. IRQn_Type TestNvicIrq;
  17. uint32_t TestNvicPreemptPriority;
  18. uint32_t TestNvicSubPriority;
  19. uint32_t TestHalTickCallCount;
  20. uint32_t TestOsCpuSysTickCallCount;
  21. HAL_StatusTypeDef TestReceiveResults[4U];
  22. uint32_t TestReceiveResultCount;
  23. uint32_t TestReceiveCallCount;
  24. uint32_t TestReceiveErrorInjectionCall;
  25. uint32_t TestAbortReceiveCallCount;
  26. uint32_t TestUartFlagClearCallCount;
  27. uint8_t TestRecoveryCallOrder[4U];
  28. uint32_t TestRecoveryCallOrderLength;
  29. uint32_t TestSemPostCallCount;
  30. uint8_t OSRunning;
  31. static void TestResetFakes(void)
  32. {
  33. (void)memset(&TestTim5, 0, sizeof(TestTim5));
  34. (void)memset(&TestGpioE, 0, sizeof(TestGpioE));
  35. (void)memset(&TestGpioF, 0, sizeof(TestGpioF));
  36. (void)memset(&TestGpioI, 0, sizeof(TestGpioI));
  37. (void)memset(&TestUsart1, 0, sizeof(TestUsart1));
  38. (void)memset(&TestFrameSem, 0, sizeof(TestFrameSem));
  39. (void)memset(&Uart1Handle, 0, sizeof(Uart1Handle));
  40. (void)memset(TestReceiveResults, 0, sizeof(TestReceiveResults));
  41. TestNvicIrq = 0;
  42. TestNvicPreemptPriority = 0U;
  43. TestNvicSubPriority = 0U;
  44. TestHalTickCallCount = 0U;
  45. TestOsCpuSysTickCallCount = 0U;
  46. TestReceiveResultCount = 0U;
  47. TestReceiveCallCount = 0U;
  48. TestReceiveErrorInjectionCall = 0U;
  49. TestAbortReceiveCallCount = 0U;
  50. TestUartFlagClearCallCount = 0U;
  51. (void)memset(TestRecoveryCallOrder, 0, sizeof(TestRecoveryCallOrder));
  52. TestRecoveryCallOrderLength = 0U;
  53. TestSemPostCallCount = 0U;
  54. OSRunning = 0U;
  55. ModbusUartLastErrorCode = 0U;
  56. ModbusUartLastRxState = 0U;
  57. ModbusUartRecoveryCount = 0U;
  58. ModbusUartRecoveryFailureCount = 0U;
  59. ModbusUartRxArmCount = 0U;
  60. ModbusUartRxArmFailureCount = 0U;
  61. ModbusUartLastRxByte = 0U;
  62. ModbusLastCompleteFrameLength = 0U;
  63. ModbusFrameSem = &TestFrameSem;
  64. ModbusReceptionNeedsRecovery = 0U;
  65. }
  66. static void TestSysTickUsesKernelAwarePriority(void)
  67. {
  68. TestResetFakes();
  69. AppInitSystemTick();
  70. assert(TestNvicIrq == SysTick_IRQn);
  71. assert(TestNvicPreemptPriority == CPU_CFG_KA_IPL_BOUNDARY);
  72. assert(TestNvicSubPriority == 0U);
  73. }
  74. static void TestSysTickDelegatesToOsPort(void)
  75. {
  76. TestResetFakes();
  77. OSRunning = OS_TRUE;
  78. SysTick_Handler();
  79. assert(TestHalTickCallCount == 1U);
  80. assert(TestOsCpuSysTickCallCount == 1U);
  81. }
  82. static void TestReceiveRecoveryRetriesAfterBusy(void)
  83. {
  84. TestResetFakes();
  85. Uart1Handle.Instance = USART1;
  86. TestReceiveResults[0U] = HAL_BUSY;
  87. TestReceiveResults[1U] = HAL_OK;
  88. TestReceiveResultCount = 2U;
  89. assert(AppRecoverUartReception() == HAL_OK);
  90. assert(TestReceiveCallCount == 2U);
  91. assert(TestAbortReceiveCallCount == 2U);
  92. assert(TestRecoveryCallOrderLength == 4U);
  93. assert(TestRecoveryCallOrder[0U] == 2U);
  94. assert(TestRecoveryCallOrder[1U] == 1U);
  95. assert(TestRecoveryCallOrder[2U] == 2U);
  96. assert(TestRecoveryCallOrder[3U] == 1U);
  97. assert(TestUartFlagClearCallCount == 2U);
  98. }
  99. static void TestUartErrorClearsFlagsBeforeRecovery(void)
  100. {
  101. TestResetFakes();
  102. Uart1Handle.Instance = USART1;
  103. Uart1Handle.ErrorCode = HAL_UART_ERROR_ORE;
  104. HAL_UART_ErrorCallback(&Uart1Handle);
  105. assert(ModbusReceptionNeedsRecovery == 1U);
  106. assert(TestUartFlagClearCallCount == 1U);
  107. assert(TestReceiveCallCount == 0U);
  108. }
  109. static void TestUartErrorDefersRecoveryToTask(void)
  110. {
  111. TestResetFakes();
  112. Uart1Handle.Instance = USART1;
  113. Uart1Handle.ErrorCode = HAL_UART_ERROR_ORE;
  114. HAL_UART_ErrorCallback(&Uart1Handle);
  115. assert(ModbusReceptionNeedsRecovery == 1U);
  116. assert(TestSemPostCallCount == 1U);
  117. assert(TestReceiveCallCount == 0U);
  118. }
  119. static void TestPendingRecoveryKeepsConcurrentErrorRequest(void)
  120. {
  121. TestResetFakes();
  122. Uart1Handle.Instance = USART1;
  123. ModbusReceptionNeedsRecovery = 1U;
  124. TestReceiveErrorInjectionCall = 1U;
  125. assert(AppRecoverPendingUartReception() == HAL_OK);
  126. assert(TestReceiveCallCount == 1U);
  127. assert(TestSemPostCallCount == 1U);
  128. assert(ModbusReceptionNeedsRecovery == 1U);
  129. }
  130. static void TestReceptionWatchdogRearmsWhenHalStateIsLost(void)
  131. {
  132. TestResetFakes();
  133. Uart1Handle.Instance = USART1;
  134. Uart1Handle.RxState = HAL_UART_STATE_READY;
  135. TestReceiveResults[0U] = HAL_OK;
  136. TestReceiveResultCount = 1U;
  137. assert(AppEnsureUartReception() == HAL_OK);
  138. assert(TestAbortReceiveCallCount == 1U);
  139. assert(TestReceiveCallCount == 1U);
  140. assert(ModbusUartRecoveryCount == 1U);
  141. }
  142. int main(void)
  143. {
  144. TestSysTickUsesKernelAwarePriority();
  145. TestSysTickDelegatesToOsPort();
  146. TestReceiveRecoveryRetriesAfterBusy();
  147. TestUartErrorClearsFlagsBeforeRecovery();
  148. TestUartErrorDefersRecoveryToTask();
  149. TestPendingRecoveryKeepsConcurrentErrorRequest();
  150. TestReceptionWatchdogRearmsWhenHalStateIsLost();
  151. return 0;
  152. }
  153. void HAL_Init(void)
  154. {
  155. }
  156. HAL_StatusTypeDef HAL_RCC_OscConfig(const RCC_OscInitTypeDef *config)
  157. {
  158. (void)config;
  159. return HAL_OK;
  160. }
  161. HAL_StatusTypeDef HAL_RCC_ClockConfig(const RCC_ClkInitTypeDef *config,
  162. uint32_t latency)
  163. {
  164. (void)config;
  165. (void)latency;
  166. return HAL_OK;
  167. }
  168. void HAL_GPIO_Init(GPIO_TypeDef *port, const GPIO_InitTypeDef *config)
  169. {
  170. (void)port;
  171. (void)config;
  172. }
  173. void HAL_GPIO_WritePin(GPIO_TypeDef *port, uint16_t pin,
  174. GPIO_PinState state)
  175. {
  176. (void)port;
  177. (void)pin;
  178. (void)state;
  179. }
  180. HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *uartHandle)
  181. {
  182. (void)uartHandle;
  183. return HAL_OK;
  184. }
  185. HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *uartHandle,
  186. uint8_t *data, uint16_t size)
  187. {
  188. HAL_StatusTypeDef result;
  189. (void)uartHandle;
  190. (void)data;
  191. (void)size;
  192. if (TestRecoveryCallOrderLength < sizeof(TestRecoveryCallOrder)) {
  193. TestRecoveryCallOrder[TestRecoveryCallOrderLength++] = 1U;
  194. }
  195. result = HAL_OK;
  196. if (TestReceiveCallCount < TestReceiveResultCount) {
  197. result = TestReceiveResults[TestReceiveCallCount];
  198. }
  199. TestReceiveCallCount++;
  200. if (result == HAL_OK) {
  201. uartHandle->RxState = HAL_UART_STATE_BUSY_RX;
  202. }
  203. if ((TestReceiveErrorInjectionCall != 0U)
  204. && (TestReceiveCallCount == TestReceiveErrorInjectionCall)) {
  205. Uart1Handle.ErrorCode = HAL_UART_ERROR_ORE;
  206. HAL_UART_ErrorCallback(&Uart1Handle);
  207. }
  208. return result;
  209. }
  210. HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *uartHandle)
  211. {
  212. (void)uartHandle;
  213. TestAbortReceiveCallCount++;
  214. if (TestRecoveryCallOrderLength < sizeof(TestRecoveryCallOrder)) {
  215. TestRecoveryCallOrder[TestRecoveryCallOrderLength++] = 2U;
  216. }
  217. return HAL_OK;
  218. }
  219. HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *uartHandle,
  220. uint8_t *data, uint16_t size)
  221. {
  222. (void)uartHandle;
  223. (void)data;
  224. (void)size;
  225. return HAL_OK;
  226. }
  227. HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *uartHandle)
  228. {
  229. (void)uartHandle;
  230. return HAL_OK;
  231. }
  232. void HAL_UART_IRQHandler(UART_HandleTypeDef *uartHandle)
  233. {
  234. (void)uartHandle;
  235. }
  236. void HAL_NVIC_SetPriority(IRQn_Type irqn, uint32_t preemptPriority,
  237. uint32_t subPriority)
  238. {
  239. TestNvicIrq = irqn;
  240. TestNvicPreemptPriority = preemptPriority;
  241. TestNvicSubPriority = subPriority;
  242. }
  243. void HAL_NVIC_EnableIRQ(IRQn_Type irqn)
  244. {
  245. (void)irqn;
  246. }
  247. void HAL_IncTick(void)
  248. {
  249. TestHalTickCallCount++;
  250. }
  251. void OSInit(void)
  252. {
  253. }
  254. void OSStart(void)
  255. {
  256. }
  257. INT8U OSTaskCreateExt(void (*task)(void *), void *argument, OS_STK *stackTop,
  258. INT8U priority, INT16U taskId, OS_STK *stackBottom,
  259. INT32U stackSize, void *extension, INT16U options)
  260. {
  261. (void)task;
  262. (void)argument;
  263. (void)stackTop;
  264. (void)priority;
  265. (void)taskId;
  266. (void)stackBottom;
  267. (void)stackSize;
  268. (void)extension;
  269. (void)options;
  270. return OS_ERR_NONE;
  271. }
  272. OS_EVENT *OSSemCreate(INT16U count)
  273. {
  274. (void)count;
  275. return &TestFrameSem;
  276. }
  277. void OSSemPend(OS_EVENT *event, uint32_t timeout, INT8U *error)
  278. {
  279. (void)event;
  280. (void)timeout;
  281. if (error != NULL) {
  282. *error = OS_ERR_NONE;
  283. }
  284. }
  285. INT8U OSSemPost(OS_EVENT *event)
  286. {
  287. (void)event;
  288. TestSemPostCallCount++;
  289. return OS_ERR_NONE;
  290. }
  291. void OSTaskSuspend(INT8U priority)
  292. {
  293. (void)priority;
  294. }
  295. void OSTimeDly(uint32_t ticks)
  296. {
  297. (void)ticks;
  298. }
  299. uint32_t OSTimeGet(void)
  300. {
  301. return 0U;
  302. }
  303. void OSIntEnter(void)
  304. {
  305. }
  306. void OSIntExit(void)
  307. {
  308. }
  309. void OSTimeTick(void)
  310. {
  311. }
  312. void OS_CPU_SysTickHandler(void)
  313. {
  314. TestOsCpuSysTickCallCount++;
  315. }
  316. MODBUS_STATUS ModbusBackupRestore(MODBUS_SLAVE *slave)
  317. {
  318. (void)slave;
  319. return MODBUS_STATUS_OK;
  320. }
  321. MODBUS_STATUS ModbusBackupSave(const MODBUS_SLAVE *slave)
  322. {
  323. (void)slave;
  324. return MODBUS_STATUS_OK;
  325. }