我有一个队列结构,我尝试使用循环缓冲区来实现它,我在网络应用程序中使用它。我正在寻找一些指导和反馈。首先,让我介绍一下相关代码。
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),因此可以从代码中的许多地方发生并被操作系统滴答中断中断。
现在,由于该函数正在修改指向全局队列的指针,我知道它在这样做时需要阻塞。我对我应该在哪里阻塞(即禁用中断)的代码的评论是否正确?使用全局布尔变量或其他东西而不是仅仅禁用中断来制作互斥锁也会更聪明吗?
另外,我认为当事情被从队列中删除时,我应该阻止第二个地方,但我不确定它到底在哪里。它是nwk_transmit_pkt()
在我实际将数据从队列中复制到本地 ram 变量中的地方吗?
最后一个问题,如何对数组中的指针进行取模运算?我觉得它应该看起来像:
send_queue_in = ((send_queue_in + 1) % (NWK_QUEUE_SIZE*sizeof(nwk_packet_t))) + nwk_send_queue;
非常感谢任何反馈,谢谢。