mp4一结束写入就报页错误

Viewed 47

问题描述


官方例程改出来的代码,使用的时候正常写入,但是一结束就报页错误,而且mp4文件也没有文件尾,初步定位出错位置是venc_destroy_chn函数,但是不知道哪里错误,我看日志里错误的地方主要是分配缓冲页不足和物理地址未对齐,但我的地址分配都加了0x1000,没搞懂为什么,以下是周边代码:
k_s32 kd_sample_get_venc_stream(void)
{
k_s32 ret = 0;
k_venc_stream output;
k_venc_chn_status status;
k_u8 *pData;
kd_mpi_venc_start_chn(venc_chn);
while (app_run)
{
ret = kd_mpi_venc_query_status(venc_chn, &status);
if (status.cur_packs > 0)
output.pack_cnt = status.cur_packs;
else
output.pack_cnt = 1;
output.pack = (k_venc_pack *)malloc(sizeof(k_venc_pack) * output.pack_cnt);
ret = kd_mpi_venc_get_stream(venc_chn, &output,-1);
for (int i = 0; i < output.pack_cnt; i++)
{
pData = (k_u8 *)kd_mpi_sys_mmap(output.pack[i].phys_addr, output.pack[i].len);
if (pData == NULL) {
printf("venC mmap failed!\n");
continue;
}
OnVEncData(venc_chn, pData, output.pack[i].len, output.pack[i].type, output.pack[i].pts);
// printf("=====vend data size:%d\n",output.pack[i].len);

        kd_mpi_sys_munmap(pData, output.pack[i].len);
    }

    ret = kd_mpi_venc_release_stream(venc_chn, &output);

    free(output.pack);
}
kd_mpi_venc_stop_chn(venc_chn);
printf("error:%016x",kd_mpi_venc_destroy_chn(venc_chn));
return ret;

}
以下是错误日志
chn_enable: 1
isp_3dnr_en is 1 g_isp_dev_ctx[dev_num].dev_attr.pipe_ctrl.bits.dnr3_enable is 0
[D/lt9611] vtotal 1125 vactive 1080 htotal_sys 400

VsiCamDeviceCreate hw:0-vt:0 created!
ov5647_power_rest OV5647_CAM_PIN_CSI2 is 21
kd_mpi_isp_set_output_chn_format, width(1280), height(720), pix_format(5)
kd_mpi_isp_set_output_chn_format, width(1280), height(720), pix_format(16)
kd_mpi_isp_set_output_chn_format, width(1280), height(720), pix_format(5)
[dw] init, version Mar 14 2025 16:36:59
mp4 config audio channel:2,samplerate:8000
size:2764800
kmodel:1x3x320x320
shape:1x3x320x320
recv count:0, chn:0, len:86
ai2d run: duration = 2.70874 ms, fps = 369.175
<3>[9] [Func]:venc_mvx_qbuf [Line]:274 [Info]:venc_mvx_qbuf>error phys_addr 0x10 48a800
VA and PA must be page aligned. va=0x70000000, pa=0x1048a800.
<3>[9] [Func]:venc_mvx_qbuf [Line]:373 [Info]:venc_mvx_qbuf>error line 373
in_shape:1x3x320
out_shape:1x6300x7
<3>[9] [Func]:venc_mvx_qbuf [Line]:274 [Info]:venc_mvx_qbuf>error phys_addr 0x10 72d800
<3>[9] [Func]:venc_mvx_qbuf [Line]:373 [Info]:venc_mvx_qbuf>error line 373
recv count:30, chn:0, len:12561
num_valid:0
final_boxes:0
size:2764800
kmodel:1x3x320x320
shape:1x3x320x320
ai2d run: duration = 2.58982 ms, fps = 386.128
in_shape:1x3x320
out_shape:1x6300x7
recv count:60, chn:0, len:16364
recv count:90, chn:0, len:12830
qsys queue no space to push data
<3>[9] [Func]:venc_input_enqueue [Line]:415 [Info]:venc_input_enqueue>failed
sys queue no space to push data
<3>[9] [Func]:venc_input_enqueue [Line]:415 [Info]:venc_input_enqueue>failed
sys queue no space to push data
<3>[9] [Func]:venc_input_enqueue [Line]:415 [Info]:venc_input_enqueue>failed
sys queue no space to push data
<3>[9] [Func]:venc_input_enqueue [Line]:415 [Info]:venc_input_enqueue>failed
sys queue no space to push data
<3>[9] [Func]:venc_input_enqueue [Line]:415 [Info]:venc_input_enqueue>failed
<3>[4] [Func]:vb_user_sub [Line]:880 [Info]:try to sub user for a free buffer!
<3>[9] [Func]:handle_event [Line]:552 [Info]:handle_event>ch 0, stream queue ove rflow output_rrelease:9 output_rp:7 output_wp:9
recv count:120, chn:0, len:17122
<3>[4] [Func]:vb_user_add [Line]:835 [Info]:try to increase counter for a free b uffer!
<3>[4] [Func]:vb_user_add [Line]:835 [Info]:try to increase counter for a free b uffer!
<3>[4] [Func]:v<3>[4] [Func]:vb_user_sub [Line]:880 [Info]:try to sub user for a free buffer!
b_user_sub [Line]:880 [Info]:try to sub user for a free buffer!
kd_mpi_vicap_put_vb_buf, release vb block failed.
[!!!kd_mpi_isp_chn0_buf_handler, dev(0) chn(0) index(9) put vb buf failed]
<3>[4] [Func]:vb_user_sub [Line]:880 [Info]:try to sub user for a free buffer!
num_valid:0
final_boxes:0
size:2764800
kmodel:1x3x320x320
shape:1x3x320x320
ai2d run: duration = 2.1633 ms, fps = 462.258
in_shape:1x3x320
out_shape:1x6300x7
recv count:150, chn:0, len:13020
recv count:180, chn:0, len:20880
num_valid:0
final_boxes:0
size:2764800
kmodel:1x3x320x320
shape:1x3x320x320
ai2d run: duration = 2.16189 ms, fps = 462.559
in_shape:1x3x320
out_shape:1x6300x7
recv count:210, chn:0, len:13045
recv count:240, chn:0, len:20096
num_valid:0
final_boxes:0
size:2764800
kmodel:1x3x320x320
shape:1x3x320x320
ai2d run: duration = 2.32452 ms, fps = 430.197
in_shape:1x3x320
out_shape:1x6300x7
recv count:270, chn:0, len:13111

