请贴出编译日志。
awwwwa 发布的最佳帖子
-
回复: T113基于Longan在LVGL中如何播放视屏,通过tplayer发布在 GUI
static lv_style_t style_scr_act; if (style_scr_act.prop_cnt == 0) { lv_style_init(&style_scr_act); lv_style_set_bg_opa(&style_scr_act, LV_OPA_COVER); lv_obj_add_style(lv_scr_act(), &style_scr_act, 0); } lv_disp_get_default()->driver->screen_transp = 1; lv_disp_set_bg_opa(lv_disp_get_default(), LV_OPA_TRANSP); /* Empty the buffer, not emptying will cause the UI to be opaque */ lv_memset_00(lv_disp_get_default()->driver->draw_buf->buf_act, lv_disp_get_default()->driver->draw_buf->size * sizeof(lv_color32_t)); lv_style_set_bg_opa(&style_scr_act, LV_OPA_TRANSP); lv_obj_report_style_change(&style_scr_act);设置透明层
-
回复: V853使用MIPI CSI接口是否只支持RAW格式像素?发布在 V Series
@xjy_5 一般来说配置sensor0_isp_used = <0>; 就不会调用ISP,虽然会配置但是不会处理。需要再跟踪一下调用
-
回复: 求助 r128 dsp发布在 A Series
RI-2020.5-linux 编译器需要向购买开发板的商家/代理提交申请,需要提供自己的HIFI5 DSP Xtensa Xplorer的证明
-
回复: V853 SDK : PMU TWI发布在 V Series
@alb702 在 V853 SDK : PMU TWI 中说:
[267]ic cant match axp, please check...
V853 和 V853s 的芯片安全系统验证不一样,SDK不能通用,这行输出表示芯片型号验证失败,跳过初始化DRAM
-
回复: 测试编译不过发布在 V Series
-
helloworld_fel 使用了 VFP 寄存器参数,但是某个库文件(libgcc.a(_udivmoddi4.o))却不支持。
-
缺少 .note.GNU-stack 段,暗示可执行栈缺失。
-
对于具有 RWX 权限的 LOAD 段,给出了警告。
-
在链接时,出现了对 raise 函数的未定义引用。
-
-
回复: v853 vin通路配置发布在 V Series
(1)在线模式:四个vipp和dma实体,最大缩小比例为16*16,每路最多可支持16个orl
(2)离线模式:每个vipp和dma可分时复用为4个vipp和dma虚拟体,四个vipp和dma实体相互独立,在线模式和离线模式开关也是相互独立的;
(3)VIPP和DAM的分时复用(离线模式)与isp和tdm的分时复用(离线模式)是绑定关系,即tdm和isp开启了离线模式,vipp和dma的输入端如果是isp,那么vipp和dma也需要开启离线模式;
(4)只有VIPP0和dma0实体支持VE在线编码,而vipp0在线,如果vipp00的输入端为isp,那么tdm和isp也只能配置在线模式,而isp在线,那么四个vipp和dma实体都只能配置在线模式;online 和 offline 配 置 方 式 在 board.dts , 所 以 需 要 在 对 应 版 型 的 board.dts 中 找 到 vind0 节 点 配 置 列 表 , 对 应 关 系 为 tdm 对 应 节 点 , isp 对 应 isp00 节 点 , vipp 对 应 scaler00 、 scaler10 、 scaler20 和 scaler30 节 点 , dma 对 , 应 vinc00 、 vinc10 、 vinc20 和 vinc30 节 点 。
- 在线模式,单路3输出

- 离线模式,2路8输出

-
回复: 請問大大誰有usb驅動程式能下載?发布在 爱搞机专区
@abc16883
下载工具:
AllwinnertechPhoeniSuitRelease20230905.zip下载驱动:
全志USB烧录驱动20201229 -
busybox init 简介发布在 Linux
一、简介
tina 使用busybox init方式启动,首先调用执行pseudo_init(挂载文件系统,如/proc、/tmp、/sys /etc、/usr),接着会调用/sbin/init进程,而init进程调用的第一个启动脚本为/etc/init.d/rcS。
二、平台的自定义
不同的平台文件系统具有其共性与特殊性。tina/packge/busybox-init-base-files/files下提供了所有平台的基础文件。而在tina/target/allwinner/XXX/busybox-init-base-files下存放的是平台特性文件,其优先级高于前者,即当前者目录和后者存在有相同文件时,以后者为准。如有以下两个文件:A:tina/target/allwinner/r11-R11_pref1/busybox-init-base-files/etc/banner
B:tina/package/busybox-init-base-files/files/etc/banner最终拷贝到文件系统中的为A。
三、pseudo_init与rcS
pseudo_init与rcS文件中存在很多平台共性的代码,避免系统充斥大量冗余代码,以及方便基础文件的维护和开发。所以不允许在特定平台下自定义pseudo_init、rcS文件(必须使用tina/packge/busybox-init-base-files/files下的pseudo_init、rcS)。
如果需要添加平台特定配置(pseudo_init,rcS没有配置),可将其写到rc.preboot,rc.final中,参考第四节。
四、rcS脚本
1.功能描述
(1)执行/etc/init.d/rc.preboot。
为了满足开机快速启动的需求,提供了用户可自定义rc.preboot文件,即在tina/target/allwinner/XXX/busybox-init-base-files/etc/init.d/目录下创建rc.preboot脚本文件,将会被rcS最先调用执行。
(2)配置打印级别,主机名称。
(3)执行/etc/init.d/rc.log,配置系统log信息。
系统默认使用的是tina/package/busybox-init-base-files/files/etc/init.d/rc.log脚本进行配置系统log信息。用户可在tina/target/allwinner/XXX/busybox-init-base-files/etc/init.d/下创建rc.log,自定义rc.log。
如果需要使用默认rc.log,需要在make menuconfig配置。Base system ---> busybox-init-base-files......................... Busybox init base system ---> [*] Use the rc.log(4)挂载UDISK。
(5)执行/etc/init.d/rc.modules,加载内核模块。
系统默认使用的是tina/package/busybox-init-base-files/files/etc/init.d/rc.modules脚本进行内核模块自加载,用户可在tina/target/allwinner/XXX/busybox-init-base-files/etc/init.d/下创建rc.modules,自定义rc.modules。
如果需要使用默认rc.modules,需要在make menuconfig配置如下。Base system ---> busybox-init-base-files......................... Busybox init base system ---> [*] Use the rc.modules(6)启动/etc/rc.d下的脚本。
关于执行rc.d下的启动脚本,目的为兼容procd式的应用脚本。/etc/rc.d下的脚本是链接到/etc/init.d/下,默认情况下只执行adbd,如果需要执行其他脚本,需要在tina/target/allwinner/XXX/busybox-init-base-files/etc/init.d/下,自定义load_script.conf文件,文件内容中写上要启动的应用,如adbd(注意,每一个应用占一行)。可参考:tina/packge/busybox-init-base-files/files/etc/init.d/load_script.conf。如果需要执行rc.d下的启动脚本,需要在make menuconfig做如下配置。 Base system ---> busybox-init-base-files......................... Busybox init base system ---> [*] Auto load the script in /etc/rc.d(7)ota初始化。
(8)执行/etc/init.d/rc.final,用户自定义启动脚本。
用户可在tina/packge/busybox-init-base-files/files/etc/init.d/下创建一个rc.final脚本,自定义启动应用程序,该脚本将会被rcS最后调用执行。2.rc.preboot与rc.final的区别?
rc.preboot比rc.final先运行,在执行rc.preboot脚本的时候,系统的一些初始化操作还没完成,如挂载UDISK、内核模块自加载、ota等等操作。而rc.final执行的时候,以上的初始化操作已经完成。五.如何写应用的启动脚本
example:开机自启动smartlinkd(tina/package/allwinner/smartlinkd/files/smartlinkd.init)
1.方法一(特定格式要求)详细的格式参考:
https://wiki.openwrt.org/inbox/procd-init-scripts
https://wiki.openwrt.org/doc/techref/initscripts(1)procd式
#!/bin/sh /etc/rc.common #本质为script脚本,以#!开头, 之后执行/etc/rc.common START=98 #开机启动优先级(序列) [数值越小, 越先启动] STOP=98 #关机停止优先级(序列) [数值越小, 越先关闭] USE_PROCD=1 PROG=smartlinkd start_service() { #启动函数 procd_open_instance procd_set_param command $PROG -d procd_close_instance } shutdown() { echo shutdown }(2)Sys式
#!/bin/sh /etc/rc.common START=98 STOP=98 PROG=smartlinkd start() { smartlinkd -d & }使用上述procd式和sys式脚本,既能兼容procd init启动和busybox init的启动方式。
另外如果使用的是busybox init的启动方式,还需要在load_script.conf文件中换行添加内容:smartlinkd2.方法二(无特定格式要求)
创建rc.preboot或者rc.final脚本,添加启动smartlinkd的内容。 -
T113 busybox init 配置 overlayfs 为 UDISK 分区而不是 rootfs_data发布在 Linux
- 先确定挂载overlayfs
查看 pseudo_init 中 MOUNT_OVERLAY 是不是 1,如果不是配置为 1
package/busybox-init-base-files/files/pseudo_init
- 修改挂载分区
找到文件末尾,吧 rootfs_data 改成UDISK

