nRF5_SDK_17.1.0
PCA10059
According to the source code:
ret_code_t nrf_queue_push(nrf_queue_t const * p_queue, void const * p_element)
{
ret_code_t status = NRF_SUCCESS;
ASSERT(p_queue != NULL);
ASSERT(p_element != NULL);
CRITICAL_REGION_ENTER();
bool is_full = nrf_queue_is_full(p_queue);
if (!is_full || (p_queue->mode == NRF_QUEUE_MODE_OVERFLOW))
{
// Get write position.
size_t write_pos = p_queue->p_cb->back;
p_queue->p_cb->back = nrf_queue_next_idx(p_queue, p_queue->p_cb->back);
if (is_full)
{
// Overwrite the oldest element.
NRF_LOG_INST_WARNING(p_queue->p_log, "Queue full. Overwriting oldest element.");
p_queue->p_cb->front = nrf_queue_next_idx(p_queue, p_queue->p_cb->front);
}
// Write a new element.
switch (p_queue->element_size)
{
case sizeof(uint8_t):
((uint8_t *)p_queue->p_buffer)[write_pos] = *((uint8_t *)p_element);
break;
case sizeof(uint16_t):
((uint16_t *)p_queue->p_buffer)[write_pos] = *((uint16_t *)p_element);
break;
case sizeof(uint32_t):
((uint32_t *)p_queue->p_buffer)[write_pos] = *((uint32_t *)p_element);
break;
case sizeof(uint64_t):
((uint64_t *)p_queue->p_buffer)[write_pos] = *((uint64_t *)p_element);
break;
default:
memcpy((void *)((size_t)p_queue->p_buffer + write_pos * p_queue->element_size),
p_element,
p_queue->element_size);
break;
}
// Update utilization.
size_t utilization = queue_utilization_get(p_queue);
if (p_queue->p_cb->max_utilization < utilization)
{
p_queue->p_cb->max_utilization = utilization;
}
}
else
{
status = NRF_ERROR_NO_MEM;
}
CRITICAL_REGION_EXIT();
NRF_LOG_INST_DEBUG(p_queue->p_log, "pushed element 0x%08X, status:%d", p_element, status);
return status;
}
ret_code_t nrf_queue_generic_pop(nrf_queue_t const * p_queue,
void * p_element,
bool just_peek)
{
ret_code_t status = NRF_SUCCESS;
ASSERT(p_queue != NULL);
ASSERT(p_element != NULL);
CRITICAL_REGION_ENTER();
if (!nrf_queue_is_empty(p_queue))
{
// Get read position.
size_t read_pos = p_queue->p_cb->front;
// Update next read position.
if (!just_peek)
{
p_queue->p_cb->front = nrf_queue_next_idx(p_queue, p_queue->p_cb->front);
}
// Read element.
switch (p_queue->element_size)
{
case sizeof(uint8_t):
*((uint8_t *)p_element) = ((uint8_t *)p_queue->p_buffer)[read_pos];
break;
case sizeof(uint16_t):
*((uint16_t *)p_element) = ((uint16_t *)p_queue->p_buffer)[read_pos];
break;
case sizeof(uint32_t):
*((uint32_t *)p_element) = ((uint32_t *)p_queue->p_buffer)[read_pos];
break;
case sizeof(uint64_t):
*((uint64_t *)p_element) = ((uint64_t *)p_queue->p_buffer)[read_pos];
break;
default:
memcpy(p_element,
(void const *)((size_t)p_queue->p_buffer + read_pos * p_queue->element_size),
p_queue->element_size);
break;
}
}
else
{
status = NRF_ERROR_NOT_FOUND;
}
CRITICAL_REGION_EXIT();
NRF_LOG_INST_DEBUG(p_queue->p_log, "%s element 0x%08X, status:%d",
just_peek ? "peeked" : "popped", p_element, status);
return status;
}
The data length is fixed,it will still copy element-size bytes to buffer even if no so much data.
For communication packet, the length is not fixed,maybe different type with different length.
Same is nrf_ble_gq,the data written to characteristic should be variational:
nrf_ble_gq_req_t write_req;
memset(&write_req, 0, sizeof(nrf_ble_gq_req_t));
write_req.type = NRF_BLE_GQ_REQ_GATTC_WRITE;
write_req.error_handler.cb = gatt_error_handler;
write_req.error_handler.p_ctx = p_ble_tgoi_c;
write_req.params.gattc_write.handle = p_ble_tgoi_c->peer_tgoi_db.SIMO_handle;
write_req.params.gattc_write.len = dataCount;
write_req.params.gattc_write.p_value = (uint8_t*)p_data;
write_req.params.gattc_write.offset = 0;
write_req.params.gattc_write.write_op = BLE_GATT_OP_WRITE_CMD;
return nrf_ble_gq_item_add(p_ble_tgoi_c->p_gatt_queue, &write_req, p_ble_tgoi_c->conn_handle);
It push & pop with fixed length data?
If I want to add a function to push with byte count, there is a simple way(except modify nrf_queue.c directly)?
ret_code_t nrf_queue_push_bytes(nrf_queue_t const * p_queue, void const * p_element,uint16_t byte_count)
{
ret_code_t status = NRF_SUCCESS;
ASSERT(p_queue != NULL);
ASSERT(p_element != NULL);
CRITICAL_REGION_ENTER();
bool is_full = nrf_queue_is_full(p_queue);
if (!is_full || (p_queue->mode == NRF_QUEUE_MODE_OVERFLOW))
{
// Get write position.
size_t write_pos = p_queue->p_cb->back;
p_queue->p_cb->back = nrf_queue_next_idx(p_queue, p_queue->p_cb->back);
if (is_full)
{
// Overwrite the oldest element.
NRF_LOG_INST_WARNING(p_queue->p_log, "Queue full. Overwriting oldest element.");
p_queue->p_cb->front = nrf_queue_next_idx(p_queue, p_queue->p_cb->front);
}
// Write a new element.
/*switch (p_queue->element_size)
{
case sizeof(uint8_t):
((uint8_t *)p_queue->p_buffer)[write_pos] = *((uint8_t *)p_element);
break;
case sizeof(uint16_t):
((uint16_t *)p_queue->p_buffer)[write_pos] = *((uint16_t *)p_element);
break;
case sizeof(uint32_t):
((uint32_t *)p_queue->p_buffer)[write_pos] = *((uint32_t *)p_element);
break;
case sizeof(uint64_t):
((uint64_t *)p_queue->p_buffer)[write_pos] = *((uint64_t *)p_element);
break;
default:*/
memcpy((void *)((size_t)p_queue->p_buffer + write_pos * p_queue->element_size),
p_element,
byte_count/*p_queue->element_size*/);
/*break;
}*/
// Update utilization.
size_t utilization = queue_utilization_get(p_queue);
if (p_queue->p_cb->max_utilization < utilization)
{
p_queue->p_cb->max_utilization = utilization;
}
}
else
{
status = NRF_ERROR_NO_MEM;
}
CRITICAL_REGION_EXIT();
NRF_LOG_INST_DEBUG(p_queue->p_log, "pushed element 0x%08X, status:%d", p_element, status);
return status;
}