프로그래밍 초보 탈출

Libraries/C언어 Library

[Data Structure] Queue Library - BLOCK Queue

째즈토끼 2022. 6. 21. 16:54

일단 사용법

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