ch 0: 295 pictures encoded. Average FrameRate = 29 Fps
ch 0: total used pages 971
[E/DBG] [FATAL ERROR] Exception 15:Store/AMO Page Fault
[E/DBG] scause:0x000000000000000f,stval:0xffffffb8e0d0c000,sepc:0x000000000023b6 62
--------------Dump Registers-----------------
Function Registers:
ra(x1) = 0x000000000023b654()
user_sp(x2) = 0x000000000175e778()
gp(x3) = 0x0000000001532ee0()
tp(x4) = 0x000000010037ffd8()
Temporary Registers:
t0(x5) = 0x0000000000000120()
t1(x6) = 0x00000000015ea72f()
t2(x7) = 0x000000000175f000()
t3(x28) = 0x0000000001514968()
t4(x29) = 0x0000000000000020()
t5(x30) = 0x0000000000000000()
t6(x31) = 0x000000000175e742()
Saved Registers:
s0/fp(x8) = 0x000000000175e7a8()
s1(x9) = 0x0000000040044501()
s2(x18) = 0x000000010037fd8c()
s3(x19) = 0x0000000000000000()
s4(x20) = 0x000000010037fed0()
s5(x21) = 0xffffffffffffffff()
s6(x22) = 0x0000000200003cf6()
s7(x23) = 0x0000000000000000()
s8(x24) = 0x000000010037fef8()
s9(x25) = 0x000000020070f5c0()
s10(x26) = 0x0000000000000000()
s11(x27) = 0x000000010035d000()
Function Arguments Registers:
a0(x10) = 0x000000b8e0d0c000()
a1(x11) = 0x0000000000000001()
a2(x12) = 0x0000000000000000()
a3(x13) = 0x00000000015b8928()
a4(x14) = 0x000000b8e0d0c000()
a5(x15) = 0x000000b8e0d0c000()
a6(x16) = 0x0000000003c06dc0()
a7(x17) = 0x0000000000000001()
sstatus = 0x8000000200044720
Supervisor Interrupt Disabled
Last Time Supervisor Interrupt Enabled
Last Privilege is Supervisor Mode
Permit to Access User Page
Not Permit to Read Executable-only Page
satp = 0x8000000000007a24
Current Page Table(Physical) = 0x0000000007a24000
Current ASID = 0x0000000000000000
Mode = Page-based 39-bit Virtual Addressing Mode
-----------------Dump OK---------------------
riscv64-unknown-linux-musl-addr2line -e rtthread.elf -a -f 000000000023b65e 0000 00000023c266 000000000023bfb4 00000000002381b0 0000000000254dec 0000000000256b82 00000000002379f8 000000000033c8ec
[E/DBG] User Fault, killing thread: _camera.elf
num_valid:0
以下是全代码:
// #include <rtthread.h>
#include
#include
#include
#include
#include

#include "mpi_sys_api.h"

/* vicap */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/mman.h>
#include <signal.h>
#include
#include <fcntl.h>
#include <pthread.h>
#include <time.h>
#include <sys/mman.h>
#include "k_module.h"
#include "k_type.h"
#include "k_vb_comm.h"
#include "k_video_comm.h"
#include "k_sys_comm.h"
#include "mpi_vb_api.h"
#include "mpi_vicap_api.h"
#include "mpi_isp_api.h"
#include "mpi_sys_api.h"
#include "k_vo_comm.h"
#include "mpi_vo_api.h"
#include "vo_test_case.h"
#include "k_venc_comm.h"
#include "mpi_vo_api.h"
#include "sys/ioctl.h"
#include "k_type.h"
#include "k_module.h"

#include "k_connector_comm.h"
#include "mpi_connector_api.h"

#include "k_autoconf_comm.h"
#include "k_ipcmsg.h"
#include"my_model.h"
#include
#include "mp4_format.h"
#include "mpi_venc_api.h"
#define SEND_SYNC_MODULE_ID 1
#define SNED_ASYNC_MODULE_ID 2
#define SEND_ONLY_MODULE_ID 3
#define TIME_INTERVAL 1000*1000

#define CHANNEL 3

#define ISP_CHN1_HEIGHT (720)
#define ISP_CHN1_WIDTH (1280)
#define ISP_CHN0_WIDTH (1280)
#define ISP_CHN0_HEIGHT (720)
#define ISP_CHN2_WIDTH (1280)
#define ISP_CHN2_HEIGHT (720)

#define ISP_INPUT_WIDTH (1280)
#define ISP_INPUT_HEIGHT (720)

#define LCD_WIDTH (1280)
#define LCD_HEIGHT (720)

#define VENC_MAX_CHN_NUMS 1
// #define TEST_BOOT_TIME

using namespace std::chrono_literals;
static char g_mp4_pathname[256];
bool get_idr_;
uint64_t first_time_stamp_;

std::mutex frame_muxer_mutex_;

uint32_t save_size_;
std::atomic<uint64_t> first_frame_time_stamp_;
uint64_t video_first_time_stamp_;
uint32_t video_stream_count_;

enum class KdMediaVideoType {
kVideoTypeH264,
kVideoTypeH265,
kVideoTypeMjpeg,
kVideoTypeButt
};
bool start_get_video_stream_;
struct KdMediaInputConfig {
bool video_valid = false;
k_vicap_sensor_type sensor_type = IMX335_MIPI_2LANE_RAW12_1920X1080_30FPS_LINEAR;
int sensor_num = 1;
KdMediaVideoType video_type = KdMediaVideoType::kVideoTypeH265;
int venc_width = 1280;
int venc_height = 720;
int bitrate_kbps = 4000;

int audio_samplerate = 8000;
int audio_channel_cnt = 1;
int pitch_shift_semitones = 0; // [-12, 12]

};
#ifdef TEST_BOOT_TIME
#define TIME_RATE (16001000)
uint64_t perf_get_smodecycles(void);
typedef struct kd_pin_mode
{
unsigned short pin; /
pin number, from 0 to 63 /
unsigned short mode; /
pin level status, 0 low level, 1 high level */
} pin_mode_t;
static venc_output_pthread venc_output_arr[VENC_MAX_CHN_NUMS];
#define KD_GPIO_HIGH 1
#define KD_GPIO_LOW 0
#define LED_PIN_NUM1 33 //test boot time测试专用引脚,通过计算翻转之间的时间得到代码段耗时
#define LED_PIN_NUM2 32
#define GPIO_DM_OUTPUT _IOW('G', 0, int)
#define GPIO_DM_INPUT _IOW('G', 1, int)
#define GPIO_DM_INPUT_PULL_UP _IOW('G', 2, int)
#define GPIO_DM_INPUT_PULL_DOWN _IOW('G', 3, int)
#define GPIO_WRITE_LOW _IOW('G', 4, int)
#define GPIO_WRITE_HIGH _IOW('G', 5, int)

