/* * Kneron Application general functions * * Copyright (C) 2022 Kneron, Inc. All rights reserved. * */ // #define DEBUG_PRINT #include #include #include #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; }