test.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. /* Copyright 2018 Espressif Systems (Shanghai) PTE LTD
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. #include "catch.hpp"
  16. #include "serial_comm.h"
  17. #include "serial_comm_prv.h"
  18. #include "serial_io_mock.h"
  19. #include "serial_io.h"
  20. #include "loader.h"
  21. #include <string.h>
  22. #include <stdio.h>
  23. #include <iostream>
  24. #include <algorithm>
  25. using namespace std;
  26. #define TEST_SLIP_PACKET '\xdb', 'a', 'b', 'c', '\xc0', '\xdb', \
  27. 'd', 'e', '\xc0', 'f', '\xdb'
  28. #define SLIP_ENCODED_PACKET '\xdb', '\xdd', 'a', 'b', 'c', '\xdb', '\xdc', \
  29. '\xdb', '\xdd', 'd', 'e', '\xdb', '\xdc', 'f', \
  30. '\xdb', '\xdd'
  31. // Wrapper around command_t for easyer
  32. struct __attribute__((packed)) expected_response {
  33. expected_response(command_t cmd)
  34. {
  35. data.direction = READ_DIRECTION;
  36. data.command = cmd;
  37. data.size = 16;
  38. data.value = 0;
  39. data.status = STATUS_SUCCESS;
  40. data.error = 0;
  41. data.reserved_0 = 0;
  42. data.reserved_1 = 0;
  43. }
  44. response_t data;
  45. };
  46. static_assert(sizeof(expected_response) == sizeof(response_t), "Size NOT equel");
  47. inline void queue_response(expected_response &response, size_t size = sizeof(expected_response))
  48. {
  49. set_read_buffer(&response, size);
  50. }
  51. expected_response flash_begin_response(FLASH_BEGIN);
  52. expected_response flash_data_response(FLASH_DATA);
  53. expected_response flash_end_response(FLASH_END);
  54. expected_response write_reg_response(WRITE_REG);
  55. expected_response read_reg_response(READ_REG);
  56. expected_response sync_response(SYNC);
  57. template<size_t PAYLOAD_SIZE>
  58. struct __attribute__((packed)) data_frame {
  59. int8_t delimiter_1 = '\xc0';
  60. data_command_t data_cmd = {
  61. .common = {
  62. .direction = WRITE_DIRECTION,
  63. .command = FLASH_DATA,
  64. .size = 16,
  65. .checksum = 0xef,
  66. },
  67. .data_size = PAYLOAD_SIZE,
  68. .sequence_number = 0,
  69. .zero_0 = 0,
  70. .zero_1 = 0,
  71. };
  72. uint8_t payload[PAYLOAD_SIZE];
  73. int8_t delimiter_2 = '\xc0';
  74. };
  75. template<size_t DATA_FRAME_SIZE, size_t NUM_OF_DATA_FRAMES>
  76. struct __attribute__((packed)) write_packet {
  77. int8_t delimiter_1 = '\xc0';
  78. begin_command_t begin_cmd = {
  79. .common = {
  80. .direction = WRITE_DIRECTION,
  81. .command = FLASH_BEGIN,
  82. .size = 16,
  83. .checksum = 0,
  84. },
  85. .erase_size = DATA_FRAME_SIZE * 3,
  86. .packet_count = 3,
  87. .packet_size = DATA_FRAME_SIZE,
  88. .offset = 0,
  89. };
  90. int8_t delimiter_2 = '\xc0';
  91. data_frame<DATA_FRAME_SIZE> data[NUM_OF_DATA_FRAMES];
  92. int8_t delimiter_3 = '\xc0';
  93. flash_end_command_t end_cmd = {
  94. .common = {
  95. .direction = WRITE_DIRECTION,
  96. .command = FLASH_END,
  97. .size = 4,
  98. .checksum = 0,
  99. },
  100. .stay_in_loader = 1,
  101. };
  102. int8_t delimiter_4 = '\xc0';
  103. write_packet()
  104. {
  105. for (size_t i = 0; i < NUM_OF_DATA_FRAMES; i++) {
  106. memset(data[i].payload, 0xFF, FLASH_WRITE_SIZE); // Padding
  107. data[i].data_cmd.data_size = DATA_FRAME_SIZE;
  108. data[i].data_cmd.sequence_number = i;
  109. }
  110. }
  111. };
  112. int8_t large_data[2500];
  113. TEST_CASE( "Large payload that does not fit FLASH_WRITE_SIZE is split into \
  114. multiple data frames. Last data frame is padded with 0xFF" )
  115. {
  116. write_packet<FLASH_WRITE_SIZE, 3> expected;
  117. uint32_t remaining_size = sizeof(large_data) - 2 * FLASH_WRITE_SIZE;
  118. memset(large_data, 0x11, sizeof(large_data));
  119. memcpy(&expected.data[0].payload, large_data, FLASH_WRITE_SIZE);
  120. memcpy(&expected.data[1].payload, large_data, FLASH_WRITE_SIZE);
  121. memcpy(&expected.data[2].payload, large_data, remaining_size);
  122. expected.data[2].data_cmd.data_size = remaining_size;
  123. clear_buffers();
  124. queue_response(flash_begin_response);
  125. queue_response(flash_data_response);
  126. queue_response(flash_data_response);
  127. queue_response(flash_data_response);
  128. queue_response(flash_end_response);
  129. REQUIRE( loader_flash_write(large_data, sizeof(large_data), 0) == ESP_SUCCESS );
  130. REQUIRE( memcmp(write_buffer_data(), &expected, sizeof(expected)) == 0 );
  131. }
  132. TEST_CASE( "Can connect within specified time " )
  133. {
  134. clear_buffers();
  135. queue_response(sync_response);
  136. loader_set_timeout(50);
  137. SECTION( "Can connect" ) {
  138. serial_set_time_delay(100);
  139. REQUIRE ( loader_connect() == ESP_SUCCESS );
  140. }
  141. SECTION( "Timeout error is returned when timeout expires" ) {
  142. serial_set_time_delay(1000);
  143. REQUIRE ( loader_connect() == ESP_ERROR_TIMEOUT );
  144. }
  145. serial_set_time_delay(0);
  146. }
  147. TEST_CASE( "Register can be read correctly" )
  148. {
  149. clear_buffers();
  150. read_reg_response.data.value = 55;
  151. queue_response(read_reg_response);
  152. uint32_t reg_value = 0;
  153. loader_read_register(0, &reg_value);
  154. REQUIRE( reg_value == 55 );
  155. }
  156. const uint32_t reg_address = 0x1000;
  157. const uint32_t reg_value = 55;
  158. struct __attribute__((packed)) write_reg_cmd_response {
  159. int8_t delimiter_1 = '\xc0';
  160. write_reg_command_t write_reg_cmd = {
  161. .common = {
  162. .direction = WRITE_DIRECTION,
  163. .command = WRITE_REG,
  164. .size = 16,
  165. .checksum = 0
  166. },
  167. .address = reg_address,
  168. .value = reg_value,
  169. .mask = 0xFFFFFFFF,
  170. .delay_us = 0
  171. };
  172. int8_t delimiter_2 = '\xc0';
  173. };
  174. TEST_CASE( "Register can be written correctly" )
  175. {
  176. write_reg_cmd_response expected;
  177. clear_buffers();
  178. queue_response(write_reg_response);
  179. REQUIRE( loader_write_register(reg_address, reg_value) == ESP_SUCCESS );
  180. REQUIRE( memcmp(write_buffer_data(), &expected, sizeof(expected)) == 0 );
  181. }
  182. // -------------------- Serial comm test -----------------------
  183. TEST_CASE ( "SLIP is enceded correctly" )
  184. {
  185. flash_begin_cmd(0, 0, 0, 0); // To reset sequence number counter
  186. int8_t data[] = { TEST_SLIP_PACKET };
  187. int8_t expected[] = {
  188. '\xc0', // Begin
  189. 0x00, // Write direction
  190. 0x03, // FLASH_DATA command
  191. 16, 0, // Number of characters to send
  192. 0x33, 0, 0, 0,// Checksum
  193. sizeof(data), 0, 0, 0, // Data size
  194. 0, 0, 0, 0, // Sequence number
  195. 0, 0, 0, 0, // zero
  196. 0, 0, 0, 0, // zero
  197. SLIP_ENCODED_PACKET,
  198. '\xc0', // End
  199. };
  200. // write_buffer_print();
  201. // print_array(expected, sizeof(expected));
  202. clear_buffers();
  203. queue_response(flash_data_response);
  204. REQUIRE( flash_data_cmd(data, sizeof(data), 0) == ESP_SUCCESS );
  205. REQUIRE( memcmp(write_buffer_data(), expected, sizeof(expected)) == 0 );
  206. }
  207. TEST_CASE( "Synd command is constructed correctly" )
  208. {
  209. int8_t expected[] = {
  210. '\xc0', // Begin
  211. 0x00, // Write direction
  212. 0x08, // SYNC command
  213. 36, 0, // Number of characters to send
  214. 0, 0, 0, 0, // Checksum is ignored for this command
  215. 0x07, 0x07, 0x12, 0x20,
  216. 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
  217. 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
  218. 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
  219. 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
  220. '\xc0', // End
  221. };
  222. clear_buffers();
  223. queue_response(sync_response);
  224. REQUIRE( sync_cmd() == ESP_SUCCESS );
  225. REQUIRE( memcmp(write_buffer_data(), expected, sizeof(expected)) == 0 );
  226. }
  227. // TEST_CASE( "Register can be read and decoded correctly" )
  228. // {
  229. // clear_buffers();
  230. // read_reg_response.data.value = 55;
  231. // queue_response(read_reg_response);
  232. // uint32_t reg_value = 0;
  233. // read_reg(0, &reg_value);
  234. // REQUIRE( reg_value == 55 );
  235. // }
  236. // Test flash offset
  237. // -------------------- Serial mock test -----------------------
  238. TEST_CASE( "Serial read works correctly" )
  239. {
  240. uint32_t reg_value = 5;
  241. int8_t readout[sizeof(reg_value) + 2];
  242. int8_t expected[] = { '\xc0', 5, 0, 0, 0, '\xc0' };
  243. clear_buffers();
  244. set_read_buffer(&reg_value, sizeof(reg_value));
  245. SECTION( "Read buffer can be read" ) {
  246. serial_read(readout, sizeof(readout), 0);
  247. REQUIRE( memcmp(readout, expected, sizeof(readout)) == 0 );
  248. }
  249. SECTION ( "Read buffer can be read in smaller chunks" ) {
  250. serial_read(&readout[0], 3, 0);
  251. serial_read(&readout[3], 3, 0);
  252. REQUIRE( memcmp(readout, expected, sizeof(readout)) == 0 );
  253. }
  254. SECTION ( "Timeout is retuned when requested amount of data is not available" ) {
  255. REQUIRE( serial_read(readout, sizeof(readout) + 1, 0) == ESP_ERROR_TIMEOUT);
  256. }
  257. SECTION ( "Read buffer is correctly SLIP encoded " ) {
  258. int8_t data_to_encode[] = { TEST_SLIP_PACKET };
  259. int8_t expected[] = { '\xc0', SLIP_ENCODED_PACKET, '\xc0'};
  260. int8_t encoded[sizeof(expected)];
  261. clear_buffers();
  262. fill(encoded, &encoded[sizeof(encoded)], 0);
  263. set_read_buffer(data_to_encode, sizeof(data_to_encode));
  264. serial_read(encoded, sizeof(encoded), 0);
  265. REQUIRE( memcmp(expected, encoded, sizeof(expected)) == 0 );
  266. }
  267. }
  268. // static void arrays_match(int8_t *array_1, int8_t *array_2, size_t size)
  269. // {
  270. // for (size_t i = 0; i < size; i++) {
  271. // if (array_1[i] != array_2[i]) {
  272. // printf("\nArrays do NOT match on index: %lu, with vaules %0x, %0x \n",
  273. // i, array_1[i], array_2[i]);
  274. // return;
  275. // }
  276. // }
  277. // printf("Arrays Match\n");
  278. // }
  279. // int8_t expected[] = {
  280. // '\xc0', // Begin
  281. // 0x00, // Write direction
  282. // 0x02, // FLASH_BEGIN command
  283. // 16, 0, // Number of characters to send
  284. // 0, 0, 0, 0, // Checksum is ignored for this command
  285. // sizeof(data), 0, 0, 0, // Size to erase
  286. // 1, 0, 0, 0, // Number of data packets
  287. // 0, 4, 0, 0, // Data size in one packet
  288. // 0, 0, 0, 0, // Flash offset
  289. // '\xc0', // End
  290. // '\xc0', // Begin
  291. // 0x00, // Write direction
  292. // 0x03, // FLASH_DATA command
  293. // 16, 0, // Number of characters to send
  294. // 0x33, 0, 0, 0,// Checksum
  295. // sizeof(data), 0, 0, 0, // Data size
  296. // 0, 0, 0, 0, // Sequence number
  297. // 0, 0, 0, 0, // zero
  298. // 0, 0, 0, 0, // zero
  299. // SLIP_ENCODED_PACKET,
  300. // '\xc0', // End
  301. // '\xc0', // Begin
  302. // 0x00, // Write direction
  303. // 0x04, // FLASH_END command
  304. // 4, 0, // Number of characters to send
  305. // 0, 0, 0, 0, // Checksum is ignored for this command
  306. // 1, 0, 0, 0, // Do not reboot (1)
  307. // '\xc0', // End
  308. // };
  309. // write_packet expected = {
  310. // // Begin command
  311. // .delimiter_1 = '\xc0',
  312. // .begin_cmd = {
  313. // .common = {
  314. // .direction = WRITE_DIRECTION,
  315. // .command = FLASH_BEGIN,
  316. // .size = 16,
  317. // .checksum = 0,
  318. // },
  319. // .erase_size = FLASH_WRITE_SIZE * 3,
  320. // .packet_count = 3,
  321. // .packet_size = FLASH_WRITE_SIZE,
  322. // .offset = 0,
  323. // },
  324. // .delimiter_2 = '\xc0',
  325. // // Data frames
  326. // .data = {
  327. // {
  328. // .delimiter_3 = '\xc0',
  329. // .data_cmd = {
  330. // .common = {
  331. // .direction = WRITE_DIRECTION,
  332. // .command = FLASH_DATA,
  333. // .size = 16,
  334. // .checksum = 0xef,
  335. // },
  336. // .data_size = FLASH_WRITE_SIZE,
  337. // .sequence_number = 0,
  338. // .zero_0 = 0,
  339. // .zero_1 = 0,
  340. // },
  341. // .payload = { 0xFF },
  342. // .delimiter_4 = '\xc0',
  343. // },
  344. // {
  345. // .delimiter_3 = '\xc0',
  346. // .data_cmd = {
  347. // .common = {
  348. // .direction = WRITE_DIRECTION,
  349. // .command = FLASH_DATA,
  350. // .size = 16,
  351. // .checksum = 0xef,
  352. // },
  353. // .data_size = FLASH_WRITE_SIZE,
  354. // .sequence_number = 1,
  355. // .zero_0 = 0,
  356. // .zero_1 = 0,
  357. // },
  358. // .payload = { 0xFF },
  359. // .delimiter_4 = '\xc0',
  360. // },
  361. // {
  362. // .delimiter_3 = '\xc0',
  363. // .data_cmd = {
  364. // .common = {
  365. // .direction = WRITE_DIRECTION,
  366. // .command = FLASH_DATA,
  367. // .size = 16,
  368. // .checksum = 0xef,
  369. // },
  370. // .data_size = remaining_size,
  371. // .sequence_number = 2,
  372. // .zero_0 = 0,
  373. // .zero_1 = 0,
  374. // },
  375. // .payload = { 0xFF },
  376. // .delimiter_4 = '\xc0',
  377. // },
  378. // },
  379. // // End command
  380. // .delimiter_5 = '\xc0',
  381. // .end_cmd = {
  382. // .common = {
  383. // .direction = WRITE_DIRECTION,
  384. // .command = FLASH_END,
  385. // .size = 4,
  386. // .checksum = 0,
  387. // },
  388. // .stay_in_loader = 1,
  389. // },
  390. // .delimiter_6 = '\xc0',
  391. // };