#define GPIO_PE_RISING _IOW('G', 7, int)
#define GPIO_PE_FALLING _IOW('G', 8, int)
#define GPIO_PE_BOTH _IOW('G', 9, int)
#define GPIO_PE_HIGH _IOW('G', 10, int)
#define GPIO_PE_LOW _IOW('G', 11, int)

#define GPIO_READ_VALUE _IOW('G', 12, int)
int unitest_gpio_read_write(int fd)
{
int ret;
pin_mode_t mode27;
mode27.pin = LED_PIN_NUM2;
ret = ioctl(fd, GPIO_DM_OUTPUT, &mode27); //pin33 input
if (ret)
{
perror("ioctl /dev/pin err\n");
return -1;
}
ioctl(fd, GPIO_WRITE_LOW, &mode27);
ioctl(fd, GPIO_WRITE_HIGH, &mode27);
ioctl(fd, GPIO_READ_VALUE, &mode27);
printf("mode27.mode %d\n",mode27.mode);
return ret;
}

int gpio_write_high(int fd)
{
int ret;
pin_mode_t mode27;
mode27.pin = LED_PIN_NUM2;
// ret = ioctl(fd, GPIO_DM_OUTPUT, &mode27);
// if (ret)
// {
// perror("ioctl /dev/pin err\n");
// return -1;
// }
// printf("---mode27.mode %d\n",mode27.mode);
ioctl(fd, GPIO_WRITE_HIGH, &mode27);
return ret;
}

int gpio_write_low(int fd)
{
int ret;
pin_mode_t mode27;
mode27.pin = LED_PIN_NUM2;
// ret = ioctl(fd, GPIO_DM_OUTPUT, &mode27);
// if (ret)
// {
// perror("ioctl /dev/pin err\n");
// return -1;
// }
ioctl(fd, GPIO_WRITE_LOW, &mode27);
return ret;
}

int sample_gpio_op(void)
{
int ret;
int gpio_fd = -1;
pin_mode_t mode27;
mode27.pin = LED_PIN_NUM2;
gpio_fd = open("/dev/gpio", O_RDWR);
if (gpio_fd < 0)
{
perror("open /dev/pin err\n");
return -1;
}
ret = ioctl(gpio_fd, GPIO_DM_OUTPUT, &mode27);
return gpio_fd;
}

static int test_fd;
static k_u64 start_time,stop_time;
#define TEST_TIME(func, func_name) start_time = perf_get_smodecycles();
func;
stop_time = perf_get_smodecycles();
printf("%s use time:%d ms\n", func_name,(stop_time - start_time) / TIME_RATE);

static inline void TEST_BOOT_TIME_INIT(void)
{
// int test_fd = -1;
test_fd = sample_gpio_op();
gpio_write_high(test_fd);
gpio_write_low(test_fd);
}

static inline void TEST_BOOT_TIME_TRIGER(void)
{
gpio_write_high(test_fd);
gpio_write_low(test_fd);
}

static inline void PRINT_TIME_NOW(void)
{
printf("current time:%ld ms\n", perf_get_smodecycles()/TIME_RATE);
}
#else
#define TEST_TIME(func, func_name) func
#define TEST_BOOT_TIME_INIT()
#define TEST_BOOT_TIME_TRIGER()
#define PRINT_TIME_NOW()
#endif

int sample_sys_bind_init(void);

std::atomic quit(true);

bool app_run = true;

void fun_sig(int sig)
{
if(sig == SIGINT)
{
printf("recive ctrl+c\n");
quit.store(false);
}
}

uint64_t perf_get_smodecycles(void)
{
uint64_t cnt;
asm volatile(
"rdcycle %0" : "=r"(cnt)
);
return cnt;
}/统模式(Supervisor Mode)时钟周期统计接口,核心功能是读取 RISC-V 处理器的系统模式专用周期计数器,返回从处理器上电 / 复位到当前时刻的 64 位系统模式总执行时钟周期数,用于高精度性能计时、代码执行耗时统计、实时性分析等场景。/

k_vo_draw_frame vo_frame = (k_vo_draw_frame) {
1,
16,
16,
128,
128,
1
};

int vo_creat_layer_test(k_vo_layer chn_id, layer_info *info)
{
k_vo_video_layer_attr attr;

// check layer
if ((chn_id >= K_MAX_VO_LAYER_NUM) || ((info->func & K_VO_SCALER_ENABLE) && (chn_id != K_VO_LAYER0))
        || ((info->func != 0) && (chn_id == K_VO_LAYER2)))
{
    printf("input layer num failed \n");
    return -1 ;
}

memset(&attr, 0, sizeof(attr));

// set offset
attr.display_rect = info->offset;
// set act
attr.img_size = info->act_size;
// sget size
info->size = info->act_size.height * info->act_size.width * 3 / 2;
//set pixel format
attr.pixel_format = info->format;
if (info->format != PIXEL_FORMAT_YVU_PLANAR_420)
{
    printf("input pix format failed \n");
    return -1;
}
// set stride
attr.stride = (info->act_size.width / 8 - 1) + ((info->act_size.height - 1) << 16);
// set function
attr.func = info->func;
// set scaler attr
attr.scaler_attr = info->attr;

// set video layer atrr
kd_mpi_vo_set_video_layer_attr(chn_id, &attr);

// enable layer
kd_mpi_vo_enable_video_layer(chn_id);

return 0;

}

k_s32 sample_connector_init(void)
{
k_u32 ret = 0;
k_s32 connector_fd;

k_connector_type connector_type = LT9611_MIPI_4LAN_1920X1080_30FPS;// HX8377_V2_MIPI_4LAN_1080X1920_30FPS;

k_connector_info connector_info;

memset(&connector_info, 0, sizeof(k_connector_info));

//connector get sensor info
ret = kd_mpi_get_connector_info(connector_type, &connector_info);
if (ret) {
    printf("sample_vicap, the sensor type not supported!\n");
    return ret;
}

connector_fd = kd_mpi_connector_open(connector_info.connector_name);
if (connector_fd < 0) {
    printf("%s, connector open failed.\n", __func__);
    return K_ERR_VO_NOTREADY;
}

// set connect power
kd_mpi_connector_power_set(connector_fd, K_TRUE);
// connector init
kd_mpi_connector_init(connector_fd, connector_info);

return 0;

}

