mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-08-10 12:07:55 +00:00
babblesim/edtt: Refactor queue handling
This reworks events handling in EDTT. The "service_events" routine is now handled in separate task which blocks until new event is put in queue. This is possible since we use os_eventq to pass events and this means any get from queue will put task to sleep properly and trigger context switch if necessary. The blocking edtt_read() will now sleep if not data is available instead of advancing time machine forward so it does not interfere with timing. OS_TICKS_PER_SEC was increased to 1024 to have better granularity and allow ~5ms sleep time for edtt poller task as required. Also some non-LL code is simplified to use simple calloc/free as it does not really seem to be cessary to use mempools there, i.e. we just need some memory block to pass data and it does not really matter how it's allocated. Also using calloc/free means we will never run out of memory so no need to check for that.
This commit is contained in:
@@ -11,8 +11,7 @@
|
||||
#include <bs_tracing.h>
|
||||
#include "sysinit/sysinit.h"
|
||||
#include "syscfg/syscfg.h"
|
||||
#include "os/os_cputime.h"
|
||||
#include "os/os.h"
|
||||
#include "os/os_eventq.h"
|
||||
|
||||
/* BLE */
|
||||
#include "nimble/ble.h"
|
||||
@@ -34,9 +33,6 @@
|
||||
#define BLE_HCI_EDTT_ACL 0x02
|
||||
#define BLE_HCI_EDTT_EVT 0x04
|
||||
|
||||
#define K_NO_WAIT 0
|
||||
#define K_FOREVER 1
|
||||
|
||||
#define BT_HCI_OP_VS_WRITE_BD_ADDR 0xFC06
|
||||
|
||||
/* Callbacks for sending commands and acl data to ble_ll task */
|
||||
@@ -84,33 +80,23 @@ static os_membuf_t ble_hci_edtt_acl_buf[
|
||||
|
||||
/* A packet for queueing EDTT/HCI commands and events */
|
||||
struct ble_hci_edtt_pkt {
|
||||
struct os_event ev;
|
||||
STAILQ_ENTRY(ble_hci_edtt_pkt) next;
|
||||
uint32_t timestamp;
|
||||
uint8_t type;
|
||||
void *data;
|
||||
};
|
||||
|
||||
/* Memory pool for ble_hci_edtt_pkt packets */
|
||||
static struct os_mempool ble_hci_edtt_pkt_pool;
|
||||
static os_membuf_t ble_hci_edtt_pkt_buf[
|
||||
OS_MEMPOOL_SIZE(BLE_HCI_EDTT_EVT_COUNT + 1 +
|
||||
MYNEWT_VAL(BLE_HCI_ACL_OUT_COUNT),
|
||||
sizeof(struct ble_hci_edtt_pkt))
|
||||
];
|
||||
|
||||
STAILQ_HEAD(ble_hci_edtt_pkt_queue, ble_hci_edtt_pkt);
|
||||
static struct ble_hci_edtt_pkt_queue data_queue;
|
||||
static struct ble_hci_edtt_pkt_queue rx_queue;
|
||||
static struct ble_hci_edtt_pkt_queue event_queue;
|
||||
static struct os_eventq edtt_q_svc;
|
||||
static struct os_eventq edtt_q_data;
|
||||
static struct os_eventq edtt_q_event;
|
||||
static uint8_t edtt_q_event_count;
|
||||
|
||||
static uint16_t waiting_opcode;
|
||||
static enum commands_t waiting_response;
|
||||
static uint8_t m_events;
|
||||
|
||||
#define EDTT_POLLER_STACK_SZ OS_STACK_ALIGN(4000)
|
||||
static int edtt_poller_running;
|
||||
static struct os_task edtt_poller_task;
|
||||
static os_stack_t edtt_poller_stack[EDTT_POLLER_STACK_SZ];
|
||||
static struct os_task edtt_service_task;
|
||||
|
||||
#if EDTT_HCI_LOGS
|
||||
extern unsigned int global_device_nbr;
|
||||
@@ -184,7 +170,6 @@ static int
|
||||
ble_hci_edtt_acl_tx(struct os_mbuf *om)
|
||||
{
|
||||
struct ble_hci_edtt_pkt *pkt;
|
||||
os_sr_t sr;
|
||||
|
||||
/* If this packet is zero length, just free it */
|
||||
if (OS_MBUF_PKTLEN(om) == 0) {
|
||||
@@ -192,18 +177,11 @@ ble_hci_edtt_acl_tx(struct os_mbuf *om)
|
||||
return 0;
|
||||
}
|
||||
|
||||
pkt = os_memblock_get(&ble_hci_edtt_pkt_pool);
|
||||
if (pkt == NULL) {
|
||||
os_mbuf_free_chain(om);
|
||||
return BLE_ERR_MEM_CAPACITY;
|
||||
}
|
||||
|
||||
pkt = calloc(1, sizeof(*pkt));
|
||||
pkt->type = BLE_HCI_EDTT_ACL;
|
||||
pkt->data = om;
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
STAILQ_INSERT_TAIL(&rx_queue, pkt, next);
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
os_eventq_put(&edtt_q_svc, &pkt->ev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -212,20 +190,12 @@ static int
|
||||
ble_hci_edtt_cmdevt_tx(uint8_t *hci_ev, uint8_t edtt_type)
|
||||
{
|
||||
struct ble_hci_edtt_pkt *pkt;
|
||||
os_sr_t sr;
|
||||
|
||||
pkt = os_memblock_get(&ble_hci_edtt_pkt_pool);
|
||||
if (pkt == NULL) {
|
||||
ble_hci_trans_buf_free(hci_ev);
|
||||
return BLE_ERR_MEM_CAPACITY;
|
||||
}
|
||||
|
||||
pkt = calloc(1, sizeof(*pkt));
|
||||
pkt->type = edtt_type;
|
||||
pkt->data = hci_ev;
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
STAILQ_INSERT_TAIL(&rx_queue, pkt, next);
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
os_eventq_put(&edtt_q_svc, &pkt->ev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -242,58 +212,6 @@ ble_hci_edtt_set_rx_cbs(ble_hci_trans_rx_cmd_fn *cmd_cb,
|
||||
ble_hci_edtt_rx_acl_arg = acl_arg;
|
||||
}
|
||||
|
||||
/* Free data buffer */
|
||||
static void
|
||||
ble_hci_edtt_free_buf(uint8_t type, uint8_t *cmdevt, struct os_mbuf *acl)
|
||||
{
|
||||
switch (type) {
|
||||
case BLE_HCI_EDTT_NONE:
|
||||
break;
|
||||
|
||||
case BLE_HCI_EDTT_CMD:
|
||||
case BLE_HCI_EDTT_EVT:
|
||||
ble_hci_trans_buf_free(cmdevt);
|
||||
break;
|
||||
|
||||
case BLE_HCI_EDTT_ACL:
|
||||
os_mbuf_free_chain(acl);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
edtt_pkt_dequeue_and_free(struct ble_hci_edtt_pkt_queue *queue, struct ble_hci_edtt_pkt *pkt)
|
||||
{
|
||||
/* Dequeue pkt header */
|
||||
STAILQ_REMOVE(queue, pkt, ble_hci_edtt_pkt, next);
|
||||
/* Free data buffer */
|
||||
ble_hci_edtt_free_buf(pkt->type, pkt->data, pkt->data);
|
||||
/* Free buffer of pkt header */
|
||||
os_memblock_put(&ble_hci_edtt_pkt_pool, pkt);
|
||||
}
|
||||
|
||||
/* Get first element of queue, without dequeueing */
|
||||
static struct ble_hci_edtt_pkt *
|
||||
edtt_pkt_get(struct ble_hci_edtt_pkt_queue *queue, uint8_t block)
|
||||
{
|
||||
struct ble_hci_edtt_pkt *pkt;
|
||||
|
||||
if (block == K_FOREVER) {
|
||||
while (STAILQ_EMPTY(queue)) {}
|
||||
|
||||
pkt = STAILQ_FIRST(queue);
|
||||
assert(pkt != NULL);
|
||||
} else {
|
||||
pkt = STAILQ_FIRST(queue);
|
||||
}
|
||||
|
||||
return pkt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an HCI event from the controller to the host.
|
||||
*
|
||||
@@ -435,35 +353,6 @@ ble_hci_trans_cfg_ll(ble_hci_trans_rx_cmd_fn *cmd_cb,
|
||||
ble_hci_edtt_set_rx_cbs(cmd_cb, cmd_arg, acl_cb, acl_arg);
|
||||
}
|
||||
|
||||
void
|
||||
ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *cmd_cb,
|
||||
void *cmd_arg,
|
||||
ble_hci_trans_rx_acl_fn *acl_cb,
|
||||
void *acl_arg)
|
||||
{
|
||||
ble_hci_edtt_set_rx_cbs(cmd_cb, cmd_arg, acl_cb, acl_arg);
|
||||
}
|
||||
|
||||
int
|
||||
ble_hci_trans_reset(void)
|
||||
{
|
||||
struct ble_hci_edtt_pkt *pkt;
|
||||
|
||||
while ((pkt = STAILQ_FIRST(&data_queue)) != NULL) {
|
||||
edtt_pkt_dequeue_and_free(&data_queue, pkt);
|
||||
}
|
||||
|
||||
while ((pkt = STAILQ_FIRST(&event_queue)) != NULL) {
|
||||
edtt_pkt_dequeue_and_free(&event_queue, pkt);
|
||||
}
|
||||
|
||||
while ((pkt = STAILQ_FIRST(&rx_queue)) != NULL) {
|
||||
edtt_pkt_dequeue_and_free(&rx_queue, pkt);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clean out excess bytes from the input buffer
|
||||
*/
|
||||
@@ -556,23 +445,23 @@ echo(uint16_t size)
|
||||
* @brief Handle Command Complete HCI event
|
||||
*/
|
||||
static void
|
||||
command_complete(struct ble_hci_ev *hdr)
|
||||
command_complete(struct ble_hci_ev *evt)
|
||||
{
|
||||
struct ble_hci_ev_command_complete *evt = (void *) hdr->data;
|
||||
struct ble_hci_ev_command_complete *evt_cc = (void *) evt->data;
|
||||
uint16_t response = waiting_response;
|
||||
uint16_t size = hdr->length - sizeof(evt->num_packets) - sizeof(evt->opcode);
|
||||
uint16_t size = evt->length - sizeof(evt_cc->num_packets) - sizeof(evt_cc->opcode);
|
||||
|
||||
if (evt->opcode == waiting_opcode) {
|
||||
if (evt_cc->opcode == waiting_opcode) {
|
||||
bs_trace_raw_time(9, "Command complete for 0x%04x", waiting_opcode);
|
||||
|
||||
edtt_write((uint8_t *) &response, sizeof(response), EDTTT_BLOCK);
|
||||
edtt_write((uint8_t *) &size, sizeof(size), EDTTT_BLOCK);
|
||||
edtt_write((uint8_t *) &evt->status, sizeof(evt->status), EDTTT_BLOCK);
|
||||
edtt_write((uint8_t *) &evt->return_params, size - sizeof(evt->status), EDTTT_BLOCK);
|
||||
edtt_write((uint8_t *) &evt_cc->status, sizeof(evt_cc->status), EDTTT_BLOCK);
|
||||
edtt_write((uint8_t *) &evt_cc->return_params, size - sizeof(evt_cc->status), EDTTT_BLOCK);
|
||||
waiting_opcode = 0;
|
||||
} else {
|
||||
bs_trace_raw_time(5, "Not waiting for 0x(%04x) command status,"
|
||||
" expected 0x(%04x)", evt->opcode, waiting_opcode);
|
||||
" expected 0x(%04x)", evt_cc->opcode, waiting_opcode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -580,22 +469,22 @@ command_complete(struct ble_hci_ev *hdr)
|
||||
* @brief Handle Command Status HCI event
|
||||
*/
|
||||
static void
|
||||
command_status(struct ble_hci_ev *buf)
|
||||
command_status(struct ble_hci_ev *evt)
|
||||
{
|
||||
struct ble_hci_ev_command_status *evt = (void *) buf->data;
|
||||
uint16_t opcode = evt->opcode;
|
||||
struct ble_hci_ev_command_status *evt_cs = (void *) evt->data;
|
||||
uint16_t opcode = evt_cs->opcode;
|
||||
uint16_t response = waiting_response;
|
||||
uint16_t size;
|
||||
|
||||
size = buf->length - sizeof(evt->num_packets) - sizeof(evt->opcode);
|
||||
size = evt->length - sizeof(evt_cs->num_packets) - sizeof(evt_cs->opcode);
|
||||
|
||||
if (opcode == waiting_opcode) {
|
||||
bs_trace_raw_time(9, "Command status for 0x%04x", waiting_opcode);
|
||||
|
||||
edtt_write((uint8_t *) &response, sizeof(response), EDTTT_BLOCK);
|
||||
edtt_write((uint8_t *) &size, sizeof(size), EDTTT_BLOCK);
|
||||
edtt_write((uint8_t *) &evt->status, sizeof(evt->status), EDTTT_BLOCK);
|
||||
edtt_write((uint8_t *) &evt->num_packets, size - sizeof(evt->status), EDTTT_BLOCK);
|
||||
edtt_write((uint8_t *) &evt_cs->status, sizeof(evt_cs->status), EDTTT_BLOCK);
|
||||
edtt_write((uint8_t *) &evt_cs->num_packets, size - sizeof(evt_cs->status), EDTTT_BLOCK);
|
||||
waiting_opcode = 0;
|
||||
} else {
|
||||
bs_trace_raw_time(5, "Not waiting for 0x(%04x) command status,"
|
||||
@@ -603,105 +492,104 @@ command_status(struct ble_hci_ev *buf)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Remove an event from the event queue
|
||||
*/
|
||||
static void
|
||||
discard_event(void)
|
||||
free_data(struct ble_hci_edtt_pkt *pkt)
|
||||
{
|
||||
struct ble_hci_edtt_pkt *evt = edtt_pkt_get(&event_queue, K_FOREVER);
|
||||
edtt_pkt_dequeue_and_free(&event_queue, evt);
|
||||
m_events--;
|
||||
assert(pkt);
|
||||
os_mbuf_free_chain(pkt->data);
|
||||
free(pkt);
|
||||
}
|
||||
|
||||
static void
|
||||
free_event(struct ble_hci_edtt_pkt *pkt)
|
||||
{
|
||||
assert(pkt);
|
||||
ble_hci_trans_buf_free((void *)pkt->data);
|
||||
free(pkt);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allocate and store an event in the event queue
|
||||
*/
|
||||
static struct ble_hci_edtt_pkt *
|
||||
queue_event(struct ble_hci_ev *buf)
|
||||
queue_event(struct ble_hci_ev *evt)
|
||||
{
|
||||
struct ble_hci_edtt_pkt *evt;
|
||||
struct ble_hci_edtt_pkt *pkt;
|
||||
|
||||
evt = os_memblock_get(&ble_hci_edtt_pkt_pool);
|
||||
if (evt) {
|
||||
evt->timestamp = tm_get_hw_time();
|
||||
evt->type = BLE_HCI_EDTT_EVT;
|
||||
evt->data = buf;
|
||||
pkt = calloc(1, sizeof(*pkt));
|
||||
assert(pkt);
|
||||
pkt->timestamp = tm_get_hw_time();
|
||||
pkt->type = BLE_HCI_EDTT_EVT;
|
||||
pkt->data = evt;
|
||||
|
||||
STAILQ_INSERT_TAIL(&event_queue, evt, next);
|
||||
m_events++;
|
||||
}
|
||||
return evt;
|
||||
os_eventq_put(&edtt_q_event, &pkt->ev);
|
||||
edtt_q_event_count++;
|
||||
|
||||
return pkt;
|
||||
}
|
||||
|
||||
static struct ble_hci_edtt_pkt *
|
||||
queue_data(struct os_mbuf *om)
|
||||
{
|
||||
struct ble_hci_edtt_pkt *pkt;
|
||||
|
||||
pkt = calloc(1, sizeof(*pkt));
|
||||
assert(pkt);
|
||||
pkt->timestamp = tm_get_hw_time();
|
||||
pkt->type = BLE_HCI_EDTT_ACL;
|
||||
pkt->data = om;
|
||||
|
||||
os_eventq_put(&edtt_q_data, &pkt->ev);
|
||||
|
||||
return pkt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Thread to service events and ACL data packets from the HCI input queue
|
||||
*/
|
||||
static void
|
||||
service_events(void)
|
||||
service_events(void *arg)
|
||||
{
|
||||
struct ble_hci_edtt_pkt *rx_pkt, *evt_pkt, *data_pkt;
|
||||
struct ble_hci_ev *hdr;
|
||||
struct os_mbuf *om;
|
||||
struct ble_hci_edtt_pkt *pkt;
|
||||
struct ble_hci_ev *evt;
|
||||
|
||||
rx_pkt = edtt_pkt_get(&rx_queue, K_NO_WAIT);
|
||||
if (rx_pkt == NULL) {
|
||||
return;
|
||||
}
|
||||
while (1) {
|
||||
pkt = (void *)os_eventq_get(&edtt_q_svc);
|
||||
|
||||
if (rx_pkt->type == BLE_HCI_EDTT_EVT) {
|
||||
hdr = (void *) rx_pkt->data;
|
||||
if (pkt->type == BLE_HCI_EDTT_EVT) {
|
||||
evt = (void *)pkt->data;
|
||||
|
||||
#if EDTT_HCI_LOGS
|
||||
log_hci_evt(hdr);
|
||||
log_hci_evt(hdr);
|
||||
#endif
|
||||
|
||||
/* Prepare and send EDTT events */
|
||||
switch (hdr->opcode) {
|
||||
/* Prepare and send EDTT events */
|
||||
switch (evt->opcode) {
|
||||
case BLE_HCI_EVCODE_COMMAND_COMPLETE:
|
||||
evt_pkt = queue_event(hdr);
|
||||
if (!evt_pkt) {
|
||||
discard_event();
|
||||
evt_pkt = queue_event(hdr);
|
||||
}
|
||||
command_complete(hdr);
|
||||
queue_event(evt);
|
||||
command_complete(evt);
|
||||
break;
|
||||
case BLE_HCI_EVCODE_COMMAND_STATUS:
|
||||
evt_pkt = queue_event(hdr);
|
||||
if (!evt_pkt) {
|
||||
discard_event();
|
||||
evt_pkt = queue_event(hdr);
|
||||
}
|
||||
command_status(hdr);
|
||||
queue_event(evt);
|
||||
command_status(evt);
|
||||
break;
|
||||
case BLE_HCI_EVCODE_NUM_COMP_PKTS:
|
||||
/* EDTT does not handle this event and treats like fail */
|
||||
case BLE_HCI_OPCODE_NOP:
|
||||
/* Ignore noop bytes from Link layer */
|
||||
edtt_pkt_dequeue_and_free(&rx_queue, rx_pkt);
|
||||
return;
|
||||
ble_hci_trans_buf_free((void *)evt);
|
||||
break;
|
||||
default:
|
||||
/* Queue HCI events. We will send them to EDTT
|
||||
* on CMD_GET_EVENT_REQ. */
|
||||
evt_pkt = queue_event(hdr);
|
||||
if (!evt_pkt) {
|
||||
bs_trace_raw_time(4, "Failed to allocated buffer for event!\n");
|
||||
}
|
||||
queue_event(evt);
|
||||
}
|
||||
} else if (pkt->type == BLE_HCI_EDTT_ACL) {
|
||||
queue_data(pkt->data);
|
||||
}
|
||||
} else if (rx_pkt->type == BLE_HCI_EDTT_ACL) {
|
||||
om = (struct os_mbuf *) rx_pkt->data;
|
||||
data_pkt = os_memblock_get(&ble_hci_edtt_pkt_pool);
|
||||
|
||||
if (data_pkt) {
|
||||
data_pkt->type = BLE_HCI_EDTT_ACL;
|
||||
data_pkt->data = om;
|
||||
STAILQ_INSERT_TAIL(&data_queue, data_pkt, next);
|
||||
}
|
||||
free(pkt);
|
||||
}
|
||||
|
||||
/* Free only header buffer, not rx_pkt->data buffer */
|
||||
STAILQ_REMOVE(&rx_queue, rx_pkt, ble_hci_edtt_pkt, next);
|
||||
os_memblock_put(&ble_hci_edtt_pkt_pool, rx_pkt);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -711,11 +599,11 @@ static void
|
||||
flush_events(uint16_t size)
|
||||
{
|
||||
uint16_t response = CMD_FLUSH_EVENTS_RSP;
|
||||
struct ble_hci_edtt_pkt *buf;
|
||||
struct ble_hci_edtt_pkt *pkt;
|
||||
|
||||
while ((buf = edtt_pkt_get(&event_queue, K_NO_WAIT))) {
|
||||
edtt_pkt_dequeue_and_free(&event_queue, buf);
|
||||
m_events--;
|
||||
while ((pkt = (void *)os_eventq_get_no_wait(&edtt_q_event))) {
|
||||
free_event(pkt);
|
||||
edtt_q_event_count--;
|
||||
}
|
||||
read_excess_bytes(size);
|
||||
size = 0;
|
||||
@@ -732,24 +620,24 @@ get_event(uint16_t size)
|
||||
{
|
||||
uint16_t response = CMD_GET_EVENT_RSP;
|
||||
struct ble_hci_edtt_pkt *pkt;
|
||||
struct ble_hci_ev *hdr;
|
||||
struct ble_hci_ev *evt;
|
||||
|
||||
read_excess_bytes(size);
|
||||
size = 0;
|
||||
|
||||
edtt_write((uint8_t *)&response, sizeof(response), EDTTT_BLOCK);
|
||||
pkt = edtt_pkt_get(&event_queue, K_FOREVER);
|
||||
|
||||
pkt = (void*)os_eventq_get(&edtt_q_event);
|
||||
if (pkt) {
|
||||
hdr = pkt->data;
|
||||
size = sizeof(pkt->timestamp) + sizeof(*hdr) + hdr->length;
|
||||
evt = pkt->data;
|
||||
size = sizeof(pkt->timestamp) + sizeof(*evt) + evt->length;
|
||||
|
||||
edtt_write((uint8_t *)&size, sizeof(size), EDTTT_BLOCK);
|
||||
edtt_write((uint8_t *)&pkt->timestamp, sizeof(pkt->timestamp), EDTTT_BLOCK);
|
||||
edtt_write((uint8_t *)hdr, sizeof(*hdr) + hdr->length, EDTTT_BLOCK);
|
||||
edtt_write((uint8_t *)evt, sizeof(*evt) + evt->length, EDTTT_BLOCK);
|
||||
|
||||
edtt_pkt_dequeue_and_free(&event_queue, pkt);
|
||||
m_events--;
|
||||
free_event(pkt);
|
||||
|
||||
edtt_q_event_count--;
|
||||
} else {
|
||||
edtt_write((uint8_t *)&size, sizeof(size), EDTTT_BLOCK);
|
||||
}
|
||||
@@ -763,8 +651,8 @@ get_events(uint16_t size)
|
||||
{
|
||||
uint16_t response = CMD_GET_EVENT_RSP;
|
||||
struct ble_hci_edtt_pkt *pkt;
|
||||
struct ble_hci_ev *hdr;
|
||||
uint8_t count = m_events;
|
||||
struct ble_hci_ev *evt;
|
||||
uint8_t count = edtt_q_event_count;
|
||||
|
||||
read_excess_bytes(size);
|
||||
size = 0;
|
||||
@@ -773,16 +661,18 @@ get_events(uint16_t size)
|
||||
edtt_write((uint8_t *)&count, sizeof(count), EDTTT_BLOCK);
|
||||
|
||||
while (count--) {
|
||||
pkt = edtt_pkt_get(&event_queue, K_FOREVER);
|
||||
hdr = pkt->data;
|
||||
size = sizeof(pkt->timestamp) + sizeof(*hdr) + hdr->length;
|
||||
pkt = (void *)os_eventq_get_no_wait(&edtt_q_event);
|
||||
assert(pkt);
|
||||
evt = pkt->data;
|
||||
size = sizeof(pkt->timestamp) + sizeof(*evt) + evt->length;
|
||||
|
||||
edtt_write((uint8_t *)&size, sizeof(size), EDTTT_BLOCK);
|
||||
edtt_write((uint8_t *)&pkt->timestamp, sizeof(pkt->timestamp), EDTTT_BLOCK);
|
||||
edtt_write((uint8_t *)hdr, sizeof(*hdr) + hdr->length, EDTTT_BLOCK);
|
||||
edtt_write((uint8_t *)evt, sizeof(*evt) + evt->length, EDTTT_BLOCK);
|
||||
|
||||
edtt_pkt_dequeue_and_free(&event_queue, pkt);
|
||||
m_events--;
|
||||
free_event(pkt);
|
||||
|
||||
edtt_q_event_count--;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -800,7 +690,7 @@ has_event(uint16_t size)
|
||||
struct has_event_resp le_response = {
|
||||
.response = CMD_HAS_EVENT_RSP,
|
||||
.size = 1,
|
||||
.count = m_events
|
||||
.count = edtt_q_event_count
|
||||
};
|
||||
|
||||
if (size > 0) {
|
||||
@@ -816,11 +706,12 @@ static void
|
||||
le_flush_data(uint16_t size)
|
||||
{
|
||||
uint16_t response = CMD_LE_FLUSH_DATA_RSP;
|
||||
struct ble_hci_edtt_pkt *buf;
|
||||
struct ble_hci_edtt_pkt *pkt;
|
||||
|
||||
while ((buf = edtt_pkt_get(&data_queue, K_NO_WAIT))) {
|
||||
edtt_pkt_dequeue_and_free(&data_queue, buf);
|
||||
while ((pkt = (void *)os_eventq_get_no_wait(&edtt_q_data))) {
|
||||
free_data(pkt);
|
||||
}
|
||||
|
||||
read_excess_bytes(size);
|
||||
size = 0;
|
||||
|
||||
@@ -849,7 +740,8 @@ le_data_ready(uint16_t size)
|
||||
read_excess_bytes(size);
|
||||
}
|
||||
|
||||
if (STAILQ_EMPTY(&data_queue)) {
|
||||
/* There's no API to check if eventq is empty but a little hack will do... */
|
||||
if (edtt_q_data.evq_list.stqh_first == NULL) {
|
||||
le_response.empty = 1;
|
||||
}
|
||||
|
||||
@@ -870,8 +762,7 @@ le_data_read(uint16_t size)
|
||||
size = 0;
|
||||
|
||||
edtt_write((uint8_t *)&response, sizeof(response), EDTTT_BLOCK);
|
||||
pkt = edtt_pkt_get(&data_queue, K_FOREVER);
|
||||
|
||||
pkt = (void *)os_eventq_get(&edtt_q_data);
|
||||
if (pkt) {
|
||||
om = pkt->data;
|
||||
size = OS_MBUF_PKTLEN(om);
|
||||
@@ -882,8 +773,7 @@ le_data_read(uint16_t size)
|
||||
om = SLIST_NEXT(om, om_next);
|
||||
}
|
||||
|
||||
om = pkt->data;
|
||||
os_mbuf_free_chain(om);
|
||||
free_data(pkt);
|
||||
} else {
|
||||
edtt_write((uint8_t *)&size, sizeof(size), EDTTT_BLOCK);
|
||||
}
|
||||
@@ -968,13 +858,11 @@ edtt_poller(void *arg) {
|
||||
uint16_t command;
|
||||
uint16_t size;
|
||||
uint16_t opcode;
|
||||
uint8_t received_cmd_bytes = 0;
|
||||
os_sr_t sr;
|
||||
|
||||
/* Initialize HCI command opcode and response variables */
|
||||
waiting_opcode = 0;
|
||||
waiting_response = CMD_NOTHING;
|
||||
m_events = 0;
|
||||
edtt_q_event_count = 0;
|
||||
|
||||
/* Initialize and start EDTT system */
|
||||
enable_edtt_mode();
|
||||
@@ -986,28 +874,12 @@ edtt_poller(void *arg) {
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
/* Try to receive a command without blocking */
|
||||
received_cmd_bytes = edtt_read((uint8_t *) &command + received_cmd_bytes, sizeof(command) - received_cmd_bytes, EDTTT_NONBLOCK);
|
||||
|
||||
if (received_cmd_bytes < sizeof(command)) {
|
||||
/* No command arrived - try to handle new ble_ll events */
|
||||
service_events();
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
/* Limited tick prevents bypassing EDTT timeouts,
|
||||
* when a longer time gap between timers happens */
|
||||
tm_tick_limited(6000);
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
continue;
|
||||
}
|
||||
|
||||
received_cmd_bytes = 0;
|
||||
|
||||
edtt_read((uint8_t *) &command, sizeof(command), EDTTT_BLOCK);
|
||||
edtt_read((uint8_t *) &size, sizeof(size), EDTTT_BLOCK);
|
||||
|
||||
bs_trace_raw_time(4, "command 0x%04X received (size %u) "
|
||||
"events=%u\n",
|
||||
command, size, m_events);
|
||||
command, size, edtt_q_event_count);
|
||||
|
||||
switch (command) {
|
||||
case CMD_ECHO_REQ:
|
||||
@@ -1061,15 +933,19 @@ edtt_poller(void *arg) {
|
||||
int
|
||||
edtt_init(void)
|
||||
{
|
||||
os_stack_t dummy_stack;
|
||||
int rc;
|
||||
|
||||
if (!edtt_poller_running) {
|
||||
edtt_poller_running = 1;
|
||||
rc = os_task_init(&edtt_poller_task, "edttpoll", edtt_poller, NULL,
|
||||
MYNEWT_VAL(EDTT_POLLER_PRIO), OS_WAIT_FOREVER,
|
||||
edtt_poller_stack, EDTT_POLLER_STACK_SZ);
|
||||
assert(rc == 0);
|
||||
}
|
||||
rc = os_task_init(&edtt_poller_task, "edttpoll", edtt_poller, NULL,
|
||||
MYNEWT_VAL(EDTT_POLLER_PRIO), OS_WAIT_FOREVER,
|
||||
&dummy_stack, 1);
|
||||
assert(rc == 0);
|
||||
|
||||
rc = os_task_init(&edtt_service_task, "edttsvc", service_events, NULL,
|
||||
MYNEWT_VAL(EDTT_POLLER_PRIO) + 1, OS_WAIT_FOREVER,
|
||||
&dummy_stack, 1);
|
||||
assert(rc == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1127,23 +1003,9 @@ ble_hci_edtt_init(void)
|
||||
"ble_hci_edtt_evt_lo_pool");
|
||||
SYSINIT_PANIC_ASSERT(rc == 0);
|
||||
|
||||
/*
|
||||
* Create memory pool of packet list nodes. NOTE: the number of these
|
||||
* buffers should be, at least, the total number of event buffers (hi
|
||||
* and lo), the number of command buffers (currently 1) and the total
|
||||
* number of buffers that the controller could possibly hand to the host.
|
||||
*/
|
||||
rc = os_mempool_init(&ble_hci_edtt_pkt_pool,
|
||||
BLE_HCI_EDTT_EVT_COUNT + 1 +
|
||||
MYNEWT_VAL(BLE_HCI_ACL_OUT_COUNT),
|
||||
sizeof (struct ble_hci_edtt_pkt),
|
||||
ble_hci_edtt_pkt_buf,
|
||||
"ble_hci_edtt_pkt_pool");
|
||||
SYSINIT_PANIC_ASSERT(rc == 0);
|
||||
|
||||
SYSINIT_PANIC_ASSERT_MSG(rc == 0, "Failure configuring edtt HCI");
|
||||
|
||||
STAILQ_INIT(&data_queue);
|
||||
STAILQ_INIT(&event_queue);
|
||||
STAILQ_INIT(&rx_queue);
|
||||
os_eventq_init(&edtt_q_svc);
|
||||
os_eventq_init(&edtt_q_event);
|
||||
os_eventq_init(&edtt_q_data);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include <time_machine.h>
|
||||
#include "edtt_driver.h"
|
||||
#include "os/os_sched.h"
|
||||
|
||||
/* Recheck if something arrived from the EDTT every 5ms */
|
||||
#define EDTT_IF_RECHECK_DELTA 5 /* ms */
|
||||
@@ -124,7 +125,9 @@ int edtt_read(uint8_t *ptr, size_t size, int flags)
|
||||
bs_trace_raw_time(9, "EDTT: No enough data yet,"
|
||||
"sleeping for %i ms\n",
|
||||
EDTT_IF_RECHECK_DELTA);
|
||||
tm_tick_limited(6000);
|
||||
os_sched_sleep(os_sched_get_current_task(),
|
||||
os_time_ms_to_ticks32(EDTT_IF_RECHECK_DELTA));
|
||||
os_sched(NULL);
|
||||
} else {
|
||||
bs_trace_raw_time(9, "EDTT: No enough data yet,"
|
||||
"returning\n");
|
||||
|
||||
@@ -35,6 +35,7 @@ syscfg.defs:
|
||||
|
||||
syscfg.vals:
|
||||
HAL_SBRK: 0
|
||||
OS_TICKS_PER_SEC: 1024
|
||||
OS_MAIN_STACK_SIZE: 8000
|
||||
MCU_TIMER_POLLER_PRIO: 0
|
||||
BLE_LL_PRIO: 1
|
||||
|
||||
Reference in New Issue
Block a user