일단 사용법
static queue_block_t g_tx_queue;
static queue_block_t g_rx_queue;
static can_packet_t g_tx_queue_buffer[CONFIG_CAN_TX_QUEUE_SIZE];
static can_packet_t g_rx_queue_buffer[CONFIG_CAN_RX_QUEUE_SIZE];
#define TXQ (&g_tx_queue)
#define RXQ (&g_rx_queue)
//....
init()
{
queue_block_initialize(TXQ, CONFIG_CAN_TX_QUEUE_SIZE, sizeof(can_packet_t), g_tx_queue_buffer, can_critical_txrx);
queue_block_initialize(RXQ, CONFIG_CAN_RX_QUEUE_SIZE, sizeof(can_packet_t), g_rx_queue_buffer, can_critical_txrx);
}
//....
bool8_t can_write_raw(can_packet_t *pkt)
{
while (queue_block_is_full(TXQ)) CAN->IF1IFS = CAN_IF1IFS_STATUS;;
queue_block_push(TXQ, pkt);
CAN->IF1IFS = CAN_IF1IFS_STATUS;
return true;
}
/*
* lib_queue__common.h
*
* Created on: 2022. 3. 18.
* Author: jazz1
*/
#ifndef CUST_LIB_LIB_QUEUE__COMMON_H_
#define CUST_LIB_LIB_QUEUE__COMMON_H_
//=================================================================================================
//
//=================================================================================================
#include "lib_types.h"
typedef void (*queue_critical_section_func_t)(bool8_t enter_critical);
//=================================================================================================
//
//=================================================================================================
#endif /* CUST_LIB_LIB_QUEUE__COMMON_H_ */
/*
* lib_queue__block.h
*
* Created on: 2022. 3. 22.
* Author: jazz1
*/
#ifndef CUST_LIB_LIB_QUEUE__BLOCK_H_
#define CUST_LIB_LIB_QUEUE__BLOCK_H_
//=================================================================================================
//
//=================================================================================================
#include "lib_queue__common.h"
typedef struct
{
unsigned size;
volatile unsigned sp, ep;
volatile bool8_t full;
unsigned item_size;
void *buffer;
queue_critical_section_func_t critical_func;
} queue_block_t;
//=================================================================================================
//
//=================================================================================================
void queue_block_initialize(queue_block_t *queue, unsigned buffer_size, unsigned item_size, void *buffer, queue_critical_section_func_t func); // buffer_size = max item count
bool8_t queue_block_push(queue_block_t *queue, void *data);
bool8_t queue_block_pop(queue_block_t *queue, void *buffer);
bool8_t queue_block_peek(queue_block_t *queue, void **buffer);
bool8_t queue_block_drop(queue_block_t *queue);
unsigned queue_block_drops(queue_block_t *queue, unsigned Count);
unsigned queue_block_emptycount(queue_block_t *queue);
#define queue_block_data_count(queue) ((queue)->size - queue_block_empty_count(queue))
#define queue_block_is_empty(queue) (((queue)->sp == (queue)->ep) && !(queue)->full)
#define queue_block_is_full(queue) ((queue)->full)
#define queue_block_reset(queue) ((queue)->sp = (queue)->ep = 0, (queue)->full = false)
//=================================================================================================
//
//=================================================================================================
#endif /* CUST_LIB_LIB_QUEUE__BLOCK_H_ */
/*
* lib_queue__block.c
*
* Created on: 2022. 3. 22.
* Author: jazz1
*/
//=================================================================================================
//
//=================================================================================================
#include "lib_queue__block.h"
#include <string.h>
//=================================================================================================
//
//=================================================================================================
#define ________enter_critical(queue) do { if ((queue)->critical_func) (queue)->critical_func(true) ; } while (0)
#define ________leave_critical(queue) do { if ((queue)->critical_func) (queue)->critical_func(false); } while (0)
//=================================================================================================
//
//=================================================================================================
#define get_pt__sp(queue) (((uint8_t *)(queue->buffer)) + (queue->sp * queue->item_size))
#define get_pt__ep(queue) (((uint8_t *)(queue->buffer)) + (queue->ep * queue->item_size))
//=================================================================================================
//
//=================================================================================================
void queue_block_initialize(queue_block_t *queue, unsigned buffer_size, unsigned item_size, void *buffer, queue_critical_section_func_t func)
{
queue->sp = queue->ep = 0;
queue->size = buffer_size;
queue->full = false;
queue->item_size = item_size;
queue->buffer = buffer;
queue->critical_func = func;
}
unsigned queue_block_empty_count(queue_block_t *queue)
{
if (queue->full) return 0;
return ((queue->ep < queue->sp) ? (queue->sp - queue->ep) : (queue->size - queue->ep + queue->sp));
}
bool8_t queue_block_push(queue_block_t *queue, void *data)
{
if (queue->full) return false;
________enter_critical(queue);
memcpy(get_pt__ep(queue), data, queue->item_size);
if (++queue->ep == queue->size) queue->ep = 0;
queue->full = (queue->sp == queue->ep);
________leave_critical(queue);
return true;
}
bool8_t queue_block_pop(queue_block_t *queue, void *buffer)
{
if (queue_block_is_empty(queue)) return false;
________enter_critical(queue);
memcpy(buffer, get_pt__sp(queue), queue->item_size);
if (++queue->sp == queue->size) queue->sp = 0;
queue->full = false;
________leave_critical(queue);
return true;
}
bool8_t queue_block_peek(queue_block_t *queue, void **buffer)
{
if (queue->sp == queue->ep && !queue->full) return false;
*buffer = get_pt__sp(queue);
return true;
}
bool8_t queue_block_drop(queue_block_t *queue)
{
if (queue->sp == queue->ep && !queue->full) return false;
________enter_critical(queue);
queue->sp++;
if (queue->sp == queue->size) queue->sp = 0;
queue->full = false;
________leave_critical(queue);
return true;
}
unsigned queue_block_drops(queue_block_t *queue, unsigned count)
{
unsigned drop_count = queue_block_data_count(queue);
________enter_critical(queue);
if (drop_count > count) drop_count = count;
if (drop_count)
{
unsigned m = queue->size - queue->sp;
if (m > drop_count) m = drop_count;
queue->sp += m;
m = drop_count - m;
if (m) queue->sp = m;
if (queue->sp == queue->size) queue->sp = 0;
queue->full = false;
}
________leave_critical(queue);
return drop_count;
}
'Libraries > C언어 Library' 카테고리의 다른 글
[File] Disk Drive Library (0) | 2022.06.22 |
---|---|
[String] String Library - ToStr (0) | 2022.06.21 |
[Data Structure] Queue Library - BYTE Queue (0) | 2022.06.21 |
[Protocol] Modbus RTU Packet Library (0) | 2022.06.20 |