test_vfs_eventfd.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. // Copyright 2021 Espressif Systems (Shanghai) CO 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. // http://www.apache.org/licenses/LICENSE-2.0
  7. //
  8. // Unless required by applicable law or agreed to in writing, software
  9. // distributed under the License is distributed on an "AS IS" BASIS,
  10. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. // See the License for the specific language governing permissions and
  12. // limitations under the License
  13. #include "esp_vfs_eventfd.h"
  14. #include <errno.h>
  15. #include <sys/select.h>
  16. #include "driver/timer.h"
  17. #include "esp_vfs.h"
  18. #include "freertos/FreeRTOS.h"
  19. #include "unity.h"
  20. TEST_CASE("eventfd create and close", "[vfs][eventfd]")
  21. {
  22. esp_vfs_eventfd_config_t config = ESP_VFS_EVENTD_CONFIG_DEFAULT();
  23. TEST_ESP_OK(esp_vfs_eventfd_register(&config));
  24. int fd = eventfd(0, 0);
  25. TEST_ASSERT_GREATER_OR_EQUAL(0, fd);
  26. TEST_ASSERT_EQUAL(0, close(fd));
  27. fd = eventfd(0, EFD_SUPPORT_ISR);
  28. TEST_ASSERT_GREATER_OR_EQUAL(0, fd);
  29. TEST_ASSERT_EQUAL(0, close(fd));
  30. TEST_ESP_OK(esp_vfs_eventfd_unregister());
  31. }
  32. TEST_CASE("eventfd reject unknown flags", "[vfs][eventfd]")
  33. {
  34. esp_vfs_eventfd_config_t config = ESP_VFS_EVENTD_CONFIG_DEFAULT();
  35. TEST_ESP_OK(esp_vfs_eventfd_register(&config));
  36. int fd = eventfd(0, 1);
  37. TEST_ASSERT_LESS_THAN(0, fd);
  38. TEST_ASSERT_EQUAL(EINVAL, errno);
  39. fd = eventfd(0, INT_MAX);
  40. TEST_ASSERT_LESS_THAN(0, fd);
  41. TEST_ASSERT_EQUAL(EINVAL, errno);
  42. TEST_ESP_OK(esp_vfs_eventfd_unregister());
  43. }
  44. TEST_CASE("eventfd read", "[vfs][eventfd]")
  45. {
  46. esp_vfs_eventfd_config_t config = ESP_VFS_EVENTD_CONFIG_DEFAULT();
  47. TEST_ESP_OK(esp_vfs_eventfd_register(&config));
  48. unsigned int initval = 123;
  49. int fd = eventfd(initval, 0);
  50. TEST_ASSERT_GREATER_OR_EQUAL(0, fd);
  51. uint64_t val = 0;
  52. TEST_ASSERT_EQUAL(sizeof(val), read(fd, &val, sizeof(val)));
  53. TEST_ASSERT_EQUAL(initval, val);
  54. TEST_ASSERT_EQUAL(sizeof(val), read(fd, &val, sizeof(val)));
  55. TEST_ASSERT_EQUAL(0, val);
  56. TEST_ASSERT_EQUAL(0, close(fd));
  57. TEST_ESP_OK(esp_vfs_eventfd_unregister());
  58. }
  59. TEST_CASE("eventfd read invalid size", "[vfs][eventfd]")
  60. {
  61. esp_vfs_eventfd_config_t config = ESP_VFS_EVENTD_CONFIG_DEFAULT();
  62. TEST_ESP_OK(esp_vfs_eventfd_register(&config));
  63. int fd = eventfd(0, 0);
  64. TEST_ASSERT_GREATER_OR_EQUAL(0, fd);
  65. uint32_t val = 0;
  66. TEST_ASSERT_LESS_THAN(0, read(fd, &val, sizeof(val)));
  67. TEST_ASSERT_EQUAL(EINVAL, errno);
  68. TEST_ASSERT_EQUAL(0, close(fd));
  69. TEST_ESP_OK(esp_vfs_eventfd_unregister());
  70. }
  71. TEST_CASE("eventfd write invalid size", "[vfs][eventfd]")
  72. {
  73. esp_vfs_eventfd_config_t config = ESP_VFS_EVENTD_CONFIG_DEFAULT();
  74. TEST_ESP_OK(esp_vfs_eventfd_register(&config));
  75. int fd = eventfd(0, 0);
  76. TEST_ASSERT_GREATER_OR_EQUAL(0, fd);
  77. uint32_t val = 0;
  78. TEST_ASSERT_LESS_THAN(0, write(fd, &val, sizeof(val)));
  79. TEST_ASSERT_EQUAL(EINVAL, errno);
  80. TEST_ASSERT_EQUAL(0, close(fd));
  81. TEST_ESP_OK(esp_vfs_eventfd_unregister());
  82. }
  83. TEST_CASE("eventfd write then read", "[vfs][eventfd]")
  84. {
  85. esp_vfs_eventfd_config_t config = ESP_VFS_EVENTD_CONFIG_DEFAULT();
  86. TEST_ESP_OK(esp_vfs_eventfd_register(&config));
  87. int fd = eventfd(0, 0);
  88. TEST_ASSERT_GREATER_OR_EQUAL(0, fd);
  89. uint64_t val = 123;
  90. TEST_ASSERT_EQUAL(sizeof(val), write(fd, &val, sizeof(val)));
  91. TEST_ASSERT_EQUAL(sizeof(val), read(fd, &val, sizeof(val)));
  92. TEST_ASSERT_EQUAL(123, val);
  93. val = 4;
  94. TEST_ASSERT_EQUAL(sizeof(val), write(fd, &val, sizeof(val)));
  95. val = 5;
  96. TEST_ASSERT_EQUAL(sizeof(val), write(fd, &val, sizeof(val)));
  97. TEST_ASSERT_EQUAL(sizeof(val), read(fd, &val, sizeof(val)));
  98. TEST_ASSERT_EQUAL(9, val);
  99. TEST_ASSERT_EQUAL(0, close(fd));
  100. TEST_ESP_OK(esp_vfs_eventfd_unregister());
  101. }
  102. TEST_CASE("eventfd instant select", "[vfs][eventfd]")
  103. {
  104. esp_vfs_eventfd_config_t config = ESP_VFS_EVENTD_CONFIG_DEFAULT();
  105. TEST_ESP_OK(esp_vfs_eventfd_register(&config));
  106. int fd = eventfd(0, 0);
  107. TEST_ASSERT_GREATER_OR_EQUAL(0, fd);
  108. struct timeval zero_time;
  109. fd_set read_fds, write_fds, error_fds;
  110. zero_time.tv_sec = 0;
  111. zero_time.tv_usec = 0;
  112. FD_ZERO(&read_fds);
  113. FD_ZERO(&write_fds);
  114. FD_ZERO(&error_fds);
  115. FD_SET(fd, &read_fds);
  116. int ret = select(fd + 1, &read_fds, &write_fds, &error_fds, &zero_time);
  117. TEST_ASSERT_EQUAL(0, ret);
  118. TEST_ASSERT(!FD_ISSET(fd, &read_fds));
  119. uint64_t val = 1;
  120. TEST_ASSERT_EQUAL(sizeof(val), write(fd, &val, sizeof(val)));
  121. FD_ZERO(&read_fds);
  122. FD_ZERO(&write_fds);
  123. FD_ZERO(&error_fds);
  124. FD_SET(fd, &read_fds);
  125. ret = select(fd + 1, &read_fds, &write_fds, &error_fds, &zero_time);
  126. TEST_ASSERT_EQUAL(1, ret);
  127. TEST_ASSERT(FD_ISSET(fd, &read_fds));
  128. TEST_ASSERT_EQUAL(sizeof(val), read(fd, &val, sizeof(val)));
  129. FD_ZERO(&read_fds);
  130. FD_ZERO(&write_fds);
  131. FD_ZERO(&error_fds);
  132. FD_SET(fd, &read_fds);
  133. ret = select(fd + 1, &read_fds, &write_fds, &error_fds, &zero_time);
  134. TEST_ASSERT_EQUAL(0, ret);
  135. TEST_ASSERT(!FD_ISSET(fd, &read_fds));
  136. TEST_ASSERT_EQUAL(0, close(fd));
  137. TEST_ESP_OK(esp_vfs_eventfd_unregister());
  138. }
  139. static void signal_task(void *arg)
  140. {
  141. int fd = *((int *)arg);
  142. vTaskDelay(pdMS_TO_TICKS(1000));
  143. uint64_t val = 1;
  144. TEST_ASSERT_EQUAL(sizeof(val), write(fd, &val, sizeof(val)));
  145. vTaskDelete(NULL);
  146. }
  147. TEST_CASE("eventfd signal from task", "[vfs][eventfd]")
  148. {
  149. esp_vfs_eventfd_config_t config = ESP_VFS_EVENTD_CONFIG_DEFAULT();
  150. TEST_ESP_OK(esp_vfs_eventfd_register(&config));
  151. int fd0 = eventfd(0, 0);
  152. int fd1 = eventfd(0, 0);
  153. int max_fd = fd1 > fd0 ? fd1 : fd0;
  154. TEST_ASSERT_GREATER_OR_EQUAL(0, fd0);
  155. TEST_ASSERT_GREATER_OR_EQUAL(0, fd1);
  156. xTaskCreate(signal_task, "signal_task", 2048, &fd0, 5, NULL);
  157. struct timeval wait_time;
  158. struct timeval zero_time;
  159. fd_set read_fds;
  160. FD_ZERO(&read_fds);
  161. FD_SET(fd0, &read_fds);
  162. FD_SET(fd1, &read_fds);
  163. wait_time.tv_sec = 2;
  164. wait_time.tv_usec = 0;
  165. zero_time.tv_sec = 0;
  166. zero_time.tv_usec = 0;
  167. int ret = select(max_fd + 1, &read_fds, NULL, NULL, &wait_time);
  168. TEST_ASSERT_EQUAL(1, ret);
  169. TEST_ASSERT(FD_ISSET(fd0, &read_fds));
  170. uint64_t val = 1;
  171. TEST_ASSERT_EQUAL(sizeof(val), write(fd1, &val, sizeof(val)));
  172. FD_ZERO(&read_fds);
  173. FD_SET(fd0, &read_fds);
  174. FD_SET(fd1, &read_fds);
  175. ret = select(max_fd + 1, &read_fds, NULL, NULL, &zero_time);
  176. TEST_ASSERT_EQUAL(2, ret);
  177. TEST_ASSERT(FD_ISSET(fd0, &read_fds));
  178. TEST_ASSERT(FD_ISSET(fd1, &read_fds));
  179. TEST_ASSERT_EQUAL(0, close(fd0));
  180. TEST_ASSERT_EQUAL(0, close(fd1));
  181. TEST_ESP_OK(esp_vfs_eventfd_unregister());
  182. }
  183. static void eventfd_select_test_isr(void *arg)
  184. {
  185. int fd = *((int *)arg);
  186. uint64_t val = 1;
  187. timer_group_clr_intr_status_in_isr(TIMER_GROUP_0, TIMER_0);
  188. int ret = write(fd, &val, sizeof(val));
  189. assert(ret == sizeof(val));
  190. }
  191. TEST_CASE("eventfd signal from ISR", "[vfs][eventfd]")
  192. {
  193. esp_vfs_eventfd_config_t config = ESP_VFS_EVENTD_CONFIG_DEFAULT();
  194. TEST_ESP_OK(esp_vfs_eventfd_register(&config));
  195. int fd = eventfd(0, EFD_SUPPORT_ISR);
  196. TEST_ASSERT_GREATER_OR_EQUAL(0, fd);
  197. timer_config_t timer_config = {
  198. .divider = 16,
  199. .counter_dir = TIMER_COUNT_UP,
  200. .counter_en = TIMER_PAUSE,
  201. .alarm_en = TIMER_ALARM_EN,
  202. .auto_reload = false,
  203. };
  204. TEST_ESP_OK(timer_init(TIMER_GROUP_0, TIMER_0, &timer_config));
  205. TEST_ESP_OK(timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0x00000000ULL));
  206. TEST_ESP_OK(timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, TIMER_BASE_CLK / 16));
  207. TEST_ESP_OK(timer_enable_intr(TIMER_GROUP_0, TIMER_0));
  208. TEST_ESP_OK(timer_isr_register(TIMER_GROUP_0, TIMER_0, eventfd_select_test_isr,
  209. &fd, ESP_INTR_FLAG_LOWMED, NULL));
  210. TEST_ESP_OK(timer_start(TIMER_GROUP_0, TIMER_0));
  211. struct timeval wait_time;
  212. fd_set read_fds, write_fds, error_fds;
  213. FD_ZERO(&read_fds);
  214. FD_ZERO(&write_fds);
  215. FD_ZERO(&error_fds);
  216. FD_SET(fd, &read_fds);
  217. wait_time.tv_sec = 2;
  218. wait_time.tv_usec = 0;
  219. FD_SET(fd, &read_fds);
  220. int ret = select(fd + 1, &read_fds, &write_fds, &error_fds, &wait_time);
  221. TEST_ASSERT_EQUAL(1, ret);
  222. TEST_ASSERT(FD_ISSET(fd, &read_fds));
  223. timer_deinit(TIMER_GROUP_0, TIMER_0);
  224. TEST_ASSERT_EQUAL(0, close(fd));
  225. TEST_ESP_OK(esp_vfs_eventfd_unregister());
  226. }
  227. static void close_task(void *arg)
  228. {
  229. int fd = *((int *)arg);
  230. vTaskDelay(pdMS_TO_TICKS(1000));
  231. TEST_ASSERT_EQUAL(0, close(fd));
  232. vTaskDelete(NULL);
  233. }
  234. TEST_CASE("eventfd select closed fd", "[vfs][eventfd]")
  235. {
  236. esp_vfs_eventfd_config_t config = ESP_VFS_EVENTD_CONFIG_DEFAULT();
  237. TEST_ESP_OK(esp_vfs_eventfd_register(&config));
  238. int fd = eventfd(0, 0);
  239. TEST_ASSERT_GREATER_OR_EQUAL(0, fd);
  240. xTaskCreate(close_task, "close_task", 2048, &fd, 5, NULL);
  241. struct timeval wait_time;
  242. fd_set read_fds, write_fds, error_fds;
  243. FD_ZERO(&read_fds);
  244. FD_ZERO(&write_fds);
  245. FD_ZERO(&error_fds);
  246. FD_SET(fd, &read_fds);
  247. FD_SET(fd, &error_fds);
  248. wait_time.tv_sec = 2;
  249. wait_time.tv_usec = 0;
  250. int ret = select(fd + 1, &read_fds, &write_fds, &error_fds, &wait_time);
  251. TEST_ASSERT_EQUAL(1, ret);
  252. TEST_ASSERT(FD_ISSET(fd, &error_fds));
  253. TEST_ESP_OK(esp_vfs_eventfd_unregister());
  254. }
  255. typedef struct {
  256. xQueueHandle queue;
  257. int fd;
  258. } select_task_args_t;
  259. static void select_task(void *arg)
  260. {
  261. select_task_args_t *select_arg = (select_task_args_t *)arg;
  262. int fd = select_arg->fd;
  263. struct timeval wait_time;
  264. fd_set read_fds;
  265. FD_ZERO(&read_fds);
  266. FD_SET(fd, &read_fds);
  267. wait_time.tv_sec = 2;
  268. wait_time.tv_usec = 0;
  269. int ret = select(fd + 1, &read_fds, NULL, NULL, &wait_time);
  270. assert(ret == 1);
  271. xQueueSend(select_arg->queue, select_arg, 0);
  272. vTaskDelete(NULL);
  273. }
  274. TEST_CASE("eventfd multiple selects", "[vfs][eventfd]")
  275. {
  276. esp_vfs_eventfd_config_t config = ESP_VFS_EVENTD_CONFIG_DEFAULT();
  277. TEST_ESP_OK(esp_vfs_eventfd_register(&config));
  278. int fd = eventfd(0, 0);
  279. TEST_ASSERT_GREATER_OR_EQUAL(0, fd);
  280. select_task_args_t args = {
  281. .queue = xQueueCreate(10, sizeof(select_task_args_t)),
  282. .fd = fd,
  283. };
  284. select_task_args_t ret_args;
  285. xTaskCreate(select_task, "select_task0", 2048, &args, 5, NULL);
  286. xTaskCreate(select_task, "select_task1", 2048, &args, 5, NULL);
  287. uint64_t val = 1;
  288. TEST_ASSERT_EQUAL(sizeof(val), write(fd, &val, sizeof(val)));
  289. vTaskDelay(pdMS_TO_TICKS(100));
  290. TEST_ASSERT(xQueueReceive(args.queue, &ret_args, 0));
  291. TEST_ASSERT_EQUAL(ret_args.fd, fd);
  292. TEST_ASSERT(xQueueReceive(args.queue, &ret_args, 0));
  293. TEST_ASSERT_EQUAL(ret_args.fd, fd);
  294. vQueueDelete(args.queue);
  295. TEST_ASSERT_EQUAL(0, close(fd));
  296. TEST_ESP_OK(esp_vfs_eventfd_unregister());
  297. }