static k_s32 vo_layer_vdss_bind_vo_config(void)
{
layer_info info;
k_vo_layer chn_id = K_VO_LAYER1;

memset(&info, 0, sizeof(info));

sample_connector_init();


info.act_size.width = ISP_CHN0_HEIGHT;//1080;//640;//1080;
info.act_size.height = ISP_CHN0_WIDTH;//1920;//480;//1920;
info.format = PIXEL_FORMAT_YVU_PLANAR_420;
info.func = K_ROTATION_0;

info.global_alptha = 0xff;
info.offset.x = 0;//(1080-w)/2,
info.offset.y = 0;//(1920-h)/2;
vo_creat_layer_test(chn_id, &info);

return 0;

}

static void sample_vo_fn(void *arg)
{
usleep(10000);
vo_layer_vdss_bind_vo_config();
sample_sys_bind_init();
return;
}

static void *sample_vo_thread(void *arg)
{
TEST_TIME(sample_vo_fn(arg), "sample_vo_fn");
return NULL;
}

k_vicap_dev vicap_dev;
k_vicap_chn vicap_chn;
k_vicap_chn vicap_chn_venc;
k_s32 venc_chn;
k_vicap_dev_attr dev_attr;
k_vicap_chn_attr chn_attr;
k_vicap_chn_attr chn_attr_venc;
k_vicap_sensor_info sensor_info;
k_vicap_sensor_type sensor_type;
k_video_frame_info dump_info;

static void sample_vicap_unbind(k_mpp_chn vicap_mpp_chn,k_mpp_chn vicap_mpp_chn_venc, k_mpp_chn vo_mpp_chn,k_mpp_chn venc_mpp_chn)
{
k_s32 ret;

ret = kd_mpi_sys_unbind(&vicap_mpp_chn, &vo_mpp_chn);
if (ret) {
    printf("kd_mpi_sys_unbind failed:0x%x\n", ret);
}
ret = kd_mpi_sys_unbind(&vicap_mpp_chn_venc, &venc_mpp_chn);
if (ret) {
    printf("kd_mpi_sys_unbind failed:0x%x\n", ret);
}
return;

}

int sample_sys_bind_init(void)
{
k_s32 ret = 0;
k_mpp_chn vicap_mpp_chn;
k_mpp_chn vo_mpp_chn;
vicap_mpp_chn.mod_id = K_ID_VI;
vicap_mpp_chn.dev_id = vicap_dev;
vicap_mpp_chn.chn_id = vicap_chn;

vo_mpp_chn.mod_id = K_ID_VO;
vo_mpp_chn.dev_id = K_VO_DISPLAY_DEV_ID;
vo_mpp_chn.chn_id = K_VO_DISPLAY_CHN_ID1;

ret = kd_mpi_sys_bind(&vicap_mpp_chn, &vo_mpp_chn);
if (ret) {
    printf("kd_mpi_sys_unbind failed:0x%x\n", ret);
}

k_mpp_chn vicap_mpp_chn_venc;
k_mpp_chn venc_mpp_chn;
vicap_mpp_chn_venc.mod_id = K_ID_VI;
vicap_mpp_chn_venc.dev_id = vicap_dev;
vicap_mpp_chn_venc.chn_id = vicap_chn_venc;
venc_mpp_chn.mod_id = K_ID_VENC;
venc_mpp_chn.dev_id = 0;
venc_mpp_chn.chn_id = venc_chn;

ret = kd_mpi_sys_unbind(&vicap_mpp_chn, &venc_mpp_chn);
if (ret) {
    printf("kd_mpi_sys_unbind failed:0x%x\n", ret);
}
ret = kd_mpi_sys_bind(&vicap_mpp_chn,&venc_mpp_chn);
if (ret) {
    printf("kd_mpi_sys_bind failed:0x%x\n", ret);
}
return ret;

}

int sample_vb_init(void)
{
k_s32 ret;
k_vb_config config;
int venc_width=720,venc_height=1280;
memset(&config, 0, sizeof(config));
config.max_pool_cnt = 64;
//VB for YUV420SP output
config.comm_pool[0].blk_cnt = 5;
config.comm_pool[0].mode = VB_REMAP_MODE_NOCACHE;
config.comm_pool[0].blk_size = VICAP_ALIGN_UP((ISP_CHN0_WIDTH * ISP_CHN0_HEIGHT * 3 / 2), VICAP_ALIGN_1K);

//VB for RGB888 output
config.comm_pool[1].blk_cnt = 5;
config.comm_pool[1].mode = VB_REMAP_MODE_NOCACHE;
config.comm_pool[1].blk_size = VICAP_ALIGN_UP((ISP_CHN1_HEIGHT * ISP_CHN1_WIDTH * 3 ), VICAP_ALIGN_1K);
//VB for YUV420SP venc
config.comm_pool[2].blk_cnt = 8;
config.comm_pool[2].mode = VB_REMAP_MODE_NOCACHE;
config.comm_pool[2].blk_size = VICAP_ALIGN_UP((ISP_CHN2_WIDTH * ISP_CHN2_HEIGHT * 3 / 2),0x1000);
//VB for venc
k_u64 pic_size = ISP_CHN0_WIDTH*  ISP_CHN0_HEIGHT* 2;
k_u64 stream_size = ISP_CHN0_WIDTH * ISP_CHN0_HEIGHT / 2;
config.comm_pool[3].blk_cnt = 8;
config.comm_pool[3].blk_size = ((pic_size + 0xfff) & ~0xfff);
config.comm_pool[3].mode = VB_REMAP_MODE_NOCACHE;
config.comm_pool[4].blk_cnt = 30;
config.comm_pool[4].blk_size = ((stream_size + 0xfff) & ~0xfff);
config.comm_pool[4].mode = VB_REMAP_MODE_NOCACHE;
ret = kd_mpi_vb_set_config(&config);
if (ret) {
    printf("vb_set_config failed ret:%d\n", ret);
    return ret;
}

k_vb_supplement_config supplement_config;
memset(&supplement_config, 0, sizeof(supplement_config));
supplement_config.supplement_config |= VB_SUPPLEMENT_JPEG_MASK;

ret = kd_mpi_vb_set_supplement_config(&supplement_config);
if (ret) {
    printf("vb_set_supplement_config failed ret:%d\n", ret);
    return ret;
}
ret = kd_mpi_vb_init();
if (ret) {
    printf("vb_init failed ret:%d\n", ret);
}
return ret;

}

