@nlj_moon 大佬您好,同样的问题,解决了吗?
Cohen0415 发布的帖子
-
v853 xr829 蓝牙出不来hci0
问题:执行bt_test,报错bring up hci0 failed
然后单独执行hciattach -n ttyS2 xradio >/dev/null 2>&1 &,打印如下:
xr829 蓝牙部分原图如下,用的是uart2:
设备树如下:
kernel_menuconfig和menuconfig配置按照如下操作了,但是tina配置里没发现有kmod-net-xrbtlpm:
看其它帖子说在内核配置把H5也打开了。
请教大佬们,这要怎么解决 -
libc.so: No such file or directory (needed by /usr/lib/libext2fs.so.2)
v853 tina sdk。
现在问题是,部分文件系统挂载不全,想实现成这样:
但现在是这样:
tina配置中,已开启e2fsprogs,部分启动日志如下:
执行mkfs.ext2也是报这个错:
root@TinaLinux:/# mkfs.ext2 Error loading shared library /home/book/platform/v85x/v853/dshanpi-aict/tina-v853/out/v853-aict/staging_dir/target/rootfs/lib/libc.so: No such file or directory (needed by /usr/lib/libext2fs.so.2)
-
回复: mdev: can't create 'mmcblk0rpmb': Read-only file system
make menuconfig开启这两个配置:
CONFIG_KERNEL_DEVTMPFS=y
CONFIG_KERNEL_DEVTMPFS_MOUNT=y -
mdev: can't create 'mmcblk0rpmb': Read-only file system
v853 tina sdk。
system init选的是busy-box init。
目前启动一直会打印这些,请问一般是啥问题。进入系统后,倒不影响使用:
log.txt -
飞凌T527扩大rootfs分区(buildroot系统)
一、实验环境介绍
硬件:飞凌T527开发板(2G+16G)
软件:全志Tina sdk二、查看当前存储分布
登入开发板,执行 fdisk -l 查看存储分布,全志会把剩余空间全部分给userdata分区:
三、修改分区表
分区表路径在:<sdk>/device/config/chips/t527/configs/okt527/longan/sys_partition.fex修改分区表,将rootfs分区扩大至10G:
计算方式如下(一个扇区512字节,size值是以扇区为单位的):
10GB * 1024 = 10240MB
10240MB * 1024 = 10485760KB
10485760KB * 1024 = 10737418240Byte
10737418240Byte / 512 = 20971520(扇区)四、打包、更新镜像
修改完分区表后,在源码根目录下执行 ./build.sh && ./build.sh pack 编译打包,并更新镜像。五、测试
镜像更新完成后,登入开发板,重新执行 fdisk -l 查看存储分布,可以看到rootfs分区的大小已经变成了10G:
-
T113 uboot 识别不到u盘设备
T113 S3,tina5.0,想在uboot上弄一个基于U盘的镜像离线烧录功能。进入uboot后,识别不出u盘设备,u盘是fat32格式的,USB2.0,进入内核是可以正常使用U盘的。
-
飞凌OKT527开发板U-Boot添加自定义菜单
昨日,终于收到了心心念念的飞凌OK-T527开发板,板子很漂亮,外设丰富,性能强悍,T527创新性地使用了RISC-V架构的协处理器,后期值得研究一下异核的使用:
有趣的是,板子上电,按任意键进入U-Boot会自动列出一个功能菜单,有切换屏幕等功能:
基于此,本文将分析如何在U-Boot添加自定义菜单。一、实验环境介绍
硬件:飞凌OK-T527开发板
软件:全志Longan SDK(U-Boot版本2018)
说明:本次实验不限制平台,请参考实际情况阅读。二、目标
本文主要分析U-Boot在程序中的执行顺序,又如何在U-Boot阶段调起菜单?相信大家都试过,在U-Boot倒数结束前按任意按键后,会进入U-Boot命令行模式。
这里先留一个问题:如何做到按键按下后,调启的是自己的U-Boot菜单,而不再是进入命令行模式?三、U-Boot如何自动调起菜单
U-Boot的入口程序文件是 <u-boot>/common/main.c,入口函数main_loop():/* <u-boot>/common/main.c */ ... /* We come here after U-Boot is initialised and ready to process commands */ /* 在U-Boot初始化并准备好处理命令之后,我们来到这里。 */ void main_loop(void) { const char *s; bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop"); #ifdef CONFIG_VERSION_VARIABLE env_set("ver", version_string); /* set version variable */ #endif /* CONFIG_VERSION_VARIABLE */ cli_init(); //命令初始化有关,初始化 hush shell 相关的变量 run_preboot_environment_command(); //获取环境变量 perboot 的内容 #if defined(CONFIG_UPDATE_TFTP) update_tftp(0UL, NULL, NULL); #endif /* CONFIG_UPDATE_TFTP */ s = bootdelay_process(); //此函数会读取环境变量 bootdelay 和 bootcmd 的内容 if (cli_process_fdt(&s)) cli_secure_boot_cmd(s); autoboot_command(s); //开启倒计时,并在倒计时结束前检测是否有按键按下 cli_loop(); //命令行处理函数(即进入U-Boot命令行) panic("No CLI available"); }
关键函数是autoboot_command(),该函数的实现在 <u-boot>/common/autoboot.c:
/* <u-boot>/common/autoboot.c */ ... void autoboot_command(const char *s) { debug("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>"); if (stored_bootdelay != -1 && s && !abortboot(stored_bootdelay)) { // 倒计时过程中,没有按键按下 #if defined(CONFIG_AUTOBOOT_KEYED) && !defined(CONFIG_AUTOBOOT_KEYED_CTRLC) int prev = disable_ctrlc(1); /* disable Control C checking */ #endif run_command_list(s, -1, 0); // 倒计时结束后,启动内核 #if defined(CONFIG_AUTOBOOT_KEYED) && !defined(CONFIG_AUTOBOOT_KEYED_CTRLC) disable_ctrlc(prev); /* restore Control C checking */ #endif } #ifdef CONFIG_MENUKEY if (menukey == CONFIG_MENUKEY) { s = env_get("menucmd"); if (s) run_command_list(s, -1, 0); } #endif /* CONFIG_MENUKEY */ }
进入 autoboot_command() 后,先看第一个if:
void autoboot_command(const char *s) { ... if (stored_bootdelay != -1 && s && !abortboot(stored_bootdelay)) ... }
这里有三个条件:
● stored_bootdelay != -1:stored_bootdelay是倒数的总时间,就是常见的3秒、5秒不等;
● s:传进来的参数s不能为空;
● !abortboot(stored_bootdelay):该函数会从stored_bootdelay开始倒计时,期间判断是否有按键按下。函数实现如下,倒计时过程中若检测到按键按下,则令abort=1。无按键按下,则abort=0。最后返回abort。/* <u-boot>/common/autoboot.c */ ... static int __abortboot(int bootdelay) { int abort = 0; unsigned long ts; #ifdef CONFIG_MENUPROMPT printf(CONFIG_MENUPROMPT); #else printf("Hit any key to stop autoboot: %2d ", bootdelay); #endif /* * Check if key already pressed */ if (tstc()) { /* we got a key press */ (void) getc(); /* consume input */ puts("\b\b\b 0"); abort = 1; /* don't auto boot */ } while ((bootdelay > 0) && (!abort)) { --bootdelay; /* delay 1000 ms */ ts = get_timer(0); do { if (tstc()) { /* we got a key press */ abort = 1; /* don't auto boot */ bootdelay = 0; /* no more delay */ # ifdef CONFIG_MENUKEY menukey = getc(); # else (void) getc(); /* consume input */ # endif break; } udelay(10000); } while (!abort && get_timer(ts) < 1000); printf("\b\b\b%2d ", bootdelay); } putc('\n'); return abort; } ...
刚刚说了,abortboot() 函数执行期间有按键按下的话,abortboot() 会返回1,那就不会进入第一个if,程序会接着往下运行直至该函数运行结束。autoboot_command() 结束后继续返回到main_loop(),随后立刻执行cli_loop(),进入我们所熟悉的U-Boot命令行模式。
至此,就实现了U-Boot倒数期间,有按键按下,则进入U-Boot的命令行模式。
现在继续回到第一个if:/* <u-boot>/common/autoboot.c */ void autoboot_command(const char *s) { ... if (stored_bootdelay != -1 && s && !abortboot(stored_bootdelay)) { // 倒计时过程中,没有按键按下 #if defined(CONFIG_AUTOBOOT_KEYED) && !defined(CONFIG_AUTOBOOT_KEYED_CTRLC) int prev = disable_ctrlc(1); /* disable Control C checking */ #endif run_command_list(s, -1, 0); // 倒计时结束后,启动内核 #if defined(CONFIG_AUTOBOOT_KEYED) && !defined(CONFIG_AUTOBOOT_KEYED_CTRLC) disable_ctrlc(prev); /* restore Control C checking */ #endif } ... }
如果在autoboot倒计时结束前,一直没有按键按下呢?那 abortboot() 最后会返回0,第一个if的三个条件全部满足。进入if,run_command_list() 执行一系列命令后,启动内核。注意,这里的现象是直接启动内核,run_command_list() 后的程序不再执行。
解析到这里,我们得出一个结论:在autoboot倒计时中,如果有按键按下的话,会进入U-Boot的命令行模式。无按键按下则在倒计时结束后直接启动内核。
那现在可以回答第一个问题,如何做到按下按键后,是自启动U-Boot菜单,而不是进入U-Boot命令行呢?答案是在执行cli_loop()之前,我们可以在autoboot检测到按键按下后,调用run_command()函数执行menu命令,从而调起菜单。void autoboot_command(const char *s) { debug("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>"); if (stored_bootdelay != -1 && s && !abortboot(stored_bootdelay)) { #if defined(CONFIG_AUTOBOOT_KEYED) && !defined(CONFIG_AUTOBOOT_KEYED_CTRLC) int prev = disable_ctrlc(1); /* disable Control C checking */ #endif run_command_list(s, -1, 0); #if defined(CONFIG_AUTOBOOT_KEYED) && !defined(CONFIG_AUTOBOOT_KEYED_CTRLC) disable_ctrlc(prev); /* restore Control C checking */ #endif } //在此处启动菜单 run_command("menu", 0); #ifdef CONFIG_MENUKEY if (menukey == CONFIG_MENUKEY) { s = env_get("menucmd"); if (s) run_command_list(s, -1, 0); } #endif /* CONFIG_MENUKEY */ }
四、U-Boot添加自定义命令
难道通过 run_command() 执行menu命令后,菜单就自己出来了?这是一个理所当然的猜想。实际上U-Boot根本不认识menu命令:
接下来看看如何添加U-Boot命令,参考一下别人的代码:/* <u-boot>/board/BuS/eb_cpu5282/eb_cpu5282.c */ int do_brightness(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int rcode = 0; ulong side; ulong bright; switch (argc) { case 3: side = simple_strtoul(argv[1], NULL, 10); bright = simple_strtoul(argv[2], NULL, 10); if ((side >= 0) && (side <= 3) && (bright >= 0) && (bright <= 1000)) { vcxk_setbrightness(side, bright); rcode = 0; } else { printf("parameters out of range\n"); printf("Usage:\n%s\n", cmdtp->usage); rcode = 1; } break; default: printf("Usage:\n%s\n", cmdtp->usage); rcode = 1; break; } return rcode; } U_BOOT_CMD( bright, 3, 0, do_brightness, "here is uboot mymenu\n", "here is uboot mymenu, make in 2024-05-15\n" );
先看最底下的U_BOOT_CMD,这是一个宏,用来添加U-Boot命令:
/* <u-boot>/include/command.h */ #define U_BOOT_CMD(_name, _maxargs, _rep, _cmd, _usage, _help) \ U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, NULL)
● _name:命令的名字
● _maxargs:添加的命令最多有几个参数
● _rep:是否重复(1重复,0不重复),指在U-Boot命令行按下Enter键的时候,重复执行上次的命令
● _cmd:执行函数(即执行该命令后,运行哪个函数)
● _usage:短帮助信息
● _help:长帮助信息再来看看执行函数do_brightness的声名:
int (*cmd)(struct cmd_tbl_s *cmdtp, int flag, int argc, char *const argv[]);
● cmdtp:Table entry describing the command (see above).
● flag:A bitmap which may contain the following bit
○ CMD_FLAG_REPEAT - The last command is repeated.
○ CMD_FLAG_BOOTD - The command is called by the bootd command.
○ CMD_FLAG_ENV - The command is called by the run command.
● argc:执行命令时,传入的参数数量
● argv:传入的参数五、实践
下面,添加一个U-Boot菜单,不过只作打印,没有实际功能。
在 <u-boot>/drivers 下创建一个名为mymenu的文件夹:
在mymenu文件夹下创建mymenu.c,内容如下:#include <common.h> #include <command.h> #include <linux/ctype.h> #include <cli.h> #include <fs.h> static int do_mymenu(struct cmd_tbl_s *cmdtp, int flag, int argc, char *const argv[]) { printf("\n======== Title ========\n"); printf("== [1] xxxxxx\n"); printf("== [2] xxxxxx\n"); printf("== [3] xxxxxx\n"); printf("== [4] xxxxxx\n"); printf("=========================\n\n"); return 0; } U_BOOT_CMD( menu, 1, 1, do_mymenu, "here is uboot menu\n", "here is uboot menu, make in 2024-06-27\n" );
还需在mymenu文件夹下创建一个Makefile文件,内容如下:
obj-y += mymenu.o
最后修改 <u-boot>/drivers/ 下的Makefile,在结尾加上如下内容,表示要编译mymenu路径下的文件:
ifeq ($(CONFIG_SPL_BUILD)$(CONFIG_TPL_BUILD),) obj-y += mymenu/ endif
编译U-Boot,更新U-Boot,重启单板,在U-Boot倒计时结束前,按任意按键就进入我们自定义的菜单:
剩下的菜单程序编写就是根据实际功能来开发了。六、总结
若有描述错误欢迎指出。 -
T113 mmc list识别不到sd卡
请教各位大神!T113,使用sd卡启动,目前是可以正常进入系统的。现在的问题是在uboot命令行中,使用mmc list识别不到sd卡。现象如下:
-
回复: T113 tina5.0 无法进入uboot命令行
@cohen0415
已找到问题,uboot设备树lcd节点下的pinctrl-0属性改成rgb18_pins_a,pinctrl-1属性改成rgb18_pins_b。就可以进入uboot命令行了。
但是为啥会这样?我目前uboot和内核所使用的调试串口为uart3(PB6、PB7),和RGB引脚也不冲突啊。 -
T113 tina5.0 无法进入uboot命令行
T113,tina5.0。现在遇到一个问题,在适配完lcd屏后,现在按任意键进不了uboot命令行,按s也不行,按空格也不行。bootdelay是有的。
目前适配屏幕只修改了两个文件,分别是kernel和uboot的设备树。
kernel设备树修改如下:
uboot设备树修改如下:
在未适配屏幕前,是可以按任意键进入uboot的,所以很奇怪,不知道哪里有问题。和设备树中的disp节点设置有关吗?目前disp节点是没有设置的。
-
T113使用OverlayFS(Tina5.0)
请教大佬们。现在用的是tina5.0,T113,使用的buildroot系统不是openwrt。
怎么正经使用OverlayFS,比如现在是可以手动挂载的,下面命令是把根目录下的/usr挂载到/overlay/merge/usr:mount -t overlay overlay -o lowerdir=/usr,upperdir=/overlay/upper/usr,workdir=/overlay/work/usr /overlay/merge/usr
但这种做法只是体验了一下OverlayFS的应用。如何让整个根目录就是merge目录。需要增加什么分区吗?或者是个什么思路?
-
T113调试7寸RGB电容触摸屏
软硬件介绍
软件
基于Tina5.0 SDK。
板卡
韦东山的T113工业板:
屏幕
韦东山的7寸RGB电容触摸屏:
显示调试
修改内核设备树
打开内核设备树
<SDK>/device/config/chips/t113/configs/evb1_auto/linux-5.4/board.dts
,找到lcd0节点:/* board.dts */ ... ... &lcd0 { lcd_used = <1>; lcd_driver_name = "default_lcd"; lcd_backlight = <50>; lcd_if = <0>; lcd_x = <1024>; lcd_y = <600>; lcd_width = <150>; lcd_height = <94>; lcd_dclk_freq = <50>; lcd_pwm_used = <1>; lcd_pwm_ch = <7>; lcd_pwm_freq = <50000>; lcd_pwm_pol = <1>; lcd_pwm_max_limit = <255>; lcd_hbp = <160>; lcd_ht = <1344>; lcd_hspw = <20>; lcd_vbp = <23>; lcd_vt = <635>; lcd_vspw = <3>; lcd_lvds_if = <0>; lcd_lvds_colordepth = <0>; lcd_lvds_mode = <0>; lcd_frm = <1>; lcd_hv_clk_phase = <0>; lcd_hv_sync_polarity= <0>; lcd_gamma_en = <0>; lcd_bright_curve_en = <0>; lcd_cmap_en = <0>; deu_mode = <0>; lcdgamma4iep = <22>; smart_color = <90>; pinctrl-0 = <&rgb24_pins_a>; pinctrl-1 = <&rgb24_pins_b>; }; ... ...
只需关注以下参数:
lcd_if = <3>; // 0:LCD 3:LVDS lcd_x = <1024>; // x方向分辨率 lcd_y = <600>; // y方向分辨率 lcd_dclk_freq = <50>; // lcd_ht * lcd_vt * fps(60),单位MHz lcd_hbp = <160>; // 对应屏厂HBP lcd_ht = <1344>; // 对应屏厂Width + HSW + HBP + HFP lcd_hspw = <20>; // 对应屏厂HSW lcd_vbp = <23>; // 对应屏厂VBP lcd_vt = <635>; // 对应屏厂Height + VSW + VBP + VFP lcd_vspw = <3>; // 对应屏厂VSW lcd_frm = <1>; // 1:rgb666 pinctrl-0 = <&rgb24_pins_a>; // pinctrl-1 = <&rgb24_pins_b>; //
修改U-Boot设备树
打开内核设备树
<SDK>/device/config/chips/t113/configs/evb1_auto/uboot-board.dts
,找到lcd0节点,把刚刚修改过的内核设备树中的lcd0节点复制到U-Boot设备树。
注意:一定要同步修改U-Boot设备树,若只修改内核中的设备树,是点不亮屏幕的。显示测试
花屏测试:
cat /dev/urandom > /dev/fb0
colorbar测试:
cat /dev/zero > /dev/fb0 echo 8 > /sys/class/disp/disp/attr/colorbar
至此,屏幕已成功点亮。
添加启动logo
正常情况下,当屏幕可以正常驱动后,开机上电,logo就会显示在屏幕中间。在Tina5.0中,logo文件存放在
<SDK>/device/config/chips/t113/boot-resource/boot-resource/bootlogo.bmp
,替换bootlogo.bmp为自己的logo后,重新pack打包即可。
关于bootlogo.bmp图片的格式,需要注意以下几点:
1、bootlogo.bmp的名字不能随便起,包括后缀;
2、图片的分辨率不能大于屏幕的分辨率,否则不会显示;
3、若是32位色的图片(即ARGB格式),请注意图片的透明度不能为0,否则不会显示;
若logo图片太大导致打包时出现错误,修改分区表<SDK>/device/config/chips/t113/configs/evb1_auto/buildroot/sys_partition.fex
中的boot-resource分区大小即可:
其它问题
若出现颜色显示错误,请留意数据脚的顺序,LD23-LD0中,高8位为R通道,低8位为B通道,中间的8位为G通道:
触摸调试
修改内核设备树
该屏幕的驱动IC为GT911,通过原理图可以看到是接在TWI2(PE12、PE13),INT脚为PE1,RST脚为PE0:
打开内核设备树<SDK>/device/config/chips/t113/configs/evb1_auto/linux-5.4/board.dts
,将ctp节点挂在TWI2节点下,并启用TWI2和ctp。注意要按实际情况修改INT脚和RST脚:
触摸测试
查看输入节点:
cat /proc/bus/input/devices
查看原始触摸数据:hexdump /dev/input/event5
查看中断:cat /proc/interrupts