296 lines
7.5 KiB
C
296 lines
7.5 KiB
C
|
|
/**
|
|
******************************************************************************
|
|
* @file app_x-cube-ai.c
|
|
* @author X-CUBE-AI C code generator
|
|
* @brief AI program body
|
|
******************************************************************************
|
|
* @attention
|
|
*
|
|
* Copyright (c) 2025 STMicroelectronics.
|
|
* All rights reserved.
|
|
*
|
|
* This software is licensed under terms that can be found in the LICENSE file
|
|
* in the root directory of this software component.
|
|
* If no LICENSE file comes with this software, it is provided AS-IS.
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* Includes ------------------------------------------------------------------*/
|
|
|
|
#if defined ( __ICCARM__ )
|
|
#elif defined ( __CC_ARM ) || ( __GNUC__ )
|
|
#endif
|
|
|
|
/* System headers */
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <inttypes.h>
|
|
#include <string.h>
|
|
|
|
#include "app_x-cube-ai.h"
|
|
#include "bsp_ai.h"
|
|
#include "aiSystemPerformance.h"
|
|
#include "ai_datatypes_defines.h"
|
|
|
|
/* USER CODE BEGIN includes */
|
|
/* USER CODE END includes */
|
|
|
|
/* IO buffers ----------------------------------------------------------------*/
|
|
|
|
DEF_DATA_IN
|
|
|
|
DEF_DATA_OUT
|
|
/* Activations buffers -------------------------------------------------------*/
|
|
|
|
AI_ALIGNED(32)
|
|
static uint8_t pool0[AI_MODEL_DATA_ACTIVATION_1_SIZE];
|
|
|
|
ai_handle data_activations0[] = {pool0};
|
|
|
|
/* Entry points --------------------------------------------------------------*/
|
|
|
|
void MX_X_CUBE_AI_Init(void)
|
|
{
|
|
MX_UARTx_Init();
|
|
aiSystemPerformanceInit();
|
|
/* USER CODE BEGIN 5 */
|
|
/* USER CODE END 5 */
|
|
}
|
|
|
|
void MX_X_CUBE_AI_Process(void)
|
|
{
|
|
aiSystemPerformanceProcess();
|
|
HAL_Delay(1000); /* delay 1s */
|
|
/* USER CODE BEGIN 6 */
|
|
/* USER CODE END 6 */
|
|
}
|
|
/* Multiple network support --------------------------------------------------*/
|
|
|
|
#include <string.h>
|
|
#include "ai_datatypes_defines.h"
|
|
|
|
static const ai_network_entry_t networks[AI_MNETWORK_NUMBER] = {
|
|
{
|
|
.name = (const char *)AI_MODEL_MODEL_NAME,
|
|
.config = AI_MODEL_DATA_CONFIG,
|
|
.ai_get_report = ai_model_get_report,
|
|
.ai_create = ai_model_create,
|
|
.ai_destroy = ai_model_destroy,
|
|
.ai_get_error = ai_model_get_error,
|
|
.ai_init = ai_model_init,
|
|
.ai_run = ai_model_run,
|
|
.ai_forward = ai_model_forward,
|
|
.ai_data_params_get = ai_model_data_params_get,
|
|
.activations = data_activations0
|
|
},
|
|
};
|
|
|
|
struct network_instance {
|
|
const ai_network_entry_t *entry;
|
|
ai_handle handle;
|
|
ai_network_params params;
|
|
};
|
|
|
|
/* Number of instance is aligned on the number of network */
|
|
AI_STATIC struct network_instance gnetworks[AI_MNETWORK_NUMBER] = {0};
|
|
|
|
AI_DECLARE_STATIC
|
|
ai_bool ai_mnetwork_is_valid(const char* name,
|
|
const ai_network_entry_t *entry)
|
|
{
|
|
if (name && (strlen(entry->name) == strlen(name)) &&
|
|
(strncmp(entry->name, name, strlen(entry->name)) == 0))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
AI_DECLARE_STATIC
|
|
struct network_instance *ai_mnetwork_handle(struct network_instance *inst)
|
|
{
|
|
for (int i=0; i<AI_MNETWORK_NUMBER; i++) {
|
|
if ((inst) && (&gnetworks[i] == inst))
|
|
return inst;
|
|
else if ((!inst) && (gnetworks[i].entry == NULL))
|
|
return &gnetworks[i];
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
AI_DECLARE_STATIC
|
|
void ai_mnetwork_release_handle(struct network_instance *inst)
|
|
{
|
|
for (int i=0; i<AI_MNETWORK_NUMBER; i++) {
|
|
if ((inst) && (&gnetworks[i] == inst)) {
|
|
gnetworks[i].entry = NULL;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
AI_API_ENTRY
|
|
const char* ai_mnetwork_find(const char *name, ai_int idx)
|
|
{
|
|
const ai_network_entry_t *entry;
|
|
|
|
for (int i=0; i<AI_MNETWORK_NUMBER; i++) {
|
|
entry = &networks[i];
|
|
if (ai_mnetwork_is_valid(name, entry))
|
|
return entry->name;
|
|
else {
|
|
if (!idx--)
|
|
return entry->name;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
AI_API_ENTRY
|
|
ai_error ai_mnetwork_create(const char *name, ai_handle* network,
|
|
const ai_buffer* network_config)
|
|
{
|
|
const ai_network_entry_t *entry;
|
|
const ai_network_entry_t *found = NULL;
|
|
ai_error err;
|
|
struct network_instance *inst = ai_mnetwork_handle(NULL);
|
|
|
|
if (!inst) {
|
|
err.type = AI_ERROR_ALLOCATION_FAILED;
|
|
err.code = AI_ERROR_CODE_NETWORK;
|
|
return err;
|
|
}
|
|
|
|
for (int i=0; i<AI_MNETWORK_NUMBER; i++) {
|
|
entry = &networks[i];
|
|
if (ai_mnetwork_is_valid(name, entry)) {
|
|
found = entry;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!found) {
|
|
err.type = AI_ERROR_INVALID_PARAM;
|
|
err.code = AI_ERROR_CODE_NETWORK;
|
|
return err;
|
|
}
|
|
|
|
if (network_config == NULL)
|
|
err = found->ai_create(network, found->config);
|
|
else
|
|
err = found->ai_create(network, network_config);
|
|
if ((err.code == AI_ERROR_CODE_NONE) && (err.type == AI_ERROR_NONE)) {
|
|
inst->entry = found;
|
|
inst->handle = *network;
|
|
*network = (ai_handle*)inst;
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
AI_API_ENTRY
|
|
ai_handle ai_mnetwork_destroy(ai_handle network)
|
|
{
|
|
struct network_instance *inn;
|
|
inn = ai_mnetwork_handle((struct network_instance *)network);
|
|
if (inn) {
|
|
ai_handle hdl = inn->entry->ai_destroy(inn->handle);
|
|
if (hdl != inn->handle) {
|
|
ai_mnetwork_release_handle(inn);
|
|
network = AI_HANDLE_NULL;
|
|
}
|
|
}
|
|
return network;
|
|
}
|
|
|
|
AI_API_ENTRY
|
|
ai_bool ai_mnetwork_get_report(ai_handle network, ai_network_report* report)
|
|
{
|
|
struct network_instance *inn;
|
|
inn = ai_mnetwork_handle((struct network_instance *)network);
|
|
if (inn)
|
|
return inn->entry->ai_get_report(inn->handle, report);
|
|
else
|
|
return false;
|
|
}
|
|
|
|
AI_API_ENTRY
|
|
ai_error ai_mnetwork_get_error(ai_handle network)
|
|
{
|
|
struct network_instance *inn;
|
|
ai_error err;
|
|
err.type = AI_ERROR_INVALID_PARAM;
|
|
err.code = AI_ERROR_CODE_NETWORK;
|
|
|
|
inn = ai_mnetwork_handle((struct network_instance *)network);
|
|
if (inn)
|
|
return inn->entry->ai_get_error(inn->handle);
|
|
else
|
|
return err;
|
|
}
|
|
|
|
AI_API_ENTRY
|
|
ai_bool ai_mnetwork_init(ai_handle network)
|
|
{
|
|
struct network_instance *inn;
|
|
ai_network_params par;
|
|
|
|
inn = ai_mnetwork_handle((struct network_instance *)network);
|
|
if (inn) {
|
|
inn->entry->ai_data_params_get(&par);
|
|
for (int idx=0; idx < par.map_activations.size; idx++)
|
|
AI_BUFFER_ARRAY_ITEM_SET_ADDRESS(&par.map_activations, idx, inn->entry->activations[idx]);
|
|
return inn->entry->ai_init(inn->handle, &par);
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
AI_API_ENTRY
|
|
ai_i32 ai_mnetwork_run(ai_handle network, const ai_buffer* input,
|
|
ai_buffer* output)
|
|
{
|
|
struct network_instance* inn;
|
|
inn = ai_mnetwork_handle((struct network_instance *)network);
|
|
if (inn)
|
|
return inn->entry->ai_run(inn->handle, input, output);
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
AI_API_ENTRY
|
|
ai_i32 ai_mnetwork_forward(ai_handle network, const ai_buffer* input)
|
|
{
|
|
struct network_instance *inn;
|
|
inn = ai_mnetwork_handle((struct network_instance *)network);
|
|
if (inn)
|
|
return inn->entry->ai_forward(inn->handle, input);
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
AI_API_ENTRY
|
|
int ai_mnetwork_get_private_handle(ai_handle network,
|
|
ai_handle *phandle,
|
|
ai_network_params *pparams)
|
|
{
|
|
struct network_instance* inn;
|
|
inn = ai_mnetwork_handle((struct network_instance *)network);
|
|
if (inn && phandle && pparams) {
|
|
*phandle = inn->handle;
|
|
*pparams = inn->params;
|
|
return 0;
|
|
}
|
|
else
|
|
return -1;
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|