int sample_vivcap_init( void )
{
k_s32 ret = 0;

sensor_type = OV_OV5647_MIPI_CSI2_1920X1080_30FPS_10BIT_LINEAR_V2;

vicap_dev = VICAP_DEV_ID_0;



memset(&sensor_info, 0, sizeof(k_vicap_sensor_info));
ret = kd_mpi_vicap_get_sensor_info(sensor_type, &sensor_info);	
if (ret) {
    printf("sample_vicap, the sensor type not supported!\n");
    return ret;
}

memset(&dev_attr, 0, sizeof(k_vicap_dev_attr));
dev_attr.acq_win.h_start = 0;
dev_attr.acq_win.v_start = 0;
dev_attr.acq_win.width = ISP_INPUT_WIDTH;
dev_attr.acq_win.height = ISP_INPUT_HEIGHT;
dev_attr.mode = VICAP_WORK_ONLINE_MODE;

dev_attr.pipe_ctrl.data = 0xFFFFFFFF;
dev_attr.pipe_ctrl.bits.af_enable = 0;
dev_attr.pipe_ctrl.bits.ahdr_enable = 0;
dev_attr.pipe_ctrl.bits.dnr3_enable = 0;


dev_attr.cpature_frame = 0;
memcpy(&dev_attr.sensor_info, &sensor_info, sizeof(k_vicap_sensor_info));

ret = kd_mpi_vicap_set_dev_attr(vicap_dev, dev_attr);
if (ret) {
    printf("sample_vicap, kd_mpi_vicap_set_dev_attr failed.\n");
    return ret;
}

memset(&chn_attr, 0, sizeof(k_vicap_chn_attr));

//set chn0 output yuv420sp
// chn_attr.out_win = dev_attr.acq_win;
// chn_attr.crop_win = chn_attr.out_win;
chn_attr.out_win.h_start = 0;
chn_attr.out_win.v_start = 0;
chn_attr.out_win.width = ISP_CHN0_WIDTH;
chn_attr.out_win.height = ISP_CHN0_HEIGHT;
chn_attr.crop_win = dev_attr.acq_win;
chn_attr.scale_win = chn_attr.out_win;
chn_attr.crop_enable = K_FALSE;
chn_attr.scale_enable = K_FALSE;
// chn_attr.dw_enable = K_FALSE;
chn_attr.chn_enable = K_TRUE;
chn_attr.pix_format = PIXEL_FORMAT_YVU_PLANAR_420;
chn_attr.buffer_num = VICAP_MAX_FRAME_COUNT;//at least 3 buffers for isp
chn_attr.buffer_size = VICAP_ALIGN_UP((ISP_CHN0_WIDTH * ISP_CHN0_HEIGHT * 3 / 2), VICAP_ALIGN_1K);
vicap_chn = VICAP_CHN_ID_0;

// printf("sample_vicap ...kd_mpi_vicap_set_chn_attr, buffer_size[%d]\n", chn_attr.buffer_size);
ret = kd_mpi_vicap_set_chn_attr(vicap_dev, vicap_chn, chn_attr);
if (ret) {
    printf("sample_vicap, kd_mpi_vicap_set_chn_attr failed.\n");
    return ret;
}

//set chn1 output rgb888p
chn_attr.out_win.h_start = 0;
chn_attr.out_win.v_start = 0;
chn_attr.out_win.width = ISP_CHN1_WIDTH ;
chn_attr.out_win.height = ISP_CHN1_HEIGHT;

chn_attr.crop_win = dev_attr.acq_win;
chn_attr.scale_win = chn_attr.out_win;
chn_attr.crop_enable = K_FALSE;
chn_attr.scale_enable = K_FALSE;
// chn_attr.dw_enable = K_FALSE;
chn_attr.chn_enable = K_TRUE;
chn_attr.pix_format = PIXEL_FORMAT_RGB_888_PLANAR;
chn_attr.buffer_num = VICAP_MAX_FRAME_COUNT;//at least 3 buffers for isp
chn_attr.buffer_size = VICAP_ALIGN_UP((ISP_CHN1_HEIGHT * ISP_CHN1_WIDTH * 3 ), VICAP_ALIGN_1K);
vicap_chn = VICAP_CHN_ID_1;
// printf("sample_vicap ...kd_mpi_vicap_set_chn_attr, buffer_size[%d]\n", chn_attr.buffer_size);
ret = kd_mpi_vicap_set_chn_attr(vicap_dev, VICAP_CHN_ID_1, chn_attr);
if (ret) {
    printf("sample_vicap, kd_mpi_vicap_set_chn_attr failed.\n");
    return ret;
}
//set chn2 venc yuv420sp
// chn_attr.out_win = dev_attr.acq_win;
// chn_attr.crop_win = chn_attr.out_win;
chn_attr.out_win.h_start = 0;
chn_attr.out_win.v_start = 0;
chn_attr.out_win.width =  VICAP_ALIGN_UP(ISP_CHN2_WIDTH, 16);
chn_attr.out_win.height = ISP_CHN2_HEIGHT;
chn_attr.crop_win = dev_attr.acq_win;
chn_attr.scale_win = chn_attr.out_win;
chn_attr.crop_enable = K_FALSE;
chn_attr.scale_enable = K_FALSE;
// chn_attr.dw_enable = K_FALSE;
chn_attr.chn_enable = K_TRUE;
chn_attr.pix_format = PIXEL_FORMAT_YUV_SEMIPLANAR_420;
chn_attr.buffer_num = 8;//at least 3 buffers for isp
chn_attr.alignment = 12;
chn_attr.buffer_size = VICAP_ALIGN_UP(VICAP_ALIGN_UP(ISP_CHN2_WIDTH, 16) * ISP_CHN2_HEIGHT * 3 / 2, 0x1000);
vicap_chn = VICAP_CHN_ID_2;
vicap_chn_venc=VICAP_CHN_ID_2;
// printf("sample_vicap ...kd_mpi_vicap_set_chn_attr, buffer_size[%d]\n", chn_attr.buffer_size);
ret = kd_mpi_vicap_set_chn_attr(vicap_dev, vicap_chn, chn_attr);
if (ret) {
    printf("sample_vicap, kd_mpi_vicap_set_chn_attr failed.\n");
    return ret;
}
vicap_chn=VICAP_CHN_ID_0;//用于vo
// set to header file database parse mode
ret = kd_mpi_vicap_set_database_parse_mode(vicap_dev, VICAP_DATABASE_PARSE_XML_JSON);
if (ret) {
    printf("sample_vicap, kd_mpi_vicap_set_database_parse_mode failed.\n");
    return ret;
}

// printf("sample_vicap ...kd_mpi_vicap_init\n");
ret = kd_mpi_vicap_init(vicap_dev);
if (ret) {
    printf("sample_vicap, kd_mpi_vicap_init failed.\n");
    return ret;
}
ret = kd_mpi_vicap_start_stream(vicap_dev);
if (ret) {
    printf("sample_vicap, kd_mpi_vicap_start_stream failed.\n");
    return ret;
}
return ret;

}
k_s32 kd_sample_venc_init(void)
{
venc_chn=0;
printf("kd_mpi_venc_init start %d\n", venc_chn);
k_venc_chn_attr venc_attr;
k_s32 ret;
k_u64 stream_size = ISP_CHN1_WIDTH ISP_CHN2_HEIGHT / 2;
venc_attr.venc_attr.pic_width = ISP_CHN2_WIDTH;
venc_attr.venc_attr.pic_height = ISP_CHN2_HEIGHT;
venc_attr.venc_attr.stream_buf_size = ((stream_size + 0xfff) & ~0xfff);
venc_attr.venc_attr.stream_buf_cnt = 30;
venc_attr.rc_attr.rc_mode = K_VENC_RC_MODE_CBR;
venc_attr.rc_attr.cbr.src_frame_rate = 30;
venc_attr.rc_attr.cbr.dst_frame_rate = 30;
venc_attr.rc_attr.cbr.bit_rate =4000;
venc_attr.venc_attr.type = K_PT_H265;
venc_attr.venc_attr.profile = VENC_PROFILE_H265_MAIN;
printf("venc[%d] %d
%d size:%d cnt:%d srcfps:%d dstfps:%d rate:%d rc_mode:%d type:%d profile:%d\n", venc_chn,
venc_attr.venc_attr.pic_width,
venc_attr.venc_attr.pic_height,
venc_attr.venc_attr.stream_buf_size,
venc_attr.venc_attr.stream_buf_cnt,
venc_attr.rc_attr.cbr.src_frame_rate,
venc_attr.rc_attr.cbr.dst_frame_rate,
venc_attr.rc_attr.cbr.bit_rate,
(int)venc_attr.rc_attr.rc_mode,
(int)venc_attr.venc_attr.type,
(int)venc_attr.venc_attr.profile);

ret = kd_mpi_venc_create_chn(venc_chn, &venc_attr);
if (ret != K_SUCCESS)
{
    printf("kd_mpi_venc_create_chn failed:0x%x\n", ret);
    return K_FAILED;
}

printf("kd_mpi_venc_init end \n");
return K_SUCCESS;

}
k_mp4_codec_id_e _get_mp4_codec_type(KdMediaVideoType video_type)
{
if (video_type == KdMediaVideoType::kVideoTypeH265)
{
return K_MP4_CODEC_ID_H265;
}
else if (video_type == KdMediaVideoType::kVideoTypeH264)
{
return K_MP4_CODEC_ID_H264;
}

    return K_MP4_CODEC_ID_H265;

}

