stats.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. // SPDX-License-Identifier: Apache-2.0
  2. // Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  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. /** Includes **/
  16. #include "stats.h"
  17. #include "esp_hosted_config.h"
  18. #if TEST_RAW_TP
  19. #include "os_wrapper.h"
  20. #include "transport_drv.h"
  21. #endif
  22. #include "esp_log.h"
  23. // use mempool and zero copy for Tx
  24. #include "mempool.h"
  25. #if ESP_PKT_STATS
  26. struct pkt_stats_t pkt_stats;
  27. void *pkt_stats_thread = NULL;
  28. extern volatile uint8_t wifi_tx_throttling;
  29. #endif
  30. #if ESP_PKT_STATS || TEST_RAW_TP
  31. DEFINE_LOG_TAG(stats);
  32. #endif
  33. /** Constants/Macros **/
  34. #define RAW_TP_TX_TASK_STACK_SIZE 2048
  35. /** Exported variables **/
  36. /** Function declaration **/
  37. /** Exported Functions **/
  38. #if TEST_RAW_TP
  39. static int test_raw_tp = 0;
  40. static uint8_t log_raw_tp_stats_timer_running = 0;
  41. static uint32_t raw_tp_timer_count = 0;
  42. void *hosted_timer_handler = NULL;
  43. static void * raw_tp_tx_task_id = 0;
  44. static uint64_t test_raw_tx_len = 0;
  45. static uint64_t test_raw_rx_len = 0;
  46. static struct mempool * buf_mp_g = NULL;
  47. void stats_mempool_free(void* ptr)
  48. {
  49. mempool_free(buf_mp_g, ptr);
  50. }
  51. void test_raw_tp_cleanup(void)
  52. {
  53. int ret = 0;
  54. if (log_raw_tp_stats_timer_running) {
  55. ret = g_h.funcs->_h_timer_stop(hosted_timer_handler);
  56. if (!ret) {
  57. log_raw_tp_stats_timer_running = 0;
  58. }
  59. raw_tp_timer_count = 0;
  60. }
  61. if (raw_tp_tx_task_id) {
  62. ret = g_h.funcs->_h_thread_cancel(raw_tp_tx_task_id);
  63. raw_tp_tx_task_id = 0;
  64. }
  65. }
  66. void raw_tp_timer_func(void * arg)
  67. {
  68. #if USE_FLOATING_POINT
  69. double actual_bandwidth_tx = 0;
  70. double actual_bandwidth_rx = 0;
  71. #else
  72. uint64_t actual_bandwidth_tx = 0;
  73. uint64_t actual_bandwidth_rx = 0;
  74. #endif
  75. int32_t div = 1024;
  76. actual_bandwidth_tx = (test_raw_tx_len*8)/TEST_RAW_TP__TIMEOUT;
  77. actual_bandwidth_rx = (test_raw_rx_len*8)/TEST_RAW_TP__TIMEOUT;
  78. #if USE_FLOATING_POINT
  79. ESP_LOGI(TAG, "%lu-%lu sec Tx:%.2f Rx:%.2f kbps\n\r", raw_tp_timer_count, raw_tp_timer_count + TEST_RAW_TP__TIMEOUT, actual_bandwidth_tx/div, actual_bandwidth_rx/div);
  80. #else
  81. ESP_LOGI(TAG, "%lu-%lu sec Tx:%lu Rx:%lu Kbps", raw_tp_timer_count, raw_tp_timer_count + TEST_RAW_TP__TIMEOUT, (unsigned long)actual_bandwidth_tx/div, (unsigned long)actual_bandwidth_rx/div);
  82. #endif
  83. raw_tp_timer_count+=TEST_RAW_TP__TIMEOUT;
  84. test_raw_tx_len = test_raw_rx_len = 0;
  85. }
  86. static void raw_tp_tx_task(void const* pvParameters)
  87. {
  88. int ret;
  89. static uint16_t seq_num = 0;
  90. uint8_t *raw_tp_tx_buf = NULL;
  91. uint32_t *ptr = NULL;
  92. uint32_t i = 0;
  93. g_h.funcs->_h_sleep(5);
  94. buf_mp_g = mempool_create(MAX_TRANSPORT_BUFFER_SIZE);
  95. #ifdef CONFIG_ESP_CACHE_MALLOC
  96. assert(channel->memp);
  97. #endif
  98. while (1) {
  99. #if CONFIG_H_LOWER_MEMCOPY
  100. raw_tp_tx_buf = (uint8_t*)g_h.funcs->_h_calloc(1, MAX_TRANSPORT_BUFFER_SIZE);
  101. ptr = (uint32_t*) raw_tp_tx_buf;
  102. for (i=0; i<(TEST_RAW_TP__BUF_SIZE/4-1); i++, ptr++)
  103. *ptr = 0xBAADF00D;
  104. ret = esp_hosted_tx(ESP_TEST_IF, 0, raw_tp_tx_buf, TEST_RAW_TP__BUF_SIZE, H_BUFF_ZEROCOPY, H_DEFLT_FREE_FUNC);
  105. #else
  106. raw_tp_tx_buf = mempool_alloc(buf_mp_g, MAX_TRANSPORT_BUFFER_SIZE, true);
  107. ptr = (uint32_t*) (raw_tp_tx_buf + H_ESP_PAYLOAD_HEADER_OFFSET);
  108. for (i=0; i<(TEST_RAW_TP__BUF_SIZE/4-1); i++, ptr++)
  109. *ptr = 0xBAADF00D;
  110. ret = esp_hosted_tx(ESP_TEST_IF, 0, raw_tp_tx_buf, TEST_RAW_TP__BUF_SIZE, H_BUFF_ZEROCOPY, stats_mempool_free);
  111. #endif
  112. if (ret != STM_OK) {
  113. ESP_LOGE(TAG, "Failed to send to queue\n");
  114. continue;
  115. }
  116. #if CONFIG_H_LOWER_MEMCOPY
  117. g_h.funcs->_h_free(raw_tp_tx_buf);
  118. #endif
  119. test_raw_tx_len += (TEST_RAW_TP__BUF_SIZE);
  120. seq_num++;
  121. }
  122. }
  123. static void process_raw_tp_flags(uint8_t cap)
  124. {
  125. test_raw_tp_cleanup();
  126. if (test_raw_tp) {
  127. hosted_timer_handler = g_h.funcs->_h_timer_start(TEST_RAW_TP__TIMEOUT,
  128. RPC__TIMER_PERIODIC, raw_tp_timer_func, NULL);
  129. if (!hosted_timer_handler) {
  130. ESP_LOGE(TAG, "Failed to create timer\n\r");
  131. return;
  132. }
  133. log_raw_tp_stats_timer_running = 1;
  134. ESP_LOGD(TAG, "capabilities: %d", cap);
  135. if ((cap & ESP_TEST_RAW_TP__HOST_TO_ESP) ||
  136. (cap & ESP_TEST_RAW_TP__BIDIRECTIONAL)) {
  137. raw_tp_tx_task_id = g_h.funcs->_h_thread_create("raw_tp_tx", DFLT_TASK_PRIO,
  138. RAW_TP_TX_TASK_STACK_SIZE, raw_tp_tx_task, NULL);
  139. assert(raw_tp_tx_task_id);
  140. }
  141. }
  142. }
  143. static void start_test_raw_tp(void)
  144. {
  145. test_raw_tp = 1;
  146. }
  147. static void stop_test_raw_tp(void)
  148. {
  149. test_raw_tp = 0;
  150. }
  151. void process_test_capabilities(uint8_t cap)
  152. {
  153. ESP_LOGI(TAG, "ESP peripheral capabilities: 0x%x", cap);
  154. if ((cap & ESP_TEST_RAW_TP) == ESP_TEST_RAW_TP) {
  155. start_test_raw_tp();
  156. ESP_LOGI(TAG, "***** Host Raw throughput Testing (report per %u sec) *****\n\r",TEST_RAW_TP__TIMEOUT);
  157. } else {
  158. ESP_LOGW(TAG, "Raw Throughput testing not enabled on slave. Stopping test.");
  159. stop_test_raw_tp();
  160. }
  161. process_raw_tp_flags(H_TEST_RAW_TP_DIR);
  162. }
  163. void update_test_raw_tp_rx_len(uint16_t len)
  164. {
  165. test_raw_rx_len+=(len);
  166. }
  167. #endif
  168. #if H_MEM_STATS
  169. struct mem_stats h_stats_g;
  170. #endif
  171. #if ESP_PKT_STATS
  172. void stats_timer_func(void * arg)
  173. {
  174. ESP_LOGI(TAG, "slave: sta_rx_in: %lu sta_rx_out: %lu sta_tx_in [pass: %lu drop: %lu] sta_tx_out: %lu ",
  175. pkt_stats.sta_rx_in,pkt_stats.sta_rx_out,
  176. pkt_stats.sta_tx_in_pass, pkt_stats.sta_tx_in_drop, pkt_stats.sta_tx_out);
  177. ESP_LOGI(TAG, "wifi_tx_throttling %u", wifi_tx_throttling);
  178. }
  179. #endif
  180. void create_debugging_tasks(void)
  181. {
  182. #if ESP_PKT_STATS
  183. if (ESP_PKT_STATS_REPORT_INTERVAL) {
  184. ESP_LOGI(TAG, "Start Pkt_stats reporting thread [timer: %u sec]", ESP_PKT_STATS_REPORT_INTERVAL);
  185. pkt_stats_thread = g_h.funcs->_h_timer_start(ESP_PKT_STATS_REPORT_INTERVAL,
  186. RPC__TIMER_PERIODIC, stats_timer_func, NULL);
  187. assert(pkt_stats_thread);
  188. }
  189. #endif
  190. }