test_emac.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "freertos/FreeRTOS.h"
  4. #include "freertos/task.h"
  5. #include "freertos/event_groups.h"
  6. #include "unity.h"
  7. #include "test_utils.h"
  8. #include "esp_event.h"
  9. #include "esp_eth.h"
  10. #include "esp_log.h"
  11. #include "esp_http_client.h"
  12. #include "esp_rom_md5.h"
  13. #include "soc/soc_caps.h"
  14. #if SOC_EMAC_SUPPORTED
  15. static const char *TAG = "esp32_eth_test";
  16. #define ETH_START_BIT BIT(0)
  17. #define ETH_STOP_BIT BIT(1)
  18. #define ETH_CONNECT_BIT BIT(2)
  19. #define ETH_GOT_IP_BIT BIT(3)
  20. #define ETH_DOWNLOAD_END_BIT BIT(4)
  21. #define ETH_START_TIMEOUT_MS (10000)
  22. #define ETH_CONNECT_TIMEOUT_MS (40000)
  23. #define ETH_STOP_TIMEOUT_MS (10000)
  24. #define ETH_GET_IP_TIMEOUT_MS (60000)
  25. #define ETH_DOWNLOAD_END_TIMEOUT_MS (240000)
  26. extern const char dl_espressif_com_root_cert_pem_start[] asm("_binary_dl_espressif_com_root_cert_pem_start");
  27. extern const char dl_espressif_com_root_cert_pem_end[] asm("_binary_dl_espressif_com_root_cert_pem_end");
  28. // compute md5 of download file
  29. static md5_context_t md5_context;
  30. static uint8_t digest[16];
  31. /** Event handler for Ethernet events */
  32. static void eth_event_handler(void *arg, esp_event_base_t event_base,
  33. int32_t event_id, void *event_data)
  34. {
  35. EventGroupHandle_t eth_event_group = (EventGroupHandle_t)arg;
  36. switch (event_id) {
  37. case ETHERNET_EVENT_CONNECTED:
  38. xEventGroupSetBits(eth_event_group, ETH_CONNECT_BIT);
  39. ESP_LOGI(TAG, "Ethernet Link Up");
  40. break;
  41. case ETHERNET_EVENT_DISCONNECTED:
  42. ESP_LOGI(TAG, "Ethernet Link Down");
  43. break;
  44. case ETHERNET_EVENT_START:
  45. xEventGroupSetBits(eth_event_group, ETH_START_BIT);
  46. ESP_LOGI(TAG, "Ethernet Started");
  47. break;
  48. case ETHERNET_EVENT_STOP:
  49. xEventGroupSetBits(eth_event_group, ETH_STOP_BIT);
  50. ESP_LOGI(TAG, "Ethernet Stopped");
  51. break;
  52. default:
  53. break;
  54. }
  55. }
  56. /** Event handler for IP_EVENT_ETH_GOT_IP */
  57. static void got_ip_event_handler(void *arg, esp_event_base_t event_base,
  58. int32_t event_id, void *event_data)
  59. {
  60. EventGroupHandle_t eth_event_group = (EventGroupHandle_t)arg;
  61. ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
  62. const esp_netif_ip_info_t *ip_info = &event->ip_info;
  63. ESP_LOGI(TAG, "Ethernet Got IP Address");
  64. ESP_LOGI(TAG, "~~~~~~~~~~~");
  65. ESP_LOGI(TAG, "ETHIP:" IPSTR, IP2STR(&ip_info->ip));
  66. ESP_LOGI(TAG, "ETHMASK:" IPSTR, IP2STR(&ip_info->netmask));
  67. ESP_LOGI(TAG, "ETHGW:" IPSTR, IP2STR(&ip_info->gw));
  68. ESP_LOGI(TAG, "~~~~~~~~~~~");
  69. xEventGroupSetBits(eth_event_group, ETH_GOT_IP_BIT);
  70. }
  71. static esp_err_t test_uninstall_driver(esp_eth_handle_t eth_hdl, uint32_t ms_to_wait)
  72. {
  73. int i = 0;
  74. ms_to_wait += 100;
  75. for (i = 0; i < ms_to_wait / 100; i++) {
  76. vTaskDelay(pdMS_TO_TICKS(100));
  77. if (esp_eth_driver_uninstall(eth_hdl) == ESP_OK) {
  78. break;
  79. }
  80. }
  81. if (i < ms_to_wait / 10) {
  82. return ESP_OK;
  83. } else {
  84. return ESP_FAIL;
  85. }
  86. }
  87. TEST_CASE("esp32 ethernet io test", "[ethernet][test_env=UT_T2_Ethernet]")
  88. {
  89. eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
  90. mac_config.flags = ETH_MAC_FLAG_PIN_TO_CORE; // pin to core
  91. esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&mac_config);
  92. eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
  93. // auto detect PHY address
  94. phy_config.phy_addr = ESP_ETH_PHY_ADDR_AUTO;
  95. esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config);
  96. esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
  97. esp_eth_handle_t eth_handle = NULL;
  98. TEST_ESP_OK(esp_eth_driver_install(&eth_config, &eth_handle));
  99. /* get MAC address */
  100. uint8_t mac_addr[6];
  101. memset(mac_addr, 0, sizeof(mac_addr));
  102. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, mac_addr));
  103. ESP_LOGI(TAG, "Ethernet MAC Address: %02x:%02x:%02x:%02x:%02x:%02x",
  104. mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
  105. TEST_ASSERT(mac_addr[0] != 0);
  106. /* get PHY address */
  107. int phy_addr = -1;
  108. TEST_ESP_OK(esp_eth_ioctl(eth_handle, ETH_CMD_G_PHY_ADDR, &phy_addr));
  109. ESP_LOGI(TAG, "Ethernet PHY Address: %d", phy_addr);
  110. TEST_ASSERT(phy_addr >= 0 && phy_addr <= 31);
  111. TEST_ESP_OK(esp_eth_driver_uninstall(eth_handle));
  112. TEST_ESP_OK(phy->del(phy));
  113. TEST_ESP_OK(mac->del(mac));
  114. }
  115. TEST_CASE("esp32 ethernet event test", "[ethernet][test_env=UT_T2_Ethernet]")
  116. {
  117. EventBits_t bits = 0;
  118. EventGroupHandle_t eth_event_group = xEventGroupCreate();
  119. TEST_ASSERT(eth_event_group != NULL);
  120. TEST_ESP_OK(esp_event_loop_create_default());
  121. TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, eth_event_group));
  122. eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
  123. esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&mac_config);
  124. eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
  125. esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config);
  126. esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
  127. esp_eth_handle_t eth_handle = NULL;
  128. TEST_ESP_OK(esp_eth_driver_install(&eth_config, &eth_handle));
  129. // this test only test layer2 event, so don't need to register input callback (i.e. esp_eth_update_input_path)
  130. TEST_ESP_OK(esp_eth_start(eth_handle));
  131. /* wait for connection start */
  132. bits = xEventGroupWaitBits(eth_event_group, ETH_START_BIT, true, true, pdMS_TO_TICKS(ETH_START_TIMEOUT_MS));
  133. TEST_ASSERT((bits & ETH_START_BIT) == ETH_START_BIT);
  134. /* wait for connection establish */
  135. bits = xEventGroupWaitBits(eth_event_group, ETH_CONNECT_BIT, true, true, pdMS_TO_TICKS(ETH_CONNECT_TIMEOUT_MS));
  136. TEST_ASSERT((bits & ETH_CONNECT_BIT) == ETH_CONNECT_BIT);
  137. // stop Ethernet driver
  138. TEST_ESP_OK(esp_eth_stop(eth_handle));
  139. /* wait for connection stop */
  140. bits = xEventGroupWaitBits(eth_event_group, ETH_STOP_BIT, true, true, pdMS_TO_TICKS(ETH_STOP_TIMEOUT_MS));
  141. TEST_ASSERT((bits & ETH_STOP_BIT) == ETH_STOP_BIT);
  142. /* driver should be uninstalled within 2 seconds */
  143. TEST_ESP_OK(test_uninstall_driver(eth_handle, 2000));
  144. TEST_ESP_OK(phy->del(phy));
  145. TEST_ESP_OK(mac->del(mac));
  146. TEST_ESP_OK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler));
  147. TEST_ESP_OK(esp_event_loop_delete_default());
  148. vEventGroupDelete(eth_event_group);
  149. }
  150. TEST_CASE("esp32 ethernet dhcp test", "[ethernet][test_env=UT_T2_Ethernet]")
  151. {
  152. EventBits_t bits = 0;
  153. EventGroupHandle_t eth_event_group = xEventGroupCreate();
  154. TEST_ASSERT(eth_event_group != NULL);
  155. test_case_uses_tcpip();
  156. TEST_ESP_OK(esp_event_loop_create_default());
  157. // create TCP/IP netif
  158. esp_netif_config_t netif_cfg = ESP_NETIF_DEFAULT_ETH();
  159. esp_netif_t *eth_netif = esp_netif_new(&netif_cfg);
  160. eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
  161. esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&mac_config);
  162. eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
  163. esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config);
  164. esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
  165. esp_eth_handle_t eth_handle = NULL;
  166. // install Ethernet driver
  167. TEST_ESP_OK(esp_eth_driver_install(&eth_config, &eth_handle));
  168. // combine driver with netif
  169. esp_eth_netif_glue_handle_t glue = esp_eth_new_netif_glue(eth_handle);
  170. TEST_ESP_OK(esp_netif_attach(eth_netif, glue));
  171. // register user defined event handers
  172. TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, eth_event_group));
  173. TEST_ESP_OK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, eth_event_group));
  174. // start Ethernet driver
  175. TEST_ESP_OK(esp_eth_start(eth_handle));
  176. /* wait for IP lease */
  177. bits = xEventGroupWaitBits(eth_event_group, ETH_GOT_IP_BIT, true, true, pdMS_TO_TICKS(ETH_GET_IP_TIMEOUT_MS));
  178. TEST_ASSERT((bits & ETH_GOT_IP_BIT) == ETH_GOT_IP_BIT);
  179. // stop Ethernet driver
  180. TEST_ESP_OK(esp_eth_stop(eth_handle));
  181. /* wait for connection stop */
  182. bits = xEventGroupWaitBits(eth_event_group, ETH_STOP_BIT, true, true, pdMS_TO_TICKS(ETH_STOP_TIMEOUT_MS));
  183. TEST_ASSERT((bits & ETH_STOP_BIT) == ETH_STOP_BIT);
  184. TEST_ESP_OK(esp_eth_del_netif_glue(glue));
  185. /* driver should be uninstalled within 2 seconds */
  186. TEST_ESP_OK(test_uninstall_driver(eth_handle, 2000));
  187. TEST_ESP_OK(phy->del(phy));
  188. TEST_ESP_OK(mac->del(mac));
  189. TEST_ESP_OK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, got_ip_event_handler));
  190. TEST_ESP_OK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler));
  191. esp_netif_destroy(eth_netif);
  192. TEST_ESP_OK(esp_event_loop_delete_default());
  193. vEventGroupDelete(eth_event_group);
  194. }
  195. TEST_CASE("esp32 ethernet start/stop stress test", "[ethernet][test_env=UT_T2_Ethernet][timeout=240]")
  196. {
  197. EventBits_t bits = 0;
  198. EventGroupHandle_t eth_event_group = xEventGroupCreate();
  199. TEST_ASSERT(eth_event_group != NULL);
  200. test_case_uses_tcpip();
  201. TEST_ESP_OK(esp_event_loop_create_default());
  202. // create TCP/IP netif
  203. esp_netif_config_t netif_cfg = ESP_NETIF_DEFAULT_ETH();
  204. esp_netif_t *eth_netif = esp_netif_new(&netif_cfg);
  205. eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
  206. esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&mac_config);
  207. eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
  208. esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config);
  209. esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
  210. esp_eth_handle_t eth_handle = NULL;
  211. // install Ethernet driver
  212. TEST_ESP_OK(esp_eth_driver_install(&eth_config, &eth_handle));
  213. // combine driver with netif
  214. esp_eth_netif_glue_handle_t glue = esp_eth_new_netif_glue(eth_handle);
  215. TEST_ESP_OK(esp_netif_attach(eth_netif, glue));
  216. // register user defined event handers
  217. TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, eth_event_group));
  218. TEST_ESP_OK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, eth_event_group));
  219. for (int i = 0; i < 10; i++) {
  220. // start Ethernet driver
  221. TEST_ESP_OK(esp_eth_start(eth_handle));
  222. /* wait for IP lease */
  223. bits = xEventGroupWaitBits(eth_event_group, ETH_GOT_IP_BIT, true, true, pdMS_TO_TICKS(ETH_GET_IP_TIMEOUT_MS));
  224. TEST_ASSERT((bits & ETH_GOT_IP_BIT) == ETH_GOT_IP_BIT);
  225. // stop Ethernet driver
  226. TEST_ESP_OK(esp_eth_stop(eth_handle));
  227. /* wait for connection stop */
  228. bits = xEventGroupWaitBits(eth_event_group, ETH_STOP_BIT, true, true, pdMS_TO_TICKS(ETH_STOP_TIMEOUT_MS));
  229. TEST_ASSERT((bits & ETH_STOP_BIT) == ETH_STOP_BIT);
  230. }
  231. TEST_ESP_OK(esp_eth_del_netif_glue(glue));
  232. /* driver should be uninstalled within 2 seconds */
  233. TEST_ESP_OK(test_uninstall_driver(eth_handle, 2000));
  234. TEST_ESP_OK(phy->del(phy));
  235. TEST_ESP_OK(mac->del(mac));
  236. TEST_ESP_OK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, got_ip_event_handler));
  237. TEST_ESP_OK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler));
  238. esp_netif_destroy(eth_netif);
  239. TEST_ESP_OK(esp_event_loop_delete_default());
  240. vEventGroupDelete(eth_event_group);
  241. }
  242. esp_err_t http_event_handle(esp_http_client_event_t *evt)
  243. {
  244. switch (evt->event_id) {
  245. case HTTP_EVENT_ERROR:
  246. ESP_LOGE(TAG, "HTTP_EVENT_ERROR");
  247. break;
  248. case HTTP_EVENT_ON_CONNECTED:
  249. ESP_LOGI(TAG, "HTTP_EVENT_ON_CONNECTED");
  250. break;
  251. case HTTP_EVENT_HEADER_SENT:
  252. ESP_LOGI(TAG, "HTTP_EVENT_HEADER_SENT");
  253. break;
  254. case HTTP_EVENT_ON_HEADER:
  255. ESP_LOGI(TAG, "HTTP_EVENT_ON_HEADER");
  256. break;
  257. case HTTP_EVENT_ON_DATA:
  258. esp_rom_md5_update(&md5_context, evt->data, evt->data_len);
  259. break;
  260. case HTTP_EVENT_ON_FINISH:
  261. ESP_LOGI(TAG, "HTTP_EVENT_ON_FINISH");
  262. break;
  263. case HTTP_EVENT_DISCONNECTED:
  264. ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED");
  265. break;
  266. }
  267. return ESP_OK;
  268. }
  269. static void eth_download_task(void *param)
  270. {
  271. EventGroupHandle_t eth_event_group = (EventGroupHandle_t)param;
  272. esp_rom_md5_init(&md5_context);
  273. esp_http_client_config_t config = {
  274. .url = "https://dl.espressif.com/dl/misc/2MB.bin",
  275. .cert_pem = dl_espressif_com_root_cert_pem_start,
  276. .event_handler = http_event_handle,
  277. .buffer_size = 5120
  278. };
  279. esp_http_client_handle_t client = esp_http_client_init(&config);
  280. TEST_ASSERT_NOT_NULL(client);
  281. TEST_ESP_OK(esp_http_client_perform(client));
  282. TEST_ESP_OK(esp_http_client_cleanup(client));
  283. esp_rom_md5_final(digest, &md5_context);
  284. xEventGroupSetBits(eth_event_group, ETH_DOWNLOAD_END_BIT);
  285. vTaskDelete(NULL);
  286. }
  287. TEST_CASE("esp32 ethernet download test", "[ethernet][test_env=UT_T2_Ethernet][timeout=240]")
  288. {
  289. EventBits_t bits = 0;
  290. EventGroupHandle_t eth_event_group = xEventGroupCreate();
  291. TEST_ASSERT(eth_event_group != NULL);
  292. test_case_uses_tcpip();
  293. TEST_ESP_OK(esp_event_loop_create_default());
  294. // create TCP/IP netif
  295. esp_netif_config_t netif_cfg = ESP_NETIF_DEFAULT_ETH();
  296. esp_netif_t *eth_netif = esp_netif_new(&netif_cfg);
  297. eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
  298. esp_eth_mac_t *mac = esp_eth_mac_new_esp32(&mac_config);
  299. eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
  300. esp_eth_phy_t *phy = esp_eth_phy_new_ip101(&phy_config);
  301. esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(mac, phy);
  302. esp_eth_handle_t eth_handle = NULL;
  303. // install Ethernet driver
  304. TEST_ESP_OK(esp_eth_driver_install(&eth_config, &eth_handle));
  305. // combine driver with netif
  306. esp_eth_netif_glue_handle_t glue = esp_eth_new_netif_glue(eth_handle);
  307. TEST_ESP_OK(esp_netif_attach(eth_netif, glue));
  308. // register user defined event handers
  309. TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, eth_event_group));
  310. TEST_ESP_OK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, eth_event_group));
  311. // start Ethernet driver
  312. TEST_ESP_OK(esp_eth_start(eth_handle));
  313. /* wait for IP lease */
  314. bits = xEventGroupWaitBits(eth_event_group, ETH_GOT_IP_BIT, true, true, pdMS_TO_TICKS(ETH_GET_IP_TIMEOUT_MS));
  315. TEST_ASSERT((bits & ETH_GOT_IP_BIT) == ETH_GOT_IP_BIT);
  316. xTaskCreate(eth_download_task, "eth_dl", 4096, eth_event_group, tskIDLE_PRIORITY + 2, NULL);
  317. /* wait for download end */
  318. bits = xEventGroupWaitBits(eth_event_group, ETH_DOWNLOAD_END_BIT, true, true, pdMS_TO_TICKS(ETH_DOWNLOAD_END_TIMEOUT_MS));
  319. TEST_ASSERT_EQUAL(ETH_DOWNLOAD_END_BIT, bits & ETH_DOWNLOAD_END_BIT);
  320. // check MD5 digest
  321. // MD5: df61db8564d145bbe67112aa8ecdccd8
  322. uint8_t expect_digest[16] = {223, 97, 219, 133, 100, 209, 69, 187, 230, 113, 18, 170, 142, 205, 204, 216};
  323. printf("MD5 Digest: ");
  324. for (int i = 0; i < 16; i++) {
  325. printf("%d ", digest[i]);
  326. }
  327. printf("\r\n");
  328. TEST_ASSERT(memcmp(expect_digest, digest, sizeof(digest)) == 0);
  329. // stop Ethernet driver
  330. TEST_ESP_OK(esp_eth_stop(eth_handle));
  331. /* wait for connection stop */
  332. bits = xEventGroupWaitBits(eth_event_group, ETH_STOP_BIT, true, true, pdMS_TO_TICKS(ETH_STOP_TIMEOUT_MS));
  333. TEST_ASSERT((bits & ETH_STOP_BIT) == ETH_STOP_BIT);
  334. TEST_ESP_OK(esp_eth_del_netif_glue(glue));
  335. /* driver should be uninstalled within 2 seconds */
  336. TEST_ESP_OK(test_uninstall_driver(eth_handle, 2000));
  337. TEST_ESP_OK(phy->del(phy));
  338. TEST_ESP_OK(mac->del(mac));
  339. TEST_ESP_OK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, got_ip_event_handler));
  340. TEST_ESP_OK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler));
  341. esp_netif_destroy(eth_netif);
  342. TEST_ESP_OK(esp_event_loop_delete_default());
  343. vEventGroupDelete(eth_event_group);
  344. }
  345. #endif // SOC_EMAC_SUPPORTED