class MyMp4muxer
{
public:
MyMp4muxer() {}

void OnVEncData(k_u32 chn_id, void *data, size_t size, k_venc_pack_type type, uint64_t first_time_stamp)
{
std::unique_lock lck(frame_muxer_mutex_);
if (first_frame_time_stamp_ == 0)
{
first_frame_time_stamp_ = first_time_stamp;
}
if (app_run)
{
if (video_stream_count_ % 30 == 0)
printf("recv count:%d, chn:%d, len:%d\n", video_stream_count_, 0, size);

    k_mp4_frame_data_s frame_data;
    memset(&frame_data, 0, sizeof(frame_data));
    frame_data.codec_id = _get_mp4_codec_type(KdMediaVideoType::kVideoTypeH265);
    frame_data.data =  (uint8_t *)data;
    frame_data.data_length = size;
    frame_data.time_stamp = first_time_stamp - first_frame_time_stamp_;

    if (!get_idr_) {
        memcpy(save_idr_ + save_size_, frame_data.data, frame_data.data_length);
        save_size_ += frame_data.data_length;
        first_time_stamp_ = first_time_stamp - first_frame_time_stamp_;
    }

    video_stream_count_++;
    if (video_stream_count_ == 2) {
        get_idr_ = 1;
        memset(&frame_data, 0, sizeof(frame_data));
        frame_data.codec_id = _get_mp4_codec_type(KdMediaVideoType::kVideoTypeH265);
        frame_data.data =  save_idr_;
        frame_data.data_length = save_size_;
        frame_data.time_stamp = first_time_stamp_;
    }

    if (get_idr_) {
        k_u32 ret = kd_mp4_write_frame(mp4_muxer_, video_track_handle_, &frame_data);
        if (ret < 0) {
            printf("mp4 write video frame failed.\n");
            return ;
        }
    }

    }
}

k_s32 kd_sample_get_venc_stream(void)
{
k_s32 ret = 0;
k_venc_stream output;
k_venc_chn_status status;
k_u8 *pData;
kd_mpi_venc_start_chn(venc_chn);
while (app_run)
{
ret = kd_mpi_venc_query_status(venc_chn, &status);
if (status.cur_packs > 0)
output.pack_cnt = status.cur_packs;
else
output.pack_cnt = 1;
output.pack = (k_venc_pack *)malloc(sizeof(k_venc_pack) * output.pack_cnt);
ret = kd_mpi_venc_get_stream(venc_chn, &output,-1);
for (int i = 0; i < output.pack_cnt; i++)
{
pData = (k_u8 *)kd_mpi_sys_mmap(output.pack[i].phys_addr, output.pack[i].len);
if (pData == NULL) {
printf("venC mmap failed!\n");
continue;
}
OnVEncData(venc_chn, pData, output.pack[i].len, output.pack[i].type, output.pack[i].pts);
// printf("=====vend data size:%d\n",output.pack[i].len);

        kd_mpi_sys_munmap(pData, output.pack[i].len);
    }

    ret = kd_mpi_venc_release_stream(venc_chn, &output);

    free(output.pack);
}
kd_mpi_venc_stop_chn(venc_chn);
printf("error:%016x",kd_mpi_venc_destroy_chn(venc_chn));
return ret;

}
int Init(const KdMediaInputConfig &config)
{
mp4_muxer_init(config);

    return 0;
}
int DeInit()
{
    Stop();
printf("2222222222\n");
    mp4_muxer_deinit();
    return 0;
}

int Start()
{
    if (app_run)
    kd_sample_get_venc_stream();
    app_run = true;
    printf("11111\n");
    return 0;
}
int Stop()
{
    if (!app_run)
        return 0;
}

protected:
int mp4_muxer_init(const KdMediaInputConfig &config)
{
printf("mp4 config audio channel:%d,samplerate:%d\n",config.audio_channel_cnt,config.audio_samplerate);

    config_ = config;
    k_s32 ret;
    k_mp4_config_s mp4_config;
    memset(&mp4_config, 0, sizeof(mp4_config));
    mp4_config.config_type = K_MP4_CONFIG_MUXER;
    strcpy(mp4_config.muxer_config.file_name, "/sharefs/video_tmp/test.mp4");
    mp4_config.muxer_config.fmp4_flag = 0;

    ret = kd_mp4_create(&mp4_muxer_, &mp4_config);
    if (ret < 0)
    {
        printf("mp4 muxer create failed.\n");
        return -1;
    }

    // create video track
    k_mp4_track_info_s video_track_info;
    memset(&video_track_info, 0, sizeof(video_track_info));
    video_track_info.track_type = K_MP4_STREAM_VIDEO;
    video_track_info.time_scale = 1000;
    video_track_info.video_info.width = config.venc_width;
    video_track_info.video_info.height = config.venc_height;
    ret = kd_mp4_create_track(mp4_muxer_, &video_track_handle_, &video_track_info);
    if (ret < 0)
    {
        printf("create video track failed.\n");
        return -1;
    }

    if (ret < 0)
    {
        printf("create video track failed.\n");
        return -1;
    }
    first_save_idr_frame_ = false;
    video_header_len_ = 0;

    return 0;
}

int mp4_muxer_deinit()
{
    k_s32 ret;
    ret = kd_mp4_destroy_tracks(mp4_muxer_);
    if (ret < 0)
    {
        printf("destroy mp4 tracks failed.\n");
        return -1;
    }

    ret = kd_mp4_destroy(mp4_muxer_);
    if (ret < 0)
    {
        printf("destroy mp4 failed.\n");
        return -1;
    }

    return 0;
}

k_mp4_codec_id_e _get_mp4_codec_type(KdMediaVideoType video_type)
{
    if (video_type == KdMediaVideoType::kVideoTypeH265)
    {
        return K_MP4_CODEC_ID_H265;
    }
    else if (video_type == KdMediaVideoType::kVideoTypeH264)
    {
        return K_MP4_CODEC_ID_H264;
    }

    return K_MP4_CODEC_ID_H265;
}

private:
KD_HANDLE mp4_muxer_{NULL};
KD_HANDLE video_track_handle_{NULL};
KD_HANDLE audio_track_handle_{NULL};
std::string stream_url_;
std::atomic first_save_idr_frame_{false};
KdMediaInputConfig config_;
uint8_t save_idr_[1920 * 1080 * 3 / 2];
uint32_t video_header_len_{0};
pthread_t mp4_th;
uint32_t video_stream_count_{0};
};