-
回复: V851S tina linux ov5647 驱动程序没有 dmesg发布在 V Series
使用 V3s SDK 提供VFE框架的驱动移植到VIN框架下抓图成功。但是图像非常暗,并且撕裂,抓raw数据查看也是一样,考虑可能mclk不同步导致。
sensor0:sensor@0 { device_type = "sensor0"; sensor0_mname = "ov5648_mipi"; sensor0_twi_cci_id = <0>; sensor0_twi_addr = <0x6c>; sensor0_mclk_id = <0>; sensor0_pos = "rear"; sensor0_isp_used = <1>; sensor0_fmt = <1>; sensor0_stby_mode = <0>; sensor0_vflip = <0>; sensor0_hflip = <0>; sensor0_iovdd-supply = <>; sensor0_iovdd_vol = <1800000>; sensor0_avdd-supply = <>; sensor0_avdd_vol = <2800000>; sensor0_dvdd-supply = <>; sensor0_dvdd_vol = <1200000>; sensor0_power_en = <>; sensor0_reset = <&pio PA 18 1 0 1 0>; sensor0_pwdn = <&pio PA 19 1 0 1 0>; sensor0_sm_hs = <>; sensor0_sm_vs = <>; flash_handle = <>; act_handle = <>; status = "okay"; };/* * A V4L2 driver for ov5647 Raw cameras. * * Copyright (c) 2022 by YuzukiTsuru <gloomyghost@gloomyghost.com> * Copyright (c) 2018 by Allwinnertech Co., Ltd. http://www.allwinnertech.com * * Authors: Zheng ZeQun <zequnzheng@allwinnertech.com> * Liang WeiJie <liangweijie@allwinnertech.com> * YuzukiTsuru <gloomyghost@gloomyghost.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include <linux/init.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/i2c.h> #include <linux/delay.h> #include <linux/videodev2.h> #include <linux/clk.h> #include <media/v4l2-device.h> #include <media/v4l2-mediabus.h> #include <linux/io.h> #include "camera.h" #include "sensor_helper.h" MODULE_AUTHOR("YuzukiTsuru"); MODULE_DESCRIPTION("A low-level driver for ov5647 sensors"); MODULE_LICENSE("GPL"); #define MCLK (24*1000*1000) #define V4L2_IDENT_SENSOR 0x5648 /* * Our nominal (default) frame rate. */ #define SENSOR_FRAME_RATE 30 /* * The GC0310 i2c address */ #define I2C_ADDR 0x6c #define SENSOR_NAME "ov5648_mipi" /* * The default register settings */ static struct regval_list sensor_default_regs[] = { //Slave_ID=0x6c; {0x0100, 0x00},// ; software standby {0x0103, 0x01},// ; software reset {REG_DLY, 0x25}, {0x370c, 0x03},// ; analog control {0x5000, 0x06},// ; lens off, bpc on, wpc on {0x5003, 0x08},// ; buf_en {0x5a00, 0x08},// {0x3000, 0xff},// ; D[9:8] output {0x3001, 0xff},// ; D[7:0] output {0x3002, 0xff},// ; Vsync, Href, PCLK, Frex, Strobe, SDA, GPIO1, GPIO0 output {0x301d, 0xf0},// {0x3a18, 0x00},// ; gain ceiling = 15.5x {0x3a19, 0xf8},// ; gain ceiling {0x3c01, 0x80},// ; band detection manual mode {0x3b07, 0x0c},// ; strobe frex mode //; analog control {0x3630, 0x2e}, {0x3632, 0xe2}, {0x3633, 0x23}, {0x3634, 0x44}, {0x3620, 0x64}, {0x3621, 0xe0}, {0x3600, 0x37}, {0x3704, 0xa0}, {0x3703, 0x5a}, {0x3715, 0x78}, {0x3717, 0x01}, {0x3731, 0x02}, {0x370b, 0x60}, {0x3705, 0x1a}, {0x3f05, 0x02}, {0x3f06, 0x10}, {0x3f01, 0x0a}, //; AG/AE target {0x3a0f, 0x58},// ; stable in high {0x3a10, 0x50},// ; stable in low {0x3a1b, 0x58},// ; stable out high {0x3a1e, 0x50},// ; stable out low {0x3a11, 0x60},// ; fast zone high {0x3a1f, 0x28},// ; fast zone low {0x4001, 0x02},// ; BLC start line {0x4000, 0x09},// ; BLC enable {0x3000, 0x00},// ; D[9:8] input {0x3001, 0x00},// ; D[7:0] input {0x3002, 0x00},// ; Vsync, Href, PCLK, Frex, Strobe, SDA, GPIO1, GPIO0 input {0x3017, 0xe0},// ; MIPI PHY {0x301c, 0xfc},// {0x3636, 0x06},// ; analog control {0x3016, 0x08},// ; MIPI pad enable {0x3827, 0xec},// {0x3018, 0x44},// ; MIPI 2 lane, MIPI enable {0x3035, 0x21},// ; PLL {0x3106, 0xf5},// ; PLL {0x3034, 0x1a},// ; PLL {0x301c, 0xf8},// {0x3503, 0x03},// ; Gain has no latch delay, AGC manual, AEC {0x3501, 0x10},// ; exposure[15:8] {0x3502, 0x80},// ; exposure[7:0] {0x350a, 0x00},// ; gain[9:8] {0x350b, 0x7f},// ; gain[7:0] {0x5001, 0x01},// ; AWB on {0x5180, 0x08},// ; AWB manual gain enable {0x5186, 0x04},// ; manual red gain high {0x5187, 0x00},// ; manual red gain low {0x5188, 0x04},// ; manual green gain high {0x5189, 0x00},// ; manual green gain low {0x518a, 0x04},// ; manual blue gain high {0x518b, 0x00},// ; manual blue gain low {0x5000, 0x06},// ; lenc off, bpc on, wpc on }; static struct regval_list sensor_qsxga_regs[] = { //qsxga: 2592*1936@15fps {0x0100, 0x00},// ; software standby {0x3035, 0x21},// ; PLL {0x3036, 0x66},// ; PLL {0x303c, 0x11},// ; PLL {0x3821, 0x06},// ; ISP mirror on, Sensor mirror on {0x3820, 0x00},// ; ISP flip off, Sensor flip off {0x3612, 0x5b},// ; analog control {0x3618, 0x04},// ; analog control {0x380c, 0x0a},// ; HTS = 2752 {0x380d, 0xc0},// ; HTS {0x380e, 0x07},// ; VTS = 1974 {0x380f, 0xb6},// ; VTS {0x3814, 0x11},// ; X INC {0x3815, 0x11},// ; X INC {0x3708, 0x64},// ; analog control {0x3709, 0x12},// ; analog control {0x3808, 0x0a},// ; X OUTPUT SIZE = 2592 {0x3809, 0x20},// ; X OUTPUT SIZE {0x380a, 0x07},// ; Y OUTPUT SIZE = 1944 {0x380b, 0x98},// ; Y OUTPUT SIZE {0x3800, 0x00},// ; X Start {0x3801, 0x0c},// ; X Start {0x3802, 0x00},// ; Y Start {0x3803, 0x02},// ; Y Start {0x3804, 0x0a},// ; X End {0x3805, 0x33},// ; X End {0x3806, 0x07},// ; Y End {0x3807, 0xa1},// ; Y End ///////////; Banding filter {0x3a08, 0x01},// ; B50 {0x3a09, 0x28},// ; B50 {0x3a0a, 0x00},// ; B60 {0x3a0b, 0xf6},// ; B60 {0x3a0d, 0x07},// ; B60 max {0x3a0e, 0x06},// ; B50 max {0x4004, 0x04},// ; black line number {0x4837, 0x19},// ; MIPI pclk period {0x0100, 0x01},// ; wake up from software standby }; static struct regval_list sensor_720p_regs[] = { //720: 1280*720@30fps {0x0100, 0x00},// ; software standby {0x3035, 0x21},// ; PLL {0x3036, 0x46},// ; PLL {0x303c, 0x11},// ; PLL {0x3821, 0x07},// ; ISP mirror on, Sensor mirror on, bin on {0x3820, 0x41},// ; ISP flip off, Sensor flip off, bin on {0x3612, 0x59},// ; analog control {0x3618, 0x00},// ; analog control {0x380c, 0x07},// ; HTS = 1896 {0x380d, 0x68},// ; HTS {0x380e, 0x03},// ; VTS = 984 {0x380f, 0xd8},// ; VTS {0x3814, 0x31},// ; X INC {0x3815, 0x31},// ; Y INC {0x3708, 0x64},// ; analog control {0x3709, 0x52},// ; analog control {0x3808, 0x05},// ; X OUTPUT SIZE = 1280 {0x3809, 0x00},// ; X OUTPUT SIZE {0x380a, 0x03},// ; Y OUTPUT SIZE = 960 {0x380b, 0xc0},// ; Y OUTPUT SIZE {0x3800, 0x00},// ; X Start {0x3801, 0x18},// ; X Start {0x3802, 0x00},// ; Y Start {0x3803, 0x0e},// ; Y Start {0x3804, 0x0a},// ; X End {0x3805, 0x27},// ; X End {0x3806, 0x07},// ; Y End {0x3807, 0x95},// ; Y End // banding filter {0x3a08, 0x01},// ; B50 {0x3a09, 0x27},// ; B50 {0x3a0a, 0x00},// ; B60 {0x3a0b, 0xf6},// ; B60 {0x3a0d, 0x04},// ; B50 max {0x3a0e, 0x03},// ; B60 max {0x4004, 0x02},// ; black line number {0x4837, 0x24},// ; MIPI pclk period {0x0100, 0x01},// ; wake up from software standby }; static struct regval_list sensor_fmt_raw[] = { }; /* * Code for dealing with controls. * fill with different sensor module * different sensor module has different settings here * if not support the follow function ,retrun -EINVAL */ static int sensor_g_exp(struct v4l2_subdev *sd, __s32 *value) { struct sensor_info *info = to_state(sd); *value = info->exp; sensor_print("sensor_get_exposure = %d\n", info->exp); return 0; } static int sensor_s_exp(struct v4l2_subdev *sd, unsigned int exp_val) { unsigned char explow, expmid, exphigh; struct sensor_info *info = to_state(sd); if(exp_val>0xfffff) exp_val=0xfffff; sensor_write(sd, 0x3208, 0x00);//enter group write sensor_write(sd, 0x3503, 0x13); exphigh = (unsigned char) ( (0x0f0000&exp_val)>>16); expmid = (unsigned char) ( (0x00ff00&exp_val)>>8); explow = (unsigned char) ( (0x0000ff&exp_val) ); //sensor_write(sd, 0x3208, 0x00);//enter group write sensor_write(sd, 0x3502, explow); sensor_write(sd, 0x3501, expmid); sensor_write(sd, 0x3500, exphigh); sensor_write(sd, 0x3208, 0x10);//end group write sensor_write(sd, 0x3208, 0xa0);//init group write sensor_print("ov5647_mipi sensor_set_exp = %d, Done!\n", exp_val); info->exp = exp_val; return 0; } static int sensor_g_gain(struct v4l2_subdev *sd, __s32 *value) { struct sensor_info *info = to_state(sd); *value = info->gain; sensor_print("sensor_get_gain = %d\n", info->gain); return 0; } static int sensor_s_gain(struct v4l2_subdev *sd, unsigned int gain_val) { struct sensor_info *info = to_state(sd); unsigned char gainlow=0; unsigned char gainhigh=0; if(gain_val<1*16) gain_val=16; if(gain_val>64*16-1) gain_val=64*16-1; gainlow=(unsigned char)(gain_val&0xff); gainhigh=(unsigned char)((gain_val>>8)&0x3); sensor_write(sd, 0x3208, 0x00);//enter group write sensor_write(sd, 0x3503, 0x13); sensor_write(sd, 0x350b, gainlow); sensor_write(sd, 0x350a, gainhigh); sensor_write(sd, 0x3208, 0x10);//end group write sensor_write(sd, 0x3208, 0xa0);//init group write //printk("ov5647_mipi sensor_set_gain = %d, Done!\n", gain_val); info->gain = gain_val; return 0; } static int ov5648_sensor_vts; static int sensor_s_exp_gain(struct v4l2_subdev *sd, struct sensor_exp_gain *exp_gain) { int exp_val, gain_val,frame_length,shutter; unsigned char explow=0,expmid=0,exphigh=0; unsigned char gainlow=0,gainhigh=0; struct sensor_info *info = to_state(sd); exp_val = exp_gain->exp_val; gain_val = exp_gain->gain_val; if(gain_val<1*16) gain_val=16; if(gain_val>64*16-1) gain_val=64*16-1; if(exp_val>0xfffff) exp_val=0xfffff; gainlow=(unsigned char)(gain_val&0xff); gainhigh=(unsigned char)((gain_val>>8)&0x3); exphigh = (unsigned char) ( (0x0f0000&exp_val)>>16); expmid = (unsigned char) ( (0x00ff00&exp_val)>>8); explow = (unsigned char) ( (0x0000ff&exp_val) ); shutter = exp_val/16; sensor_print("ov5648_sensor_vts = %d\n",ov5648_sensor_vts); if(shutter > ov5648_sensor_vts- 4) frame_length = shutter + 4; else frame_length = ov5648_sensor_vts; sensor_write(sd, 0x3503, 0x07); sensor_write(sd, 0x380f, (frame_length & 0xff)); sensor_write(sd, 0x380e, (frame_length >> 8)); sensor_print("exp_val = %d,gain_val = %d\n",exp_val,gain_val); sensor_write(sd, 0x3208, 0x00);//enter group write sensor_write(sd, 0x350b, gainlow); sensor_write(sd, 0x350a, gainhigh); sensor_write(sd, 0x3502, explow); sensor_write(sd, 0x3501, expmid); sensor_write(sd, 0x3500, exphigh); sensor_write(sd, 0x3208, 0x10);//end group write sensor_write(sd, 0x3208, 0xa0);//init group write info->exp = exp_val; info->gain = gain_val; return 0; } static void sensor_s_sw_stby(struct v4l2_subdev *sd, int on_off) { int ret = 0; return ret; } /* * Stuff that knows about the sensor. */ static int sensor_power(struct v4l2_subdev *sd, int on) { int ret = 0; sensor_print("ov5648 sensor_power\n"); switch (on) { case STBY_ON: sensor_print("STBY_ON!\n"); cci_lock(sd); sensor_s_sw_stby(sd, STBY_ON); usleep_range(1000, 1200); cci_unlock(sd); break; case STBY_OFF: sensor_print("STBY_OFF!\n"); cci_lock(sd); usleep_range(1000, 1200); sensor_s_sw_stby(sd, STBY_OFF); cci_unlock(sd); break; case PWR_ON: sensor_print("PWR_ON!100\n"); cci_lock(sd); vin_gpio_set_status(sd, PWDN, 1); vin_gpio_write(sd, RESET, CSI_GPIO_HIGH); vin_gpio_set_status(sd, POWER_EN, 1); vin_gpio_write(sd, PWDN, CSI_GPIO_LOW); vin_gpio_write(sd, RESET, CSI_GPIO_LOW); vin_gpio_write(sd, POWER_EN, CSI_GPIO_HIGH); usleep_range(7000, 8000); vin_set_pmu_channel(sd, IOVDD, ON); usleep_range(7000, 8000); vin_set_pmu_channel(sd, AVDD, ON); vin_set_pmu_channel(sd, AFVDD, ON); usleep_range(7000, 8000); vin_set_pmu_channel(sd, DVDD, ON); usleep_range(7000, 8000); vin_set_mclk_freq(sd, MCLK); vin_set_mclk(sd, ON); usleep_range(10000, 12000); vin_gpio_write(sd, RESET, CSI_GPIO_HIGH); vin_gpio_write(sd, PWDN, CSI_GPIO_HIGH); vin_set_pmu_channel(sd, CAMERAVDD, ON);/*AFVCC ON*/ usleep_range(10000, 12000); cci_unlock(sd); break; case PWR_OFF: sensor_print("PWR_OFF!\n"); cci_lock(sd); vin_gpio_write(sd, PWDN, CSI_GPIO_HIGH); vin_gpio_write(sd, RESET, CSI_GPIO_HIGH); vin_set_mclk(sd, OFF); usleep_range(7000, 8000); vin_set_pmu_channel(sd, DVDD, OFF); vin_gpio_write(sd, PWDN, CSI_GPIO_LOW); vin_gpio_write(sd, RESET, CSI_GPIO_LOW); vin_gpio_write(sd, POWER_EN, CSI_GPIO_LOW); vin_set_pmu_channel(sd, AVDD, OFF); vin_set_pmu_channel(sd, IOVDD, OFF); vin_set_pmu_channel(sd, AFVDD, OFF); vin_set_pmu_channel(sd, CAMERAVDD, OFF);/*AFVCC ON*/ cci_unlock(sd); break; default: return -EINVAL; } return 0; } static int sensor_reset(struct v4l2_subdev *sd, u32 val) { switch (val) { case 0: vin_gpio_write(sd, RESET, CSI_GPIO_HIGH); usleep_range(10000,12000); break; case 1: vin_gpio_write(sd, RESET, CSI_GPIO_LOW); usleep_range(10000,12000); break; default: return -EINVAL; } return 0; } static int sensor_detect(struct v4l2_subdev *sd) { data_type rdval; unsigned int SENSOR_ID = 0; sensor_read(sd, 0x300A, &rdval); SENSOR_ID |= rdval; SENSOR_ID |= (rdval << 8); sensor_read(sd, 0x300B, &rdval); SENSOR_ID |= (rdval); sensor_print("V4L2_IDENT_SENSOR = 0x%x\n", SENSOR_ID); if (SENSOR_ID != V4L2_IDENT_SENSOR) { sensor_print("ov5648 %s error, chip found is not an target chip", __func__); //return -ENODEV; } return 0; } static int sensor_init(struct v4l2_subdev *sd, u32 val) { int ret; struct sensor_info *info = to_state(sd); sensor_print("sensor_init\n"); /*Make sure it is a target sensor */ ret = sensor_detect(sd); if (ret) { sensor_err("chip found is not an target chip.\n"); return ret; } info->focus_status = 0; info->low_speed = 0; info->width = QSXGA_WIDTH; info->height = QSXGA_HEIGHT; info->hflip = 0; info->vflip = 0; info->gain = 0; info->tpf.numerator = 1; info->tpf.denominator = 30; /* 30fps */ info->preview_first_flag = 1; return 0; } static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { int ret = 0; struct sensor_info *info = to_state(sd); switch (cmd) { case GET_CURRENT_WIN_CFG: if (info->current_wins != NULL) { memcpy(arg, info->current_wins, sizeof(struct sensor_win_size)); ret = 0; } else { sensor_err("empty wins!\n"); ret = -1; } break; case SET_FPS: ret = 0; break; case VIDIOC_VIN_SENSOR_EXP_GAIN: ret = sensor_s_exp_gain(sd, (struct sensor_exp_gain *)arg); break; case VIDIOC_VIN_SENSOR_CFG_REQ: sensor_cfg_req(sd, (struct sensor_config *)arg); break; case VIDIOC_VIN_ACT_INIT: ret = actuator_init(sd, (struct actuator_para *)arg); break; case VIDIOC_VIN_ACT_SET_CODE: ret = actuator_set_code(sd, (struct actuator_ctrl *)arg); break; default: return -EINVAL; } return ret; } /* * Store information about the video data format. */ static struct sensor_format_struct sensor_formats[] = { { .desc = "Raw RGB Bayer", .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10, .regs = sensor_fmt_raw, .regs_size = ARRAY_SIZE(sensor_fmt_raw), .bpp = 1 }, }; #define N_FMTS ARRAY_SIZE(sensor_formats) /* * Then there is the issue of window sizes. Try to capture the info here. */ static struct sensor_win_size sensor_win_sizes[] = { { .width = QSXGA_WIDTH, .height = QSXGA_HEIGHT, .hoffset = 0, .voffset = 4, .hts = 2752, .vts = 1974, .pclk = 81486720, .mipi_bps = 408*1000*1000, .fps_fixed = 2, .bin_factor = 1, .intg_min = 1, .intg_max = (1974)<<4, .gain_min = 1<<4, .gain_max = 12<<4, .regs = sensor_qsxga_regs, .regs_size = ARRAY_SIZE(sensor_qsxga_regs), .set_size = NULL, }, { .width = HD720_WIDTH, .height = HD720_HEIGHT, .hoffset = 0, .voffset = 120, .hts = 1896, .vts = 984, .pclk = 56*1000*1000, .mipi_bps = 280*1000*1000, .fps_fixed = 1, .bin_factor = 1, .intg_min = 1, .intg_max = 984<<4, .gain_min = 1<<4, .gain_max = 12<<4, .regs = sensor_720p_regs,// .regs_size = ARRAY_SIZE(sensor_720p_regs),// .set_size = NULL, }, }; #define N_WIN_SIZES (ARRAY_SIZE(sensor_win_sizes)) static int sensor_reg_init(struct sensor_info *info) { int ret; struct v4l2_subdev *sd = &info->sd; struct sensor_format_struct *sensor_fmt = info->fmt; struct sensor_win_size *wsize = info->current_wins; ret = sensor_write_array(sd, sensor_default_regs, ARRAY_SIZE(sensor_default_regs)); if (ret < 0) { sensor_err("write sensor_default_regs error\n"); return ret; } sensor_print("sensor_reg_init\n"); sensor_write_array(sd, sensor_fmt->regs, sensor_fmt->regs_size); if (wsize->regs) sensor_write_array(sd, wsize->regs, wsize->regs_size); if (wsize->set_size) wsize->set_size(sd); info->width = wsize->width; info->height = wsize->height; info->exp = 0; info->gain = 0; ov5648_sensor_vts = wsize->vts; sensor_print("s_fmt set width = %d, height = %d\n", wsize->width, wsize->height); return 0; } static int sensor_s_stream(struct v4l2_subdev *sd, int enable) { struct sensor_info *info = to_state(sd); sensor_print("%s on = %d, %d*%d fps: %d code: %x\n", __func__, enable, info->current_wins->width, info->current_wins->height, info->current_wins->fps_fixed, info->fmt->mbus_code); if (!enable) return 0; return sensor_reg_init(info); } static int sensor_g_mbus_config(struct v4l2_subdev *sd, struct v4l2_mbus_config *cfg) { cfg->type = V4L2_MBUS_CSI2; cfg->flags = 0 | V4L2_MBUS_CSI2_2_LANE | V4L2_MBUS_CSI2_CHANNEL_0; return 0; } static int sensor_g_ctrl(struct v4l2_ctrl *ctrl) { struct sensor_info *info = container_of(ctrl->handler, struct sensor_info, handler); struct v4l2_subdev *sd = &info->sd; switch (ctrl->id) { case V4L2_CID_GAIN: return sensor_g_gain(sd, &ctrl->val); case V4L2_CID_EXPOSURE: return sensor_g_exp(sd, &ctrl->val); } return -EINVAL; } static int sensor_s_ctrl(struct v4l2_ctrl *ctrl) { struct sensor_info *info = container_of(ctrl->handler, struct sensor_info, handler); struct v4l2_subdev *sd = &info->sd; switch (ctrl->id) { case V4L2_CID_GAIN: return sensor_s_gain(sd, ctrl->val); case V4L2_CID_EXPOSURE: return sensor_s_exp(sd, ctrl->val); } return -EINVAL; } /* ----------------------------------------------------------------------- */ static const struct v4l2_ctrl_ops sensor_ctrl_ops = { .g_volatile_ctrl = sensor_g_ctrl, .s_ctrl = sensor_s_ctrl, }; static const struct v4l2_subdev_core_ops sensor_core_ops = { .reset = sensor_reset, .init = sensor_init, .s_power = sensor_power, .ioctl = sensor_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl32 = sensor_compat_ioctl32, #endif }; static const struct v4l2_subdev_video_ops sensor_video_ops = { .s_parm = sensor_s_parm, .g_parm = sensor_g_parm, .s_stream = sensor_s_stream, .g_mbus_config = sensor_g_mbus_config, }; static const struct v4l2_subdev_pad_ops sensor_pad_ops = { .enum_mbus_code = sensor_enum_mbus_code, .enum_frame_size = sensor_enum_frame_size, .get_fmt = sensor_get_fmt, .set_fmt = sensor_set_fmt, }; static const struct v4l2_subdev_ops sensor_ops = { .core = &sensor_core_ops, .video = &sensor_video_ops, .pad = &sensor_pad_ops, }; /* ----------------------------------------------------------------------- */ static struct cci_driver cci_drv = { .name = SENSOR_NAME, .addr_width = CCI_BITS_16, .data_width = CCI_BITS_8, }; static const struct v4l2_ctrl_config sensor_custom_ctrls[] = { { .ops = &sensor_ctrl_ops, .id = V4L2_CID_FRAME_RATE, .name = "frame rate", .type = V4L2_CTRL_TYPE_INTEGER, .min = 15, .max = 120, .step = 1, .def = 120, }, }; static int sensor_init_controls(struct v4l2_subdev *sd, const struct v4l2_ctrl_ops *ops) { struct sensor_info *info = to_state(sd); struct v4l2_ctrl_handler *handler = &info->handler; struct v4l2_ctrl *ctrl; int i; int ret = 0; v4l2_ctrl_handler_init(handler, 2 + ARRAY_SIZE(sensor_custom_ctrls)); v4l2_ctrl_new_std(handler, ops, V4L2_CID_GAIN, 1 * 1600, 256 * 1600, 1, 1 * 1600); ctrl = v4l2_ctrl_new_std(handler, ops, V4L2_CID_EXPOSURE, 0, 65536 * 16, 1, 0); if (ctrl != NULL) ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; for (i = 0; i < ARRAY_SIZE(sensor_custom_ctrls); i++) v4l2_ctrl_new_custom(handler, &sensor_custom_ctrls[i], NULL); if (handler->error) { ret = handler->error; v4l2_ctrl_handler_free(handler); } sd->ctrl_handler = handler; return ret; } static int sensor_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct v4l2_subdev *sd; struct sensor_info *info; info = kzalloc(sizeof(struct sensor_info), GFP_KERNEL); if (info == NULL) return -ENOMEM; sd = &info->sd; cci_dev_probe_helper(sd, client, &sensor_ops, &cci_drv); sensor_init_controls(sd, &sensor_ctrl_ops); mutex_init(&info->lock); #ifdef CONFIG_SAME_I2C info->sensor_i2c_addr = I2C_ADDR >> 1; #endif info->fmt = &sensor_formats[0]; info->fmt_pt = &sensor_formats[0]; info->win_pt = &sensor_win_sizes[0]; info->fmt_num = N_FMTS; info->win_size_num = N_WIN_SIZES; info->sensor_field = V4L2_FIELD_NONE; info->stream_seq = MIPI_BEFORE_SENSOR; info->af_first_flag = 1; info->exp = 0; info->gain = 0; return 0; } static int sensor_remove(struct i2c_client *client) { struct v4l2_subdev *sd; sd = cci_dev_remove_helper(client, &cci_drv); kfree(to_state(sd)); return 0; } static const struct i2c_device_id sensor_id[] = { {SENSOR_NAME, 0}, {} }; MODULE_DEVICE_TABLE(i2c, sensor_id); static struct i2c_driver sensor_driver = { .driver = { .owner = THIS_MODULE, .name = SENSOR_NAME, }, .probe = sensor_probe, .remove = sensor_remove, .id_table = sensor_id, }; static __init int init_sensor(void) { return cci_dev_init_helper(&sensor_driver); } static __exit void exit_sensor(void) { cci_dev_exit_helper(&sensor_driver); } module_init(init_sensor); module_exit(exit_sensor);另外建议使用支持列表中的摄像头,例如gc2053,gc2063,这些摄像头已经适配量产完成并且调整ISP后画质更佳,也支持aiisp实现低照度全彩画质,树莓派的摄像头不推荐使用,因为他是外挂mclk的会引起芯片处于错误的模式,另外原厂也没有相应的支持(2017年前的芯片才有这个支持)
IMX219 同样可以使用,但是请注意4lane的摄像头不可适配2lane的数据
-
回复: t113使用sd卡启动卡住了发布在 Linux
@xingxing8 在 t113使用sd卡启动卡住了 中说:
先看这行
VFS: Cannot open root device "mmcblk0p5" or unknown-block(0,0): error -6
这行表示没有挂载上mmc设备
再往上找
[ 4.002919] sunxi-mmc 4020000.sdmmc: Got CD GPIO
[ 4.008458] sunxi-mmc 4020000.sdmmc: set cd-gpios as 24M fail
[ 4.018859] sunxi-mmc 4020000.sdmmc: sdc set ios:clk 0Hz bm PP pm UP vdd 21 width 1 timing LEGACY(SDR12) dt BCD卡检测GPIO检测不到卡,关闭MMC驱动
Linux中的驱动为了省电会根据CD引脚检测卡是否存在,不存在则关闭MMC驱动,U-boot驱动没有这个逻辑
解决方法:
- 正向解决法
- 根据实物硬件查看CD引脚配置,上下拉状态是否正常,是否反转CD

