mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-08-27 04:10:04 +00:00
Merge pull request #519 from andrzej-kaczmarek/monitor-dev
nimble/monitor: Various improvements X-Original-Commit: c02b2f248dea963d21a13b342975c5b886a4dbad
This commit is contained in:
@@ -105,7 +105,7 @@ STATS_NAME_START(ble_hs_stats)
|
||||
STATS_NAME(ble_hs_stats, sync)
|
||||
STATS_NAME_END(ble_hs_stats)
|
||||
|
||||
static struct os_eventq *
|
||||
struct os_eventq *
|
||||
ble_hs_evq_get(void)
|
||||
{
|
||||
return ble_hs_evq;
|
||||
@@ -428,7 +428,7 @@ ble_hs_enqueue_hci_event(uint8_t *hci_evt)
|
||||
ev->ev_queued = 0;
|
||||
ev->ev_cb = ble_hs_event_rx_hci_ev;
|
||||
ev->ev_arg = hci_evt;
|
||||
os_eventq_put(ble_hs_evq_get(), ev);
|
||||
os_eventq_put(ble_hs_evq, ev);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -446,7 +446,7 @@ ble_hs_notifications_sched(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
os_eventq_put(ble_hs_evq_get(), &ble_hs_ev_tx_notifications);
|
||||
os_eventq_put(ble_hs_evq, &ble_hs_ev_tx_notifications);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -462,7 +462,7 @@ ble_hs_sched_reset(int reason)
|
||||
BLE_HS_DBG_ASSERT(ble_hs_reset_reason == 0);
|
||||
|
||||
ble_hs_reset_reason = reason;
|
||||
os_eventq_put(ble_hs_evq_get(), &ble_hs_ev_reset);
|
||||
os_eventq_put(ble_hs_evq, &ble_hs_ev_reset);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -491,7 +491,7 @@ ble_hs_start(void)
|
||||
|
||||
ble_hs_parent_task = os_sched_get_current_task();
|
||||
|
||||
os_callout_init(&ble_hs_timer_timer, ble_hs_evq_get(),
|
||||
os_callout_init(&ble_hs_timer_timer, ble_hs_evq,
|
||||
ble_hs_timer_exp, NULL);
|
||||
|
||||
rc = ble_gatts_start();
|
||||
@@ -518,7 +518,7 @@ ble_hs_rx_data(struct os_mbuf *om, void *arg)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = os_mqueue_put(&ble_hs_rx_q, ble_hs_evq_get(), om);
|
||||
rc = os_mqueue_put(&ble_hs_rx_q, ble_hs_evq, om);
|
||||
if (rc != 0) {
|
||||
os_mbuf_free_chain(om);
|
||||
return BLE_HS_EOS;
|
||||
@@ -541,7 +541,7 @@ ble_hs_tx_data(struct os_mbuf *om)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = os_mqueue_put(&ble_hs_tx_q, ble_hs_evq_get(), om);
|
||||
rc = os_mqueue_put(&ble_hs_tx_q, ble_hs_evq, om);
|
||||
if (rc != 0) {
|
||||
os_mbuf_free_chain(om);
|
||||
return BLE_HS_EOS;
|
||||
|
||||
@@ -119,6 +119,7 @@ void ble_hs_unlock(void);
|
||||
void ble_hs_hw_error(uint8_t hw_code);
|
||||
void ble_hs_timer_resched(void);
|
||||
void ble_hs_notifications_sched(void);
|
||||
struct os_eventq *ble_hs_evq_get(void);
|
||||
|
||||
#if MYNEWT_VAL(LOG_LEVEL) <= LOG_LEVEL_DEBUG && !BLE_MONITOR
|
||||
|
||||
|
||||
+138
-45
@@ -35,27 +35,31 @@
|
||||
#if MYNEWT_VAL(BLE_MONITOR_RTT)
|
||||
#include "rtt/SEGGER_RTT.h"
|
||||
#endif
|
||||
#include "ble_hs_priv.h"
|
||||
#include "ble_monitor_priv.h"
|
||||
|
||||
/* UTC Timestamp for Jan 2016 00:00:00 */
|
||||
#define UTC01_01_2016 1451606400
|
||||
|
||||
struct os_mutex lock;
|
||||
|
||||
#if MYNEWT_VAL(BLE_MONITOR_UART)
|
||||
struct uart_dev *uart;
|
||||
|
||||
static uint8_t tx_ringbuf[64];
|
||||
static uint8_t tx_ringbuf[MYNEWT_VAL(BLE_MONITOR_UART_BUFFER_SIZE)];
|
||||
static uint8_t tx_ringbuf_head;
|
||||
static uint8_t tx_ringbuf_tail;
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_MONITOR_RTT)
|
||||
static uint8_t rtt_buf[256];
|
||||
static uint8_t rtt_buf[MYNEWT_VAL(BLE_MONITOR_RTT_BUFFER_SIZE)];
|
||||
static int rtt_index;
|
||||
#if MYNEWT_VAL(BLE_MONITOR_RTT_BUFFERED)
|
||||
static uint8_t rtt_pktbuf[256];
|
||||
static uint8_t rtt_pktbuf[MYNEWT_VAL(BLE_MONITOR_RTT_BUFFER_SIZE)];
|
||||
static size_t rtt_pktbuf_pos;
|
||||
static struct {
|
||||
bool dropped;
|
||||
struct os_callout tmo;
|
||||
struct ble_monitor_drops_hdr drops_hdr;
|
||||
} rtt_drops;
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -120,12 +124,60 @@ monitor_write(const void *buf, size_t len)
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_MONITOR_RTT)
|
||||
|
||||
#if MYNEWT_VAL(BLE_MONITOR_RTT_BUFFERED)
|
||||
static void
|
||||
update_drop_counters(struct ble_monitor_hdr *failed_hdr)
|
||||
{
|
||||
uint8_t *cnt;
|
||||
|
||||
rtt_drops.dropped = true;
|
||||
|
||||
switch (failed_hdr->opcode) {
|
||||
case BLE_MONITOR_OPCODE_COMMAND_PKT:
|
||||
cnt = &rtt_drops.drops_hdr.cmd;
|
||||
break;
|
||||
case BLE_MONITOR_OPCODE_EVENT_PKT:
|
||||
cnt = &rtt_drops.drops_hdr.evt;
|
||||
break;
|
||||
case BLE_MONITOR_OPCODE_ACL_TX_PKT:
|
||||
cnt = &rtt_drops.drops_hdr.acl_tx;
|
||||
break;
|
||||
case BLE_MONITOR_OPCODE_ACL_RX_PKT:
|
||||
cnt = &rtt_drops.drops_hdr.acl_rx;
|
||||
break;
|
||||
default:
|
||||
cnt = &rtt_drops.drops_hdr.other;
|
||||
break;
|
||||
}
|
||||
|
||||
if (*cnt < UINT8_MAX) {
|
||||
(*cnt)++;
|
||||
os_callout_reset(&rtt_drops.tmo, OS_TICKS_PER_SEC);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
reset_drop_counters(void)
|
||||
{
|
||||
rtt_drops.dropped = false;
|
||||
rtt_drops.drops_hdr.cmd = 0;
|
||||
rtt_drops.drops_hdr.evt = 0;
|
||||
rtt_drops.drops_hdr.acl_tx = 0;
|
||||
rtt_drops.drops_hdr.acl_rx = 0;
|
||||
rtt_drops.drops_hdr.other = 0;
|
||||
|
||||
os_callout_stop(&rtt_drops.tmo);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
monitor_write(const void *buf, size_t len)
|
||||
{
|
||||
#if MYNEWT_VAL(BLE_MONITOR_RTT_BUFFERED)
|
||||
struct ble_monitor_hdr *hdr = (struct ble_monitor_hdr *) rtt_pktbuf;
|
||||
bool discard;
|
||||
unsigned ret = 0;
|
||||
|
||||
/* We will discard any packet which exceeds length of intermediate buffer */
|
||||
discard = rtt_pktbuf_pos + len > sizeof(rtt_pktbuf);
|
||||
@@ -139,9 +191,14 @@ monitor_write(const void *buf, size_t len)
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: count dropped packets
|
||||
if (!discard) {
|
||||
SEGGER_RTT_WriteNoLock(rtt_index, rtt_pktbuf, rtt_pktbuf_pos);
|
||||
ret = SEGGER_RTT_WriteNoLock(rtt_index, rtt_pktbuf, rtt_pktbuf_pos);
|
||||
}
|
||||
|
||||
if (ret > 0) {
|
||||
reset_drop_counters();
|
||||
} else {
|
||||
update_drop_counters(hdr);
|
||||
}
|
||||
|
||||
rtt_pktbuf_pos = 0;
|
||||
@@ -151,6 +208,49 @@ monitor_write(const void *buf, size_t len)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
monitor_write_header(uint16_t opcode, uint16_t len)
|
||||
{
|
||||
struct ble_monitor_hdr hdr;
|
||||
struct ble_monitor_ts_hdr ts_hdr;
|
||||
uint8_t hdr_len;
|
||||
int64_t ts;
|
||||
|
||||
hdr_len = sizeof(ts_hdr);
|
||||
#if MYNEWT_VAL(BLE_MONITOR_RTT) && MYNEWT_VAL(BLE_MONITOR_RTT_BUFFERED)
|
||||
if (rtt_drops.dropped) {
|
||||
hdr_len += sizeof(rtt_drops.drops_hdr);
|
||||
}
|
||||
#endif
|
||||
|
||||
hdr.data_len = htole16(4 + hdr_len + len);
|
||||
hdr.hdr_len = hdr_len;
|
||||
hdr.opcode = htole16(opcode);
|
||||
hdr.flags = 0;
|
||||
|
||||
/* Use uptime for timestamp */
|
||||
ts = os_get_uptime_usec();
|
||||
|
||||
/*
|
||||
* btsnoop specification states that fields of extended header must be
|
||||
* sorted in increasing order so we will send drops (if any) headers before
|
||||
* timestamp header.
|
||||
*/
|
||||
|
||||
monitor_write(&hdr, sizeof(hdr));
|
||||
|
||||
#if MYNEWT_VAL(BLE_MONITOR_RTT) && MYNEWT_VAL(BLE_MONITOR_RTT_BUFFERED)
|
||||
if (rtt_drops.dropped) {
|
||||
monitor_write(&rtt_drops.drops_hdr, sizeof(rtt_drops.drops_hdr));
|
||||
}
|
||||
#endif
|
||||
|
||||
ts_hdr.type = BLE_MONITOR_EXTHDR_TS32;
|
||||
ts_hdr.ts32 = htole32(ts / 100);
|
||||
|
||||
monitor_write(&ts_hdr, sizeof(ts_hdr));
|
||||
}
|
||||
|
||||
static size_t
|
||||
btmon_write(FILE *instance, const char *bp, size_t n)
|
||||
{
|
||||
@@ -165,32 +265,23 @@ static FILE *btmon = (FILE *) &(struct File) {
|
||||
},
|
||||
};
|
||||
|
||||
#if MYNEWT_VAL(BLE_MONITOR_RTT) && MYNEWT_VAL(BLE_MONITOR_RTT_BUFFERED)
|
||||
static void
|
||||
encode_monitor_hdr(struct ble_monitor_hdr *hdr, int64_t ts, uint16_t opcode,
|
||||
uint16_t len)
|
||||
drops_tmp_cb(struct os_event *ev)
|
||||
{
|
||||
int rc;
|
||||
struct os_timeval tv;
|
||||
os_mutex_pend(&lock, OS_TIMEOUT_NEVER);
|
||||
|
||||
hdr->hdr_len = sizeof(hdr->type) + sizeof(hdr->ts32);
|
||||
hdr->data_len = htole16(4 + hdr->hdr_len + len);
|
||||
hdr->opcode = htole16(opcode);
|
||||
hdr->flags = 0;
|
||||
/*
|
||||
* There's no "nop" in btsnoop protocol so we just send empty system note
|
||||
* to indicate drops.
|
||||
*/
|
||||
|
||||
/* Calculate timestamp if not present (same way as used in log module) */
|
||||
if (ts < 0) {
|
||||
rc = os_gettimeofday(&tv, NULL);
|
||||
if (rc || tv.tv_sec < UTC01_01_2016) {
|
||||
ts = os_get_uptime_usec();
|
||||
} else {
|
||||
ts = tv.tv_sec * 1000000 + tv.tv_usec;
|
||||
}
|
||||
}
|
||||
monitor_write_header(BLE_MONITOR_OPCODE_SYSTEM_NOTE, 1);
|
||||
monitor_write("", 1);
|
||||
|
||||
/* Extended header */
|
||||
hdr->type = BLE_MONITOR_EXTHDR_TS32;
|
||||
hdr->ts32 = htole32(ts / 100);
|
||||
os_mutex_release(&lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
ble_monitor_init(void)
|
||||
@@ -216,6 +307,15 @@ ble_monitor_init(void)
|
||||
|
||||
#if MYNEWT_VAL(BLE_MONITOR_RTT)
|
||||
#if MYNEWT_VAL(BLE_MONITOR_RTT_BUFFERED)
|
||||
os_callout_init(&rtt_drops.tmo, ble_hs_evq_get(), drops_tmp_cb, NULL);
|
||||
|
||||
/* Initialize types in header (we won't touch them later) */
|
||||
rtt_drops.drops_hdr.type_cmd = BLE_MONITOR_EXTHDR_COMMAND_DROPS;
|
||||
rtt_drops.drops_hdr.type_evt = BLE_MONITOR_EXTHDR_EVENT_DROPS;
|
||||
rtt_drops.drops_hdr.type_acl_tx = BLE_MONITOR_EXTHDR_ACL_TX_DROPS;
|
||||
rtt_drops.drops_hdr.type_acl_rx = BLE_MONITOR_EXTHDR_ACL_RX_DROPS;
|
||||
rtt_drops.drops_hdr.type_other = BLE_MONITOR_EXTHDR_OTHER_DROPS;
|
||||
|
||||
rtt_index = SEGGER_RTT_AllocUpBuffer(MYNEWT_VAL(BLE_MONITOR_RTT_BUFFER_NAME),
|
||||
rtt_buf, sizeof(rtt_buf),
|
||||
SEGGER_RTT_MODE_NO_BLOCK_SKIP);
|
||||
@@ -238,13 +338,9 @@ ble_monitor_init(void)
|
||||
int
|
||||
ble_monitor_send(uint16_t opcode, const void *data, size_t len)
|
||||
{
|
||||
struct ble_monitor_hdr hdr;
|
||||
|
||||
encode_monitor_hdr(&hdr, -1, opcode, len);
|
||||
|
||||
os_mutex_pend(&lock, OS_TIMEOUT_NEVER);
|
||||
|
||||
monitor_write(&hdr, sizeof(hdr));
|
||||
monitor_write_header(opcode, len);
|
||||
monitor_write(data, len);
|
||||
|
||||
os_mutex_release(&lock);
|
||||
@@ -256,7 +352,6 @@ int
|
||||
ble_monitor_send_om(uint16_t opcode, const struct os_mbuf *om)
|
||||
{
|
||||
const struct os_mbuf *om_tmp;
|
||||
struct ble_monitor_hdr hdr;
|
||||
uint16_t length = 0;
|
||||
|
||||
om_tmp = om;
|
||||
@@ -265,11 +360,9 @@ ble_monitor_send_om(uint16_t opcode, const struct os_mbuf *om)
|
||||
om_tmp = SLIST_NEXT(om_tmp, om_next);
|
||||
}
|
||||
|
||||
encode_monitor_hdr(&hdr, -1, opcode, length);
|
||||
|
||||
os_mutex_pend(&lock, OS_TIMEOUT_NEVER);
|
||||
|
||||
monitor_write(&hdr, sizeof(hdr));
|
||||
monitor_write_header(opcode, length);
|
||||
|
||||
while (om) {
|
||||
monitor_write(om->om_data, om->om_len);
|
||||
@@ -301,7 +394,6 @@ int
|
||||
ble_monitor_log(int level, const char *fmt, ...)
|
||||
{
|
||||
static const char id[] = "nimble";
|
||||
struct ble_monitor_hdr hdr;
|
||||
struct ble_monitor_user_logging ulog;
|
||||
va_list va;
|
||||
int len;
|
||||
@@ -330,12 +422,10 @@ ble_monitor_log(int level, const char *fmt, ...)
|
||||
|
||||
ulog.ident_len = sizeof(id);
|
||||
|
||||
encode_monitor_hdr(&hdr, -1, BLE_MONITOR_OPCODE_USER_LOGGING,
|
||||
sizeof(ulog) + sizeof(id) + len + 1);
|
||||
|
||||
os_mutex_pend(&lock, OS_TIMEOUT_NEVER);
|
||||
|
||||
monitor_write(&hdr, sizeof(hdr));
|
||||
monitor_write_header(BLE_MONITOR_OPCODE_USER_LOGGING,
|
||||
sizeof(ulog) + sizeof(id) + len + 1);
|
||||
monitor_write(&ulog, sizeof(ulog));
|
||||
monitor_write(id, sizeof(id));
|
||||
|
||||
@@ -354,12 +444,15 @@ ble_monitor_log(int level, const char *fmt, ...)
|
||||
int
|
||||
ble_monitor_out(int c)
|
||||
{
|
||||
static char buf[128];
|
||||
static char buf[MYNEWT_VAL(BLE_MONITOR_CONSOLE_BUFFER_SIZE)];
|
||||
static size_t len;
|
||||
|
||||
if (c != '\n' && len < sizeof(buf) - 1) {
|
||||
if (c != '\n') {
|
||||
buf[len++] = c;
|
||||
return c;
|
||||
|
||||
if (len < sizeof(buf) - 1) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
buf[len++] = '\0';
|
||||
|
||||
@@ -38,7 +38,6 @@ extern "C" {
|
||||
#define BLE_MONITOR_OPCODE_VENDOR_DIAG 11
|
||||
#define BLE_MONITOR_OPCODE_SYSTEM_NOTE 12
|
||||
#define BLE_MONITOR_OPCODE_USER_LOGGING 13
|
||||
#define BLE_MONITOR_OPCODE_NOP 255
|
||||
|
||||
#define BLE_MONITOR_EXTHDR_COMMAND_DROPS 1
|
||||
#define BLE_MONITOR_EXTHDR_EVENT_DROPS 2
|
||||
@@ -54,8 +53,22 @@ struct ble_monitor_hdr {
|
||||
uint16_t opcode;
|
||||
uint8_t flags;
|
||||
uint8_t hdr_len;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Extended header (timestamp always present) */
|
||||
struct ble_monitor_drops_hdr {
|
||||
uint8_t type_cmd;
|
||||
uint8_t cmd;
|
||||
uint8_t type_evt;
|
||||
uint8_t evt;
|
||||
uint8_t type_acl_tx;
|
||||
uint8_t acl_tx;
|
||||
uint8_t type_acl_rx;
|
||||
uint8_t acl_rx;
|
||||
uint8_t type_other;
|
||||
uint8_t other;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct ble_monitor_ts_hdr {
|
||||
uint8_t type;
|
||||
uint32_t ts32;
|
||||
} __attribute__((packed));
|
||||
|
||||
@@ -50,12 +50,20 @@ syscfg.defs:
|
||||
BLE_MONITOR_UART_BAUDRATE:
|
||||
description: Baudrate for monitor interface UART
|
||||
value: 1000000
|
||||
BLE_MONITOR_UART_BUFFER_SIZE:
|
||||
description: >
|
||||
Monitor interface ringbuffer size for UART.
|
||||
This value should be a power of 2.
|
||||
value: 64
|
||||
BLE_MONITOR_RTT:
|
||||
description: Enables monitor interface over RTT
|
||||
value: 0
|
||||
BLE_MONITOR_RTT_BUFFER_NAME:
|
||||
description: Monitor interface upstream buffer name
|
||||
value: '"monitor"'
|
||||
BLE_MONITOR_RTT_BUFFER_SIZE:
|
||||
description: Monitor interface upstream buffer size
|
||||
value: 256
|
||||
BLE_MONITOR_RTT_BUFFERED:
|
||||
description: >
|
||||
Enables buffering when using monitor interface over RTT. The data
|
||||
@@ -64,6 +72,11 @@ syscfg.defs:
|
||||
space in RTT buffer (e.g. there is no reader connected). If disabled,
|
||||
monitor will simply block waiting for RTT to free space in buffer.
|
||||
value: 1
|
||||
BLE_MONITOR_CONSOLE_BUFFER_SIZE:
|
||||
description: >
|
||||
Size of internal buffer for console output. Any line exceeding this
|
||||
length value will be split.
|
||||
value: 128
|
||||
|
||||
# L2CAP settings.
|
||||
BLE_L2CAP_MAX_CHANS:
|
||||
|
||||
Reference in New Issue
Block a user