static void *exit_app(void arg)
{
printf("press 'q' to exit application!!\n");
while(getchar() != 'q')
{
usleep(10000);
}
app_run = false;
return NULL;
}
void * thread_for_mp4(void
)
{
KdMediaInputConfig config = {
.video_valid = true,
.sensor_type = OV_OV5647_MIPI_CSI2_1920X1080_30FPS_10BIT_LINEAR_V2,
.sensor_num = 1,
.video_type = KdMediaVideoType::kVideoTypeH265,
.venc_width = 1280,
.venc_height = 720,
.bitrate_kbps = 4000,

    .audio_samplerate = 8000,
    .audio_channel_cnt = 2,
    .pitch_shift_semitones = 0};

MyMp4muxer *mp4muxer = new MyMp4muxer();
if (!mp4muxer || mp4muxer->Init(config) < 0)
{
std::cout << "mp4muxer Init failed." << std::endl;
return nullptr;
}
mp4muxer->Start();
printf("11111\n");
mp4muxer->DeInit();
printf("22222\n");
return nullptr;
}
static k_bool s_bStopSend = K_FALSE;

void * mthread_receive(void ptr);
void * mthread_sender(void * arg);
void handle_message(k_s32 s32Id, k_ipcmsg_message_t
pstMsg);
typedef struct
{
k_s32 id;
k_char name[sizeof("big35_out_two")];
void (handle)(k_s32 s32Id, k_ipcmsg_message_t pstMsg);
}Message;
void handle_message(k_s32 s32Id, k_ipcmsg_message_t* pstMsg);
Message m={0,"big35_out_two",handle_message};
int main(int argc, char *argv[])
{
/Allow one frame time for the VO to release the VB block/
k_u32 display_ms = 1000 / 33;
int car_count = 1;
k_vo_draw_frame frame{false,0,0,0,0,0};
Model model("car_d.kmodel","/sharefs/car_d.kmodel");
pthread_t p;
char cmd[64];
get_idr_=false;
video_stream_count_=0;
video_first_time_stamp_=0;
first_time_stamp_=0;
start_get_video_stream_=false;
first_frame_time_stamp_=0;
save_size_=0;

//单核通信服务
k_ipcmsg_connect_t  pstConnectAttr;
pstConnectAttr.u32RemoteId = 0;
pstConnectAttr.u32Port = 202;
pstConnectAttr.u32Priority = 1;
//kd_ipcmsg_add_service(m.name, &pstConnectAttr);
//pthread_create(&p,nullptr,mthread_receive,&m);

int num = 0;
int ret;
PRINT_TIME_NOW();

/ixed operation for ctrl+c***/
struct sigaction sa;
memset( &sa, 0, sizeof(sa) );
sa.sa_handler = fun_sig;
sigfillset(&sa.sa_mask);
sigaction(SIGINT, &sa, NULL);

pthread_t vo_thread_handle;
pthread_t exit_thread_handle;
pthread_t mp4_th;
pthread_create(&exit_thread_handle, NULL, exit_app, NULL);
size_t size = CHANNEL * ISP_CHN1_HEIGHT * ISP_CHN1_WIDTH;

TEST_BOOT_TIME_INIT();

TEST_TIME(ret = sample_vb_init(), "sample_vb_init");
if(ret) {
    goto vb_init_error;
}

pthread_create(&vo_thread_handle, NULL, sample_vo_thread, NULL);
kd_sample_venc_init();//venc
TEST_TIME(ret = sample_vivcap_init(),"sample_vicap_init");
pthread_join(vo_thread_handle, NULL);
pthread_create(&mp4_th, NULL, thread_for_mp4, NULL);
if(ret) {
    goto vicap_init_error;
}
TEST_BOOT_TIME_TRIGER();



while(app_run)
{
    memset(&dump_info, 0 , sizeof(k_video_frame_info));
    ret = kd_mpi_vicap_dump_frame(vicap_dev, VICAP_CHN_ID_1, VICAP_DUMP_RGB, &dump_info, 1000);
    if (ret) {
        quit.store(false);
        printf("sample_vicap...kd_mpi_vicap_dump_frame failed.\n");
        break;
    }
printf("size:%d\n",size);
auto vbvaddr = kd_mpi_sys_mmap(dump_info.v_frame.phys_addr[0], size);
    // memcpy(vaddr, (void *)vbvaddr, ISP_CHN1_HEIGHT * ISP_CHN1_WIDTH * 3);
    // run kpu
    TEST_BOOT_TIME_TRIGER();
car_count=model.run(reinterpret_cast<uintptr_t>(vbvaddr), reinterpret_cast<uintptr_t>(dump_info.v_frame.phys_addr[0]));

    kd_mpi_sys_munmap(vbvaddr, size);
   

    ret = kd_mpi_vicap_dump_release(vicap_dev, VICAP_CHN_ID_1, &dump_info);
    if (ret) {
        printf("sample_vicap...kd_mpi_vicap_dump_release failed.\n");
    }
}

app_exit:
pthread_join(exit_thread_handle, NULL);
pthread_join(mp4_th,NULL);
ret = kd_mpi_vicap_stop_stream(vicap_dev);
if (ret) {
printf("sample_vicap, stop stream failed.\n");
}
ret = kd_mpi_vicap_deinit(vicap_dev);
if (ret) {
printf("sample_vicap, kd_mpi_vicap_deinit failed.\n");
return ret;
}
vicap_init_error:
printf("vicap init error.\n");
kd_mpi_vo_disable_video_layer(K_VO_LAYER1);

k_mpp_chn vicap_mpp_chn;
k_mpp_chn vicap_mpp_chn_venc;
k_mpp_chn vo_mpp_chn;
k_mpp_chn venc_mpp_chn;
vicap_mpp_chn.mod_id = K_ID_VI;
vicap_mpp_chn.dev_id = vicap_dev;
vicap_mpp_chn.chn_id = vicap_chn;
vicap_mpp_chn_venc.mod_id = K_ID_VI;
vicap_mpp_chn_venc.dev_id = vicap_dev;
vicap_mpp_chn_venc.chn_id = vicap_chn_venc;

vo_mpp_chn.mod_id = K_ID_VO;
vo_mpp_chn.dev_id = K_VO_DISPLAY_DEV_ID;
vo_mpp_chn.chn_id = K_VO_DISPLAY_CHN_ID1;
venc_mpp_chn.mod_id=K_ID_VENC;
venc_mpp_chn.dev_id=0;
venc_mpp_chn.chn_id=venc_chn;
sample_vicap_unbind(vicap_mpp_chn,vicap_mpp_chn_venc, vo_mpp_chn,venc_mpp_chn);
usleep(1000 * display_ms);

ret = kd_mpi_vb_exit();
if (ret) {
    printf("fastboot_app, kd_mpi_vb_exit failed.\n");
    return ret;
}

vb_init_error:
return 0;
}