- 软件规避法
- 直接关闭CD检测功能,取消注释
broken-cd;

-
回复: V853S mipi LCD显示驱动调试,colorbar显示异常发布在 V Series
dclk过高,屏幕分屏了?
这里提供一个py脚本计算分频系数,这里对应的是HV屏,DSI也可以参考def find_closest_clock(target_clock, clock_list): clock_list = sorted(clock_list) low, high = 0, len(clock_list) - 1 closest = clock_list[low] while low <= high: mid = (low + high) // 2 if clock_list[mid] < target_clock: low = mid + 1 elif clock_list[mid] > target_clock: high = mid - 1 else: return clock_list[mid] if abs(clock_list[mid] - target_clock) < abs(closest - target_clock): closest = clock_list[mid] return closest def calculate_divisor(clock_need, clock_list, min_divisor=6): is_perfect = True for i in clock_list: for j in range(0, 255): if (clock_need * j) == i: closest_clock = i divisor = j return closest_clock, divisor, is_perfect is_perfect = False closest_clock = find_closest_clock(clock_need, clock_list) if closest_clock == 0: return None, None, None divisor = closest_clock // clock_need if divisor < min_divisor: min_diff = float('inf') best_clock = None for clock in clock_list: if clock >= clock_need * min_divisor: current_divisor = clock // clock_need if current_divisor < min_divisor: continue diff = abs(clock - clock_need * current_divisor) if diff < min_diff: min_diff = diff best_clock = clock if best_clock is not None: return best_clock, best_clock // clock_need, is_perfect return closest_clock, divisor, is_perfect clock_list = [ 408, 420, 432, 444, 456, 468, 480, 492, 504, 516, 528, 540, 552, 564, 576, 588, 600, 612, 624, 636, 648, 660, 672, 684, 696, 708, 720, 732, 744, 756, 768, 780, 792, 804, 816, 828, 840, 852, 864, 876, 888, 900, 912, 924, 936, 948, 960, 972, 984, 996, 1008, 1020, 1032, 1044, 1056, 1068, 1080, 1092, 1104, 1116, 1128, 1140, 1152, 1164, 1176, 1188, 1200, 1212, 1224, 1236, 1248, 1260, 1272, 1284, 1296, 1308, 1320, 1332, 1344, 1356, 1368, 1380, 1392, 1404, 1416, 1428, 1440, 1452, 1464, 1476, 1488, 1500, 1512, 1524, 1536, 1548, 1560, 1572, 1584, 1596, 1608, 1620, 1632, 1644, 1656, 1668, 1680, 1692 ] clock_need = int(input("请输入需要的时钟(MHz): ")) closest_clock, divisor, is_perfect = calculate_divisor(clock_need, clock_list) if is_perfect: print(f"父时钟: {closest_clock}MHz, 分频系数: {divisor}, 分频后的频率: {closest_clock / divisor}MHz") else: print(f"无法找到完美,最近的父时钟: {closest_clock}, 分频系数: {divisor}, 分频后的频率: {closest_clock / divisor}MHz") print("请修改分频系数表 clk_tbl 中 HV 分频系数为: {LCD_IF_HV, " + hex(divisor) + ", 1, 1, 0}") -
回复: 请教如何排查 linux kernel 启动卡主的问题发布在 Linux
@xsyr1024 在 请教如何排查 linux kernel 启动卡主的问题 中说:
[ 0.969253] 000: printk: console [ttyS0] enabled
[ 0.973945] 000: printk: bootconsole [earlycon0] disabled看着是earlycon0作为串口输出驱动正常,但是切换到ttyS0作为串口输出的时候ttyS0没有输出,先检查uart部分
另外这个是LinuxRT内核吗
-
回复: V853 和 V853S NPU算力差了0.2,这个0.2在具体应用上会有明显的性能差距吗?主要用来做目标检测,静态场景。发布在 V Series
根据具体的模型和需求的规格来看,实际感觉差不多
-
回复: 全志提供的交叉编译环境头文件的问题发布在 Linux
obj-m := hello.o KERNEL := ../lichee/linux-5.4/ PWD := $(shell pwd) modules : $(MAKE) -C $(KERNEL) M=$(PWD) modules .PHONEY:clean clean : rm -f *.o *.ko这是一个基本的内核模块Makefile。下面是各个变量和命令的含义:
obj-m := hello.o定义要编译的内核模块的目标文件名为
hello.o。这里使用了obj-m变量,它是一个特殊的变量,用于编译内核模块。KERNEL := ../lichee/linux-5.4/定义内核源代码目录的位置,这里是
../lichee/linux-5.4/。根据实际情况修改该路径。PWD := $(shell pwd)定义当前目录的路径为
PWD。这里使用了shell命令来获取当前目录的路径。modules : $(MAKE) -C $(KERNEL) M=$(PWD) modules定义一个名为
modules的伪目标,它的依赖关系为空。执行该目标时,会进入内核源代码目录$(KERNEL),并使用M=$(PWD)选项告诉内核Makefile,模块源代码在当前目录中。最后执行modules目标,编译内核模块。.PHONEY:clean clean : rm -f *.o *.ko定义一个伪目标
clean,它的依赖关系为空。执行该目标时,会删除当前目录下的所有.o和.ko文件。如果需要编译多个内核模块,可以将
obj-m变量中的目标文件名替换为多个目标文件名,如obj-m := hello.o world.o another.o。此外,还可以在Makefile中定义其他命令,比如安装、卸载等命令,以更方便地管理内核模块。编译指令如下:
make ARCH=arm CROSS_COMPILE=$(pwd)/../prebuilt/gcc/linux-x86/arm/toolchain-sunxi-glibc/toolchain/bin/arm-openwrt-linux-gnueabi-这是一个编译ARM架构的程序的Makefile命令。下面是各个参数的含义:
ARCH=arm指定目标架构为ARM。
CROSS_COMPILE=$(pwd)/../prebuilt/gcc/linux-x86/arm/toolchain-sunxi-glibc/toolchain/bin/arm-openwrt-linux-gnueabi-指定交叉编译器的路径及前缀。这里使用了
$(pwd)变量获取当前工作目录的路径,并拼接上交叉编译器的路径及前缀。根据实际情况修改该路径。使用交叉编译器可以在x86主机上编译ARM平台的程序。
arm-openwrt-linux-gnueabi-是交叉编译器的前缀,表示编译出来的可执行文件适用于OpenWrt系统。在执行该命令之前,需要确保已经安装了相应的交叉编译工具链,并将其加入环境变量中。如果没有安装,请参考相关文档进行安装。
-
回复: tina SDK ERROR: Dependence broken. Firmware maybe incorrect & cannot booting up...发布在 Linux
@hgs1975 This is not a error, you can normal boot up while showing this error. What's your hardware and how to configure it
-
回复: 只用的全志的板子,怎么才能往rootfs中添加文件发布在 Linux
target/allwinner/t113-nezha/base-files
target/allwinner/t113-nezha/busybox-init-base-files根据选择的overlay方式而定
-
回复: v821切换到spi nand flash(XT26G01CWSIG) 系统无法启动发布在 V Series
看日志是内核整套ubi都没开起来,可以再次运行quick_config,重新编译SDK测试下
-
回复: V853使用MIPI CSI接口是否只支持RAW格式像素?发布在 V Series
@xjy_5 RGB888_1X24 我感觉是直出RGB信号的吧
这个DTSI是在T507上配置的,可以参考一下
vind0:vind@0 { compatible = "allwinner,sunxi-vin-media", "simple-bus"; #address-cells = <2>; #size-cells = <2>; ranges; device_id = <0>; vind0_clk = <384000000>; reg = <0x0 0x06600800 0x0 0x200>, <0x0 0x06600000 0x0 0x800>; clocks = <&clk_csi_top>, <&clk_pll_csi>, <&clk_csi_master0>, <&clk_hosc>, <&clk_pll_csi>, <&clk_csi_master1>, <&clk_hosc>, <&clk_pll_csi>; pinctrl-names = "mclk0-default","mclk0-sleep","mclk1-default","mclk1-sleep"; pinctrl-0 = <&csi_mclk0_pins_a>; pinctrl-1 = <&csi_mclk0_pins_b>; pinctrl-2 = <&csi_mclk1_pins_a>; pinctrl-3 = <&csi_mclk1_pins_b>; status = "okay"; csi_cci0:cci@0 { compatible = "allwinner,sunxi-csi_cci"; reg = <0x0 0x06614000 0x0 0x400>; interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>; pinctrl-names = "default","sleep"; pinctrl-0 = <&csi_cci0_pins_a>; pinctrl-1 = <&csi_cci0_pins_b>; device_id = <0>; status = "okay"; }; csi_cci1:cci@1 { compatible = "allwinner,sunxi-csi_cci"; reg = <0x0 0x06614400 0x0 0x400>; interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>; pinctrl-names = "default","sleep"; pinctrl-0 = <&csi_cci1_pins_a>; pinctrl-1 = <&csi_cci1_pins_b>; device_id = <1>; status = "okay"; }; csi0:csi@0 { device_type = "csi0"; compatible = "allwinner,sunxi-csi"; reg = <0x0 0x06601000 0x0 0x1000>; interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; device_id = <0>; iommus = <&mmu_aw 4 1>; status = "okay"; }; csi1:csi@1 { device_type = "csi1"; compatible = "allwinner,sunxi-csi"; reg = <0x0 0x06602000 0x0 0x1000>; interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>; pinctrl-names = "default","sleep"; pinctrl-0 = <&csi1_pins_a>; pinctrl-1 = <&csi1_pins_b>; device_id = <1>; iommus = <&mmu_aw 4 1>; status = "okay"; }; mipi0:mipi@0 { compatible = "allwinner,sunxi-mipi"; reg = <0x0 0x0660C000 0x0 0x1000>; interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>; device_id = <0>; status = "okay"; }; isp0:isp@0 { compatible = "allwinner,sunxi-isp"; device_id = <0>; status = "okay"; }; isp1:isp@1 { compatible = "allwinner,sunxi-isp"; device_id = <1>; status = "okay"; }; scaler0:scaler@0 { compatible = "allwinner,sunxi-scaler"; device_id = <0>; iommus = <&mmu_aw 4 1>; status = "okay"; }; scaler1:scaler@1 { compatible = "allwinner,sunxi-scaler"; device_id = <1>; iommus = <&mmu_aw 4 1>; status = "okay"; }; scaler2:scaler@2 { compatible = "allwinner,sunxi-scaler"; device_id = <2>; iommus = <&mmu_aw 4 1>; status = "okay"; }; scaler3:scaler@3 { compatible = "allwinner,sunxi-scaler"; device_id = <3>; iommus = <&mmu_aw 4 1>; status = "okay"; }; scaler4:scaler@4 { compatible = "allwinner,sunxi-scaler"; device_id = <4>; iommus = <&mmu_aw 4 1>; status = "okay"; }; scaler5:scaler@5 { compatible = "allwinner,sunxi-scaler"; device_id = <5>; iommus = <&mmu_aw 4 1>; status = "okay"; }; actuator0:actuator@0 { device_type = "actuator0"; compatible = "allwinner,sunxi-actuator"; actuator0_name = "ad5820_act"; actuator0_slave = <0x18>; actuator0_af_pwdn = <>; actuator0_afvdd = "afvcc-csi"; actuator0_afvdd_vol = <2800000>; status = "disabled"; }; flash0:flash@0 { device_type = "flash0"; compatible = "allwinner,sunxi-flash"; flash0_type = <2>; flash0_en = <>; flash0_mode = <>; flash0_flvdd = ""; flash0_flvdd_vol = <>; device_id = <0>; status = "disabled"; }; sensor0:sensor@0 { device_type = "sensor0"; compatible = "allwinner,sunxi-sensor"; sensor0_mname = "tc358743_mipi"; sensor0_twi_cci_id = <2>; sensor0_twi_addr = <0x1f>; sensor0_mclk_id = <0>; sensor0_pos = "rear"; sensor0_isp_used = <0>; sensor0_fmt = <0>; sensor0_stby_mode = <0>; sensor0_vflip = <0>; sensor0_hflip = <0>; sensor0_cameravdd-supply = <>; sensor0_cameravdd_vol = <2800000>; sensor0_iovdd-supply = <®_cldo4>; sensor0_iovdd_vol = <1800000>; sensor0_avdd-supply = <>; sensor0_avdd_vol = <>; sensor0_dvdd-supply = <>; sensor0_dvdd_vol = <>; sensor0_power_en = <>; sensor0_reset = <&pio PI 8 1 0 1 0>; sensor0_pwdn = <>; sensor0_sm_vs = <>; flash_handle = <&flash0>; act_handle = <&actuator0>; device_id = <0>; status = "okay"; }; sensor1:sensor@1 { device_type = "sensor1"; compatible = "allwinner,sunxi-sensor"; sensor1_mname = "ov5647"; sensor1_twi_cci_id = <1>; sensor1_twi_addr = <0x6c>; sensor1_mclk_id = <1>; sensor1_pos = "front"; sensor1_isp_used = <0>; sensor1_fmt = <0>; sensor1_stby_mode = <0>; sensor1_vflip = <0>; sensor1_hflip = <0>; sensor1_cameravdd-supply = <>; sensor1_cameravdd_vol = <2800000>; sensor1_iovdd-supply = <>; sensor1_iovdd_vol = <2800000>; sensor1_avdd-supply = <>; sensor1_avdd_vol = <2800000>; sensor1_dvdd-supply = <>; sensor1_dvdd_vol = <1500000>; sensor1_power_en = <>; sensor1_reset = <&pio PE 14 1 0 1 0>; sensor1_pwdn = <&pio PE 15 1 0 1 0>; sensor1_sm_vs = <>; flash_handle = <>; act_handle = <>; device_id = <1>; status = "disable"; }; vinc0:vinc@0 { device_type = "vinc0"; compatible = "allwinner,sunxi-vin-core"; reg = <0x0 0x06609000 0x0 0x200>; interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>; vinc0_csi_sel = <0>; vinc0_mipi_sel = <0>; vinc0_isp_sel = <0>; vinc0_isp_tx_ch = <0>; vinc0_rear_sensor_sel = <0>; vinc0_front_sensor_sel = <0>; vinc0_sensor_list = <0>; device_id = <0>; iommus = <&mmu_aw 4 1>; status = "okay"; }; vinc1:vinc@1 { device_type = "vinc1"; compatible = "allwinner,sunxi-vin-core"; reg = <0x0 0x06609200 0x0 0x200>; interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; vinc1_csi_sel = <0>; vinc1_mipi_sel = <0>; vinc1_isp_sel = <0>; vinc1_isp_tx_ch = <0>; vinc1_rear_sensor_sel = <0>; vinc1_front_sensor_sel = <0>; vinc1_sensor_list = <0>; device_id = <1>; iommus = <&mmu_aw 4 1>; status = "okay"; }; vinc2:vinc@2 { device_type = "vinc2"; compatible = "allwinner,sunxi-vin-core"; reg = <0x0 0x06609400 0x0 0x200>; interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; vinc2_csi_sel = <0>; vinc2_mipi_sel = <0>; vinc2_isp_sel = <0>; vinc2_isp_tx_ch = <0>; vinc2_rear_sensor_sel = <0>; vinc2_front_sensor_sel = <0>; vinc2_sensor_list = <0>; device_id = <2>; iommus = <&mmu_aw 4 1>; status = "disabled"; }; vinc3:vinc@3 { device_type = "vinc3"; compatible = "allwinner,sunxi-vin-core"; reg = <0x0 0x06609600 0x0 0x200>; interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>; vinc3_csi_sel = <0>; vinc3_mipi_sel = <0>; vinc3_isp_sel = <0>; vinc3_isp_tx_ch = <0>; vinc3_rear_sensor_sel = <0>; vinc3_front_sensor_sel = <0>; vinc3_sensor_list = <0>; device_id = <3>; iommus = <&mmu_aw 4 1>; status = "disabled"; }; vinc4:vinc@4 { device_type = "vinc4"; compatible = "allwinner,sunxi-vin-core"; reg = <0x0 0x06609800 0x0 0x200>; interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>; vinc4_csi_sel = <1>; vinc4_mipi_sel = <0xff>; vinc4_isp_sel = <1>; vinc4_isp_tx_ch = <0>; vinc4_rear_sensor_sel = <1>; vinc4_front_sensor_sel = <1>; vinc4_sensor_list = <0>; device_id = <4>; iommus = <&mmu_aw 5 1>; status = "disabled"; }; vinc5:vinc@5 { device_type = "vinc5"; compatible = "allwinner,sunxi-vin-core"; reg = <0x0 0x06609A00 0x0 0x200>; interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>; vinc5_csi_sel = <1>; vinc5_mipi_sel = <0xff>; vinc5_isp_sel = <1>; vinc5_isp_tx_ch = <0>; vinc5_rear_sensor_sel = <1>; vinc5_front_sensor_sel = <1>; vinc5_sensor_list = <0>; device_id = <5>; iommus = <&mmu_aw 5 1>; status = "disabled"; }; }; -
回复: V853使用MIPI CSI接口是否只支持RAW格式像素?发布在 V Series
sensor0:sensor@0 { device_type = "sensor0"; sensor0_mname = "gc2053_mipi"; /* 必须要和驱动的 SENSOR_NAME 一致 */ sensor0_twi_cci_id = <1>; /* 所使用的twi id号,本例中使用的是twi1,故填写为1 */ sensor0_twi_addr = <0x6e>; /* sensor 设备ID地址,必须与驱动中的I2C_ADDR一致 */ sensor0_mclk_id = <0>; /* 所使用的mclk id号,本例中使用的是MCLK0,故填写为0 */ sensor0_pos = "rear"; sensor0_isp_used = <1>; /* 所使用的sensor为raw sensor,需要过ISP处理,故填写为1 */ sensor0_fmt = <1>; /* sensor输出的图像格式,YUV:0,RAW:1 */ sensor0_stby_mode = <0>; sensor0_vflip = <0>; /* VIPP 图像垂直翻转 */ sensor0_hflip = <0>; /* VIPP 图像水平翻转 */ sensor0_iovdd-supply = <®_aldo2>;/* sensor iovdd 连接的 ldo,根据硬件原理图的连接来决定(在硬件原理图中搜索aldo,然后找到CSI-iovdd对应的 是哪一个aldo即可) */ sensor0_iovdd_vol = <1800000>; /* iovdd的电压 */ sensor0_avdd-supply = <®_bldo2>; /* sensor avdd连接的 ldo,根据硬件原理图的连接来决定 */ sensor0_avdd_vol = <2800000>; /* 同上 */ sensor0_dvdd-supply = <®_dldo2>; /* 同上 */ sensor0_dvdd_vol = <1200000>; /* 同上 */ sensor0_power_en = <>; sensor0_reset = <&pio PA 11 1 0 1 0>; /* GPIO 信息配置:pio 端口 组内序号 功能分配 内部电阻状态 驱动能力 输出电平状态,本例中使用的是PA11*/ sensor0_pwdn = <&pio PA 9 1 0 1 0>; /* GPIO 信息配置:pio 端口 组内序号 功能分配 内部电阻状态 驱动能力 输出电平状态,本例中使用的是PA9*/ flash_handle = <&flash0>; act_handle = <&actuator0>; status = "okay"; };填写
Sensor输出图像格式
sensor输出图像格式定义在sensor_format_struct结构体中,vin v4l2驱动框架通过获取sensor_format_struct结构体成员信息来获取当前sensor输出图像格式,sensor_formats结构体中需要填写的成员是.desc和.mbus_code。
.desc是描述sensor输出的图像格式,本例中gc2053是RGB Raw sensor,故.desc成员填写为"Raw RGB Bayer"。.mbus_code为sensor图像数据输出顺序,sensor RAW图像是以Bayer格式传输的(每个像素只表示RGB其中一个分量),常见的Bayer格式为:RGGB、BGGR、GRBG、GBRG,这个可以询问一下sensor原厂或者翻阅sensor datasheet进行查找。.mbus_code若填错, 会导致色彩偏紫红和出现网格状纹理。 本例中
gc2053图像输出格式为RGGB,且当前的配置是10bit mipi接口,故.mbus_code填写为
MEDIA_BUS_FMT_SRGGB10_1X10,若当前调试的sensor配置是8bit输出,
则.mbus_code填写为MEDIA_BUS_FMT_SRGGB8_1X8,按照这种规则进行填写。static struct sensor_format_struct sensor_formats[] = { { .desc = "Raw RGB Bayer", /* 填写 Sensor 初始化时默认的 Bayer 格式,目的是告知主控端ISP当前图像的 Bayer 格式,ISP需要以同样的格式来接收和处理图像数据 */ .mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10, .regs = sensor_fmt_raw, .regs_size = ARRAY_SIZE(sensor_fmt_raw), .bpp = 1 }, }; 如果
sensor输出图像格式是YUV的话,则需要根据sensor图像数据输出顺序选择YUYV/VYUY/UYVY/YVYU其中一种,如下:static struct sensor_format_struct sensor_formats[] = { { .desc = "YUYV 4:2:2", .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .regs = sensor_fmt_raw, .regs_size = ARRAY_SIZE(sensor_fmt_raw), .bpp = 2, }, }; 同时,
sensor_get_fmt_mbus_core函数也要将当前sensor的图像输出格式赋值给函数参数*code,有些sensor在翻转后RGB顺序不会自动进行调整,需要主控端ISP需要按照当前sensor翻转后的图像格式更新RGB顺序,避免翻转后出现图像色彩异常的问题,如下,gc2053支持翻转后sensor内部自动调整RGB顺序,所以函数参数*code仍赋值为MEDIA_BUS_FMT_SRGGB10_1X10。static int sensor_get_fmt_mbus_core(struct v4l2_subdev *sd, int *code) { *code = MEDIA_BUS_FMT_SRGGB10_1X10; // gc2053 support change the rgb format by itself } static long sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { int ret = 0; struct sensor_info *info = to_state(sd); switch (cmd) { case VIDIOC_VIN_GET_SENSOR_CODE: /* vin v4l2框架层在sensor翻转接口被调用后, 通过VIDIOC_VIN_GET_SENSOR_CODE获取当前sensor的RGB顺序 */ sensor_get_fmt_mbus_core(sd, (int *)arg); break; default: return -EINVAL; } return ret; } -
回复: V853无法烧写SPI Nand发布在 V Series
[05.750]sunxi-spinand-phy: read id failed : -110 try nand failnand找不到,确认一下sys_config.fex的spi引脚配置对不对
-
V853点亮d320fpc2403发布在 V Series
设备树配置
&lcd0 { base_config_start = <1>; lcd_used = <1>; lcd_driver_name = "d320fpc2403"; lcd_backlight = <50>; lcd_if = <4>; lcd_x = <1024>; lcd_y = <768>; lcd_width = <64>; lcd_height = <48>; lcd_dclk_freq = <54>; lcd_pwm_used = <1>; lcd_pwm_ch = <9>; lcd_pwm_freq = <5000>; lcd_pwm_pol = <1>; lcd_pwm_max_limit = <255>; lcd_hbp = <50>; lcd_ht = <1114>; lcd_hspw = <10>; lcd_vbp = <29>; lcd_vt = <809>; lcd_vspw = <8>; lcd_dsi_if = <0>; lcd_dsi_lane = <4>; lcd_dsi_format = <0>; lcd_dsi_te = <0>; lcd_dsi_eotp = <0>; lcd_frm = <0>; lcd_io_phase = <0x0000>; lcd_hv_clk_phase = <0>; lcd_hv_sync_polarity= <0>; lcd_gamma_en = <0>; lcd_bright_curve_en = <0>; lcd_cmap_en = <0>; lcdgamma4iep = <22>; lcd_gpio_0 = <&pio PE 17 1 0 3 1>; pinctrl-0 = <&dsi4lane_pins_a>; pinctrl-1 = <&dsi4lane_pins_b>; base_config_end = <1>; };驱动
/* drivers/video/sunxi/disp2/disp/lcd/d320fpc2403.c * * Copyright (c) 2025 Weidongshan <weidongshan@qq.com> * * d320fpc2403 panel driver * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include "d320fpc2403.h" static void lcd_power_on(u32 sel); static void lcd_power_off(u32 sel); static void lcd_bl_open(u32 sel); static void lcd_bl_close(u32 sel); static void lcd_panel_init(u32 sel); static void lcd_panel_exit(u32 sel); #define panel_reset(sel, val) sunxi_lcd_gpio_set_value(sel, 0, val) static void lcd_cfg_panel_info(struct panel_extend_para *info) { u32 i = 0, j = 0; u32 items; u8 lcd_gamma_tbl[][2] = { { 0, 0 }, { 15, 15 }, { 30, 30 }, { 45, 45 }, { 60, 60 }, { 75, 75 }, { 90, 90 }, { 105, 105 }, { 120, 120 }, { 135, 135 }, { 150, 150 }, { 165, 165 }, { 180, 180 }, { 195, 195 }, { 210, 210 }, { 225, 225 }, { 240, 240 }, { 255, 255 }, }; u32 lcd_cmap_tbl[2][3][4] = { { { LCD_CMAP_G0, LCD_CMAP_B1, LCD_CMAP_G2, LCD_CMAP_B3 }, { LCD_CMAP_B0, LCD_CMAP_R1, LCD_CMAP_B2, LCD_CMAP_R3 }, { LCD_CMAP_R0, LCD_CMAP_G1, LCD_CMAP_R2, LCD_CMAP_G3 }, }, { { LCD_CMAP_B3, LCD_CMAP_G2, LCD_CMAP_B1, LCD_CMAP_G0 }, { LCD_CMAP_R3, LCD_CMAP_B2, LCD_CMAP_R1, LCD_CMAP_B0 }, { LCD_CMAP_G3, LCD_CMAP_R2, LCD_CMAP_G1, LCD_CMAP_R0 }, }, }; items = sizeof(lcd_gamma_tbl) / 2; for (i = 0; i < items - 1; i++) { u32 num = lcd_gamma_tbl[i + 1][0] - lcd_gamma_tbl[i][0]; for (j = 0; j < num; j++) { u32 value = 0; value = lcd_gamma_tbl[i][1] + ((lcd_gamma_tbl[i + 1][1] - lcd_gamma_tbl[i][1]) * j) / num; info->lcd_gamma_tbl[lcd_gamma_tbl[i][0] + j] = (value << 16) + (value << 8) + value; } } info->lcd_gamma_tbl[255] = (lcd_gamma_tbl[items - 1][1] << 16) + (lcd_gamma_tbl[items - 1][1] << 8) + lcd_gamma_tbl[items - 1][1]; memcpy(info->lcd_cmap_tbl, lcd_cmap_tbl, sizeof(lcd_cmap_tbl)); } static s32 lcd_open_flow(u32 sel) { LCD_OPEN_FUNC(sel, lcd_power_on, 120); LCD_OPEN_FUNC(sel, lcd_panel_init, 10); LCD_OPEN_FUNC(sel, sunxi_lcd_tcon_enable, 10); LCD_OPEN_FUNC(sel, lcd_bl_open, 0); return 0; } static s32 lcd_close_flow(u32 sel) { LCD_CLOSE_FUNC(sel, lcd_bl_close, 0); LCD_CLOSE_FUNC(sel, lcd_panel_exit, 200); LCD_CLOSE_FUNC(sel, sunxi_lcd_tcon_disable, 0); LCD_CLOSE_FUNC(sel, lcd_power_off, 500); return 0; } static void lcd_power_on(u32 sel) { /* reset lcd by gpio */ panel_reset(sel, 1); sunxi_lcd_delay_ms(100); panel_reset(sel, 0); sunxi_lcd_delay_ms(500); panel_reset(sel, 1); sunxi_lcd_delay_ms(500); sunxi_lcd_pin_cfg(sel, 1); } static void lcd_power_off(u32 sel) { sunxi_lcd_pin_cfg(sel, 0); sunxi_lcd_delay_ms(20); panel_reset(sel, 0); sunxi_lcd_delay_ms(5); } static void lcd_bl_open(u32 sel) { sunxi_lcd_pwm_enable(sel); } static void lcd_bl_close(u32 sel) { sunxi_lcd_backlight_disable(sel); } #define REGFLAG_DELAY 0XFC #define REGFLAG_END_OF_TABLE 0xFD /* END OF REGISTERS MARKER */ struct LCM_setting_table { u8 cmd; u32 count; u8 para_list[64]; }; static struct LCM_setting_table lcm_initialization_setting[] = { { 0xdf, 3, { 0x91, 0x68, 0xf9 } }, { 0xde, 1, { 0x00 } }, // {0xc2, 1, {0x30}}, { 0xb2, 2, { 0x00, 0x7e } }, { 0xb3, 2, { 0x00, 0x7e } }, { 0xc1, 6, { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00 } }, { 0xbb, 7, { 0x02, 0x24, 0x07, 0x61, 0x19, 0x44, 0x44 } }, { 0xbe, 2, { 0x1a, 0xf2 } }, { 0xc3, 14, { 0x10, 0x17, 0x5a, 0x17, 0x5a, 0x05, 0x05, 0x05, 0x05, 0x15, 0x15, 0x31, 0x05, 0xdf } }, { 0xc4, 7, { 0x11, 0x80, 0x00, 0xdf, 0x09, 0x06, 0x14 } }, { 0xce, 23, { 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x0f, 0x03 } }, { 0xcf, 9, { 0x00, 0x01, 0x40, 0x01, 0xca, 0x01, 0xca, 0x01, 0xca } }, { 0xd0, 23, { 0x00, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x03, 0x01, 0x05, 0x07, 0x09, 0x0b, 0x1e, 0x15, 0x1f, 0x1f, 0x15, 0x1f } }, { 0xd1, 23, { 0x00, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x02, 0x00, 0x04, 0x06, 0x08, 0x0a, 0x1e, 0x15, 0x1f, 0x1f, 0x15, 0x1f } }, { 0xd2, 23, { 0x00, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x00, 0x02, 0x0a, 0x08, 0x06, 0x04, 0x1f, 0x15, 0x1f, 0x1f, 0x15, 0x1e } }, { 0xd3, 23, { 0x00, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x01, 0x03, 0x0b, 0x09, 0x07, 0x05, 0x1f, 0x15, 0x1f, 0x1f, 0x15, 0x1e } }, { 0xd4, 37, { 0x30, 0x00, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x11, 0x00, 0x01, 0xc0, 0x04, 0x01, 0x01, 0x11, 0x80, 0x01, 0xc0, 0x05, 0x01, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x06, 0x18, 0x02, 0xe3 } }, { 0xd5, 8, { 0x68, 0x73, 0x00, 0x08, 0x08, 0x00, 0x03, 0x00 } }, { 0xb7, 6, { 0x00, 0xd8, 0x00, 0x00, 0xd8, 0x00 } }, { 0xc8, 38, { 0x7f, 0x69, 0x5a, 0x4e, 0x4a, 0x3b, 0x40, 0x2a, 0x44, 0x43, 0x44, 0x63, 0x51, 0x59, 0x4c, 0x48, 0x3a, 0x28, 0x0f, 0x7f, 0x69, 0x5a, 0x4e, 0x4a, 0x3b, 0x40, 0x2a, 0x44, 0x43, 0x44, 0x63, 0x51, 0x59, 0x4c, 0x48, 0x3a, 0x28, 0x0f } }, { 0xde, 1, { 0x02 } }, { 0xbb, 4, { 0x00, 0x5b, 0x5c, 0x41 } }, { 0xb5, 3, { 0x00, 0x5a, 0x0a } }, { 0xc6, 1, { 0x22 } }, { 0xd7, 1, { 0x12 } }, { 0xe7, 2, { 0x00, 0x00 } }, { 0xde, 1, { 0x04 } }, { 0xcc, 1, { 0x02 } }, { 0xe7, 1, { 0x01 } }, { 0xde, 1, { 0x00 } }, { 0x35, 1, { 0x00 } }, { 0x11, 0, { 0x00 } }, { REGFLAG_DELAY, REGFLAG_DELAY, { 120 } }, { 0x29, 0, { 0x00 } }, { REGFLAG_DELAY, REGFLAG_DELAY, { 20 } }, { REGFLAG_END_OF_TABLE, REGFLAG_END_OF_TABLE, {} }, }; static void lcd_panel_init(u32 sel) { u32 i = 0; sunxi_lcd_dsi_clk_enable(sel); sunxi_lcd_delay_ms(100); for (i = 0;; i++) { if (lcm_initialization_setting[i].cmd == REGFLAG_END_OF_TABLE) break; else if (lcm_initialization_setting[i].cmd == REGFLAG_DELAY) sunxi_lcd_delay_ms(lcm_initialization_setting[i].count); else { dsi_dcs_wr(0, lcm_initialization_setting[i].cmd, lcm_initialization_setting[i].para_list, lcm_initialization_setting[i].count); } } } static void lcd_panel_exit(u32 sel) { sunxi_lcd_dsi_dcs_write_0para(sel, 0x28); sunxi_lcd_delay_ms(80); sunxi_lcd_dsi_dcs_write_0para(sel, 0x10); sunxi_lcd_delay_ms(50); } /*sel: 0:lcd0; 1:lcd1*/ static s32 lcd_user_defined_func(u32 sel, u32 para1, u32 para2, u32 para3) { return 0; } struct __lcd_panel d320fpc2403_panel = { /* panel driver name, must mach the name of * lcd_drv_name in sys_config.fex */ .name = "d320fpc2403", .func = { .cfg_panel_info = lcd_cfg_panel_info, .cfg_open_flow = lcd_open_flow, .cfg_close_flow = lcd_close_flow, .lcd_user_defined_func = lcd_user_defined_func, }, };


