make kernel_menuconfig
Device Drivers --->
Character devices --->
[*] Virtual terminal
Graphics support --->
Frame buffer Devices --->
Video support for sunxi --->
[*] Framebuffer Console Support(sunxi)
Console display driver support --->
Library routines --->
[*] Select compiled-in fonts
YterAALV 7
@YterAA
已帮助超过1000位开发者学会插入电源
Best posts made by YterAA
-
Reply: 【V853开发板试用】使用屏幕输出命令行
-
Reply: 全志芯片Tina Linux 修改 UART 引脚、UART端口
场景二:使用UART3,需要从UART0改为UART3(PB6,PB7)
- 修改
sys_config.fex
(BOOT0与Uboot的串口)
sys_config.fex
的路径是device/config/chips/t113/configs/evb1/sys_config.fex
中的uart_debug_port
修改前:
[uart_para] uart_debug_port = 0 uart_debug_tx = port:PF02<3><1><default><default> uart_debug_rx = port:PF04<3><1><default><default>
修改后
[uart_para] uart_debug_port = 3 uart_debug_tx = port:PB06<7><1><default><default> uart_debug_rx = port:PB07<7><1><default><default>
- 修改设备树(Linux使用的串口输出)
路径:
device/config/chips/t113/configs/evb1/board.dts
修改前
uart3_pins_a: uart3_pins@0 { pins = "PC6", "PC7"; function = "uart0"; drive-strength = <10>; allwinner,muxsel = <4>; bias-pull-up; }; uart3_pins_b: uart3_pins@1 { pins = "PC6", "PC7"; function = "gpio_in"; }; &uart0 { pinctrl-names = "default", "sleep"; pinctrl-0 = <&uart0_pins_a>; pinctrl-1 = <&uart0_pins_b>; status = "okay"; }; &uart3 { pinctrl-names = "default", "sleep"; pinctrl-0 = <&uart3_pins_a>; pinctrl-1 = <&uart3_pins_b>; status = "disabled"; };
修改后
uart3_pins_a: uart3_pins@0 { pins = "PB6", "PB7"; function = "uart0"; drive-strength = <10>; allwinner,muxsel = <7>; bias-pull-up; }; uart3_pins_b: uart3_pins@1 { pins = "PB6", "PB7"; function = "gpio_in"; }; &uart0 { pinctrl-names = "default", "sleep"; pinctrl-0 = <&uart0_pins_a>; pinctrl-1 = <&uart0_pins_b>; status = "disabled"; # 关闭UART0 }; &uart3 { pinctrl-names = "default", "sleep"; pinctrl-0 = <&uart3_pins_a>; pinctrl-1 = <&uart3_pins_b>; status = "okay"; # 开启UART3 };
- 修改UBOOT CONSOLE INDEX
路径:
brandy/brandy-2.0/u-boot-2018/configs/sun8iw20p1_defconfig
增加下列内容CONFIG_SPECIFY_CONSOLE_INDEX=y CONFIG_CONS_INDEX=4 # UART 3+1 = 4
- 修改启动bootargs
路径:
device/config/chips/t113/configs/evb1/env.cfg
修改前
earlyprintk=sunxi-uart,0x02500000 initcall_debug=0 console=ttyS0,115200
修改后
earlyprintk=sunxi-uart,0x02500000
需要修改为 UART3 的地址,查阅手册可知为0x02500C00
earlyprintk=sunxi-uart,0x02500C00 initcall_debug=0 console=ttyS3,115200
注意 ARM 平台还需要设置Kernel,如下:
make kernel_menuconfig
找到 Kernel low-level debugging functions,修改寄存器地址RISC-V 不需要此操作
- 修改
-
Reply: 全志V853 NPU 导入模型修改为 yuv输入,导出NBG文件报错
YML 指定的 IMAGE_NV12 输入模式下,YUV 输入数据的方式是 Y,UV 分成两个文件送给验证程序,所以第一步,我们需要将 dog_416x416 图片转换为 YUV420 格式, 再拆分成两个文件
-
转换
我们使用 ffmpeg 将一张 416*416 的图片转换为 YUV ffmpeg -i dog_416x416.jpg -pix_fmt nv12 image_416x416.nv12.yuv
-
将 Y 和 UV 平面分开,并分成两个文件按存储。 Y 和 UV 分 bin NV12 格式的大小,按理论计算,应该是 4164161.5=259584 字节。所以,Y 分量的大小应该为 4164161 = 173056, UV 分量大小为 86528。
分 Bin 我们使用 Linux 下的 dd 工具:
dd if=image_416x416.nv12.yuv of=Y.bin bs=1 count=173056 dd if=image_416x416.nv12.yuv of=UV.bin skip=173056 bs=1
仿真需要的数据也是要事先处理好的 Y.bin,UV.bin 作为参数,工具不帮忙给做
-
-
Tina System Init 流程分析
init 进程是内核启动的第一个用户进程,它根据配置文件决定启动那些程序,比如执行某些脚本、启动 shell、运行用户指定的程序等。init 进程是后续所有进程的发起者,比如init进程启动 /bin/sh 程序后,才能在控制台输入各种命令。
init进程的执行程序通常是在/sbin/init,上面讲述的 init 进程的作用只不过是 /sbin/init 这个程序的功能。我们完全可以编写自己的 /sbin/init 程序,或者传入命令行参数“init=xxxx”指定某个程序作为init进程运行。
tina系统中目前支持两种init程序:procd init 和 busybox init。下面我们来简单分析下kernel是如何调用第一个用户进程。
如上图所示,内核启动的第一个c语言入口函数为 start_kernel(), 在函数中:会设置与体系结构相关的环境变量,初始化控制台,以及挂载根文件系统,最后启动 init 进程。
其中的 run_init_process 函数使用它的参数所指定的程序来创建第一个用户进程。
(1)如果 ramdisk_execute_command 变量指定了要运行的程序,则启动它。
ramdisk_execute_command 的取值分三种情况,
1)如果命令行参数指定了“rdinit=xxx”,则ramdisk_execute_command等于这个参数指定的程序
2)否则,如果/init程序存在,ramdisk_execute_command就等于“/init”。
3)否则,ramdisk__execute_command为空
(2)如果execute_command变量指定了要运行的程序,启动它。
如果命令行参数指定了"init=...",则execute_command等于这个参数指定的程序,否则为空
(3)如果 ramdisk_execute_command 和 execute_command 参数都没有指定,则依次执行 ”/sbin/init、/etc/init、/bin/init、/bin/sh“在tina系统中,我们可以通过去修改env.cfg文件 ”rdinit=xxx“ 或 ”init=xxx“ 参数来指定启动的第一个用户进程
example:
tina/target/allwinner/azalea-m2ultra/configs下,修改env-3.10.cfg(如果没有这个文件,则到tina/target/allwinner/generic/configs/拷贝一份env-3.10.cfg到tina/target/allwinner/azalea-m2ultra/configs/),修改文件中的”init=‘指定的应用进程’ “即可 -
解决 D1-H & D1s 驱动 RGB LCD(HV)时由于DCLK频率过高导致花屏
lichee/brandy-2.0/u-boot-2018/drivers/video/sunxi/disp2/disp
做以下修改即可
diff --git a/de/disp_display.c b/de/disp_display.c index 45cb431..e3261f2 100644 --- a/de/disp_display.c +++ b/de/disp_display.c @@ -1313,11 +1313,10 @@ s32 bsp_disp_lcd_set_panel_funs(char *name, disp_lcd_panel_fun *lcd_cfg) } /*now only support lcd0*/ num_compat_cnt = disp_get_compat_lcd_panel_num(0); - for (screen_id = 0; screen_id < num_compat_cnt; screen_id++) { - lcd = disp_get_lcd_compat(0, screen_id); + for (screen_id = 1; screen_id <= num_compat_cnt; screen_id++) { + lcd = disp_get_direct_lcd_compat(0, screen_id); if (lcd && (lcd->set_panel_func)) { if (!lcd->set_panel_func(lcd, name, lcd_cfg)) { - gdisp.lcd_registered[screen_id] = 1; registered_cnt++; DE_INF("panel driver %s register for compatible usage\n", name); } diff --git a/de/disp_lcd.c b/de/disp_lcd.c index 6dc6447..afe600f 100644 --- a/de/disp_lcd.c +++ b/de/disp_lcd.c @@ -20,8 +20,8 @@ struct disp_lcd_private_data { disp_lcd_flow open_flow; disp_lcd_flow close_flow; - /*0 for using this panel, other for index of compat_panel*/ u32 compat_panel_index; + u32 switch_to_compat_panel_index; disp_panel_para panel_info; panel_extend_para panel_extend_info; disp_lcd_cfg lcd_cfg; @@ -67,51 +67,66 @@ static void disp_lcd_post_disable_ex(unsigned int disp); s32 disp_lcd_set_bright(struct disp_device *lcd, u32 bright); s32 disp_lcd_get_bright(struct disp_device *lcd); int disp_update_lcd_param(int lcd_param_index); -/*now only lcd0 index is the index for var lcds_compat*/ -struct disp_device *disp_get_lcd_compat(u32 disp, u32 index) + +static struct disp_lcd_private_data *disp_lcd_get_priv(struct disp_device *lcd) { - u32 num_compat; - u32 num_screens; + if (NULL == lcd) { + DE_WRN("param is NULL!\n"); + return NULL; + } + return (struct disp_lcd_private_data *)lcd->priv_data; +} + +struct disp_device *disp_get_direct_lcd_compat(u32 disp, u32 index) +{ + /* + * if g_compat_index is set, means not first boot, lcd_compat is NULL. + * disp_lcd_compat_set_panel_funs may try to get lcd_compat, so return NULL + * to prevent access NULL pointer. + */ if (g_compat_index) - return NULL;/* if g_compat_index is set, means not first boot, lcd_compat is NULL. - * disp_lcd_compat_set_panel_funs may try to get lcd_compat, so return NULL. - */ - num_screens = bsp_disp_feat_get_num_screens(); - num_compat = disp_get_compat_lcd_panel_num(0); - if (disp >= num_screens || !bsp_disp_feat_is_supported_output_types(disp, DISP_OUTPUT_TYPE_LCD)) { - DE_INF("disp %d not support lcd output\n", disp); return NULL; - } - if (index >= num_compat) { - DE_INF("not find %d lcd_compatible param for disp%d \n", index, disp); + return &lcds_compat[index - 1]; +} +/*now only lcd0 index is the index for var lcds_compat*/ +static struct disp_device *disp_get_lcd_compat(u32 disp, u32 index) +{ + static int count; + struct disp_lcd_private_data *lcd_compatp = &lcd_compat_private[index - 1]; + u32 next_index = lcd_compatp->switch_to_compat_panel_index; + count++; + if (count > 100) { + DE_WRN("disp_get_lcd_compat endless loop ?\n"); return NULL; } - return &lcds_compat[index]; + if (next_index) + return disp_get_lcd_compat(disp, next_index); + else { + count = 0; + return &lcds_compat[index - 1]; + } } struct disp_device* disp_get_lcd(u32 disp) { - u32 num_screens; + u32 num_screens = bsp_disp_feat_get_num_screens(); + u32 num_compat = disp_get_compat_lcd_panel_num(0); + u32 index = ((struct disp_lcd_private_data *)(lcds[disp].priv_data))->switch_to_compat_panel_index; - num_screens = bsp_disp_feat_get_num_screens(); if (disp >= num_screens || !bsp_disp_feat_is_supported_output_types(disp, DISP_OUTPUT_TYPE_LCD)) { DE_INF("disp %d not support lcd output\n", disp); return NULL; } - if (!((struct disp_lcd_private_data *)(lcds[disp].priv_data))->compat_panel_index) - return &lcds[disp]; - else - return disp_get_lcd_compat(disp, (((struct disp_lcd_private_data *)(lcds[disp].priv_data))->compat_panel_index) - 1); -} -static struct disp_lcd_private_data *disp_lcd_get_priv(struct disp_device *lcd) -{ - if (NULL == lcd) { - DE_WRN("param is NULL!\n"); - return NULL; - } - return (struct disp_lcd_private_data *)lcd->priv_data; + if (index) { + if (index > num_compat) { + DE_WRN("not find %d lcd_compatible param for disp%d \n", index, disp); + return NULL; + } + return disp_get_lcd_compat(disp, index); + } else + return &lcds[disp]; } static s32 disp_lcd_is_used(struct disp_device* lcd) @@ -869,6 +884,7 @@ static s32 lcd_clk_exit(struct disp_device* lcd) static s32 lcd_clk_config(struct disp_device* lcd) { struct disp_lcd_private_data *lcdp = disp_lcd_get_priv(lcd); + disp_panel_para *panel = &lcdp->panel_info; struct lcd_clk_info clk_info; unsigned long pll_rate = 297000000, lcd_rate = 33000000, dclk_rate = 33000000, dsi_rate = 0;//hz unsigned long pll_rate_set = 297000000, lcd_rate_set = 33000000, dclk_rate_set = 33000000, dsi_rate_set = 0;//hz @@ -939,8 +955,19 @@ static s32 lcd_clk_config(struct disp_device* lcd) dclk_rate_set = lcd_rate_set / clk_info.tcon_div; if ((pll_rate_set != pll_rate) || (lcd_rate_set != lcd_rate) || (dclk_rate_set != dclk_rate)) { - DE_WRN("disp %d, clk: pll(%ld),clk(%ld),dclk(%ld) dsi_rate(%ld)\n clk real:pll(%ld),clk(%ld),dclk(%ld) dsi_rate(%ld)\n", - lcd->disp, pll_rate, lcd_rate, dclk_rate, dsi_rate, pll_rate_set, lcd_rate_set, dclk_rate_set, dsi_rate_set); + /* ajust the tcon_div to fix the real pll */ + if (pll_rate_set > pll_rate) { + panel->tcon_clk_div_ajust.clk_div_increase_or_decrease = INCREASE; + panel->tcon_clk_div_ajust.div_multiple = pll_rate_set / pll_rate; + dclk_rate_set /= panel->tcon_clk_div_ajust.div_multiple; + } else { + panel->tcon_clk_div_ajust.clk_div_increase_or_decrease = DECREASE; + panel->tcon_clk_div_ajust.div_multiple = pll_rate / pll_rate_set; + dclk_rate_set *= panel->tcon_clk_div_ajust.div_multiple; + } + + DE_WRN("disp %d, clk: pll(%ld),clk(%ld),dclk(%ld) dsi_rate(%ld)\n clk real:pll(%ld),clk(%ld),dclk(%ld) dsi_rate(%ld)\n", + lcd->disp, pll_rate, lcd_rate, dclk_rate, dsi_rate, pll_rate_set, lcd_rate_set, dclk_rate_set, dsi_rate_set); } return 0; @@ -1889,8 +1916,11 @@ s32 disp_lcd_switch_compat_panel(struct disp_device *lcd, unsigned int index) disp_lcd_post_disable_ex(lcd->disp); lcd->exit(lcd); lcdp = disp_lcd_get_priv(lcd); - lcdp->compat_panel_index = index; - lcd_compat = disp_get_lcd_compat(lcd->disp, index - 1); + + /*this flag make disp_get_lcd get correct compat_panel*/ + lcdp->switch_to_compat_panel_index = index; + + lcd_compat = disp_get_lcd_compat(lcd->disp, index); lcdp = disp_lcd_get_priv(lcd_compat); lcdp->need_open_again = true; @@ -51,7 +51,7 @@ #endif struct disp_device *disp_get_lcd(u32 disp); -struct disp_device *disp_get_lcd_compat(u32 disp, u32 index); +struct disp_device *disp_get_direct_lcd_compat(u32 disp, u32 index); struct disp_device *disp_get_hdmi(u32 disp); diff --git a/de/include.h b/de/include.h index 57c5db6..5e81f37 100644 --- a/de/include.h +++ b/de/include.h @@ -658,6 +658,16 @@ enum disp_lcd_dsi_port { DISP_LCD_DSI_DUAL_PORT, }; +enum div_flag { + INCREASE = 1, + DECREASE = -1, +}; + +struct clk_div_ajust { + enum div_flag clk_div_increase_or_decrease; + int div_multiple; +}; + typedef struct { disp_lcd_if lcd_if; @@ -737,6 +747,7 @@ typedef struct { unsigned int ccir_clk_div; /*not need to config for user*/ unsigned int input_csc; unsigned int lcd_hv_data_polarity; + struct clk_div_ajust tcon_clk_div_ajust; } disp_panel_para; typedef enum { diff --git a/de/lowlevel_v2x/de_dsi.c b/de/lowlevel_v2x/de_dsi.c index 6d629c5..3bb405d 100644 --- a/de/lowlevel_v2x/de_dsi.c +++ b/de/lowlevel_v2x/de_dsi.c @@ -454,8 +454,11 @@ s32 dsi_dcs_rd(u32 sel, u8 cmd, u8 *para_p, u32 *num_p) count++; dsi_delay_us(100); } - if (count >= 50) + if (count >= 50) { dsi_dev[sel]->dsi_basic_ctl0.bits.inst_st = 0; + dsi_dev[sel]->dsi_gctl.bits.dsi_en = 0; + dsi_dev[sel]->dsi_gctl.bits.dsi_en = 1; + } if (dsi_dev[sel]->dsi_cmd_ctl.bits.rx_flag) { if (dsi_dev[sel]->dsi_cmd_ctl.bits.rx_overflow) @@ -920,7 +923,6 @@ static s32 dsi_basic_cfg(u32 sel, disp_panel_para *panel) dsi_dev[sel]->dsi_trans_zero.bits.hs_zero_reduce_set = 0; } else { s32 start_delay = panel->lcd_vt - panel->lcd_y - 10; - u32 vfp = panel->lcd_vt - panel->lcd_y - panel->lcd_vbp; u32 dsi_start_delay; /* @@ -928,8 +930,7 @@ static s32 dsi_basic_cfg(u32 sel, disp_panel_para *panel) * set ready sync early to dramfreq, so set start_delay 1 */ start_delay = 1; - - dsi_start_delay = panel->lcd_vt - vfp + start_delay; + dsi_start_delay = start_delay; if (dsi_start_delay > panel->lcd_vt) dsi_start_delay -= panel->lcd_vt; if (dsi_start_delay == 0) @@ -942,7 +943,7 @@ static s32 dsi_basic_cfg(u32 sel, disp_panel_para *panel) dsi_start_delay; dsi_dev[sel]->dsi_basic_ctl1.bits.video_precision_mode_align = 1; - dsi_dev[sel]->dsi_basic_ctl1.bits.video_frame_start = 0; /* 1 */ + dsi_dev[sel]->dsi_basic_ctl1.bits.video_frame_start = 1; dsi_dev[sel]->dsi_trans_start.bits.trans_start_set = 10; dsi_dev[sel]->dsi_trans_zero.bits.hs_zero_reduce_set = 0; dsi_dev[sel]->dsi_basic_ctl1.bits.dsi_mode = 1; diff --git a/de/lowlevel_v2x/de_lcd_sun50iw10.c b/de/lowlevel_v2x/de_lcd_sun50iw10.c index 203e8a3..5a4cdf6 100644 --- a/de/lowlevel_v2x/de_lcd_sun50iw10.c +++ b/de/lowlevel_v2x/de_lcd_sun50iw10.c @@ -393,7 +393,7 @@ s32 lvds_open(u32 sel, disp_panel_para *panel) #if defined(SUPPORT_COMBO_DPHY) if (sel == 0) { lvds_combphy_open(sel, panel); - } else { + } else if (sel < DEVICE_NUM) { lcd_dev[sel]->tcon0_lvds_ana[0].bits.c = 2; lcd_dev[sel]->tcon0_lvds_ana[0].bits.v = 3; lcd_dev[sel]->tcon0_lvds_ana[0].bits.pd = 2; @@ -774,6 +774,7 @@ static s32 tcon0_cfg_mode_tri(u32 sel, disp_panel_para *panel) { u32 start_delay = 0; u32 de_clk_rate = de_get_clk_rate() / 1000000; + u32 delay_line = 0; de_clk_rate = (de_clk_rate == 0) ? 250 : de_clk_rate; @@ -783,8 +784,30 @@ static s32 tcon0_cfg_mode_tri(u32 sel, disp_panel_para *panel) lcd_dev[sel]->tcon0_cpu_tri1.bits.block_num = panel->lcd_y - 1; lcd_dev[sel]->tcon0_cpu_tri2.bits.trans_start_mode = 0; lcd_dev[sel]->tcon0_cpu_tri2.bits.sync_mode = 0; - start_delay = (panel->lcd_vt - panel->lcd_y - 8 - 1) - * panel->lcd_ht * de_clk_rate / panel->lcd_dclk_freq / 8; + + /** + * When the blanking area of LCD is too small, the following formula is + * not applicable, that calculates the start_ Delay is too large. + * + * The formula is + * start_delay = (panel->lcd_vt - panel->lcd_y - 8 - 1) + * * panel->lcd_ht * de_clk_rate / panel->lcd_dclk_freq / 8; + * + * Therefore, the following formula is obtained by balancing the + * requirements of DE, TCON and PANEL modules for pixel data speed + * + */ + if (panel->lcd_vbp > 10) + delay_line = 10; + else if (panel->lcd_vbp <= 10 && panel->lcd_vbp > 4) + delay_line = panel->lcd_vbp - 1; + else { + DE_WRN("vbp is too small, please readjust the timing parameters to increase vbp. \n"); + delay_line = panel->lcd_vbp; + } + + start_delay = delay_line * panel->lcd_ht * de_clk_rate / panel->lcd_dclk_freq / 8; + lcd_dev[sel]->tcon0_cpu_tri2.bits.start_delay = start_delay; lcd_dev[sel]->tcon0_cpu_ctl.bits.trigger_fifo_en = 1; diff --git a/de/lowlevel_v2x/disp_al.c b/de/lowlevel_v2x/disp_al.c index 635db57..cf76927 100644 --- a/de/lowlevel_v2x/disp_al.c +++ b/de/lowlevel_v2x/disp_al.c @@ -746,10 +746,6 @@ int disp_al_lcd_get_clk_info(u32 screen_id, struct lcd_clk_info *info, } #endif - if (panel->lcd_dclk_freq < 48 && panel->lcd_dclk_freq >= 3) { - tcon_div = 300 / panel->lcd_dclk_freq; - } - info->tcon_div = tcon_div; info->lcd_div = lcd_div; info->dsi_div = dsi_div; @@ -773,6 +769,11 @@ int disp_al_lcd_cfg(u32 screen_id, disp_panel_para *panel, tcon_init(screen_id); disp_al_lcd_get_clk_info(screen_id, &info, panel); + if (panel->tcon_clk_div_ajust.clk_div_increase_or_decrease == INCREASE) { + info.tcon_div = info.tcon_div * panel->tcon_clk_div_ajust.div_multiple; + } else if (panel->tcon_clk_div_ajust.clk_div_increase_or_decrease == DECREASE) { + info.tcon_div = info.tcon_div / panel->tcon_clk_div_ajust.div_multiple; + } tcon0_set_dclk_div(screen_id, info.tcon_div); #if !defined(TCON1_DRIVE_PANEL) diff --git a/dev_disp.c b/dev_disp.c index b850d96..1fcd080 100644 --- a/dev_disp.c +++ b/dev_disp.c @@ -992,6 +992,17 @@ long disp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) //----layer---- case DISP_LAYER_SET_CONFIG: { + + const unsigned int lyr_cfg_size = ARRAY_SIZE(lyr_cfg); + + if (IS_ERR_OR_NULL((void __user *)ubuffer[1])) { + __wrn("incoming pointer of user is ERR or NULL"); + return -EFAULT; + } + if (ubuffer[2] == 0 || ubuffer[2] > lyr_cfg_size) { + __wrn("layer number need to be set from 1 to %d\n", lyr_cfg_size); + return -EFAULT; + } if (copy_from_user(lyr_cfg, (void __user *)ubuffer[1], sizeof(struct disp_layer_config) * ubuffer[2])) { @@ -1005,6 +1016,17 @@ long disp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case DISP_LAYER_GET_CONFIG: { + + const unsigned int lyr_cfg_size = ARRAY_SIZE(lyr_cfg); + + if (IS_ERR_OR_NULL((void __user *)ubuffer[1])) { + __wrn("incoming pointer of user is ERR or NULL"); + return -EFAULT; + } + if (ubuffer[2] == 0 || ubuffer[2] > lyr_cfg_size) { + __wrn("layer number need to be set from 1 to %d\n", lyr_cfg_size); + return -EFAULT; + } if (copy_from_user(lyr_cfg, (void __user *)ubuffer[1], sizeof(struct disp_layer_config) * ubuffer[2])) { @@ -1026,6 +1048,17 @@ long disp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case DISP_LAYER_SET_CONFIG2: { + + const unsigned int lyr_cfg_size = ARRAY_SIZE(lyr_cfg2); + + if (IS_ERR_OR_NULL((void __user *)ubuffer[1])) { + __wrn("incoming pointer of user is ERR or NULL"); + return -EFAULT; + } + if (ubuffer[2] == 0 || ubuffer[2] > lyr_cfg_size) { + __wrn("layer number need to be set from 1 to %d\n", lyr_cfg_size); + return -EFAULT; + } if (copy_from_user(lyr_cfg2, (void __user *)ubuffer[1], sizeof(struct disp_layer_config2) * ubuffer[2])) { @@ -1040,6 +1073,17 @@ long disp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case DISP_LAYER_GET_CONFIG2: { + + const unsigned int lyr_cfg_size = ARRAY_SIZE(lyr_cfg2); + + if (IS_ERR_OR_NULL((void __user *)ubuffer[1])) { + __wrn("incoming pointer of user is ERR or NULL"); + return -EFAULT; + } + if (ubuffer[2] == 0 || ubuffer[2] > lyr_cfg_size) { + __wrn("layer number need to be set from 1 to %d\n", lyr_cfg_size); + return -EFAULT; + } if (copy_from_user(lyr_cfg2, (void __user *)ubuffer[1], sizeof(struct disp_layer_config2) * ubuffer[2])) { diff --git a/disp_sys_intf.c b/disp_sys_intf.c index a8032b5..5afccf1 100644 --- a/disp_sys_intf.c +++ b/disp_sys_intf.c @@ -378,6 +378,7 @@ int disp_get_set_lcd_param_index_from_flash(bool is_set, int idx) ret = -1; } } else { +#ifdef CONFIG_COMPATIBLE_PANEL_RECORD #ifdef CONFIG_FAT_WRITE if (idx < 0 || idx > 9) { ret = -1; @@ -399,6 +400,9 @@ int disp_get_set_lcd_param_index_from_flash(bool is_set, int idx) pr_error("please enable FAT_WRITE for lcd compatible first\n"); ret = -1; #endif +#else + ret = idx_get = idx; +#endif } exit_free: kfree(buf); --
-
【V853 Tina Linux 虚拟机】VirtualBox 虚拟机开发环境 新版本虚拟机开放
虚拟机
我们为您准备了一个配置好的可以开发 V853 的虚拟机,该虚拟机基于 Oracle VM VirtualBox 6.1.16 版本,配置四核4G内存,您可以根据您开发PC的性能修改虚拟机配置,建议您增大核心数以提到编译速度。
这个虚拟机是 开放虚拟机平台的OVA格式,支持导入 VirtualBox、VMWare 等虚拟机软件
虚拟机下载地址(大小:6GB):https://netstorage.allwinnertech.com:5001/sharing/9mbFsvtuT
系统:Ubuntu 20.04,用户名:
allwinner
,密码:Pass123456
虚拟机配置的环境
- 编译 Tina Linux 所需的依赖
- Python 环境(NPU使用)
- 交叉编译工具链
- apt,pip配置了清华源
注:本虚拟机不包含 Tina Linux SDK 与 NPU 工具链,如需要请按照下面说明自行配置
Tina Linux SDK 源码下载:https://v853.docs.aw-ol.com/study/study_3getsdk/
NPU 开发部署工具:https://v853.docs.aw-ol.com/study/study_7npu_startup/ -
Reply: Tina procd-init 与 busybox-init 切换
(1)如果ramdisk_execute_command变量指定了要运行的程序,则启动它。 ramdisk_execute_command的取值分三种情况, 1)如果命令行参数指定了“rdinit=xxx”,则ramdisk_execute_command等于这个参数指定的程序 2)否则,如果/init程序存在,ramdisk_execute_command就等于“/init”。 3)否则,ramdisk__execute_command为空 (2)如果execute_command变量指定了要运行的程序,启动它。 如果命令行参数指定了"init=...",则execute_command等于这个参数指定的程序,否则为空 (3)如果ramdisk_execute_command和execute_command参数都没有指定,则依次执行”/sbin/init、/etc/init、/bin/init、/bin/sh“ 在tina系统中,我们可以通过去修改env.cfg文件”rdinit=xxx“或”init=xxx“参数来指定启动的第一个用户进程
-
Reply: Tina linux 如何更改system init
busybox init 需要配置一些选项和 busybox-int-base-files这些东西
主要做这些修改
-CONFIG_SYSTEM_INIT_PROCD=y -# CONFIG_SYSTEM_INIT_BUSYBOX is not set +# CONFIG_SYSTEM_INIT_PROCD is not set +CONFIG_SYSTEM_INIT_BUSYBOX=y -CONFIG_PACKAGE_base-files=y -# CONFIG_BUSYBOX_CONFIG_FEATURE_CALL_TELINIT is not set -# CONFIG_BUSYBOX_CONFIG_INIT is not set -# CONFIG_BUSYBOX_CONFIG_LINUXRC is not set +CONFIG_BUSYBOX_CONFIG_INIT=y +CONFIG_BUSYBOX_CONFIG_LINUXRC=y +# CONFIG_BUSYBOX_CONFIG_FEATURE_USE_INITTAB is not set +CONFIG_BUSYBOX_CONFIG_FEATURE_INIT_SCTTY=y +CONFIG_BUSYBOX_CONFIG_FEATURE_INIT_SYSLOG=y +CONFIG_BUSYBOX_CONFIG_FEATURE_INIT_QUIET=y +CONFIG_BUSYBOX_CONFIG_FEATURE_INIT_COREDUMPS=y +CONFIG_BUSYBOX_CONFIG_INIT_TERMINAL_TYPE="" +# CONFIG_BUSYBOX_CONFIG_FEATURE_INIT_MODIFY_CMDLINE is not set -CONFIG_BUSYBOX_CONFIG_LOGGER=y +# CONFIG_BUSYBOX_CONFIG_LOGGER is not set +CONFIG_PACKAGE_busybox-init-base-files=y +CONFIG_BUSYBOX_INIT_BASE_FILES_OPTIONS=y +CONFIG_BUSYBOX_INIT_BASE_FILES_PATH="busybox-init-base-files" +# CONFIG_BUSYBOX_INIT_BASE_FILES_RC_LOG is not set +# CONFIG_BUSYBOX_INIT_BASE_FILES_RC_LOAD_SCRIPT is not set +# CONFIG_BUSYBOX_INIT_BASE_FILES_RC_MODULES is not set -CONFIG_PACKAGE_procd=y - -# -# Configuration -# -# CONFIG_PROCD_SHOW_BOOT is not set -# CONFIG_PROCD_ZRAM_TMPFS is not set -# end of Configuration - +# CONFIG_PACKAGE_procd is not set
-
Reply: 【V853 Tina Linux 虚拟机】VirtualBox 虚拟机开发环境 新版本虚拟机开放
虚拟机安装说明
首先安装一个虚拟机软件,推荐 免费开源的 VirtualBox 虚拟机。当然也支持 VMWare WorkStation,ESXi 等虚拟机软件。这里以 VirtualBox 作为示例。
下载虚拟机文件,一个 Ubuntu20.04.ova 文件,双击打开它。
进入这个配置页面中,按图中所示配置虚拟机参数。
点击导入,开始导入(虚拟机较大,可能比较慢)
导入后启动即可
虚拟机使用说明
虚拟机安装好了,不过还需要配置下增强功能,例如主机与虚拟机文件的复制、共享文件夹、共享粘贴板等等。
我们先启动虚拟机,输入密码 Pass123456 进入系统。
到 设备 -> 安装增强功能 点击并安装增强功能。
点击 Run
输入密码 Pass123456
安装完成了,按回车
重启下虚拟机
设置共享粘贴板为双向、拖放双向
同时也可以设置一下共享文件夹
-
全志芯片Tina Linux 修改 UART 引脚、UART端口
场景一:同样使用UART0,需要从PF2、PF4改到PE2、PE4
- 修改
sys_config.fex
(BOOT0与Uboot的串口)
sys_config.fex
的路径是device/config/chips/t113/configs/evb1/sys_config.fex
中的uart_debug_port
修改前:
[uart_para] uart_debug_port = 0 uart_debug_tx = port:PF02<3><1><default><default> uart_debug_rx = port:PF04<3><1><default><default>
修改后
[uart_para] uart_debug_port = 0 uart_debug_tx = port:PE02<6><1><default><default> uart_debug_rx = port:PE03<6><1><default><default>
其中
<3>
改为<6>
是查阅数据手册中 PE2、PE3 的UART0是 Function6 得知的
port:PE02 <6><1><default><default> ^ ^ PE2脚 引脚功能6(查阅datasheet得知)
- 修改设备树(Linux使用的串口输出)
路径:
device/config/chips/t113/configs/evb1/board.dts
修改前
uart0_pins_a: uart0_pins@0 { /* For EVB1 board */ pins = "PF2", "PF4"; function = "uart0"; drive-strength = <10>; allwinner,muxsel = <3>; bias-pull-up; }; uart0_pins_b: uart0_pins@1 { /* For EVB1 board */ pins = "PF2", "PF4"; function = "gpio_in"; };
修改后
uart0_pins_a: uart0_pins@0 { /* For EVB1 board */ pins = "PE2", "PE3"; function = "uart0"; drive-strength = <10>; allwinner,muxsel = <6>; bias-pull-up; }; uart0_pins_b: uart0_pins@1 { /* For EVB1 board */ pins = "PE2", "PE3"; function = "gpio_in"; };
- 修改
Latest posts made by YterAA
-
Reply: T113的spi 不能使用compatible=“spidev”?
参考 《D1-H_Linux_SPI_开发指南.pdf》
使用spidev并不需要专门设置compatible = "spidev";。而设置spidev会导致 spidev listed directly in DT 错误。这里使用的虚拟设备可以通过compatible = "rohm,dh2228fv"; 这样的 compatible 设备绕过检测
可用的spidev如下:
WARN参考spidev源码:
-
解决 T113 修改 UART3 后 Uboot 有输出但是 Kernel 无法启动
请按照如下步骤依次验证是否配置正确
使用UART3,需要从UART0改为UART3(PB6,PB7)
- 修改
sys_config.fex
(BOOT0与Uboot的串口)
sys_config.fex
的路径是device/config/chips/t113/configs/evb1/sys_config.fex
中的uart_debug_port
修改前:
[uart_para] uart_debug_port = 0 uart_debug_tx = port:PF02<3><1><default><default> uart_debug_rx = port:PF04<3><1><default><default>
修改后
[uart_para] uart_debug_port = 0 uart_debug_tx = port:PB06<7><1><default><default> uart_debug_rx = port:PB07<7><1><default><default>
- 修改设备树(Linux使用的串口输出)
路径:
device/config/chips/t113/configs/evb1/board.dts
修改前
uart3_pins_a: uart3_pins@0 { pins = "PC6", "PC7"; function = "uart0"; drive-strength = <10>; allwinner,muxsel = <4>; bias-pull-up; }; uart3_pins_b: uart3_pins@1 { pins = "PC6", "PC7"; function = "gpio_in"; }; &uart0 { pinctrl-names = "default", "sleep"; pinctrl-0 = <&uart0_pins_a>; pinctrl-1 = <&uart0_pins_b>; status = "okay"; }; &uart3 { pinctrl-names = "default", "sleep"; pinctrl-0 = <&uart3_pins_a>; pinctrl-1 = <&uart3_pins_b>; status = "disabled"; };
修改后
uart3_pins_a: uart3_pins@0 { pins = "PB6", "PB7"; function = "uart0"; drive-strength = <10>; allwinner,muxsel = <7>; bias-pull-up; }; uart3_pins_b: uart3_pins@1 { pins = "PB6", "PB7"; function = "gpio_in"; }; &uart0 { pinctrl-names = "default", "sleep"; pinctrl-0 = <&uart0_pins_a>; pinctrl-1 = <&uart0_pins_b>; status = "disabled"; # 关闭UART0 }; &uart3 { pinctrl-names = "default", "sleep"; pinctrl-0 = <&uart3_pins_a>; pinctrl-1 = <&uart3_pins_b>; status = "okay"; # 开启UART3 };
- 修改UBOOT CONSOLE INDEX
路径:
brandy/brandy-2.0/u-boot-2018/configs/sun8iw20p1_defconfig
增加下列内容CONFIG_SPECIFY_CONSOLE_INDEX=y CONFIG_CONS_INDEX=4 # UART 3+1 = 4
- 修改启动bootargs
路径:
device/config/chips/t113/configs/evb1/env.cfg
修改前
earlyprintk=sunxi-uart,0x02500000 initcall_debug=0 console=ttyS0,115200
修改后
earlyprintk=sunxi-uart,0x02500000
需要修改为 UART3 的地址,查阅手册可知为0x02500C00
earlyprintk=sunxi-uart,0x02500C00 initcall_debug=0 console=ttyS3,115200
- 修改 DEBUG_LL的地址
make kernel_menuconfig
找到 Kernel low-level debugging functions,修改寄存器地址
- 修改
-
Reply: 全志芯片Tina Linux 修改 UART 引脚、UART端口
注意 ARM 平台还需要设置Kernel,如下:
make kernel_menuconfig
找到 Kernel low-level debugging functions,修改寄存器地址RISC-V 不需要此操作
(之前忘记说了,现在补上
-
Reply: Error: "distro_bootcmd" not defined
@huangjun-zopudt 更新了mtd驱动,你可以试试全盘擦除再刷写
-
Reply: Error: "distro_bootcmd" not defined
GUID Partition Table Header signature is wrong: 0x6F627464 != 0x5452415020494645 part_get_info_efi: *** ERROR: Invalid GPT *** ERROR: attempting read past flash size *** ERROR: Can't read GPT header *** part_get_info_efi: *** ERROR: Invalid Backup GPT *** [00.265]Loading Environment from SUNXI_FLASH... GUID Partition Table Header signature is wrong: 0x6F627464 != 0x5452415020494645 part_get_info_efi: *** ERROR: Invalid GPT *** ERROR: attempting read past flash size *** ERROR: Can't read GPT header *** part_get_info_efi: *** ERROR: Invalid Backup GPT *** *** Warning - no device, using default environment
系统分区损坏了。无法读取到fs里的文件。可以参考下这个是怎么写的 https://www.aw-ol.com/downloads/resources/72