void * mthread_receive(void ptr)
{
pthread_t p;
int number=0;
Message
m_ptr = (Message*)ptr;
Message m=*m_ptr;
printf("Ipcmsg try connect.\nTime 51.\n");

for (int n=0;n<5;n++)
    {
            if((number=kd_ipcmsg_try_connect(&m.id, m.name,m.handle))!=0)
            {
                    printf("Connect fail.\nNumber:%d",number);
                    if(n==4)
                    {
                            printf("Stop connecting.\n");
                            exit(0);
                    }
                    usleep(500000);//等待500ms
                    printf("Reconnecting...\n");
            }
	else
		break;
    }
    printf("Ipcmsg %s connect.\nIpcmsg %s run.\n",m.name,m.name);

pthread_create(&p,nullptr,mthread_sender,&m);

kd_ipcmsg_run(m.id);
	
s_bStopSend=K_TRUE;

pthread_cancel(p);
pthread_join(p,nullptr);

printf("Ipcmsg %s stop running.\n",m.name);
return nullptr;

}
void* mthread_sender(void ptr)
{
Message * m=(Message
)ptr;

k_s32 ps32Id = m->id;
k_u32  u32Cmd = 0;
static k_u32 s_u32Index = 0;
char content[16];

while (K_FALSE == s_bStopSend)
{
    	memset(content, 0, 16);
    	snprintf(content, 16, "only %u\n", s_u32Index++);
    	u32Cmd = (ps32Id << 24) | s_u32Index;
   		k_ipcmsg_message_t* pReq = kd_ipcmsg_create_message(SEND_ONLY_MODULE_ID, u32Cmd, content, 16);
    	printf("sendonly modle:%x cmd:%08x \n", 2, u32Cmd);
   		kd_ipcmsg_send_only(ps32Id, pReq);
    	kd_ipcmsg_destroy_message(pReq);

    	usleep(TIME_INTERVAL);
	}

	return nullptr;

}
void handle_message(k_s32 s32Id, k_ipcmsg_message_t* pstMsg)
{
k_s32 s32Ret = 0;
char content[64];

k_ipcmsg_message_t *respMsg = kd_ipcmsg_create_resp_message(pstMsg, s32Ret, content, 64);
kd_ipcmsg_send_async(s32Id, respMsg, NULL);
kd_ipcmsg_destroy_message(respMsg);

return;

}

硬件板卡


k230_canmv_v3

1 Answers

你好,先使用官网demo,先确定官网demo是否有问题。如没问题再对比排查。