KL520_SDK_2.2/mdw/inference/kmdw_fifoq_manager.c
2025-12-17 15:55:25 +08:00

274 lines
7.9 KiB
C

/*
* Kneron Application general functions
*
* Copyright (C) 2022 Kneron, Inc. All rights reserved.
*
*/
// #define DEBUG_PRINT
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "kmdw_ipc.h"
#include "kmdw_memory.h"
#include "kmdw_model.h"
#include "kmdw_console.h"
#include "membase.h"
#include "kp_struct.h"
#include "kmdw_fifoq_manager.h"
#ifdef DEBUG_PRINT
#include "kmdw_console.h"
#define dbg_print(__format__, ...) kmdw_level_printf(LOG_CUSTOM, "[buf_mgr]"__format__, ##__VA_ARGS__)
#else
#define dbg_print(__format__, ...)
#endif
#define INF_TIMEOUT 2000 // twice
static dual_fifo2_t _image_fifioq = 0;
static dual_fifo2_t _result_fifoq = 0;
static osMessageQueueId_t _temp_image_queue;
static bool _fifoq_mem_allocated = false;
static uint32_t _fifoq_input_buf_count = 0;
static uint32_t _fifoq_input_buf_size = 0;
static uint32_t _fifoq_result_buf_count = 0;
static uint32_t _fifoq_result_buf_size = 0;
typedef struct
{
int total_num_buffer;
uint32_t buffer_addr;
int length;
int buffer_index;
} special_buffer_object_t;
void kdp2_fifoq_manager_enqueue_image_thread(void *arg)
{
special_buffer_object_t received_bobj;
buffer_object_t stored_bobj;
int num_received_img = 0;
memset(&stored_bobj, 0, sizeof(buffer_object_t));
while (true) {
osStatus_t sts = osMessageQueueGet(_temp_image_queue, (void *)&received_bobj, NULL, osWaitForever);
if (osOK != sts) {
continue;
}
stored_bobj.num_of_buffer = received_bobj.total_num_buffer;
if (NULL != stored_bobj.buffer_addr[received_bobj.buffer_index]) {
kmdw_fifoq_manager_image_put_free_buffer(stored_bobj.buffer_addr[received_bobj.buffer_index],
stored_bobj.length[received_bobj.buffer_index], osWaitForever);
} else {
num_received_img++;
}
stored_bobj.buffer_addr[received_bobj.buffer_index] = received_bobj.buffer_addr;
stored_bobj.length[received_bobj.buffer_index] = received_bobj.length;
if (num_received_img == stored_bobj.num_of_buffer) {
dual_fifo2_enqueue_data(_image_fifioq, stored_bobj, osWaitForever, false);
num_received_img = 0;
memset(&stored_bobj, 0, sizeof(buffer_object_t));
}
}
}
int kmdw_fifoq_manager_init(uint32_t image_count, uint32_t result_count)
{
kmdw_printf("creating image queue with size %d\n", image_count);
kmdw_printf("creating result queue with size %d\n", result_count);
_image_fifioq = dual_fifo2_create(image_count);
if ((uint32_t)_image_fifioq < DUAL_FIFO_VALID_ADDR)
{
kmdw_printf("image queue creating failed !!\n");
return -1;
}
_result_fifoq = dual_fifo2_create(result_count);
if ((uint32_t)_result_fifoq < DUAL_FIFO_VALID_ADDR)
{
kmdw_printf("result queue creating failed !!\n");
return -1;
}
//the size of message queue is MAX at image count as one multiple-input
_temp_image_queue = osMessageQueueNew(image_count, sizeof(special_buffer_object_t), NULL);
return 0;
}
osStatus_t kmdw_fifoq_manager_image_enqueue(uint32_t total_num_buf, uint32_t index, uint32_t buf_addr, int buf_size, uint32_t timeout, bool preempt)
{
if (0 == total_num_buf) {
return osErrorParameter;
}
special_buffer_object_t special_obj;
special_obj.total_num_buffer = total_num_buf;
special_obj.buffer_index = (1 == special_obj.total_num_buffer) ? 0 : index;
special_obj.buffer_addr = buf_addr;
special_obj.length = buf_size;
return osMessageQueuePut(_temp_image_queue, (const void *)&special_obj, (preempt) ? (1U) : (0U), timeout);
}
osStatus_t kmdw_fifoq_manager_image_dequeue(buffer_object_t *bobj, uint32_t timeout)
{
return dual_fifo2_dequeue_data(_image_fifioq, bobj, timeout);
}
osStatus_t kmdw_fifoq_manager_image_get_free_buffer(uint32_t *buf_addr, int *buf_size, uint32_t timeout, bool force_grab)
{
buffer_object_t bobj;
osStatus_t sts = dual_fifo2_get_free_buffer(_image_fifioq, &bobj, timeout, force_grab);
if (osOK != sts) {
return sts;
}
//TODO: so far, just handle num_of_buffer > 1 in the future
if (1 < bobj.num_of_buffer) {
for (int i = 1; i < bobj.num_of_buffer; i++) {
kmdw_fifoq_manager_image_put_free_buffer(bobj.buffer_addr[i], bobj.length[i], timeout);
//TODO: need to handle return value
}
}
*buf_addr = bobj.buffer_addr[0];
*buf_size = bobj.length[0];
return sts;
}
osStatus_t kmdw_fifoq_manager_image_put_free_buffer(uint32_t buf_addr, int buf_size, uint32_t timeout)
{
buffer_object_t bobj;
bobj.num_of_buffer = 1;
bobj.buffer_addr[0] = buf_addr;
bobj.length[0] = buf_size;
return dual_fifo2_put_free_buffer(_image_fifioq, bobj, timeout);
}
osStatus_t kmdw_fifoq_manager_result_enqueue(void *result_buf, int result_buf_size, bool preempt)
{
buffer_object_t bobj;
bobj.num_of_buffer = 1;
bobj.buffer_addr[0] = (uint32_t)result_buf;
bobj.length[0] = result_buf_size;
return dual_fifo2_enqueue_data(_result_fifoq, bobj, 0, preempt);
}
osStatus_t kmdw_fifoq_manager_result_dequeue(uint32_t *buf_addr, int *buf_size, uint32_t timeout)
{
buffer_object_t bobj;
osStatus_t sts = dual_fifo2_dequeue_data(_result_fifoq, &bobj, timeout);
if (osOK != sts) {
return sts;
}
//TODO: so far, just handle num_of_buffer > 1 in the future
if (1 < bobj.num_of_buffer) {
for (int i = 1; i < bobj.num_of_buffer; i++) {
kmdw_fifoq_manager_result_put_free_buffer(bobj.buffer_addr[i], bobj.length[i], timeout);
//TODO: need to handle return value
}
}
*buf_addr = bobj.buffer_addr[0];
*buf_size = bobj.length[0];
return sts;
}
void *kmdw_fifoq_manager_result_get_free_buffer(int *buf_size)
{
buffer_object_t bobj;
osStatus_t sts = dual_fifo2_get_free_buffer(_result_fifoq, &bobj, osWaitForever, false);
if (osOK != sts) {
return NULL;
}
//TODO: so far, just handle num_of_buffer > 1 in the future
if (1 < bobj.num_of_buffer) {
for (int i = 1; i < bobj.num_of_buffer; i++) {
kmdw_fifoq_manager_result_put_free_buffer(bobj.buffer_addr[i], bobj.length[i], 0);
//TODO: need to handle return value
}
}
*buf_size = bobj.length[0];
return (void *)bobj.buffer_addr[0];
}
osStatus_t kmdw_fifoq_manager_result_put_free_buffer(uint32_t buf_addr, int buf_size, uint32_t timeout)
{
buffer_object_t bobj;
bobj.num_of_buffer = 1;
bobj.buffer_addr[0] = buf_addr;
bobj.length[0] = buf_size;
return dual_fifo2_put_free_buffer(_result_fifoq, bobj, timeout);
}
void kmdw_fifoq_manager_clean_queues(void)
{
buffer_object_t bobj;
while (1)
{
if (dual_fifo2_dequeue_data(_image_fifioq, &bobj, 0) == osOK)
dual_fifo2_put_free_buffer(_image_fifioq, bobj, 0);
else
break;
}
while (1)
{
if (dual_fifo2_dequeue_data(_result_fifoq, &bobj, 0) == osOK)
dual_fifo2_put_free_buffer(_result_fifoq, bobj, 0);
else
break;
}
}
void kmdw_fifoq_manager_store_fifoq_config(uint32_t input_buf_count, uint32_t input_buf_size, uint32_t result_buf_count, uint32_t result_buf_size)
{
_fifoq_mem_allocated = true;
_fifoq_input_buf_count = input_buf_count;
_fifoq_input_buf_size = input_buf_size;
_fifoq_result_buf_count = result_buf_count;
_fifoq_result_buf_size = result_buf_size;
}
bool kmdw_fifoq_manager_get_fifoq_allocated()
{
return _fifoq_mem_allocated;
}
void kmdw_fifoq_manager_get_fifoq_config(uint32_t *input_buf_count, uint32_t *input_buf_size, uint32_t *result_buf_count, uint32_t *result_buf_size)
{
*input_buf_count = _fifoq_input_buf_count;
*input_buf_size = _fifoq_input_buf_size;
*result_buf_count = _fifoq_result_buf_count;
*result_buf_size = _fifoq_result_buf_size;
}