我有一個隊列結構,我嘗試使用循環緩衝區來實現,我在網絡應用程序中使用它。我正在尋找一些指導和反饋。首先,讓我介紹一下相關的代碼。在C中使用指針的循環緩衝區
typedef struct nwk_packet_type
{
uint8_t dest_address[NRF24_ADDR_LEN];
uint8_t data[32];
uint8_t data_len;
}nwk_packet_t;
/* The circular fifo on which outgoing packets are stored */
nwk_packet_t nwk_send_queue[NWK_QUEUE_SIZE];
nwk_packet_t* send_queue_in; /* pointer to queue head */
nwk_packet_t* send_queue_out; /* pointer to queue tail */
static nwk_packet_t* nwk_tx_pkt_allocate(void)
{
/* Make sure the send queue is not full */
if(send_queue_in == (send_queue_out - 1 + NWK_QUEUE_SIZE) % NWK_QUEUE_SIZE)
return 0;
/* return pointer to the next add and increment the tracker */
return send_queue_in++;//TODO: it's not just ++, it has to be modular by packet size
}
/* External facing function for application layer to send network data */
// simply adds the packet to the network queue if there is space
// returns an appropriate error code if anything goes wrong
uint8_t nwk_send(uint8_t* address, uint8_t* data, uint8_t len)
{
/* First check all the parameters */
if(!address)
return NWK_BAD_ADDRESS;
if(!data)
return NWK_BAD_DATA_PTR;
if(!len || len > 32)
return NWK_BAD_DATA_LEN;
//TODO: PROBABLY NEED TO START BLOCKING HERE
/* Allocate the packet on the queue */
nwk_packet_t* packet;
if(!(packet = nwk_tx_pkt_allocate()))
return NWK_QUEUE_FULL;
/* Build the packet */
memcpy(packet->dest_address, address, NRF24_ADDR_LEN);
memcpy(packet->data, data, len);
packet->data_len = len;
//TODO: PROBABLY SAFE TO STOP BLOCKING HERE
return NWK_SUCCESS;
}
/* Only called during NWK_IDLE, pushes the next item on the send queue out to the chip's "MAC" layer over SPI */
void nwk_transmit_pkt(void)
{
nwk_packet_t tx_pkt = nwk_send_queue[send_queue_out];
nrf24_send(tx_pkt->data, tx_pkt->data_len);
}
/* The callback for transceiver interrupt when a sent packet is either completed or ran out of retries */
void nwk_tx_result_cb(bool completed)
{
if((completed) && (nwk_tx_state == NWK_SENDING))
send_queue_out++;//TODO: it's not just ++, it has to be modular by packet size with in the buffer
}
好吧,現在快速解釋,然後我的問題。所以基本的想法是,我已經有了這個正在發送到網絡上的數據隊列。功能nwk_send()
可以在應用程序代碼中的任何地方被調用,該應用程序代碼中的牆將是一個小型先發制人的基於任務的操作系統(FreeRTOS),因此可以從代碼中的很多地方發生,並被OS tick中斷中斷。
現在,因爲該函數正在修改指向全局隊列的指針,所以我知道它在做這件事時需要阻塞。我在關於我應該阻止的代碼的註釋中正確(即禁用中斷)嗎?使用全局布爾變量或其他東西來創建互斥鎖會更聰明,而不僅僅是禁用中斷?
另外,我認爲當事情從隊列中排除時,我應該阻擋第二個位置,但我不確定它到底在哪。它在nwk_transmit_pkt()
哪裏我實際上是從隊列中複製數據並將其轉換爲本地ram變量?
最後的問題,我如何實現數組中指針的模數運算?我覺得它應該是這樣的:
send_queue_in = ((send_queue_in + 1) % (NWK_QUEUE_SIZE*sizeof(nwk_packet_t))) + nwk_send_queue;
任何反饋非常感謝,謝謝。
這個問題更適合在[CodeReview](http://www.codereview.stackexchange.com) – tay10r
我認爲你可能需要一個互斥量而不是依靠禁止中斷。是否有多個線程或進程可以調用send函數? – Will
@TaylorFlores啊,有趣。我看到該網站只處於測試階段。也許你是對的,我會研究這個。 – NickHalden