SEGGER_RTT_esp.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*
  2. * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include "string.h"
  7. #include "freertos/FreeRTOS.h"
  8. #include "SEGGER_RTT.h"
  9. #include "SEGGER_SYSVIEW.h"
  10. #include "SEGGER_SYSVIEW_Conf.h"
  11. #include "esp_app_trace.h"
  12. #include "esp_log.h"
  13. const static char *TAG = "segger_rtt";
  14. #define SYSVIEW_EVENTS_BUF_SZ 255U
  15. // size of down channel data buf
  16. #define SYSVIEW_DOWN_BUF_SIZE 32
  17. #define SEGGER_STOP_WAIT_TMO 1000000 //us
  18. #if CONFIG_APPTRACE_SV_BUF_WAIT_TMO == -1
  19. #define SEGGER_HOST_WAIT_TMO ESP_APPTRACE_TMO_INFINITE
  20. #else
  21. #define SEGGER_HOST_WAIT_TMO CONFIG_APPTRACE_SV_BUF_WAIT_TMO
  22. #endif
  23. static uint8_t s_events_buf[SYSVIEW_EVENTS_BUF_SZ];
  24. static uint16_t s_events_buf_filled;
  25. static uint8_t s_down_buf[SYSVIEW_DOWN_BUF_SIZE];
  26. /*********************************************************************
  27. *
  28. * Public code
  29. *
  30. **********************************************************************
  31. */
  32. /*********************************************************************
  33. *
  34. * SEGGER_RTT_ESP_FlushNoLock()
  35. *
  36. * Function description
  37. * Flushes buffered events.
  38. *
  39. * Parameters
  40. * min_sz Threshold for flushing data. If current filling level is above this value, data will be flushed. TRAX destinations only.
  41. * tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
  42. *
  43. * Return value
  44. * None.
  45. */
  46. void SEGGER_RTT_ESP_FlushNoLock(unsigned long min_sz, unsigned long tmo)
  47. {
  48. esp_err_t res;
  49. if (s_events_buf_filled > 0) {
  50. res = esp_apptrace_write(ESP_APPTRACE_DEST_TRAX, s_events_buf, s_events_buf_filled, tmo);
  51. if (res != ESP_OK) {
  52. ESP_LOGE(TAG, "Failed to flush buffered events (%d)!\n", res);
  53. }
  54. }
  55. // flush even if we failed to write buffered events, because no new events will be sent after STOP
  56. res = esp_apptrace_flush_nolock(ESP_APPTRACE_DEST_TRAX, min_sz, tmo);
  57. if (res != ESP_OK) {
  58. ESP_LOGE(TAG, "Failed to flush apptrace data (%d)!\n", res);
  59. }
  60. s_events_buf_filled = 0;
  61. }
  62. /*********************************************************************
  63. *
  64. * SEGGER_RTT_ESP_Flush()
  65. *
  66. * Function description
  67. * Flushes buffered events.
  68. *
  69. * Parameters
  70. * min_sz Threshold for flushing data. If current filling level is above this value, data will be flushed. TRAX destinations only.
  71. * tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
  72. *
  73. * Return value
  74. * None.
  75. */
  76. void SEGGER_RTT_ESP_Flush(unsigned long min_sz, unsigned long tmo)
  77. {
  78. SEGGER_SYSVIEW_LOCK();
  79. SEGGER_RTT_ESP_FlushNoLock(min_sz, tmo);
  80. SEGGER_SYSVIEW_UNLOCK();
  81. }
  82. /*********************************************************************
  83. *
  84. * SEGGER_RTT_ReadNoLock()
  85. *
  86. * Function description
  87. * Reads characters from SEGGER real-time-terminal control block
  88. * which have been previously stored by the host.
  89. * Do not lock against interrupts and multiple access.
  90. *
  91. * Parameters
  92. * BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal").
  93. * pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to.
  94. * BufferSize Size of the target application buffer.
  95. *
  96. * Return value
  97. * Number of bytes that have been read.
  98. */
  99. unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize) {
  100. uint32_t size = BufferSize;
  101. esp_err_t res = esp_apptrace_read(ESP_APPTRACE_DEST_TRAX, pData, &size, 0);
  102. if (res != ESP_OK) {
  103. return 0;
  104. }
  105. return size;
  106. }
  107. /*********************************************************************
  108. *
  109. * SEGGER_RTT_WriteSkipNoLock
  110. *
  111. * Function description
  112. * Stores a specified number of characters in SEGGER RTT
  113. * control block which is then read by the host.
  114. * SEGGER_RTT_WriteSkipNoLock does not lock the application and
  115. * skips all data, if the data does not fit into the buffer.
  116. *
  117. * Parameters
  118. * BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal").
  119. * pBuffer Pointer to character array. Does not need to point to a \0 terminated string.
  120. * NumBytes Number of bytes to be stored in the SEGGER RTT control block.
  121. *
  122. * Return value
  123. * Number of bytes which have been stored in the "Up"-buffer.
  124. *
  125. * Notes
  126. * (1) If there is not enough space in the "Up"-buffer, all data is dropped.
  127. * (2) For performance reasons this function does not call Init()
  128. * and may only be called after RTT has been initialized.
  129. * Either by calling SEGGER_RTT_Init() or calling another RTT API function first.
  130. */
  131. unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) {
  132. uint8_t *pbuf = (uint8_t *)pBuffer;
  133. uint8_t event_id = *pbuf;
  134. if (NumBytes > SYSVIEW_EVENTS_BUF_SZ) {
  135. ESP_LOGE(TAG, "Too large event %u bytes!", NumBytes);
  136. return 0;
  137. }
  138. if (cpu_hal_get_core_id()) { // dual core specific code
  139. // use the highest - 1 bit of event ID to indicate core ID
  140. // the highest bit can not be used due to event ID encoding method
  141. // this reduces supported ID range to [0..63] (for 1 byte IDs) plus [128..16383] (for 2 bytes IDs)
  142. if (*pbuf & 0x80) { // 2 bytes ID
  143. *(pbuf + 1) |= (1 << 6);
  144. } else if (NumBytes != 10 || *pbuf != 0) { // ignore sync sequence
  145. *pbuf |= (1 << 6);
  146. }
  147. }
  148. if (s_events_buf_filled + NumBytes > SYSVIEW_EVENTS_BUF_SZ) {
  149. esp_err_t res = esp_apptrace_write(ESP_APPTRACE_DEST_TRAX, s_events_buf, s_events_buf_filled, SEGGER_HOST_WAIT_TMO);
  150. if (res != ESP_OK) {
  151. return 0; // skip current data buffer only, accumulated events are kept
  152. }
  153. s_events_buf_filled = 0;
  154. }
  155. memcpy(&s_events_buf[s_events_buf_filled], pBuffer, NumBytes);
  156. s_events_buf_filled += NumBytes;
  157. if (event_id == SYSVIEW_EVTID_TRACE_STOP) {
  158. SEGGER_RTT_ESP_FlushNoLock(0, SEGGER_STOP_WAIT_TMO);
  159. }
  160. return NumBytes;
  161. }
  162. /*********************************************************************
  163. *
  164. * SEGGER_RTT_ConfigUpBuffer
  165. *
  166. * Function description
  167. * Run-time configuration of a specific up-buffer (T->H).
  168. * Buffer to be configured is specified by index.
  169. * This includes: Buffer address, size, name, flags, ...
  170. *
  171. * Parameters
  172. * BufferIndex Index of the buffer to configure.
  173. * sName Pointer to a constant name string.
  174. * pBuffer Pointer to a buffer to be used.
  175. * BufferSize Size of the buffer.
  176. * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message).
  177. *
  178. * Return value
  179. * >= 0 - O.K.
  180. * < 0 - Error
  181. *
  182. * Additional information
  183. * Buffer 0 is configured on compile-time.
  184. * May only be called once per buffer.
  185. * Buffer name and flags can be reconfigured using the appropriate functions.
  186. */
  187. int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) {
  188. s_events_buf_filled = 0;
  189. return 0;
  190. }
  191. /*********************************************************************
  192. *
  193. * SEGGER_RTT_ConfigDownBuffer
  194. *
  195. * Function description
  196. * Run-time configuration of a specific down-buffer (H->T).
  197. * Buffer to be configured is specified by index.
  198. * This includes: Buffer address, size, name, flags, ...
  199. *
  200. * Parameters
  201. * BufferIndex Index of the buffer to configure.
  202. * sName Pointer to a constant name string.
  203. * pBuffer Pointer to a buffer to be used.
  204. * BufferSize Size of the buffer.
  205. * Flags Operating modes. Define behavior if buffer is full (not enough space for entire message).
  206. *
  207. * Return value
  208. * >= 0 O.K.
  209. * < 0 Error
  210. *
  211. * Additional information
  212. * Buffer 0 is configured on compile-time.
  213. * May only be called once per buffer.
  214. * Buffer name and flags can be reconfigured using the appropriate functions.
  215. */
  216. int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) {
  217. esp_apptrace_down_buffer_config(s_down_buf, sizeof(s_down_buf));
  218. return 0;
  219. }
  220. /*************************** End of file ****************************/