Nordic mem_pool

API使用说明

‘uint32_t hci_mem_pool_rx_produce(uint32_t length, void ** pp_buffer)’
申请内存块;length申请内存块的长度,void ** pp_buffer返回申请内存的地址;返回申请内存快递状态。
‘uint32_t hci_mem_pool_rx_data_size_set(uint32_t length)’
设置内存块中数据的长度;length设置的长度;返回操作状态
‘uint32_t hci_mem_pool_rx_extract(uint8_t * pp_buffer, uint32_t p_length)’
提取内存块中的数据;uint8_t ** pp_buffer提取内存块的地址,p_length提取数据的长度;返回操作状态。
‘uint32_t hci_mem_pool_rx_consume(uint8_t * p_buffer)’
释放内存块;p_buffer待释放内存块的地址;返回操作装态。

注意事项

API使用规则务必按照上述说明顺序,因为内存池的结构是数组型,释放时请务从头开始释放,并且不要多次释放同一块内存。同时注意开辟的内存块数必须是2的幂次。

数据结构

Nordic mem_pool_第1张图片
Block_Struct内存块的数据结构;buf存放数据的实体,len存放数据的长度。
area_struct 内存池管理数据结构,成员见图中说明。

代码说明

Nordic mem_pool_第2张图片
uint32_t hci_mem_pool_rx_produce(uint32_t length, void ** pp_buffer)
{
uint32_t err_code;

if (pp_buffer == NULL)
{
    return NRF_ERROR_NULL;
}    
*pp_buffer = NULL;   //防止未申请到时,用户操作出错

if (m_rx_buffer_queue.free_window_count != 0)
{    
    if (length <= RX_BUF_SIZE)
    {    
        --(m_rx_buffer_queue.free_window_count);            
        ++(m_rx_buffer_queue.read_available_count);            

        *pp_buffer                    = 
                m_rx_buffer_queue.p_buffer[m_rx_buffer_queue.write_index].rx_buffer;

        m_rx_buffer_queue.free_index |= (1u << m_rx_buffer_queue.write_index);

        m_rx_buffer_queue.write_index = 
                (m_rx_buffer_queue.write_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u);

        err_code                      = NRF_SUCCESS;
    }
    else
    {
        err_code = NRF_ERROR_DATA_SIZE;    
    }        
}
else
{
    err_code = NRF_ERROR_NO_MEM;    
}

return err_code;

}

Nordic mem_pool_第3张图片
uint32_t hci_mem_pool_rx_extract(uint8_t * pp_buffer, uint32_t p_length)
{
uint32_t err_code;

if ((pp_buffer == NULL) || (p_length == NULL))
{
    return NRF_ERROR_NULL;
}

if (m_rx_buffer_queue.read_available_count != 0)
{
    --(m_rx_buffer_queue.read_available_count);
    ++(m_rx_buffer_queue.free_available_count);        

    *pp_buffer                   = 
        m_rx_buffer_queue.p_buffer[m_rx_buffer_queue.read_index].rx_buffer;
    *p_length                    = 
        m_rx_buffer_queue.p_buffer[m_rx_buffer_queue.read_index].length;

    m_rx_buffer_queue.read_index = 
        (m_rx_buffer_queue.read_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u); 

    err_code                     = NRF_SUCCESS;
}
else
{
    err_code                     = NRF_ERROR_NO_MEM;        
}

return err_code;

}

uint32_t hci_mem_pool_rx_consume(uint8_t * p_buffer)
{
uint32_t err_code;
uint32_t consume_index;
uint32_t start_index;

if (m_rx_buffer_queue.free_available_count != 0)
{
    err_code      = NRF_ERROR_INVALID_ADDR;
    consume_index = (m_rx_buffer_queue.read_index - m_rx_buffer_queue.free_available_count) & 
                    (RX_BUF_QUEUE_SIZE - 1u);       //找到开始释放内存的首地址,因为是数组型,必须从头开始释放
    start_index   = consume_index;

    do
    {
        if (m_rx_buffer_queue.p_buffer[consume_index].rx_buffer == p_buffer) //如果是要释放的内存块
        {
            m_rx_buffer_queue.free_index ^= (1u << consume_index); //将释放的位置置0,表示该位置已经释放,注意释放一次后不要二次释放
                        err_code = NRF_SUCCESS;
            break;
        }
        else
        {
            //如果不是释放的内存块,调整位置,指向下个内存块,继续寻找
            consume_index = (consume_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u);
        }
    }
    while (consume_index != m_rx_buffer_queue.read_index); //判断是否已经到达数据已使用的位置

    while (!(m_rx_buffer_queue.free_index & (1 << start_index)) && (m_rx_buffer_queue.free_available_count != 0))//判断当前释放的内存块是否是待释放的起始内存块,并且待释放的内存块不为0
    {
        --(m_rx_buffer_queue.free_available_count);
        ++(m_rx_buffer_queue.free_window_count);            
        start_index = (consume_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u); //调节开始释放的位置(比如释放的顺序为3012)在释放3的时候,表面上释放成功了,其实内部的free_available_count free_window_count并没有变化,3这个区域还是不能使用的,当释放2的时候会把3一起释放掉,到这一步才是真正的释放
    }
}
else
{
    err_code = NRF_ERROR_NO_MEM;
}

return err_code;    

}
Nordic mem_pool_第4张图片

你可能感兴趣的:(库)