Commit 1bca5068 authored by carbon's avatar carbon

Add mailbox based inter-processor communication

parent 56595260
...@@ -270,6 +270,7 @@ CONFIG_ION_CARVEOUT_HEAP=y ...@@ -270,6 +270,7 @@ CONFIG_ION_CARVEOUT_HEAP=y
CONFIG_ION_CMA_HEAP=y CONFIG_ION_CMA_HEAP=y
# CONFIG_IOMMU_SUPPORT is not set # CONFIG_IOMMU_SUPPORT is not set
CONFIG_CV1835_SYSDMA_REMAP=y CONFIG_CV1835_SYSDMA_REMAP=y
CONFIG_CVI_MAILBOX=y
CONFIG_PWM=y CONFIG_PWM=y
CONFIG_SIFIVE_PLIC=y CONFIG_SIFIVE_PLIC=y
CONFIG_ANDROID=y CONFIG_ANDROID=y
......
...@@ -11,22 +11,9 @@ ...@@ -11,22 +11,9 @@
enum SYS_CMD_ID { enum SYS_CMD_ID {
SYS_CMD_INFO_TRANS = 0x50, CMD_TEST_A = 0x10,
SYS_CMD_INFO_LINUX_INIT_DONE, CMD_TEST_B,
SYS_CMD_INFO_RTOS_INIT_DONE, CMD_TEST_C,
SYS_CMD_INFO_STOP_ISR,
SYS_CMD_INFO_STOP_ISR_DONE,
SYS_CMD_INFO_LINUX,
SYS_CMD_INFO_RTOS,
SYS_CMD_SYNC_TIME,
SYS_CMD_INFO_DUMP_MSG,
SYS_CMD_INFO_DUMP_EN,
SYS_CMD_INFO_DUMP_DIS,
SYS_CMD_INFO_DUMP_JPG,
SYS_CMD_INFO_TRACE_SNAPSHOT_START,
SYS_CMD_INFO_TRACE_SNAPSHOT_STOP,
SYS_CMD_INFO_TRACE_STREAM_START,
SYS_CMD_INFO_TRACE_STREAM_STOP,
SYS_CMD_INFO_LIMIT, SYS_CMD_INFO_LIMIT,
}; };
......
...@@ -19,49 +19,80 @@ ...@@ -19,49 +19,80 @@
#include "cvi_spinlock.h" #include "cvi_spinlock.h"
//#define __DEBUG__ // #define __DEBUG__
#ifdef __DEBUG__ #ifdef __DEBUG__
#define debug_printf printf #define debug_printf printf
#else #else
#define debug_printf(...) #define debug_printf(...)
#endif #endif
typedef struct _TASK_CTX_S {
char name[32];
u16 stack_size;
UBaseType_t priority;
void (*runTask)(void *pvParameters);
u8 queLength;
QueueHandle_t queHandle;
} TASK_CTX_S;
/**************************************************************************** /****************************************************************************
* Function prototypes * Function prototypes
****************************************************************************/ ****************************************************************************/
void prvQueueISR(void);
void prvCmdQuRunTask(void *pvParameters);
/**************************************************************************** /****************************************************************************
* Global parameters * Global parameters
****************************************************************************/ ****************************************************************************/
TASK_CTX_S gTaskCtx[1] = {
{
.name = "CMDQU",
.stack_size = configMINIMAL_STACK_SIZE,
.priority = tskIDLE_PRIORITY + 5,
.runTask = prvCmdQuRunTask,
.queLength = 30,
.queHandle = NULL,
},
};
/* mailbox parameters */ /* mailbox parameters */
volatile struct mailbox_set_register *mbox_reg; volatile struct mailbox_set_register *mbox_reg;
volatile struct mailbox_done_register *mbox_done_reg; volatile struct mailbox_done_register *mbox_done_reg;
volatile unsigned long *mailbox_context; // mailbox buffer context is 64 Bytess volatile unsigned long *mailbox_context; // mailbox buffer context is 64 Bytess
/**************************************************************************** /****************************************************************************
* Function definitions * Function definitions
****************************************************************************/ ****************************************************************************/
DEFINE_CVI_SPINLOCK(mailbox_lock, SPIN_MBOX);
void main_create_tasks(void)
{
u8 i = 0;
#define TASK_INIT(_idx) \
do { \
gTaskCtx[_idx].queHandle = xQueueCreate(gTaskCtx[_idx].queLength, sizeof(cmdqu_t)); \
if (gTaskCtx[_idx].queHandle != NULL && gTaskCtx[_idx].runTask != NULL) { \
xTaskCreate(gTaskCtx[_idx].runTask, gTaskCtx[_idx].name, gTaskCtx[_idx].stack_size, \
NULL, gTaskCtx[_idx].priority, NULL); \
} \
} while(0)
for (; i < ARRAY_SIZE(gTaskCtx); i++) {
DEFINE_CVI_SPINLOCK(mailbox_lock, SPIN_MBOX); TASK_INIT(i);
}
}
void main_cvirtos(void) void main_cvirtos(void)
{ {
printf("create cvi task\n"); printf("create cvi task\n");
/* Start the tasks and timer running. */ /* Start the tasks and timer running. */
request_irq(MBOX_INT_C906_2ND, prvQueueISR, 0, "mailbox", (void *)0);
main_create_tasks();
/* Start the tasks and timer running. */
vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following /* If all is well, the scheduler will now be running, and the following
...@@ -77,3 +108,160 @@ void main_cvirtos(void) ...@@ -77,3 +108,160 @@ void main_cvirtos(void)
for (;;) for (;;)
; ;
} }
void prvCmdQuRunTask(void *pvParameters)
{
/* Remove compiler warning about unused parameter. */
(void)pvParameters;
cmdqu_t rtos_cmdq;
cmdqu_t *cmdq;
cmdqu_t *rtos_cmdqu_t;
static int stop_ip = 0;
int ret = 0;
int flags;
int valid;
int send_to_cpu = SEND_TO_CPU1;
unsigned int reg_base = MAILBOX_REG_BASE;
/* to compatible code with linux side */
cmdq = &rtos_cmdq;
mbox_reg = (struct mailbox_set_register *) reg_base;
mbox_done_reg = (struct mailbox_done_register *) (reg_base + 2);
mailbox_context = (unsigned long *) (MAILBOX_REG_BUFF);
cvi_spinlock_init();
printf("prvCmdQuRunTask run\n");
for (;;) {
xQueueReceive(gTaskCtx[0].queHandle, &rtos_cmdq, portMAX_DELAY);
switch (rtos_cmdq.cmd_id) {
case CMD_TEST_A:
//do something
//send to C906B
rtos_cmdq.cmd_id = CMD_TEST_A;
rtos_cmdq.param_ptr = 0x12345678;
rtos_cmdq.resv.valid.rtos_valid = 1;
rtos_cmdq.resv.valid.linux_valid = 0;
printf("recv cmd(%d) from C906B...send [0x%x] to C906B\n", rtos_cmdq.cmd_id, rtos_cmdq.param_ptr);
goto send_label;
case CMD_TEST_B:
//nothing to do
printf("nothing to do...\n");
break;
case CMD_TEST_C:
rtos_cmdq.cmd_id = CMD_TEST_C;
rtos_cmdq.param_ptr = 0x55aa;
rtos_cmdq.resv.valid.rtos_valid = 1;
rtos_cmdq.resv.valid.linux_valid = 0;
printf("recv cmd(%d) from C906B...send [0x%x] to C906B\n", rtos_cmdq.cmd_id, rtos_cmdq.param_ptr);
goto send_label;
default:
send_label:
/* used to send command to linux*/
rtos_cmdqu_t = (cmdqu_t *) mailbox_context;
debug_printf("RTOS_CMDQU_SEND %d\n", send_to_cpu);
debug_printf("ip_id=%d cmd_id=%d param_ptr=%x\n", cmdq->ip_id, cmdq->cmd_id, (unsigned int)cmdq->param_ptr);
debug_printf("mailbox_context = %x\n", mailbox_context);
debug_printf("linux_cmdqu_t = %x\n", rtos_cmdqu_t);
debug_printf("cmdq->ip_id = %d\n", cmdq->ip_id);
debug_printf("cmdq->cmd_id = %d\n", cmdq->cmd_id);
debug_printf("cmdq->block = %d\n", cmdq->block);
debug_printf("cmdq->para_ptr = %x\n", cmdq->param_ptr);
drv_spin_lock_irqsave(&mailbox_lock, flags);
if (flags == MAILBOX_LOCK_FAILED) {
printf("[%s][%d] drv_spin_lock_irqsave failed! ip_id = %d , cmd_id = %d\n" , cmdq->ip_id , cmdq->cmd_id);
break;
}
for (valid = 0; valid < MAILBOX_MAX_NUM; valid++) {
if (rtos_cmdqu_t->resv.valid.linux_valid == 0 && rtos_cmdqu_t->resv.valid.rtos_valid == 0) {
// mailbox buffer context is 4 bytes write access
int *ptr = (int *)rtos_cmdqu_t;
cmdq->resv.valid.rtos_valid = 1;
*ptr = ((cmdq->ip_id << 0) | (cmdq->cmd_id << 8) | (cmdq->block << 15) |
(cmdq->resv.valid.linux_valid << 16) |
(cmdq->resv.valid.rtos_valid << 24));
rtos_cmdqu_t->param_ptr = cmdq->param_ptr;
debug_printf("rtos_cmdqu_t->linux_valid = %d\n", rtos_cmdqu_t->resv.valid.linux_valid);
debug_printf("rtos_cmdqu_t->rtos_valid = %d\n", rtos_cmdqu_t->resv.valid.rtos_valid);
debug_printf("rtos_cmdqu_t->ip_id =%x %d\n", &rtos_cmdqu_t->ip_id, rtos_cmdqu_t->ip_id);
debug_printf("rtos_cmdqu_t->cmd_id = %d\n", rtos_cmdqu_t->cmd_id);
debug_printf("rtos_cmdqu_t->block = %d\n", rtos_cmdqu_t->block);
debug_printf("rtos_cmdqu_t->param_ptr addr=%x %x\n", &rtos_cmdqu_t->param_ptr, rtos_cmdqu_t->param_ptr);
debug_printf("*ptr = %x\n", *ptr);
// clear mailbox
mbox_reg->cpu_mbox_set[send_to_cpu].cpu_mbox_int_clr.mbox_int_clr = (1 << valid);
// trigger mailbox valid to rtos
mbox_reg->cpu_mbox_en[send_to_cpu].mbox_info |= (1 << valid);
mbox_reg->mbox_set.mbox_set = (1 << valid);
break;
}
rtos_cmdqu_t++;
}
drv_spin_unlock_irqrestore(&mailbox_lock, flags);
if (valid >= MAILBOX_MAX_NUM) {
printf("No valid mailbox is available\n");
return -1;
}
break;
}
}
}
void prvQueueISR(void)
{
printf("prvQueueISR\n");
unsigned char set_val;
unsigned char valid_val;
int i;
cmdqu_t *cmdq;
BaseType_t YieldRequired = pdFALSE;
set_val = mbox_reg->cpu_mbox_set[RECEIVE_CPU].cpu_mbox_int_int.mbox_int;
if (set_val) {
for(i = 0; i < MAILBOX_MAX_NUM; i++) {
valid_val = set_val & (1 << i);
if (valid_val) {
cmdqu_t rtos_cmdq;
cmdq = (cmdqu_t *)(mailbox_context) + i;
debug_printf("mailbox_context =%x\n", mailbox_context);
debug_printf("sizeof mailbox_context =%x\n", sizeof(cmdqu_t));
/* mailbox buffer context is send from linux, clear mailbox interrupt */
mbox_reg->cpu_mbox_set[RECEIVE_CPU].cpu_mbox_int_clr.mbox_int_clr = valid_val;
// need to disable enable bit
mbox_reg->cpu_mbox_en[RECEIVE_CPU].mbox_info &= ~valid_val;
// copy cmdq context (8 bytes) to buffer ASAP
*((unsigned long *) &rtos_cmdq) = *((unsigned long *)cmdq);
/* need to clear mailbox interrupt before clear mailbox buffer */
*((unsigned long*) cmdq) = 0;
/* mailbox buffer context is send from linux*/
if (rtos_cmdq.resv.valid.linux_valid == 1) {
debug_printf("cmdq=%x\n", cmdq);
debug_printf("cmdq->ip_id =%d\n", rtos_cmdq.ip_id);
debug_printf("cmdq->cmd_id =%d\n", rtos_cmdq.cmd_id);
debug_printf("cmdq->param_ptr =%x\n", rtos_cmdq.param_ptr);
debug_printf("cmdq->block =%x\n", rtos_cmdq.block);
debug_printf("cmdq->linux_valid =%d\n", rtos_cmdq.resv.valid.linux_valid);
debug_printf("cmdq->rtos_valid =%x\n", rtos_cmdq.resv.valid.rtos_valid);
xQueueSendFromISR(gTaskCtx[0].queHandle, &rtos_cmdq, &YieldRequired);
portYIELD_FROM_ISR(YieldRequired);
} else
printf("rtos cmdq is not valid %d, ip=%d , cmd=%d\n",
rtos_cmdq.resv.valid.rtos_valid, rtos_cmdq.ip_id, rtos_cmdq.cmd_id);
}
}
}
}
...@@ -103,6 +103,7 @@ within this file. */ ...@@ -103,6 +103,7 @@ within this file. */
void vApplicationMallocFailedHook(void); void vApplicationMallocFailedHook(void);
void vApplicationIdleHook(void); void vApplicationIdleHook(void);
void vApplicationStackOverflowHook(TaskHandle_t pxTask, char *pcTaskName); void vApplicationStackOverflowHook(TaskHandle_t pxTask, char *pcTaskName);
void vApplicationTickHook(void);
/* configAPPLICATION_ALLOCATED_HEAP is set to 1 in FreeRTOSConfig.h so the /* configAPPLICATION_ALLOCATED_HEAP is set to 1 in FreeRTOSConfig.h so the
application can define the array used as the FreeRTOS heap. This is done so the application can define the array used as the FreeRTOS heap. This is done so the
...@@ -220,6 +221,17 @@ void vApplicationIdleHook(void) ...@@ -220,6 +221,17 @@ void vApplicationIdleHook(void)
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void vApplicationTickHook(void)
{
#ifdef FULL_DEMO
{
/* Only the comprehensive demo actually uses the tick hook. */
extern void vFullDemoTickHook(void);
vFullDemoTickHook();
}
#endif
}
/*-----------------------------------------------------------*/
/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an /* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
......
...@@ -30,4 +30,5 @@ config CVI_BT_PIN ...@@ -30,4 +30,5 @@ config CVI_BT_PIN
GPIO number to do certain action, ex. power on GPIO number to do certain action, ex. power on
or wakeup pin. or wakeup pin.
source "drivers/soc/cvitek/rtos_cmdqu/Kconfig"
endmenu endmenu
obj-$(CONFIG_CV1835_SYSDMA_REMAP) += sysdma/cv1835_dma_remap.o obj-$(CONFIG_CV1835_SYSDMA_REMAP) += sysdma/cv1835_dma_remap.o
obj-$(CONFIG_CVI_WIFI_PIN) += wifi_pin/cvi_wifi_pin.o obj-$(CONFIG_CVI_WIFI_PIN) += wifi_pin/cvi_wifi_pin.o
obj-$(CONFIG_CVI_BT_PIN) += bt_pin/cvi_bt_pin.o obj-$(CONFIG_CVI_BT_PIN) += bt_pin/cvi_bt_pin.o
\ No newline at end of file obj-$(CONFIG_CVI_MAILBOX) += rtos_cmdqu/
config CVI_MAILBOX
tristate "cv180x/cv181x mailbox dirver"
help
"cv180x/cv181x mailbox driver"
obj-$(CONFIG_CVI_MAILBOX) := cvi_mbox.o
cvi_mbox-y := rtos_cmdqu.o \
cvi_spinlock.o
ccflags-y += -I$(srctree)/$(src)/
#ifndef __CVI_MAILBOX_H__
#define __CVI_MAILBOX_H__
union cpu_mailbox_info_offset{
char mbox_info;
int reserved;
};
union cpu_mailbox_int_clr_offset{
char mbox_int_clr;
int reserved;
};
union cpu_mailbox_int_mask_offset{
char mbox_int_mask;
int reserved;
};
union cpu_mailbox_int_offset{
char mbox_int;
int reserved;
};
union cpu_mailbox_int_raw_offset{
char mbox_int_raw;
int reserved;
};
union mailbox_set{
char mbox_set;
int reserved;
};
union mailbox_status{
char mbox_status;
int reserved;
};
union cpu_mailbox_status{
char mbox_status;
int reserved;
};
/* register mapping refers to mailbox user guide*/
struct cpu_mbox_int{
union cpu_mailbox_int_clr_offset cpu_mbox_int_clr;
union cpu_mailbox_int_mask_offset cpu_mbox_int_mask;
union cpu_mailbox_int_offset cpu_mbox_int_int;
union cpu_mailbox_int_raw_offset cpu_mbox_int_raw;
};
struct mailbox_set_register{
union cpu_mailbox_info_offset cpu_mbox_en[4]; //0x00, 0x04, 0x08, 0x0c
struct cpu_mbox_int cpu_mbox_set[4]; //0x10~0x1C, 0x20~0x2C, 0x30~0x3C, 0x40~0x4C
int reserved[4]; //0x50~0x5C
union mailbox_set mbox_set; //0x60
union mailbox_status mbox_status; //0x64
int reserved2[2]; //0x68~0x6C
union cpu_mailbox_status cpu_mbox_status[4]; //0x70
};
struct mailbox_done_register{
union cpu_mailbox_info_offset cpu_mbox_done_en[4];
struct cpu_mbox_int cpu_mbox_done[4];
};
volatile struct mailbox_set_register *mbox_reg;
volatile struct mailbox_done_register *mbox_done_reg;
volatile unsigned long *mailbox_context; // mailbox buffer context is 64 Bytess
#define MAILBOX_MAX_NUM 0x0008
#define MAILBOX_DONE_OFFSET 0x0002
#define MAILBOX_CONTEXT_OFFSET 0x0400
// C906B
#define RECEIVE_CPU 1
// C906L
#define SEND_TO_CPU 2
#endif // end of__CVI_MAILBOX_H__
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) Cvitek Co., Ltd. 2019-2022. All rights reserved.
*
* File Name: cvi_spinlock.c
* Description:
*/
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/of_reserved_mem.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/uaccess.h>
#include <linux/version.h>
#include "cvi_spinlock.h"
static unsigned long reg_base;
spinlock_t reg_write_lock;
static unsigned char lockCount[SPIN_MAX+1] = {0};
static void *__iomem c906l_pc_reg;
void cvi_spinlock_init(void)
{
spin_lock_init(&reg_write_lock);
c906l_pc_reg = ioremap(0x1901070, 4);
if (c906l_pc_reg == NULL) {
pr_err("c906l_pc_reg ioremap failed!\n");
}
pr_info("[%s] success\n", __func__);
}
void cvi_spinlock_uninit(void)
{
iounmap(c906l_pc_reg);
}
void spinlock_base(unsigned long mb_base)
{
reg_base = mb_base;
}
static inline int hw_spin_trylock(hw_raw_spinlock_t *lock)
{
writew(lock->locks, (void *)(reg_base + sizeof(int) * lock->hw_field));
if (readw((void *)(reg_base + sizeof(int) * lock->hw_field)) == lock->locks)
return MAILBOX_LOCK_SUCCESS;
return MAILBOX_LOCK_FAILED;
}
int hw_spin_lock(hw_raw_spinlock_t *lock)
{
u64 i;
u64 loops = 1000000;
hw_raw_spinlock_t _lock = {.hw_field = lock->hw_field, .locks=lock->locks};
if (lock->hw_field >= SPIN_LINUX_RTOS) {
unsigned long flags;
spin_lock_irqsave(&reg_write_lock, flags);
if (lockCount[lock->hw_field] == 0) {
lockCount[lock->hw_field]++;
}
_lock.locks = lockCount[lock->hw_field];
lockCount[lock->hw_field]++;
spin_unlock_irqrestore(&reg_write_lock, flags);
}
else {
//....
}
for (i = 0; i < loops; i++) {
if (hw_spin_trylock(&_lock) == MAILBOX_LOCK_SUCCESS)
{
lock->locks = _lock.locks;
return MAILBOX_LOCK_SUCCESS;
}
udelay(1);
}
pr_err("__spin_lock_debug fail! loops = %lld\n", loops);
return MAILBOX_LOCK_FAILED;
}
int _hw_raw_spin_lock_irqsave(hw_raw_spinlock_t *lock)
{
int flag = MAILBOX_LOCK_SUCCESS;
// lock
if (hw_spin_lock(lock) == MAILBOX_LOCK_FAILED) {
pr_err("spin lock fail! C906L pc = 0x%x,reg_val=0x%x, lock->locks=0x%x\n",
ioread32(c906l_pc_reg), readw((void *)(reg_base + sizeof(int) * lock->hw_field)), lock->locks);
return MAILBOX_LOCK_FAILED;
}
return flag;
}
void _hw_raw_spin_unlock_irqrestore(hw_raw_spinlock_t *lock, int flag)
{
// unlock
if (readw((void *)(reg_base + sizeof(int) * lock->hw_field)) == lock->locks) {
writew(lock->locks, (void *)(reg_base + sizeof(int) * lock->hw_field));
} else {
pr_err("spin unlock fail! C906L pc=0x%x,reg_val=0x%x, lock->locks=0x%x\n",
ioread32(c906l_pc_reg), readw((void *)(reg_base + sizeof(int) * lock->hw_field)), lock->locks);
}
}
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __DRV_SPINLOCK_H__
#define __DRV_SPINLOCK_H__
enum SPINLOCK_FIELD {
SPIN_UART,
SPIN_LINUX_RTOS = 4, // this spinlock field is used for linux & rtos
SPIN_MBOX = SPIN_LINUX_RTOS,
SPIN_MAX = 7,
};
typedef struct hw_raw_spinlock {
unsigned short locks;
unsigned short hw_field;
} hw_raw_spinlock_t;
#define MAILBOX_LOCK_SUCCESS 1
#define MAILBOX_LOCK_FAILED (-1)
#define __CVI_ARCH_SPIN_LOCK_UNLOCKED \
(0)
#define __CVI_RAW_SPIN_LOCK_INITIALIZER(spinlock_hw_field) \
{ .locks = __CVI_ARCH_SPIN_LOCK_UNLOCKED, .hw_field = spinlock_hw_field, }
#define DEFINE_CVI_SPINLOCK(x, y) \
hw_raw_spinlock_t x = __CVI_RAW_SPIN_LOCK_INITIALIZER(y)
int _hw_raw_spin_lock_irqsave(hw_raw_spinlock_t *lock);
void _hw_raw_spin_unlock_irqrestore(hw_raw_spinlock_t *lock, int flag);
#define drv_spin_lock_irqsave(lock, flags) \
{ flags = _hw_raw_spin_lock_irqsave(lock); }
#define drv_spin_unlock_irqrestore(lock, flags) \
_hw_raw_spin_unlock_irqrestore(lock, flags)
void spinlock_base(unsigned long mb_base);
void cvi_spinlock_init(void);
void cvi_spinlock_uninit(void);
#endif // end of __DRV_SPINLOCK_H__
This diff is collapsed.
#ifndef __RTOS_COMMAND_QUEUE__
#define __RTOS_COMMAND_QUEUE__
#include <linux/kernel.h>
#define NR_SYSTEM_CMD 20
struct valid_t {
unsigned char linux_valid;
unsigned char rtos_valid;
} __attribute__((packed));
typedef union resv_t {
struct valid_t valid;
unsigned short mstime; // 0 : noblock, -1 : block infinite
} resv_t;
typedef struct cmdqu_t cmdqu_t;
/* cmdqu size should be 8 bytes because of mailbox buffer size */
struct cmdqu_t {
unsigned char ip_id;
unsigned char cmd_id : 7;
unsigned char block : 1;
union resv_t resv;
unsigned int param_ptr;
} __attribute__((packed)) __attribute__((aligned(0x8)));
/* keep those commands for ioctl system used */
enum SYSTEM_CMD_TYPE {
CMDQU_SEND = 1,
CMDQU_SEND_WAIT,
CMDQU_SEND_WAKEUP,
CMDQU_SYSTEM_LIMIT = NR_SYSTEM_CMD,
};
enum SYS_CMD_ID {
CMD_TEST_A = 0x10,
CMD_TEST_B,
CMD_TEST_C,
SYS_CMD_INFO_LIMIT,
};
#define RTOS_CMDQU_DEV_NAME "cvi-rtos-cmdqu"
#define RTOS_CMDQU_SEND _IOW('r', CMDQU_SEND, unsigned long)
#define RTOS_CMDQU_SEND_WAIT _IOW('r', CMDQU_SEND_WAIT, unsigned long)
#define RTOS_CMDQU_SEND_WAKEUP _IOW('r', CMDQU_SEND_WAKEUP, unsigned long)
int rtos_cmdqu_send(cmdqu_t *cmdq);
int rtos_cmdqu_send_wait(cmdqu_t *cmdq, int wait_cmd_id);
#endif // end of __RTOS_COMMAND_QUEUE__
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment