nuttx ai driver update

Signed-off-by: jihandong <jihandong@xiaomi.com>
This commit is contained in:
jihandong
2024-08-07 11:53:08 +08:00
committed by archer
parent 6aeb2e2996
commit d802912cba
2 changed files with 50 additions and 130 deletions
+38 -104
View File
@@ -35,23 +35,12 @@
* Private Type Definitions * Private Type Definitions
****************************************************************************/ ****************************************************************************/
enum aie_state_e
{
AIE_STATE_NOP = 0,
AIE_STATE_INITED,
AIE_STATE_FEEDED,
AIE_STATE_INFERENCED,
};
/* This structure describes the state of the upper half driver */ /* This structure describes the state of the upper half driver */
struct aie_upperhalf_s struct aie_upperhalf_s
{ {
FAR struct aie_lowerhalf_s *lower; /* The handle of lower half driver */ FAR struct aie_lowerhalf_s *lower; /* The handle of lower half driver */
volatile enum aie_state_e state; /* The device state */
mutex_t lock; /* Mutual exclusion */ mutex_t lock; /* Mutual exclusion */
uint8_t crefs; /* The number of times the engine
* has been opend. */
}; };
/**************************************************************************** /****************************************************************************
@@ -87,52 +76,37 @@ static const struct file_operations g_aie_ops =
* Name: aie_open * Name: aie_open
* *
* Description: * Description:
* A open method to increase the crefs. * A open method to open the ai engine.
* *
****************************************************************************/ ****************************************************************************/
static int aie_open(FAR struct file *filep) static int aie_open(FAR struct file *filep)
{ {
FAR struct inode *inode = filep->f_inode; FAR struct inode *inode = filep->f_inode;
FAR struct aie_upperhalf_s *upper = inode->i_private; FAR struct aie_upperhalf_s *upper = inode->i_private;
int ret; FAR struct aie_lowerhalf_s *lower;
DEBUGASSERT(upper != NULL); DEBUGASSERT(upper != NULL);
ret = nxmutex_lock(&upper->lock); lower = upper->lower;
if (ret < 0) DEBUGASSERT(lower != NULL);
{
return ret;
}
if (upper->crefs == 0) return OK;
{
upper->crefs++;
ret = OK;
}
else
{
ret = -EBUSY;
}
nxmutex_unlock(&upper->lock);
return ret;
} }
/**************************************************************************** /****************************************************************************
* Name: aie_close * Name: aie_close
* *
* Description: * Description:
* A close method to decrease the crefs. * A close method to close the ai engine.
* *
****************************************************************************/ ****************************************************************************/
static int aie_close(FAR struct file *filep) static int aie_close(FAR struct file *filep)
{ {
FAR struct inode *inode = filep->f_inode; FAR struct inode *inode = filep->f_inode;
FAR struct aie_upperhalf_s *upper = inode->i_private; FAR struct aie_upperhalf_s *upper = inode->i_private;
FAR struct aie_lowerhalf_s *lower = NULL; FAR struct aie_lowerhalf_s *lower;
int ret; int ret;
DEBUGASSERT(upper != NULL); DEBUGASSERT(upper != NULL);
lower = upper->lower; lower = upper->lower;
@@ -144,23 +118,15 @@ static int aie_close(FAR struct file *filep)
return ret; return ret;
} }
if (upper->crefs == 1) ret = (int)(intptr_t)filep->f_priv;
if (ret > 0)
{ {
ret = lower->ops->deinit(lower, filep); lower->ops->deinit(lower, ret);
if (ret == OK)
{
upper->state = AIE_STATE_NOP;
upper->crefs--;
}
}
else
{
ret = OK;
} }
nxmutex_unlock(&upper->lock); nxmutex_unlock(&upper->lock);
return ret; return OK;
} }
/**************************************************************************** /****************************************************************************
@@ -174,10 +140,10 @@ static int aie_close(FAR struct file *filep)
static int aie_ioctl(FAR struct file *filep, int cmd, unsigned long arg) static int aie_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
{ {
FAR struct inode *inode = filep->f_inode; FAR struct inode *inode = filep->f_inode;
FAR struct aie_upperhalf_s *upper = inode->i_private; FAR struct aie_upperhalf_s *upper = inode->i_private;
FAR struct aie_lowerhalf_s *lower = NULL; FAR struct aie_lowerhalf_s *lower = NULL;
int ret; int ret;
DEBUGASSERT(upper != NULL); DEBUGASSERT(upper != NULL);
lower = upper->lower; lower = upper->lower;
@@ -193,66 +159,38 @@ static int aie_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
switch (cmd) switch (cmd)
{ {
case AIE_CMD_INIT: case AIE_CMD_LOAD:
ret = lower->ops->init(lower, filep, arg); ret = (int)(intptr_t)filep->f_priv;
if (ret != OK) if (ret > 0)
{ {
break; ret = -EINVAL; /* Double load is not allowed */
} }
else
if (lower->workspace_len)
{ {
lower->workspace = kmm_malloc(lower->workspace_len); ret = lower->ops->init(lower, arg /* model */);
if (!lower->workspace) if (ret > 0)
{ {
ret = -ENOMEM; filep->f_priv = (void *)(intptr_t)ret;
break; ret = OK;
} }
} }
upper->state = AIE_STATE_INITED;
break; break;
case AIE_CMD_FEED_INPUT: case AIE_CMD_FEED_INPUT:
if (upper->state == AIE_STATE_INITED || ret = lower->ops->feed_input(lower, (int)(intptr_t)filep->f_priv,
upper->state == AIE_STATE_INFERENCED) arg /* input */);
{
lower->input = (uintptr_t)arg;
ret = lower->ops->feed_input(lower, filep);
if (ret == OK)
{
upper->state = AIE_STATE_FEEDED;
}
}
else
{
ret = -EPERM;
}
break; break;
case AIE_CMD_GET_OUTPUT: case AIE_CMD_GET_OUTPUT:
if (upper->state == AIE_STATE_FEEDED) ret = lower->ops->get_output(lower, (int)(intptr_t)filep->f_priv,
{ arg /* output */);
lower->output = (uintptr_t)arg;
ret = lower->ops->get_output(lower, filep);
if (ret == OK)
{
upper->state = AIE_STATE_INFERENCED;
}
}
else
{
ret = -EPERM;
}
break; break;
default: default:
/* Lowerhalf driver process other cmd. */
if (lower->ops->control) if (lower->ops->control)
{ {
ret = lower->ops->control(lower, filep, cmd, arg); ret = lower->ops->control(lower, (int)(intptr_t)filep->f_priv,
cmd, arg);
} }
else else
{ {
@@ -281,8 +219,8 @@ static int aie_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
int aie_register(FAR const char *path, int aie_register(FAR const char *path,
FAR struct aie_lowerhalf_s *lower) FAR struct aie_lowerhalf_s *lower)
{ {
FAR struct aie_upperhalf_s *upper = NULL; FAR struct aie_upperhalf_s *upper = NULL;
int ret = -ENOMEM; int ret = -ENOMEM;
DEBUGASSERT(path); DEBUGASSERT(path);
@@ -298,11 +236,7 @@ int aie_register(FAR const char *path,
/* Initialize the aie device structure */ /* Initialize the aie device structure */
upper->lower = lower; upper->lower = lower;
upper->state = AIE_STATE_NOP;
upper->crefs = 0;
lower->priv = upper;
nxmutex_init(&upper->lock); nxmutex_init(&upper->lock);
/* Register the aie device */ /* Register the aie device */
+12 -26
View File
@@ -39,7 +39,7 @@
enum aie_cmd_e enum aie_cmd_e
{ {
AIE_CMD_INIT = 0, AIE_CMD_LOAD = 0,
AIE_CMD_FEED_INPUT, AIE_CMD_FEED_INPUT,
AIE_CMD_GET_OUTPUT AIE_CMD_GET_OUTPUT
}; };
@@ -51,25 +51,17 @@ enum aie_cmd_e
struct aie_lowerhalf_s; struct aie_lowerhalf_s;
struct aie_ops_s struct aie_ops_s
{ {
/* Common routes */ CODE int (*init)(FAR struct aie_lowerhalf_s *lower, uintptr_t model);
CODE int (*init)(FAR struct aie_lowerhalf_s *lower, CODE int (*deinit)(FAR struct aie_lowerhalf_s *lower, int id);
FAR struct file *filep,
uintptr_t bin_model);
CODE int (*feed_input)(FAR struct aie_lowerhalf_s *lower, CODE int (*feed_input)(FAR struct aie_lowerhalf_s *lower, int id,
FAR struct file *filep); uintptr_t input);
CODE int (*get_output)(FAR struct aie_lowerhalf_s *lower, CODE int (*get_output)(FAR struct aie_lowerhalf_s *lower, int id,
FAR struct file *filep); uintptr_t output);
CODE int (*deinit)(FAR struct aie_lowerhalf_s *lower, CODE int (*control)(FAR struct aie_lowerhalf_s *lower, int id,
FAR struct file *filep);
/* Custom route */
CODE int (*control)(FAR struct aie_lowerhalf_s *lower,
FAR struct file *filep,
int cmd, unsigned long arg); int cmd, unsigned long arg);
}; };
@@ -81,17 +73,11 @@ struct aie_ops_s
struct aie_lowerhalf_s struct aie_lowerhalf_s
{ {
/* The private opaque pointer to be passed to upper-layer */ /* The heading fields of this struct must be as follow. */
FAR void *priv; FAR const struct aie_ops_s *ops;
FAR const struct aie_ops_s *ops; /* Lower half operations */
const void *bin_model; /* The model address */ /* The custom AI Engine may include additional fields after here. */
const void *input; /* The input buffer */
void *output; /* The output buffer */
void *workspace; /* Workspace free to use */
size_t workspace_len; /* Length of workspace.
* >0: need the workspace
* 0: no need */
}; };
/**************************************************************************** /****************************************************************************