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; }