您尚未登录。

#1 Re: 全志 SOC » 求助BGA焊接教程,以全志H3为例子,用钢网?风枪?焊油?锡膏? » 今天 02:04:24

sunxiang 说:

@TeveT
可以搞个简单的视频教程吗,手残党好难受

大佬,你要的教程我整了
内存植锡练手,给全志D1开发板换1GB内存 https://b23.tv/MNjIy5l

#2 全志 SOC » 给D1开发板的程序整个大豪斯(内存512MB换1GB) » 今天 02:02:31

TeveT
回复: 1

刚整了个d1的开发板玩玩,刷了debian试了下,感觉启动好慢,
另外,内存512感觉不是很舒适,刚好有废料板3288上有1GB内存,
换一下,顺便搞个植锡小过程,供没操作过bga的坑友尝尝鲜。

注意啊,这个没有任何的广告,锡膏钢网都很便宜,当然,风枪不便宜。

IMG_20220123_003812.jpg


视频整上b站了
内存植锡练手,给全志D1开发板换1GB内存 https://b23.tv/MNjIy5l

#3 Re: SigmaStar/SSD201/SSD202/SSD212 » SSD20X直接编译lvgl7.10带双缓(附源码) » 2022-01-14 20:13:24

笔走天下 说:

强啊,这个开发板有链接吗

有的,淘宝搜一下就有了,或者自己做一个。

#4 Re: SigmaStar/SSD201/SSD202/SSD212 » SSD20X直接编译lvgl7.10带双缓(附源码) » 2022-01-06 14:19:08

@pencil
注意看下你的屏幕初始化和你的屏幕是否是对上的,开发板是CC0702I50R_1024x600.h这个头文件做的初始化序列和液晶屏显示参数传递。

你如果logo正常,那就把logo那边显示的参数拿出来,来修改这个h文件
可以看下sstardisp.c 这些相关信息。

#5 Re: SigmaStar/SSD201/SSD202/SSD212 » SSD20X直接编译lvgl7.10带双缓(附源码) » 2022-01-06 10:16:55

@pencil
程序已经跑起来了,
你的屏幕初始化配置文件是否搞对了,分辨率,双缓大小是否能对上,
报错是没有触摸。

#7 Re: 全志 SOC » 求助BGA焊接教程,以全志H3为例子,用钢网?风枪?焊油?锡膏? » 2021-12-06 20:03:40

sunxiang 说:

@TeveT
可以搞个简单的视频教程吗,手残党好难受

B站的都还可以呀, 比如那个 艾奥科技啥的,不过他们都是 快克的那种手机维修热风枪,温度你要自己把握就行了

#8 Re: SigmaStar/SSD201/SSD202/SSD212 » SSD20X直接编译lvgl7.10带双缓(附源码) » 2021-12-04 16:39:14

zhou 说:

@TeveT
您好  同缓存大小 我加到8192了,接入LVGL8单缓存是能正常使用的,接入这个7.10双缓的就是会闪屏,是因为在切换双缓存导致的吗?

计算很简单的
我之所以修改为 4800 是因为 1024x600x4x2/1024 = 4800
H x V x 单一像素字节数量 x 2(双缓冲) / 1024

#9 Re: SigmaStar/SSD201/SSD202/SSD212 » SSD20X直接编译lvgl7.10带双缓(附源码) » 2021-12-04 16:37:21

zhou 说:

@TeveT
您好  同缓存大小 我加到8192了,接入LVGL8单缓存是能正常使用的,接入这个7.10双缓的就是会闪屏,是因为在切换双缓存导致的吗?

我代码里是写了除以2后刚好是整屏幕大小, 你的这个buffer 如果没有另作他用,我的代码不修改的前提下, 你的buffer大小也要写成固定的你的屏幕的缓冲区的2倍才行的,不会算的话你可以报上来你的屏幕尺寸大小我给你个数值也行。

#10 Re: SigmaStar/SSD201/SSD202/SSD212 » SSD20X直接编译lvgl7.10带双缓(附源码) » 2021-12-04 13:10:24

zhou 说:

请问  我这边接入LVGL后 显示 一亮一灭 这个是怎么导致的?显示是有的。一般是哪部分引起的现象。https://whycan.com/files/members/1813/d61c12ed6a33ecb12217fcbc4a816478.mp4

5、注意修改双缓的缓冲区大小
要修改 /config/fbdev.ini 修改缓冲区到2倍的大小 4800x1024 (原来是4096, 不改会段错误)

FB_BUFFER_LEN = 4800

你的机器不是开发板的话,需要自己计算一下,修改一下

#11 Re: 全志 SOC » 求助BGA焊接教程,以全志H3为例子,用钢网?风枪?焊油?锡膏? » 2021-12-02 12:58:56

@arychen
注意哈,
1.首先芯片确保平整,干净,要洗板水洗干净。
2.锡膏太湿润不行,要用纸巾捏一下,(最好不咋掉毛的那种,维达啥的都可以,杂牌擦屁股的别用)
3.放钢网前,底下垫一张对折后的纸巾,让芯片固定不跑,同时纸巾保温
4.钢网一定要压住不能动,刮锡膏要少量,力度均匀,一个方向
5.刮完锡膏,轻轻铲干净锡膏后,要用纸巾擦一下,去除多余的锡膏,也可以用无尘布操作
6.风枪温度根据锡膏,中温啥的不用很高300左右就可以,吹的时候不能一个点吹,要来回动一下,从一边吹开始,赶鸭子一样来回吹,赶到另一边。

#12 Re: 全志 SOC » 求助BGA焊接教程,以全志H3为例子,用钢网?风枪?焊油?锡膏? » 2021-12-02 09:44:44

@sunxiang
这个东西几十块钱套件搞定了,如果是新的芯片,自带的球了,直接看第三步
就用 锡膏和钢网,
1、烙铁抚平CPU上所有毛躁,清理干净(用洗板水),对准钢网,刮锡膏上锡,可以用中温的锡膏,有专门卖的,
2、上了后吹一下,拿掉钢网,大概8秒的时候拿掉保险,拿掉后上点点助焊剂,风枪吹一下,让锡球归位
3、PCB抚平毛躁,上点助焊剂,薄薄一层就好,对位,可以偏差0.1到0.2mm,风枪温度要自己尝试,我是用400 ,十来秒就搞定了,吹焊后会主动归位

我是买的某宝的某某易修的店铺,自己搜下就有。
是手艺活,但是不难。

#13 Re: SigmaStar/SSD201/SSD202/SSD212 » SSD20X直接编译lvgl7.10带双缓(附源码) » 2021-11-30 17:10:02

pencil 说:

放在服务器下编译,还是报很多错,我一时也搞不明白

注意project的目录,注意阅读一下Makefile

├── LVGL7.10-SSD202
│   ├── export-ssd20x-gcc.sh
│   ├── gcc-arm-8.2-2018.08-x86_64-arm-linux-gnueabihf
│   ├── linux_frame_buffer
├── project

#14 Re: SigmaStar/SSD201/SSD202/SSD212 » SSD20X直接编译lvgl7.10带双缓(附源码) » 2021-11-30 14:31:50

@pencil
芜湖? 建议使用我网盘上传的试一下。
坛主上传的我不太清楚呢,毕竟下载要分数。

#15 Re: 全志 SOC » v3s和LCD通过i8080总线模式 » 2021-11-27 18:06:23

sunxiang 说:

我也说两句,以前用过NUC977的板子,就是8080方式驱动的,感觉8080这种方式用的人还是太少了(这种接口应该更适合MCU吧)。

并不啊, 使用8080 一样可以播视频啥的,很给力的。 当然.,TE得接上

#16 Re: 全志 SOC » v3s接usb摄像头显示问题 » 2021-11-25 09:43:18

问题不大的。
测试过tina 的版本,直接使用trecorder 测试过,也自己用v4l2来测试过,完全没问题,自己弄来测试的话 拿mjpeg转一下就能用了
如果要出264,mjpeg转yuv,然后再编码264,妥妥的,我直接点过宽动态USB出的图像做视频推流,舒服的。

#17 Re: 全志 SOC » V3s tina 3.5 编译了一个固件,烧录不进去,请问是怎么回事呢? » 2021-10-08 12:02:53

大佬你是要烧录到哪里
显然,烧录的存储介质没找到。
如果是要进SD卡,要小改一下下。

#18 Re: 君正Ingenic/X1000/X2000/T10/T20/T30 » 第一次做四层板(还是BGA主控) » 2021-09-02 23:00:07

可以涂敷薄薄一层焊油,直接吹焊

sunxiang 说:

BGA封装如何焊接呢,我只会焊接LQPF,下周再试试焊接QFN封装。BGA焊接是用钢网刷锡膏,然后放芯片在PCB上,然后上热风枪吗?

#19 Re: SigmaStar/SSD201/SSD202/SSD212 » SSD20X直接编译lvgl7.10带双缓(附源码) » 2021-09-02 19:48:02

对的这个帖子就是拉lvgl fb 改的,加入了你说的初始化部分,只是填坑

regbbs 说:

lvgl_v8.zip
8.0的,lv_driver替换的时候注意不要把文件覆盖了。
其实lvgl的git上面有linux的移植,基于frame buffer。只要把ssd20x的特定初始化部分添加上就可以。

#20 Re: 全志 SOC » V3S Double Fb 有什么思路或者参考吗 大佬们 » 2021-09-02 19:46:41

大佬跑的是哪个系统代码, TINA 还是主线 还是?

#21 Re: SigmaStar/SSD201/SSD202/SSD212 » SSD20X直接编译lvgl7.10带双缓(附源码) » 2021-09-02 12:22:49

注意下我帖子里描述的依赖路径project 还有lvgl 的Makefile
你的这个缺少的库在这个路径下面:
SDK_LIBS=../project/release/nvr/i2m/common/glibc/8.2.1/mi_libs/dynamic

weiyongwill 说:

我自己搞了个demo,提示缺少库文件 libmi_disp.so

#24 Re: 全志 SOC » 分享在V3S RTL8723DS 上调试蓝牙音频的一点经验 » 2021-07-31 15:34:06

无法用dbus 发送事件去上下曲 ,应当是bluealsa 的插件没打开

#27 全志 SOC » S3/V3S芯片跑Tina 3.5版本的gpio_keys使用 » 2021-06-02 20:03:06

TeveT
回复: 0

如题,分享一下

sun8iw8p1-pinctrl.dtsi 添加:

			key_pins: key_pins@0 {
				allwinner,pins= "PB12";
				allwinner,function = "gpio_in";
				allwinner,muxsel = <0>;
				allwinner,drive = <1>;
				allwinner,pull = <1>;
			};	

board.dts 添加:

gpio_keys {
	compatible = "gpio-keys";
	pinctrl-names = "default";
	pinctrl-0 = <&key_pins>;
	
	autorepeat;
	button@1 {
			label = "Key home";
			linux,code =  <158>;
			gpios =  <&pio 1 12 6 1 1 1>;
			gpio-key,wakeup;
			//interrupt-parent = <&pio>;
			//interrupts = <1 12 IRQ_TYPE_EDGE_FALLING>; //PB12			
	};
};

好,接着奏乐,接着舞……

#29 Re: SigmaStar/SSD201/SSD202/SSD212 » SSD20X直接编译lvgl7.10带双缓(附源码) » 2021-05-30 20:37:29

有公开啊,但是没有全部公开。
比较暧昧吧,没有TRM

novice 说:

这个SSD20X有没有公开资料?

#30 Re: SigmaStar/SSD201/SSD202/SSD212 » SSD20X直接编译lvgl7.10带双缓(附源码) » 2021-05-30 12:51:03

都嘛系开源的东西,修改了抛上来共享下大大滴好,
如果有小毛病被鞭尸后还能共同进步,来嘛来嘛

duanchangstar 说:
cube 说:
duanchangstar 说:

已经搞定了AWTK的双缓冲,使用了楼主的方法。感谢~

方便分享一下diff差异文件吗?

按楼主的方法做就行了

#32 Re: SigmaStar/SSD201/SSD202/SSD212 » SSD20X直接编译lvgl7.10带双缓(附源码) » 2021-05-29 11:12:39

看来楼上的楼上大佬已经了解了fb的操作过程,改起来应当是大同小异哈,

cube 说:
duanchangstar 说:

已经搞定了AWTK的双缓冲,使用了楼主的方法。感谢~

方便分享一下diff差异文件吗?

#33 Re: SigmaStar/SSD201/SSD202/SSD212 » SSD20X直接编译lvgl7.10带双缓(附源码) » 2021-05-28 22:29:54

好滴,感谢分享,搞搞看

cube 说:
TeveT 说:

咋说,awtk 本地编译有包吗,我弄来看看

duanchangstar 说:

楼主很厉害啊,可以顺便搞一下AWTK的双缓冲吗

https://github.com/zlgopen/awtk

#34 Re: SigmaStar/SSD201/SSD202/SSD212 » SSD20X直接编译lvgl7.10带双缓(附源码) » 2021-05-28 22:14:19

咋说,awtk 本地编译有包吗,我弄来看看

duanchangstar 说:

楼主很厉害啊,可以顺便搞一下AWTK的双缓冲吗

#35 Re: 全志 SOC » 全志D1芯片之终极探索 » 2021-05-25 21:55:56

前来膜拜大神
D1包了那么多东西,然而少了MIPI-CSI 和 H264编码,不然就齐活了

#36 Re: 全志 SOC » 大佬们求帮助,自画荔枝派,ea3036芯片的电压没有输出来 » 2021-05-23 19:46:25

同时,这电感布局放置有问题,要靠近出线位置,不要怼一起。

拉轰的脚踏车 说:
hz2 说:
zzm24 说:

不看3036 datasheet,按照我用过DCDC的经验,EN都是高电平有效,楼主可以改版了

EN确实是高电平有效,奇怪,楼主没看手册吗?

闻道有先后,术业有专攻, 这个没必要苛求, 下次肯定长记性了.

#37 Re: 全志 SOC » 关于荔枝派zeroplus 底板电路几点疑问 » 2021-05-19 17:31:15

大佬,点摄像头不要共用电源,最好独立LDO, PWDN 脚可以和 LDO的供电使能联动。
点摄像头不要共用电源,点摄像头不要共用电源

#38 Re: 全志 SOC » S3/V3S芯片跑Tina版本的固定以太网MAC支持 » 2021-05-19 10:53:59

咩? 实现了吧,没太注意,这个MAC还是各种神马计算算出来的。
因为我烧录这个系统后,每个机器都是一个MAC地址,所以才烦

raspberryman 说:

zeta实现了吗?

#39 全志 SOC » S3/V3S芯片跑Tina版本的固定以太网MAC支持 » 2021-05-19 10:24:13

TeveT
回复: 2

如题,没有固定MAC,没有绑定chipid,TXD烦死了,

很烦地看了一通代码,对比下ZETA

搞上:
sun8iw8p1.dtsi 中:
    chipid: sunxi-chipid@1c23800 {
        compatible = "allwinner,sunxi-chipid";
        device_type = "chipid";
        reg = <0x0 0x01c23800 0 0x0100>; /* chipid */
    };

lichee\linux-4.9\drivers\net\ethernet\allwinner\sunxi-gmac.c 中:

extern int sunxi_get_soc_chipid(uint8_t *chip_id);
//#define sunxi_get_soc_chipid(x) {}

嗯,接着奏乐,接着舞。

#40 Re: 计算机图形/GUI/RTOS/FileSystem/OpenGL/DirectX/SDL2 » LVGL的linux_frame_buffer项目加入FB双缓 » 2021-05-15 17:43:41

一个是 ioctl 拿到的 FBIOGET_FSCREENINFO 的缓冲区大小
另外就是
查看驱动代码的ioctl, FBIOPAN_DISPLAY 是否有被处理,处理后是否调用了硬件显示资源。

lvzaina 说:

谢谢大神,请问下怎么判断目标内核支持双缓存?

#41 Re: 全志 SOC » 发现荔枝派PLUS有一个很脑残的设计,好惨 » 2021-05-15 10:35:56

我是整个板子连同他们设计的底板一起买的,那个板子没有问题。
如果是自己设计底板,当然是要小心对上。
与其说这个设计的GND和电源挨得太近, 不如说底板没设计好或者焊接出问题。
因为一旦GND和电源共死了,其他脚位也无法避免短路。

或者你说对手工焊接底板的爱好者不太友好也无可厚非。

阿黄 说:
TeveT 说:

不不不不,
这不到1mm就算紧挨着?

不至于不至于
你铺地铜间距也就8mil 10 mil 怎么不会短?
问题来了,你是怎么操作了呢,是直接下烙铁?
毕竟我的没有烧
另外固态硬盘也是m.2 意思是你也得烧几片么

microxp 说:

居然把vcc和gnd脚紧挨在一起,金手指那么细的线,间距不到1mm,一不小心就短路了,都烧了好几块了......

多方面可能,1.螺丝孔位置做的有点偏,导致固定之后板子斜了,2. 由于是2个m2座子,2个M2座子如果有安装偏差,也可能导致板子有点偏

#42 Re: 全志 SOC » 发现荔枝派PLUS有一个很脑残的设计,好惨 » 2021-05-14 09:16:02

不不不不,
这不到1mm就算紧挨着?

不至于不至于
你铺地铜间距也就8mil 10 mil 怎么不会短?
问题来了,你是怎么操作了呢,是直接下烙铁?
毕竟我的没有烧
另外固态硬盘也是m.2 意思是你也得烧几片么

microxp 说:

居然把vcc和gnd脚紧挨在一起,金手指那么细的线,间距不到1mm,一不小心就短路了,都烧了好几块了......

#43 Re: 全志 SOC » V3S tina系统 如何添加外置RTC » 2021-05-13 14:43:50

V3S tina系统 是 linux4.9 允许使用设备树

奔跑的孩子 说:

V3s的linux版本是3.4,当时没有设备树,是全志魔改的fex

#44 Re: 全志 SOC » V3S tina系统 如何添加外置RTC » 2021-05-13 14:26:03

修改到了内核代码区了?
不至于不至于,
直接设备树配置:board.dts

&twi0{
status = "okay";
        hym8563: hym8563@51 {
                compatible = "haoyu,hym8563";
                reg = <0x51>;

        };
};

同时内核打开 hym8563 的开关,编译进内核,搞定了。

只能帮你到这儿了。

#45 Re: 全志 SOC » 谁画过S3的板子的,网卡我搞不定咋办哦 » 2021-05-07 10:15:59

大佬啊, EPHY_RTX  对地有个 6K 电阻,接没接。

microxp 说:

荔枝派的zero plus,没有用官方提供的变压器+RJ45的接法,用的HR911105A,仿的这个帖子里的接法
https://whycan.com/t_3887.html
https://whycan.cn/files/members/1206/NanoPi-M1.jpg
看固件网卡运行正常,也能正常ifconfig up,但就是插上网线不通哦
咋调试呢,量了一下Link灯也不亮,link灯那个引脚有1.8v
是因为没有严格做那个100欧的差分线?我就随便画的差分线,算了下估计90欧左右,应该也能用吧
另外看索智S3和荔枝派的V3S都有一个PHY_RTX的引脚,荔枝派 plus就没有这个引脚,是不是这个原因

#46 Re: SigmaStar/SSD201/SSD202/SSD212 » SSD20X直接编译lvgl7.10带双缓(附源码) » 2021-04-21 14:54:37

详细请看 JpegPlayer ,代码包有的

981378640 说:

楼主啊,如何显示外部的jpg图片啊?有没有Demo参考一下啊

#47 Re: 全志 SOC » tiny200开发板跑tina3.5, 使用 芯天下/雷龙 sdnand芯片从SDC1启动(1BIT模式), 启动失败,但是烧录正常 » 2021-04-01 11:50:38

意思是你这个自己没有修改过TINA的boot, 直接就烧录了对吗?
我用的是V3S 的tina3.5, 是自己魔改,要看看代码。

无根浮萍 说:
TeveT 说:

uboot烧录部分改对了没

无根浮萍 说:

https://whycan.com/files/members/5755/2021-03-31_113740.png

果然只有一个分区,这是为什么呢?

请问应该怎么修改呢?我几乎翻越了所有tina文档,都木找到有。

#50 Re: 全志 SOC » 全志官方tina linux sdk sys_config.fex 的 uart_debug_port 参数是如何影响uboot和linux » 2021-03-29 08:47:41

不是直接lunch么,内核版本选择没弄过

raspberryman 说:
TeveT 说:

楼主用的是3.5的吗,4.9的内核版本,已经可以直接操作dts了呀

请问如何选择linux版本?f1c200s  tina3.5

#51 Re: 全志 SOC » 全志官方tina linux sdk sys_config.fex 的 uart_debug_port 参数是如何影响uboot和linux » 2021-03-28 23:37:42

楼主用的是3.5的吗,4.9的内核版本,已经可以直接操作dts了呀

#52 Re: 全志 SOC » 玩弄bluetoothctl的时候直接拿过来单独编译搞事情(附源码) » 2021-03-26 18:13:25

参考我的这个: https://whycan.com/t_5305.html

test0001 说:

大佬,bluez做蓝牙音箱要咋用,用pulseaudio,
搞晕了都

#53 Re: 全志 SOC » 玩弄bluetoothctl的时候直接拿过来单独编译搞事情(附源码) » 2021-03-08 15:28:16

依赖库对了吗,make clean 一下编。

leonaTian 说:

楼主,你好,最近也在这个蓝牙,用你这个代码编译(交叉编译器:arm-himix200-linux-gcc)失败,如下:
...
这个是什么情况?

#54 Re: SigmaStar/SSD201/SSD202/SSD212 » SSD20X直接编译lvgl7.10带双缓(附源码) » 2021-03-06 08:43:45

大佬另开个帖子呀,顶上去

caszhao 说:

在楼主的基础上增加rotation,开源了:
https://github.com/caszhao/ssd_lvgl

#55 Re: 全志 SOC » 玩弄bluetoothctl的时候直接拿过来单独编译搞事情(附源码) » 2021-03-05 13:45:09

可以通过bluetoothctl的代码骚修改来打开dbus的大门,哈哈哈,

sy373466062 说:

还是DBUS功能全一些

#56 Re: 全志 SOC » 玩弄bluetoothctl的时候直接拿过来单独编译搞事情(附源码) » 2021-03-05 09:21:50

吾乃菜狗,请多指教

raspberryman 说:

那有空我试一试,再次感谢楼主分享!  有不明白的问题再跟帖请教。

#57 Re: 全志 SOC » 玩弄bluetoothctl的时候直接拿过来单独编译搞事情(附源码) » 2021-03-05 09:12:38

编译器和库的依赖路径要改一下,应该是没问题的。

raspberryman 说:

dbus不适合嵌入式环境,在桌面也有点奇葩,估计是为了进程互操作和解藕吧。

我也想试一试,请问楼主这个代码可以在Ubuntu玩吗?

TeveT 说:

主要就是不想花大时间弄dbus,既然拿出来单独用就分享一下,都是bluez的代码哈哈哈哈,嵌入自己的代码只要回调注册搞一搞,界面交互效率高

raspberryman 说:

感谢楼主分享,我以前参考晕哥那个 btstack帖子搞了一个demo,后来没有玩了

郁闷,没有搞定 Ubuntu下用btstack协议栈驱动 RTL8723BS
http://whycan.com/t_1133.html#p53670

咦,居然发现楼主也玩了 btstack...

#58 Re: 全志 SOC » 玩弄bluetoothctl的时候直接拿过来单独编译搞事情(附源码) » 2021-03-05 08:58:13

没有玩btstack啦,那时候测试驱动包,
最后测试发现,蓝牙声音出问题是因为驱动打印log问题

raspberryman 说:

感谢楼主分享,我以前参考晕哥那个 btstack帖子搞了一个demo,后来没有玩了

郁闷,没有搞定 Ubuntu下用btstack协议栈驱动 RTL8723BS
http://whycan.com/t_1133.html#p53670

咦,居然发现楼主也玩了 btstack...

TeveT 说:

对的,我直接拿这部分嵌入我的代码,做蓝牙播放器界面

奔跑的孩子 说:

请问楼主 bluetoothctl 是bluez 的源码包里面的吗?

#59 Re: 全志 SOC » 玩弄bluetoothctl的时候直接拿过来单独编译搞事情(附源码) » 2021-03-05 08:54:00

主要就是不想花大时间弄dbus,既然拿出来单独用就分享一下,都是bluez的代码哈哈哈哈,嵌入自己的代码只要回调注册搞一搞,界面交互效率高

raspberryman 说:

感谢楼主分享,我以前参考晕哥那个 btstack帖子搞了一个demo,后来没有玩了

郁闷,没有搞定 Ubuntu下用btstack协议栈驱动 RTL8723BS
http://whycan.com/t_1133.html#p53670

咦,居然发现楼主也玩了 btstack...

TeveT 说:

对的,我直接拿这部分嵌入我的代码,做蓝牙播放器界面

奔跑的孩子 说:

请问楼主 bluetoothctl 是bluez 的源码包里面的吗?

#60 Re: 全志 SOC » 玩弄bluetoothctl的时候直接拿过来单独编译搞事情(附源码) » 2021-03-05 08:42:19

对的,我直接拿这部分嵌入我的代码,做蓝牙播放器界面

奔跑的孩子 说:

请问楼主 bluetoothctl 是bluez 的源码包里面的吗?

#61 全志 SOC » 玩弄bluetoothctl的时候直接拿过来单独编译搞事情(附源码) » 2021-03-03 19:22:05

TeveT
回复: 15

平台 V3S, TINA
基于C,玩弄bluez的时候总感觉要在代码里去使用bluez的agent极其蛋疼,又没怎么处理过dbus的东西,既然如此,拿现成工具搞起来? 好!
如果要直接新开进程bluetoothctl , 可以这样:
使用Local socket 去访问,用socketpair 到一个文件流节点,然后 vfork 出进程,用一个循环去读文件流节点,来取得bluetoothctl 的返回值,
代码如下:

void bluetooth_pthread(void)
{
	int i = 0, ret,haveconnect = 0,sizeread = 0;
	char * Connectedyes = NULL,* Pairedyes = NULL,* yesorno = NULL,*tt = NULL;
   	int fds[2];
	pid_t pid; 
	unsigned char *datareadp = buf;
	memset(buf,0,sizeof(buf));

	char startbluetooth[128];
	sprintf(startbluetooth, "/usr/bin/bluetoothctl\n");

	if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0)
		return -1;

	switch(pid=vfork()) {
	case -1:    /* Error */
		close(fds[0]);
		close(fds[1]);
		return -1;
	case 0:     /* child */
		close(fds[0]);
		dup2(fds[1], 0);
		dup2(fds[1], 1);
		close(fds[1]);
		execl("/bin/sh", "sh", "-c", startbluetooth, NULL);
		//system(bluectl);
		_exit(127);
	}
	/* parent */
	close(fds[1]);
	bluectl =  fds[0];


	bluesafe_write(bluectl,"power on\n",sizeof("power on\n"));//Changing power on succeeded

	while(!blueQuit)
    {
		if((sizeread = read(bluectl,datareadp,4096))> 0)
		{
			printf("\nsizeread = %d\n", sizeread);
			if(LoopBluetoothStateAndHandle(buf) == 0 )//处理你收到的bluetoothctl的返回数据
			{
				
			}
			else
			{
				
			}
		}
	}
	
	blueThreadId = 0;

	close(bluectl);

}

啊这? 大写的蛋疼! 测试的时候还发现read 会断流,简直了还得处理断帧和粘帧? 不要啊!

好了,因为蛋疼所以倒腾。
直接抓了bluetoothctl 单独拿出来编译,这样你可以嵌入任何你自己的代码里,同时可以在代码里去控制bluetooth的任何状态。
这样可以更愉快地玩耍bluez 了,dbus还不用怎么操作, 如果大佬们有更好的办法,可以分享一下,那更感谢了。
当然,这个编译,只要你平台支持了bluez, 那换个平台也是OK的。

文件见附件:
mybluetoothctl.zip

#62 Re: SigmaStar/SSD201/SSD202/SSD212 » SSD20X直接编译lvgl7.10带双缓(附源码) » 2021-03-02 13:31:48

感谢大佬分享,一步到位,

SigmaStarStudy 说:

一体打包烧录固件:
ssd202-7inch-1024x600-spinand-20210302.7z

u-boot 烧录指令:

setenv serverip 192.168.1.99;setenv ipaddr 192.168.1.33;nand erase 0x0 0x8000000;tftp 0x20000000 o/sysimage-nand.img;nand write 0x20000000 0x0 ${filesize};

官方烧录器烧录:
https://whycan.com/files/members/5985/2021-03-02_124657.png

#64 Re: SigmaStar/SSD201/SSD202/SSD212 » SSD20X直接编译lvgl7.10带双缓(附源码) » 2021-02-28 12:27:52

哈哈哈哈,真的,搞这个需要开脑洞
不过怎么感觉你这个号是晕哥的马甲?

SigmaStarStudy 说:

感谢楼主指导, 终于搞定,

这一步一定要做:

5、注意修改双缓的缓冲区大小
要修改 /config/fbdev.ini 修改缓冲区到2倍的大小 4800x1024 (原来是4096, 不改会段错误)

FB_BUFFER_LEN = 4800

#66 Re: SigmaStar/SSD201/SSD202/SSD212 » SSD20X直接编译lvgl7.10带双缓(附源码) » 2021-02-25 11:21:53

高手,学习了

达克罗德 说:
TeveT 说:

嗯? 怎么理解呢,意思是,双缓冲下,在硬件disp控制器读帧过程中顿一下么, vsync机制是当前帧被使用的时候不会被填充么

达克罗德 说:

光双缓冲,没有vsync处理,应该还是有小概率产生撕裂吧

就怕切缓冲buff地址时候,如果发生在读帧过程中,一样会导致画面撕裂。感觉和硬件设计和驱动程序有关,也许某些SOC硬件可以保证直接切换地址不会导致问题。
不过我看许多SOC都还是明确要求在帧中断去切缓冲。
DRM的文档有关于这个双缓冲和VSync的说明:
https://github.com/dvdhrm/docs/blob/master/drm-howto/modeset-double-buffered.c
https://github.com/dvdhrm/docs/blob/master/drm-howto/modeset-vsync.c

If you run this example, you will notice that there is almost no flickering,
* anymore. The buffers are now swapped as a whole so each new frame shows
* always the whole new image. If you look carefully, you will notice that the
* modeset.c example showed many screen corruptions during redraw-cycles.
*
* However, this example is still not perfect. Imagine the display-controller is
* currently scanning out a new image and we call drmModeSetCrtc()
* simultaneously. It will then have the same effect as if we used a single
* buffer and we get some tearing. But, the chance that this happens is a lot
* less likely as with a single-buffer. This is because there is a long period
* between each frame called vertical-blank where the display-controller does
* not perform a scanout. If we swap the buffers in this period, we have the
* guarantee that there will be no tearing. See the modeset-vsync.c example if
* you want to know how you can guarantee that the swap takes place at a
* vertical-sync.

根据这个理解,即使硬件支持任意切缓冲不会导致画面撕裂,也还是会有问题。当绘图刷新率不稳定的时候,有可能会导致掉帧现象。你可以想象在一帧的时间里,如果不在v-blank时间来切缓冲,有可能刚好错过当前这一帧的数据。所以PC游戏里一般有个选项,锁定帧刷新到显卡vsync

#67 Re: SigmaStar/SSD201/SSD202/SSD212 » SSD20X直接编译lvgl7.10带双缓(附源码) » 2021-02-25 10:16:58

嗯? 怎么理解呢,意思是,双缓冲下,在硬件disp控制器读帧过程中顿一下么, vsync机制是当前帧被使用的时候不会被填充么

达克罗德 说:

光双缓冲,没有vsync处理,应该还是有小概率产生撕裂吧

#68 Re: SigmaStar/SSD201/SSD202/SSD212 » SSD20X直接编译lvgl7.10带双缓(附源码) » 2021-02-24 20:54:15

不会有撕裂的,你可以用手机超级慢动作拍一下就知道了,

fogwizard 说:

在大神的热心帮助下demo跑起来了,滑动的时候几乎没有撕裂感,比单缓冲好了几条街!

#69 SigmaStar/SSD201/SSD202/SSD212 » SSD20X直接编译lvgl7.10带双缓(附源码) » 2021-02-23 22:29:24

TeveT
回复: 57

如题,上周末应晕哥邀请解决下小问题。
启明云端的群有挺多群友需要这个东西。硬件平台是7寸 1024x600 的ssd202 开发板,自带一个点菜系统的demo
这里直接打包发送网盘:

链接: https://pan.baidu.com/s/117lyj1uTXC-Rt66Co07wLA
提取码:fkk5

释放后在配置好交叉编译器的条件下可以直接make出来,可执行文件是 demossd
上传在这儿

demossd.zip

几个细节注意下:
1、注意下我的代码的Makefile 依赖 SSD20X的源代码的project文件夹,
结构是这样的:

├── LVGL7.10-SSD202
│   ├── export-ssd20x-gcc.sh
│   ├── gcc-arm-8.2-2018.08-x86_64-arm-linux-gnueabihf
│   ├── linux_frame_buffer
├── project

2、释放出来代码后阅读下Makefile 或者修改一下自己的结构让它可以调用到project 的目录。
3 、另外ssd20x 这个平台比较不一样, 使用fb之前要配置硬件信息,
我是无脑直接搬运来用,可以阅读一下 sstardisp.c, 我直接搬运ssd20x 开发板源码的 JpegPlayer
4、这个LVGL7.10 的lv_demo_music 被我改了些参数,下拉窗大小和原装的demo程序不一样。 我就不改回去了反正就是改着玩的。

5、注意修改双缓的缓冲区大小
要修改 /config/fbdev.ini 修改缓冲区到2倍的大小 4800x1024 (原来是4096, 不改会段错误)

FB_BUFFER_LEN = 4800


好了编译跑一下飞起来吧。

视频是跑printer demo 的效果




以下由 @哇酷小管家 从楼主百度网盘下载
------------------------------------
本站下载: LVGL7.10-linux_framebuffer-SSD202-TEVET-PACK-20210223.tar.7z (约65M)

#70 Re: 计算机图形/GUI/RTOS/FileSystem/OpenGL/DirectX/SDL2 » LVGL的linux_frame_buffer项目加入FB双缓 » 2021-02-21 12:55:04

不行哈,我这边搞了一波SSD202 ,测试了下,是要修改 /config/fbdev.ini 修改缓冲区到2倍的大小 4800x1024,然后重启一下。
详见 https://whycan.com/t_6006.html 第14、15楼

另外附上 SSD20X 跑LVGL 的 fbdev相关文件 和 Makefile
LVGL7.10-SSD20X-TEVET_MODIFY.zip

fogwizard 说:

搭车请教一个问题,如果平台(SSD201)的framebuffer打印出来的len是4196304,而按一帧1024@600计算应该是2457600,两倍的关系应该是4915200,目前打印的finfo.smem_len比4915200,在这个情况下还能使用双缓冲吗? 谢谢

#71 Re: SigmaStar/SSD201/SSD202/SSD212 » 启明云端的7寸 1024*600 LCD SSD202 开发板从入门到放弃 » 2021-02-21 12:46:25

注意,修改了 /config/fbdev.ini 要重启机器才生效。

TeveT 说:

....

fogwizard 说:

哥,就是按照大神的帖子改的,ssd201平台finfo.smem_len打印出来不是2倍的buffer,无法切换,会crash, 使用单缓存可以显示,但是页面切换有撕裂感

#72 Re: SigmaStar/SSD201/SSD202/SSD212 » 启明云端的7寸 1024*600 LCD SSD202 开发板从入门到放弃 » 2021-02-21 12:45:51

嗯,下载编译烧录修改追踪改了一波,
这个打印出来还不够2倍的buffer大小,要修改 /config/fbdev.ini 修改缓冲区到2倍的大小 4800x1024
代码贴一下:

[FB_DEVICE]
FB_HWLAYER_ID = 1
FB_HWWIN_ID = 0
FB_HWLAYER_DST = 3
FB_HWWIN_FORMAT = 5
FB_HWLAYER_OUTPUTCOLOR = 1
FB_WIDTH = 1024
FB_HEIGHT = 600
FB_TIMMING_WIDTH = 1920
FB_TIMMING_HEIGHT = 1080
FB_MMAP_NAME = E_MMAP_ID_FB
FB_BUFFER_LEN = 4800
#unit:Kbyte,4096=4M, fbdev.ko alloc size = FB_BUFFER_LEN*1024

FB_BUFFER_LEN = 4800
这里原来是4096, 修改成4800即可。
显然 1024*600*4 *2 =4915200 ,但是4096*1024 = 4194304 不够用,那就会crash

这里你已经可以成功单缓冲显示了,sstar_disp_init 想必你已经成功调用,这里就不贴了,我贴另一个帖子上。



fogwizard 说:

哥,就是按照大神的帖子改的,ssd201平台finfo.smem_len打印出来不是2倍的buffer,无法切换,会crash, 使用单缓存可以显示,但是页面切换有撕裂感

#73 Re: 全志 SOC » v3s和LCD通过i8080总线模式 » 2021-02-06 15:24:27

直接用彩虹派的BSP也很香啊,直接TE接上用,妥妥的

john78 说:

LZ 搞定没?我也想这样用

#74 Re: 计算机图形/GUI/RTOS/FileSystem/OpenGL/DirectX/SDL2 » LVGL的linux_frame_buffer项目加入FB双缓 » 2021-01-30 12:28:27

哥哥你可以自己试一下

pythinker 说:

请教楼主,Ubuntu的Framebuffer可以用吗?

#75 Re: 计算机图形/GUI/RTOS/FileSystem/OpenGL/DirectX/SDL2 » LVGL的linux_frame_buffer项目加入FB双缓 » 2021-01-30 10:41:49

并不是哈, fb驱动原生是有2个缓冲区的,总的是屏幕缓冲区长度2倍,IOCTL读回来就是2倍的,finfo.smem_len 打印出来看下

tango_zhu 说:
TeveT 说:

你的海思的内核支持了FBIOPAN_DISPLAY了吗,ioctl读取回来的缓存大小是你显示器的两倍吗

tango_zhu 说:

用你的方法在海思上 产生了段错误

你这边的宽度需要设置成实际宽度的两倍吗

#77 Re: 计算机图形/GUI/RTOS/FileSystem/OpenGL/DirectX/SDL2 » LVGL的linux_frame_buffer项目加入FB双缓 » 2021-01-27 09:13:22

你的海思的内核支持了FBIOPAN_DISPLAY了吗,ioctl读取回来的缓存大小是你显示器的两倍吗

tango_zhu 说:

用你的方法在海思上 产生了段错误

#79 Re: 计算机图形/GUI/RTOS/FileSystem/OpenGL/DirectX/SDL2 » LVGL6.0的linux_frame_buffer项目支持PNG解码 » 2021-01-23 09:33:22

试一下哈,ligpng可以用其他的png库替代,有就行,LVGL也有版本支持了png , lodepng
链接在这里:
https://github.com/lvgl/lv_lib_png

dgtg 说:

楼主厉害!正需要呢!!楼主威武!!!

#80 Re: 计算机图形/GUI/RTOS/FileSystem/OpenGL/DirectX/SDL2 » LVGL6.0的linux_frame_buffer项目支持PNG解码 » 2021-01-23 08:15:04

这个一定要改的,不改就没拿到png的库接口
这个其实也挺好摸索的,lvgl的参考手册写得很清楚,就改这个文件

uuid 说:

牛, 向楼主学习! Makefile 也要修改一下对吧?

#81 计算机图形/GUI/RTOS/FileSystem/OpenGL/DirectX/SDL2 » LVGL6.0的linux_frame_buffer项目支持PNG解码 » 2021-01-22 23:58:34

TeveT
回复: 5

下载下来的linux_frame_buffer 跑在V3S tina
跑起来没有支持png解码,图片啥的程序从单片机那边过来,都是bin啊啥的,ARGB8888 数据超大还占磁盘,很难受啊。
tina环境已经支持了libpng,这里边默认是调用了libpng里边的接口。
话不多说,上代码:

/**
 * @file lv_img_decoder.c
 *
 */

/*********************
 *      INCLUDES
 *********************/
#include "lv_img_decoder.h"
#include "../lv_core/lv_debug.h"
#include "../lv_draw/lv_draw_img.h"
#include "../lv_misc/lv_ll.h"
#include "../lv_misc/lv_color.h"
#include "../lv_misc/lv_gc.h"

#if defined(LV_GC_INCLUDE)
#include LV_GC_INCLUDE
#endif /* LV_ENABLE_GC */

/*********************
 *      DEFINES
 *********************/
#define CF_BUILT_IN_FIRST LV_IMG_CF_TRUE_COLOR
#define CF_BUILT_IN_LAST LV_IMG_CF_ALPHA_8BIT

#define USE_PNG 1


/**********************
 *      TYPEDEFS
 **********************/
typedef struct
{
#if LV_USE_FILESYSTEM
    lv_fs_file_t * f;
#endif
    lv_color_t * palette;
    lv_opa_t * opa;
} lv_img_decoder_built_in_data_t;

/**********************
 *  STATIC PROTOTYPES
 **********************/
static lv_res_t lv_img_decoder_built_in_line_true_color(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y,
                                                        lv_coord_t len, uint8_t * buf);
static lv_res_t lv_img_decoder_built_in_line_alpha(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y,
                                                   lv_coord_t len, uint8_t * buf);
static lv_res_t lv_img_decoder_built_in_line_indexed(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y,
                                                     lv_coord_t len, uint8_t * buf);

/**********************
 *  STATIC VARIABLES
 **********************/

/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
 **********************/

/**
 * Initialize the image decoder module
 * */
void lv_img_decoder_init(void)
{
    lv_ll_init(&LV_GC_ROOT(_lv_img_defoder_ll), sizeof(lv_img_decoder_t));

    lv_img_decoder_t * decoder;

    /*Create a decoder for the built in color format*/
    decoder = lv_img_decoder_create();
    if(decoder == NULL) {
        LV_LOG_WARN("lv_img_decoder_init: out of memory");
        LV_ASSERT_MEM(decoder);
        return;
    }

    lv_img_decoder_set_info_cb(decoder, lv_img_decoder_built_in_info);
    lv_img_decoder_set_open_cb(decoder, lv_img_decoder_built_in_open);
    lv_img_decoder_set_read_line_cb(decoder, lv_img_decoder_built_in_read_line);
    lv_img_decoder_set_close_cb(decoder, lv_img_decoder_built_in_close);
}

/**
 * Get information about an image.
 * Try the created image decoder one by one. Once one is able to get info that info will be used.
 * @param src the image source. E.g. file name or variable.
 * @param header the image info will be stored here
 * @return LV_RES_OK: success; LV_RES_INV: wasn't able to get info about the image
 */
lv_res_t lv_img_decoder_get_info(const char * src, lv_img_header_t * header)
{
    header->always_zero = 0;

    lv_res_t res = LV_RES_INV;
    lv_img_decoder_t * d;
    LV_LL_READ(LV_GC_ROOT(_lv_img_defoder_ll), d)
    {
        res = LV_RES_INV;
        if(d->info_cb) {
            res = d->info_cb(d, src, header);
            if(res == LV_RES_OK) break;
        }
    }

    return res;
}

/**
 * Open an image.
 * Try the created image decoder one by one. Once one is able to open the image that decoder is save in `dsc`
 * @param dsc describe a decoding session. Simply a pointer to an `lv_img_decoder_dsc_t` variable.
 * @param src the image source. Can be
 *  1) File name: E.g. "S:folder/img1.png" (The drivers needs to registered via `lv_fs_add_drv()`)
 *  2) Variable: Pointer to an `lv_img_dsc_t` variable
 *  3) Symbol: E.g. `LV_SYMBOL_OK`
 * @param style the style of the image
 * @return LV_RES_OK: opened the image. `dsc->img_data` and `dsc->header` are set.
 *         LV_RES_INV: none of the registered image decoders were able to open the image.
 */
lv_res_t lv_img_decoder_open(lv_img_decoder_dsc_t * dsc, const void * src, const lv_style_t * style)
{
    dsc->style     = style;
    dsc->src_type  = lv_img_src_get_type(src);
    dsc->user_data = NULL;

    if(dsc->src_type == LV_IMG_SRC_FILE) {
        size_t fnlen = strlen(src);
        dsc->src = lv_mem_alloc(fnlen + 1);
        strcpy((char *)dsc->src, src);
    } else {
        dsc->src       = src;
    }

    lv_res_t res = LV_RES_INV;

    lv_img_decoder_t * d;
    LV_LL_READ(LV_GC_ROOT(_lv_img_defoder_ll), d)
    {
        /*Info an Open callbacks are required*/
        if(d->info_cb == NULL || d->open_cb == NULL) continue;

        res = d->info_cb(d, src, &dsc->header);
        if(res != LV_RES_OK) continue;

        dsc->error_msg = NULL;
        dsc->img_data  = NULL;
        dsc->decoder   = d;

        res = d->open_cb(d, dsc);

        /*Opened successfully. It is a good decoder to for this image source*/
        if(res == LV_RES_OK) break;
    }

    return res;
}

/**
 * Read a line from an opened image
 * @param dsc pointer to `lv_img_decoder_dsc_t` used in `lv_img_decoder_open`
 * @param x start X coordinate (from left)
 * @param y start Y coordinate (from top)
 * @param len number of pixels to read
 * @param buf store the data here
 * @return LV_RES_OK: success; LV_RES_INV: an error occurred
 */
lv_res_t lv_img_decoder_read_line(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y, lv_coord_t len, uint8_t * buf)
{
    lv_res_t res = LV_RES_INV;
    if(dsc->decoder->read_line_cb) res = dsc->decoder->read_line_cb(dsc->decoder, dsc, x, y, len, buf);

    return res;
}

/**
 * Close a decoding session
 * @param dsc pointer to `lv_img_decoder_dsc_t` used in `lv_img_decoder_open`
 */
void lv_img_decoder_close(lv_img_decoder_dsc_t * dsc)
{
    if(dsc->decoder) {
        if(dsc->decoder->close_cb) dsc->decoder->close_cb(dsc->decoder, dsc);

        if(dsc->src_type == LV_IMG_SRC_FILE) {
            lv_mem_free(dsc->src);
            dsc->src = NULL;
        }
    }
}

/**
 * Create a new image decoder
 * @return pointer to the new image decoder
 */
lv_img_decoder_t * lv_img_decoder_create(void)
{
    lv_img_decoder_t * decoder;
    decoder = lv_ll_ins_head(&LV_GC_ROOT(_lv_img_defoder_ll));
    LV_ASSERT_MEM(decoder);
    if(decoder == NULL) return NULL;

    memset(decoder, 0, sizeof(lv_img_decoder_t));

    return decoder;
}

/**
 * Delete an image decoder
 * @param decoder pointer to an image decoder
 */
void lv_img_decoder_delete(lv_img_decoder_t * decoder)
{
    lv_ll_rem(&LV_GC_ROOT(_lv_img_defoder_ll), decoder);
    lv_mem_free(decoder);
}

/**
 * Set a callback to get information about the image
 * @param decoder pointer to an image decoder
 * @param info_cb a function to collect info about an image (fill an `lv_img_header_t` struct)
 */
void lv_img_decoder_set_info_cb(lv_img_decoder_t * decoder, lv_img_decoder_info_f_t info_cb)
{
    decoder->info_cb = info_cb;
}

/**
 * Set a callback to open an image
 * @param decoder pointer to an image decoder
 * @param open_cb a function to open an image
 */
void lv_img_decoder_set_open_cb(lv_img_decoder_t * decoder, lv_img_decoder_open_f_t open_cb)
{
    decoder->open_cb = open_cb;
}

/**
 * Set a callback to a decoded line of an image
 * @param decoder pointer to an image decoder
 * @param read_line_cb a function to read a line of an image
 */
void lv_img_decoder_set_read_line_cb(lv_img_decoder_t * decoder, lv_img_decoder_read_line_f_t read_line_cb)
{
    decoder->read_line_cb = read_line_cb;
}

/**
 * Set a callback to close a decoding session. E.g. close files and free other resources.
 * @param decoder pointer to an image decoder
 * @param close_cb a function to close a decoding session
 */
void lv_img_decoder_set_close_cb(lv_img_decoder_t * decoder, lv_img_decoder_close_f_t close_cb)
{
    decoder->close_cb = close_cb;
}

/**
 * Get info about a built-in image
 * @param decoder the decoder where this function belongs
 * @param src the image source: pointer to an `lv_img_dsc_t` variable, a file path or a symbol
 * @param header store the image data here
 * @return LV_RES_OK: the info is successfully stored in `header`; LV_RES_INV: unknown format or other error.
 */
lv_res_t lv_img_decoder_built_in_info(lv_img_decoder_t * decoder, const void * src, lv_img_header_t * header)
{
    (void)decoder; /*Unused*/

    lv_img_src_t src_type = lv_img_src_get_type(src);
    if(src_type == LV_IMG_SRC_VARIABLE) {
        lv_img_cf_t cf = ((lv_img_dsc_t *)src)->header.cf;
        if(cf < CF_BUILT_IN_FIRST || cf > CF_BUILT_IN_LAST) return LV_RES_INV;

        header->w  = ((lv_img_dsc_t *)src)->header.w;
        header->h  = ((lv_img_dsc_t *)src)->header.h;
        header->cf = ((lv_img_dsc_t *)src)->header.cf;
    }
#if LV_USE_FILESYSTEM
    else if(src_type == LV_IMG_SRC_FILE) {
        lv_fs_file_t file;
        lv_fs_res_t res;
        uint32_t rn;
        unsigned short readx = 0,ready = 0;

     #if USE_PNG   

        if(fh_png_getsize(src,&readx,&ready) == 0)//libpng的接口
        {
            header->w = readx;
            header->h = ready;
            header->cf = LV_IMG_CF_RAW_ALPHA;

        }
		
    #else    
        res = lv_fs_open(&file, src, LV_FS_MODE_RD);

         if(res == LV_FS_RES_OK) {

            res = lv_fs_read(&file, header, sizeof(lv_img_header_t), &rn);
            //very very important, here copy header , but this file now is png, not bin, so header should modify in pcfs_read

            lv_fs_close(&file);
        }
    

        if(header->cf < CF_BUILT_IN_FIRST || header->cf > CF_BUILT_IN_LAST) return LV_RES_INV;
 #endif
    }
#endif
    else if(src_type == LV_IMG_SRC_SYMBOL) {
        /*The size depend on the font but it is unknown here. It should be handled outside of the
         * function*/
        header->w = 1;
        header->h = 1;
        /* Symbols always have transparent parts. Important because of cover check in the design
         * function. The actual value doesn't matter because lv_draw_label will draw it*/
        header->cf = LV_IMG_CF_ALPHA_1BIT;
    } else {
        LV_LOG_WARN("Image get info found unknown src type");
        return LV_RES_INV;
    }
    return LV_RES_OK;
}

/**
 * Open a built in image
 * @param decoder the decoder where this function belongs
 * @param dsc pointer to decoder descriptor. `src`, `style` are already initialized in it.
 * @return LV_RES_OK: the info is successfully stored in `header`; LV_RES_INV: unknown format or other error.
 */
lv_res_t lv_img_decoder_built_in_open(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc)
{
    /*Open the file if it's a file*/
    if(dsc->src_type == LV_IMG_SRC_FILE) {
    
#if LV_USE_FILESYSTEM
   
    #if USE_PNG
     /*Support only "*.bin" files*/
        if(strcmp(lv_fs_get_ext(dsc->src), "png")) return LV_RES_INV;

 //       lv_fs_file_t f;
 //       lv_fs_res_t res = lv_fs_open(&f, dsc->src, LV_FS_MODE_RD);
 //       if(res != LV_FS_RES_OK) {
 //           LV_LOG_WARN("Built-in image decoder can't open the file");
 //           return LV_RES_INV;
 //       }

        /*If the file was open successfully save the file descriptor*/
  //      if(dsc->user_data == NULL) {
  //          dsc->user_data = lv_mem_alloc(sizeof(lv_img_decoder_built_in_data_t));
  //          if(dsc->user_data == NULL) {
  //              LV_LOG_ERROR("img_decoder_built_in_open: out of memory");
  //              LV_ASSERT_MEM(dsc->user_data);
  //          }
 //           memset(dsc->user_data, 0, sizeof(lv_img_decoder_built_in_data_t));
  //      }

 //       lv_img_decoder_built_in_data_t * user_data = dsc->user_data;
 //       user_data->f                               = lv_mem_alloc(sizeof(f));
 //       if(user_data->f == NULL) {
 //           LV_LOG_ERROR("img_decoder_built_in_open: out of memory");
 //           LV_ASSERT_MEM(user_data->f);
 //       }

 //       memcpy(user_data->f, &f, sizeof(f));

    #else
        /*Support only "*.bin" files*/
        if(strcmp(lv_fs_get_ext(dsc->src), "bin")) return LV_RES_INV;

        lv_fs_file_t f;
        lv_fs_res_t res = lv_fs_open(&f, dsc->src, LV_FS_MODE_RD);
        if(res != LV_FS_RES_OK) {
            LV_LOG_WARN("Built-in image decoder can't open the file");
            return LV_RES_INV;
        }

        /*If the file was open successfully save the file descriptor*/
        if(dsc->user_data == NULL) {
            dsc->user_data = lv_mem_alloc(sizeof(lv_img_decoder_built_in_data_t));
            if(dsc->user_data == NULL) {
                LV_LOG_ERROR("img_decoder_built_in_open: out of memory");
                LV_ASSERT_MEM(dsc->user_data);
            }
            memset(dsc->user_data, 0, sizeof(lv_img_decoder_built_in_data_t));
        }

        lv_img_decoder_built_in_data_t * user_data = dsc->user_data;
        user_data->f                               = lv_mem_alloc(sizeof(f));
        if(user_data->f == NULL) {
            LV_LOG_ERROR("img_decoder_built_in_open: out of memory");
            LV_ASSERT_MEM(user_data->f);
        }

        memcpy(user_data->f, &f, sizeof(f));
    #endif

#else
        LV_LOG_WARN("Image built-in decoder cannot read file because LV_USE_FILESYSTEM = 0");
        return LV_RES_INV;
#endif
    }

    lv_img_cf_t cf = dsc->header.cf;
    /*Process true color formats*/
    if(cf == LV_IMG_CF_TRUE_COLOR || cf == LV_IMG_CF_TRUE_COLOR_ALPHA || cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED) {
        if(dsc->src_type == LV_IMG_SRC_VARIABLE) {
            /* In case of uncompressed formats the image stored in the ROM/RAM.
             * So simply give its pointer*/
            dsc->img_data = ((lv_img_dsc_t *)dsc->src)->data;
            return LV_RES_OK;
        } else {
            /*If it's a file it need to be read line by line later*/
            dsc->img_data = NULL;
            return LV_RES_OK;
        }
    }
    /*Process indexed images. Build a palette*/
    else if(cf == LV_IMG_CF_INDEXED_1BIT || cf == LV_IMG_CF_INDEXED_2BIT || cf == LV_IMG_CF_INDEXED_4BIT ||
            cf == LV_IMG_CF_INDEXED_8BIT) {

#if LV_IMG_CF_INDEXED
        uint8_t px_size       = lv_img_color_format_get_px_size(cf);
        uint32_t palette_size = 1 << px_size;

        /*Allocate the palette*/
        if(dsc->user_data == NULL) {
            dsc->user_data = lv_mem_alloc(sizeof(lv_img_decoder_built_in_data_t));
            if(dsc->user_data == NULL) {
                LV_LOG_ERROR("img_decoder_built_in_open: out of memory");
                LV_ASSERT_MEM(dsc->user_data);
            }
            memset(dsc->user_data, 0, sizeof(lv_img_decoder_built_in_data_t));
        }

        lv_img_decoder_built_in_data_t * user_data = dsc->user_data;
        user_data->palette                         = lv_mem_alloc(palette_size * sizeof(lv_color_t));
        user_data->opa                             = lv_mem_alloc(palette_size * sizeof(lv_opa_t));
        if(user_data->palette == NULL || user_data->opa == NULL) {
            LV_LOG_ERROR("img_decoder_built_in_open: out of memory");

            LV_ASSERT_MEM(user_data->palette);
            LV_ASSERT_MEM(user_data->opa);
        }

        if(dsc->src_type == LV_IMG_SRC_FILE) {
            /*Read the palette from file*/
#if LV_USE_FILESYSTEM
            lv_fs_seek(user_data->f, 4); /*Skip the header*/
            lv_color32_t cur_color;
            uint32_t i;
            for(i = 0; i < palette_size; i++) {
                lv_fs_read(user_data->f, &cur_color, sizeof(lv_color32_t), NULL);
                user_data->palette[i] = lv_color_make(cur_color.ch.red, cur_color.ch.green, cur_color.ch.blue);
                user_data->opa[i]     = cur_color.ch.alpha;
            }
#else
            LV_LOG_WARN("Image built-in decoder can read the palette because LV_USE_FILESYSTEM = 0");
            return LV_RES_INV;
#endif
        } else {
            /*The palette begins in the beginning of the image data. Just point to it.*/
            lv_color32_t * palette_p = (lv_color32_t *)((lv_img_dsc_t *)dsc->src)->data;

            uint32_t i;
            for(i = 0; i < palette_size; i++) {
                user_data->palette[i] = lv_color_make(palette_p[i].ch.red, palette_p[i].ch.green, palette_p[i].ch.blue);
                user_data->opa[i]     = palette_p[i].ch.alpha;
            }
        }

        dsc->img_data = NULL;
        return LV_RES_OK;
#else
        LV_LOG_WARN("Indexed (palette) images are not enabled in lv_conf.h. See LV_IMG_CF_INDEXED");
        return LV_RES_INV;
#endif
    }
    /*Alpha indexed images. */
    else if(cf == LV_IMG_CF_ALPHA_1BIT || cf == LV_IMG_CF_ALPHA_2BIT || cf == LV_IMG_CF_ALPHA_4BIT ||
            cf == LV_IMG_CF_ALPHA_8BIT) {
#if LV_IMG_CF_ALPHA
        dsc->img_data = NULL;
        return LV_RES_OK; /*Nothing to process*/
#else
        LV_LOG_WARN("Alpha indexed images are not enabled in lv_conf.h. See LV_IMG_CF_ALPHA");
        return LV_RES_INV;
#endif
    }
#if USE_PNG
    else if(cf == LV_IMG_CF_RAW_ALPHA)
    {
       // uint8_t *pbuf;	
        int file_size;

        file_size = (dsc->header.w)*(dsc->header.h)*(LV_COLOR_DEPTH/8);

        dsc->img_data = lv_mem_alloc(file_size);
        fh_png_load(dsc->src,dsc->img_data,dsc->header.w,dsc->header.h);//libpng的接口
        printf("lv_img_decoder_built_in_open  fh_png_load src = %s file_size = %d \n",dsc->src,file_size);   
		return LV_RES_OK;
    }
#endif
    /*Unknown format. Can't decode it.*/
    else {
        /*Free the potentially allocated memories*/
        lv_img_decoder_built_in_close(decoder, dsc);

        LV_LOG_WARN("Image decoder open: unknown color format")
        return LV_RES_INV;
    }
}

/**
 * Decode `len` pixels starting from the given `x`, `y` coordinates and store them in `buf`.
 * Required only if the "open" function can't return with the whole decoded pixel array.
 * @param decoder pointer to the decoder the function associated with
 * @param dsc pointer to decoder descriptor
 * @param x start x coordinate
 * @param y start y coordinate
 * @param len number of pixels to decode
 * @param buf a buffer to store the decoded pixels
 * @return LV_RES_OK: ok; LV_RES_INV: failed
 */
lv_res_t lv_img_decoder_built_in_read_line(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc, lv_coord_t x,
                                                  lv_coord_t y, lv_coord_t len, uint8_t * buf)
{
    (void)decoder; /*Unused*/

    lv_res_t res = LV_RES_INV;

    if(dsc->header.cf == LV_IMG_CF_TRUE_COLOR || dsc->header.cf == LV_IMG_CF_TRUE_COLOR_ALPHA ||
       dsc->header.cf == LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED) {
        /* For TRUE_COLOR images read line required only for files.
         * For variables the image data was returned in `open`*/
        if(dsc->src_type == LV_IMG_SRC_FILE) {
            res = lv_img_decoder_built_in_line_true_color(dsc, x, y, len, buf);
        }
    } else if(dsc->header.cf == LV_IMG_CF_ALPHA_1BIT || dsc->header.cf == LV_IMG_CF_ALPHA_2BIT ||
              dsc->header.cf == LV_IMG_CF_ALPHA_4BIT || dsc->header.cf == LV_IMG_CF_ALPHA_8BIT) {

        res = lv_img_decoder_built_in_line_alpha(dsc, x, y, len, buf);
    } else if(dsc->header.cf == LV_IMG_CF_INDEXED_1BIT || dsc->header.cf == LV_IMG_CF_INDEXED_2BIT ||
              dsc->header.cf == LV_IMG_CF_INDEXED_4BIT || dsc->header.cf == LV_IMG_CF_INDEXED_8BIT) {
        res = lv_img_decoder_built_in_line_indexed(dsc, x, y, len, buf);
    } else {
        LV_LOG_WARN("Built-in image decoder read not supports the color format");
        return LV_RES_INV;
    }

    return res;
}

/**
 * Close the pending decoding. Free resources etc.
 * @param decoder pointer to the decoder the function associated with
 * @param dsc pointer to decoder descriptor
 */
void lv_img_decoder_built_in_close(lv_img_decoder_t * decoder, lv_img_decoder_dsc_t * dsc)
{
    (void)decoder; /*Unused*/

    lv_img_decoder_built_in_data_t * user_data = dsc->user_data;
#if USE_PNG	
    if(dsc->img_data)
    {
      lv_mem_free(dsc->img_data);
    }
#endif	
    if(user_data) {
#if LV_USE_FILESYSTEM
        if(user_data->f) {
            lv_fs_close(user_data->f);
            lv_mem_free(user_data->f);
        }
#endif
        if(user_data->palette) lv_mem_free(user_data->palette);
        if(user_data->opa) lv_mem_free(user_data->opa);

        lv_mem_free(user_data);

        dsc->user_data = NULL;
    }
}


/**********************
 *   STATIC FUNCTIONS
 **********************/

static lv_res_t lv_img_decoder_built_in_line_true_color(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y,
                                                        lv_coord_t len, uint8_t * buf)
{
#if LV_USE_FILESYSTEM
    lv_img_decoder_built_in_data_t * user_data = dsc->user_data;
    lv_fs_res_t res;
    uint8_t px_size = lv_img_color_format_get_px_size(dsc->header.cf);

    uint32_t pos = ((y * dsc->header.w + x) * px_size) >> 3;
    pos += 4; /*Skip the header*/
    res = lv_fs_seek(user_data->f, pos);
    if(res != LV_FS_RES_OK) {
        LV_LOG_WARN("Built-in image decoder seek failed");
        return LV_RES_INV;
    }
    uint32_t btr = len * (px_size >> 3);
    uint32_t br  = 0;
    lv_fs_read(user_data->f, buf, btr, &br);
    if(res != LV_FS_RES_OK || btr != br) {
        LV_LOG_WARN("Built-in image decoder read failed");
        return LV_RES_INV;
    }

    return LV_RES_OK;
#else
    LV_LOG_WARN("Image built-in decoder cannot read file because LV_USE_FILESYSTEM = 0");
    return LV_RES_INV;
#endif
}

static lv_res_t lv_img_decoder_built_in_line_alpha(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y,
                                                   lv_coord_t len, uint8_t * buf)
{

#if LV_IMG_CF_ALPHA
    const lv_opa_t alpha1_opa_table[2]  = {0, 255};          /*Opacity mapping with bpp = 1 (Just for compatibility)*/
    const lv_opa_t alpha2_opa_table[4]  = {0, 85, 170, 255}; /*Opacity mapping with bpp = 2*/
    const lv_opa_t alpha4_opa_table[16] = {0,  17, 34,  51,  /*Opacity mapping with bpp = 4*/
                                           68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255};

    /*Simply fill the buffer with the color. Later only the alpha value will be modified.*/
    lv_color_t bg_color = dsc->style->image.color;
    lv_coord_t i;
    for(i = 0; i < len; i++) {
#if LV_COLOR_DEPTH == 8 || LV_COLOR_DEPTH == 1
        buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE] = bg_color.full;
#elif LV_COLOR_DEPTH == 16
        /*Because of Alpha byte 16 bit color can start on odd address which can cause crash*/
        buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE] = bg_color.full & 0xFF;
        buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE + 1] = (bg_color.full >> 8) & 0xFF;
#elif LV_COLOR_DEPTH == 32
        *((uint32_t *)&buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE]) = bg_color.full;
#else
#error "Invalid LV_COLOR_DEPTH. Check it in lv_conf.h"
#endif
    }

    const lv_opa_t * opa_table = NULL;
    uint8_t px_size            = lv_img_color_format_get_px_size(dsc->header.cf);
    uint16_t mask              = (1 << px_size) - 1; /*E.g. px_size = 2; mask = 0x03*/

    lv_coord_t w = 0;
    uint32_t ofs = 0;
    int8_t pos   = 0;
    switch(dsc->header.cf) {
        case LV_IMG_CF_ALPHA_1BIT:
            w = (dsc->header.w >> 3); /*E.g. w = 20 -> w = 2 + 1*/
            if(dsc->header.w & 0x7) w++;
            ofs += w * y + (x >> 3); /*First pixel*/
            pos       = 7 - (x & 0x7);
            opa_table = alpha1_opa_table;
            break;
        case LV_IMG_CF_ALPHA_2BIT:
            w = (dsc->header.w >> 2); /*E.g. w = 13 -> w = 3 + 1 (bytes)*/
            if(dsc->header.w & 0x3) w++;
            ofs += w * y + (x >> 2); /*First pixel*/
            pos       = 6 - ((x & 0x3) * 2);
            opa_table = alpha2_opa_table;
            break;
        case LV_IMG_CF_ALPHA_4BIT:
            w = (dsc->header.w >> 1); /*E.g. w = 13 -> w = 6 + 1 (bytes)*/
            if(dsc->header.w & 0x1) w++;
            ofs += w * y + (x >> 1); /*First pixel*/
            pos       = 4 - ((x & 0x1) * 4);
            opa_table = alpha4_opa_table;
            break;
        case LV_IMG_CF_ALPHA_8BIT:
            w = dsc->header.w; /*E.g. x = 7 -> w = 7 (bytes)*/
            ofs += w * y + x;  /*First pixel*/
            pos = 0;
            break;
    }

#if LV_USE_FILESYSTEM
    lv_img_decoder_built_in_data_t * user_data = dsc->user_data;
    uint8_t fs_buf[LV_HOR_RES_MAX];
#endif

    const uint8_t * data_tmp = NULL;
    if(dsc->src_type == LV_IMG_SRC_VARIABLE) {
        const lv_img_dsc_t * img_dsc = dsc->src;

        data_tmp = img_dsc->data + ofs;
    } else {
#if LV_USE_FILESYSTEM
        lv_fs_seek(user_data->f, ofs + 4); /*+4 to skip the header*/
        lv_fs_read(user_data->f, fs_buf, w, NULL);
        data_tmp = fs_buf;
#else
        LV_LOG_WARN("Image built-in alpha line reader can't read file because LV_USE_FILESYSTEM = 0");
        data_tmp = NULL; /*To avoid warnings*/
        return LV_RES_INV;
#endif
    }

    uint8_t byte_act = 0;
    uint8_t val_act;
    for(i = 0; i < len; i++) {
        val_act = (data_tmp[byte_act] & (mask << pos)) >> pos;

        buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE + LV_IMG_PX_SIZE_ALPHA_BYTE - 1] =
            dsc->header.cf == LV_IMG_CF_ALPHA_8BIT ? val_act : opa_table[val_act];

        pos -= px_size;
        if(pos < 0) {
            pos = 8 - px_size;
            data_tmp++;
        }
    }

    return LV_RES_OK;

#else
    LV_LOG_WARN("Image built-in alpha line reader failed because LV_IMG_CF_ALPHA is 0 in lv_conf.h");
    return LV_RES_INV;
#endif
}

static lv_res_t lv_img_decoder_built_in_line_indexed(lv_img_decoder_dsc_t * dsc, lv_coord_t x, lv_coord_t y,
                                                     lv_coord_t len, uint8_t * buf)
{

#if LV_IMG_CF_INDEXED
    uint8_t px_size = lv_img_color_format_get_px_size(dsc->header.cf);
    uint16_t mask   = (1 << px_size) - 1; /*E.g. px_size = 2; mask = 0x03*/

    lv_coord_t w = 0;
    int8_t pos   = 0;
    uint32_t ofs = 0;
    switch(dsc->header.cf) {
        case LV_IMG_CF_INDEXED_1BIT:
            w = (dsc->header.w >> 3); /*E.g. w = 20 -> w = 2 + 1*/
            if(dsc->header.w & 0x7) w++;
            ofs += w * y + (x >> 3); /*First pixel*/
            ofs += 8;                /*Skip the palette*/
            pos = 7 - (x & 0x7);
            break;
        case LV_IMG_CF_INDEXED_2BIT:
            w = (dsc->header.w >> 2); /*E.g. w = 13 -> w = 3 + 1 (bytes)*/
            if(dsc->header.w & 0x3) w++;
            ofs += w * y + (x >> 2); /*First pixel*/
            ofs += 16;               /*Skip the palette*/
            pos = 6 - ((x & 0x3) * 2);
            break;
        case LV_IMG_CF_INDEXED_4BIT:
            w = (dsc->header.w >> 1); /*E.g. w = 13 -> w = 6 + 1 (bytes)*/
            if(dsc->header.w & 0x1) w++;
            ofs += w * y + (x >> 1); /*First pixel*/
            ofs += 64;               /*Skip the palette*/
            pos = 4 - ((x & 0x1) * 4);
            break;
        case LV_IMG_CF_INDEXED_8BIT:
            w = dsc->header.w; /*E.g. x = 7 -> w = 7 (bytes)*/
            ofs += w * y + x;  /*First pixel*/
            ofs += 1024;       /*Skip the palette*/
            pos = 0;
            break;
    }

    lv_img_decoder_built_in_data_t * user_data = dsc->user_data;

#if LV_USE_FILESYSTEM
    uint8_t fs_buf[LV_HOR_RES_MAX];
#endif
    const uint8_t * data_tmp = NULL;
    if(dsc->src_type == LV_IMG_SRC_VARIABLE) {
        const lv_img_dsc_t * img_dsc = dsc->src;
        data_tmp                     = img_dsc->data + ofs;
    } else {
#if LV_USE_FILESYSTEM
        lv_fs_seek(user_data->f, ofs + 4); /*+4 to skip the header*/
        lv_fs_read(user_data->f, fs_buf, w, NULL);
        data_tmp = fs_buf;
#else
        LV_LOG_WARN("Image built-in indexed line reader can't read file because LV_USE_FILESYSTEM = 0");
        data_tmp = NULL; /*To avoid warnings*/
        return LV_RES_INV;
#endif
    }

    uint8_t val_act;
    lv_coord_t i;
    for(i = 0; i < len; i++) {
        val_act = (*data_tmp & (mask << pos)) >> pos;

        lv_color_t color = user_data->palette[val_act];
#if LV_COLOR_DEPTH == 8 || LV_COLOR_DEPTH == 1
        buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE] = color.full;
#elif LV_COLOR_DEPTH == 16
        /*Because of Alpha byte 16 bit color can start on odd address which can cause crash*/
        buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE] = color.full & 0xFF;
        buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE + 1] = (color.full >> 8) & 0xFF;
#elif LV_COLOR_DEPTH == 32
        *((uint32_t *)&buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE]) = color.full;
#else
#error "Invalid LV_COLOR_DEPTH. Check it in lv_conf.h"
#endif
        buf[i * LV_IMG_PX_SIZE_ALPHA_BYTE + LV_IMG_PX_SIZE_ALPHA_BYTE - 1] = user_data->opa[val_act];

        pos -= px_size;
        if(pos < 0) {
            pos = 8 - px_size;
            data_tmp++;
        }
    }

    return LV_RES_OK;
#else
    LV_LOG_WARN("Image built-in indexed line reader failed because LV_IMG_CF_INDEXED is 0 in lv_conf.h");
    return LV_RES_INV;
#endif
}

注意看一下宏定义USE_PNG 下添加的代码,其实添加的东西很少。
主要3个处理:
1、返回图像的大小和类型
2、读取PNG的元数据(直接解出来后的)
3、关闭解码器的时候释放掉解出来的时候申请的内存


当前这个操作的情况下,可以直接在初始化的时候加入图片列表png文件:
形如:
lv_img_dsc_t *image;

image->header.cf = LV_IMG_CF_RAW_ALPHA;
image->header.always_zero = 0;
image->data = file_name;//file_name 就是png文件路径


能调用Png解码到内存显示后,可以调整:
lv_conf.h的
#  define LV_MEM_SIZE    (2U * 1024U * 1024U)

可以限制LVGL使用的内存大小,然后和cache配合使用,在下面:

lv_conf.h的
#define LV_IMG_CACHE_DEF_SIZE       5

可以约束调用解码显示到当前页面的缓冲图片源数量,减少访问图片源文件次数


完结,撒花~

#82 Re: 全志 SOC » 感谢彩虹派, 收到赠送的 V3s + OV2710 + ILI934x 开发板 » 2021-01-20 14:34:58

嗯? 可以直接参考彩虹派的这个驱动喔,看看RGB格式啊啥的,接上 TE 信号,做触发模式,直接参考彩虹派的驱动,没得错!

raspberryman 说:
TeveT 说:

感谢晕哥分享, 这个BSP给了很多帮助,搞定了另一款I80 屏幕

我也想点亮i80屏幕,请问方便分享分享宝贵经验吗?

#83 Re: 计算机图形/GUI/RTOS/FileSystem/OpenGL/DirectX/SDL2 » LVGL的linux_frame_buffer项目加入FB双缓 » 2021-01-20 14:23:31

我这边用的是V3S tina,
手头还有个SSD202的开发板里边附带的LVGL例程也是有裂开的现象,后面有空再看看。
ubuntu上没用过,但是在v3s上是肯定有的

raspberryman 说:

楼主用的是哪个平台呢?我用Ubuntu测试貌似没有出现撕裂的问题

#84 计算机图形/GUI/RTOS/FileSystem/OpenGL/DirectX/SDL2 » LVGL的linux_frame_buffer项目加入FB双缓 » 2021-01-20 09:58:34

TeveT
回复: 17

下载下来的linux_frame_buffer 跑在V3S tina
跑起来没有支持双缓,画面切换撕裂很难受呀,
可以支持FBIOPAN_DISPLAY的平台应该都可以相同的操作。
话不多说,上代码:

/**
 * @file fbdev.c
 *
 */

/*********************
 *      INCLUDES
 *********************/
#include "fbdev.h"
#if USE_FBDEV || USE_BSD_FBDEV

#include <stdlib.h>
#include <unistd.h>
#include <stddef.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/ioctl.h>

#if USE_BSD_FBDEV
#include <sys/fcntl.h>
#include <sys/time.h>
#include <sys/consio.h>
#include <sys/fbio.h>
#else  /* USE_BSD_FBDEV */
#include <linux/fb.h>
#include   <pthread.h>
#include <sys/epoll.h>
#endif /* USE_BSD_FBDEV */

/*********************
 *      DEFINES
 *********************/
#ifndef FBDEV_PATH
#define FBDEV_PATH  "/dev/fb0"
#endif

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *      STRUCTURES
 **********************/

struct bsd_fb_var_info{
    uint32_t xoffset;
    uint32_t yoffset;
    uint32_t xres;
    uint32_t yres;
    int bits_per_pixel;
 };

struct bsd_fb_fix_info{
    long int line_length;
    long int smem_len;
};

/**********************
 *  STATIC PROTOTYPES
 **********************/

/**********************
 *  STATIC VARIABLES
 **********************/
#if USE_BSD_FBDEV
static struct bsd_fb_var_info vinfo;
static struct bsd_fb_fix_info finfo;
#else
static struct fb_var_screeninfo vinfo;
static struct fb_fix_screeninfo finfo;
#endif /* USE_BSD_FBDEV */
static char *fbp = 0,*fbpbase = 0;
static long int screensize = 0;
static long int half_screensize = 0;
static int fbfd = 0;

/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
 **********************/


void fbdev_init(void)
{
    // Open the file for reading and writing
    fbfd = open(FBDEV_PATH, O_RDWR);
    if(fbfd == -1) {
        perror("Error: cannot open framebuffer device");
        return;
    }
    printf("The framebuffer device was opened successfully.\n");

#if USE_BSD_FBDEV
    struct fbtype fb;
    unsigned line_length;

    //Get fb type
    if (ioctl(fbfd, FBIOGTYPE, &fb) != 0) {
        perror("ioctl(FBIOGTYPE)");
        return;
    }

    //Get screen width
    if (ioctl(fbfd, FBIO_GETLINEWIDTH, &line_length) != 0) {
        perror("ioctl(FBIO_GETLINEWIDTH)");
        return;
    }

    vinfo.xres = (unsigned) fb.fb_width;
    vinfo.yres = (unsigned) fb.fb_height;
    vinfo.bits_per_pixel = fb.fb_depth + 8;
    vinfo.xoffset = 0;
    vinfo.yoffset = 0;
    finfo.line_length = line_length;
    finfo.smem_len = finfo.line_length * vinfo.yres;
#else /* USE_BSD_FBDEV */

    // Get fixed screen information
    if(ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) == -1) {
        perror("Error reading fixed information");
        return;
    }

    // Get variable screen information
    if(ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) == -1) {
        perror("Error reading variable information");
        return;
    }
#endif /* USE_BSD_FBDEV */

    printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);

    // Figure out the size of the screen in bytes
    screensize =  finfo.smem_len; //finfo.line_length * vinfo.yres;    
    half_screensize = screensize/2;
    // Map the device to memory
    fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
	fbpbase =  fbp;
    if((intptr_t)fbp == -1) {
        perror("Error: failed to map framebuffer device to memory");
        return;
    }
    memset(fbp, 0, screensize);

    printf("The framebuffer device was mapped to memory successfully.\n");

}

void fbdev_exit(void)
{
    close(fbfd);
}




char toggle = 0;
/**
 * Flush a buffer to the marked area
 * @param drv pointer to driver where this function belongs
 * @param area an area where to copy `color_p`
 * @param color_p an array of pixel to copy to the `area` part of the screen
 */
void fbdev_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_p)
{
    if(fbp == NULL ||
            area->x2 < 0 ||
            area->y2 < 0 ||
            area->x1 > (int32_t)vinfo.xres - 1 ||
            area->y1 > (int32_t)vinfo.yres - 1) {
        lv_disp_flush_ready(drv);
        return;
    }

	if(toggle == 0)
	{
		toggle = 1;

		vinfo.yoffset = 0;
		fbp =fbpbase;
	}
	else
	{
		toggle = 0;
		vinfo.yoffset = vinfo.yres;	
		fbp =  fbpbase + half_screensize;


	
	}	
	
	
	

    /*Truncate the area to the screen*/
    int32_t act_x1 = area->x1 < 0 ? 0 : area->x1;
    int32_t act_y1 = area->y1 < 0 ? 0 : area->y1;
    int32_t act_x2 = area->x2 > (int32_t)vinfo.xres - 1 ? (int32_t)vinfo.xres - 1 : area->x2;
    int32_t act_y2 = area->y2 > (int32_t)vinfo.yres - 1 ? (int32_t)vinfo.yres - 1 : area->y2;


    lv_coord_t w = (act_x2 - act_x1 + 1);
    long int location = 0;
    long int byte_location = 0;
    unsigned char bit_location = 0;

    /*32 or 24 bit per pixel*/
    if(vinfo.bits_per_pixel == 32 || vinfo.bits_per_pixel == 24) {
        uint32_t * fbp32 = (uint32_t *)fbp;
        int32_t y;
        for(y = act_y1; y <= act_y2; y++) {
            location = (act_x1 ) + (y ) * finfo.line_length / 4;
            memcpy(&fbp32[location], (uint32_t *)color_p, (act_x2 - act_x1 + 1) * 4);
            color_p += w;
        }
    }
  else {
        /*Not supported bit per pixel*/
    }
	
	

	
//	memcpy(fbp,tmpbuf,640*480*4);

	if (ioctl(fbfd, FBIOPAN_DISPLAY, &vinfo) < 0) {
		fprintf(stderr, "active fb swap failed\n");
	}
	
	
    //May be some direct update command is required
    //ret = ioctl(state->fd, FBIO_UPDATE, (unsigned long)((uintptr_t)rect));

    lv_disp_flush_ready(drv);

}

/**********************
 *   STATIC FUNCTIONS
 **********************/

#endif

其实就是标准的linux下的ioctl双缓操作,
另外,这个操作要在初始化lvgl的时候加入双缓冲区。

    static lv_color_t buf[DISP_BUF_SIZE],buf1[DISP_BUF_SIZE];
    static lv_disp_buf_t disp_buf;
    lv_disp_buf_init(&disp_buf, buf, buf1, DISP_BUF_SIZE);

这里的 DISP_BUF_SIZE 要和显存大小一致,我这里用了ARGB 8888。


编译操作一下,画面撕裂消失,起飞!

#85 Re: 全志 SOC » 感谢彩虹派, 收到赠送的 V3s + OV2710 + ILI934x 开发板 » 2021-01-15 14:48:45

感谢晕哥分享, 这个BSP给了很多帮助,搞定了另一款I80 屏幕

#87 Re: 全志 SOC » 荔枝派zero-V3S搞上bluez5.54+pulseaudio 13.0 来个蓝牙终端播放 » 2020-11-24 11:51:45

是的,高手你好。
bluealsa 直接播 也行的,我试过。pulseaudio 用着爽,因为前面还搞了下VLC

powerpan 说:

pulseaudio比较重,最简单的是 bluealsa,可以支持 aptx/aptx-hd以及最新的LDAC。

我们是专业的。。咔咔

#90 Re: 全志 SOC » 荔枝派Zero根据晕哥的USB线刷做的ubuntu下生成固件img » 2020-10-02 20:58:37

shawn.d 说:

点个赞!

别,别,看下二楼,这个东西本就有个脚本生成了我还自己瞎折腾了。

#91 Re: 全志 SOC » 荔枝派Zero根据晕哥的USB线刷做的ubuntu下生成固件img » 2020-09-30 00:08:28

孤星泪 说:

分享全志主线u-boot/linux 打包 TF/SD/SDNAND 镜像脚本
http://whycan.com/t_4008.html
(出处:哇酷开发者社区【全志 V3S/F1C100s/X3】)

谢谢分享,

#92 全志 SOC » 荔枝派Zero根据晕哥的USB线刷做的ubuntu下生成固件img » 2020-09-29 23:43:27

TeveT
回复: 5

如题,感觉拿个TF卡刷入镜像再dd出来有点愚蠢。所以……

根据CSDN的帖子:
https://blog.csdn.net/armkits/article/details/93848472

我用的是256MB 的sd nand
自己摸索了一下下,汇总在下面:


qemu-img create V3S-OK.img 245M

sfdisk --in-order --Linux --unit M ./V3S-OK.img  <<EOF
4,20,L
,,L
EOF

kpartx -av V3S-OK.img

mkfs.vfat -F 16 /dev/mapper/loop0p1 -n boot
mkfs.ext4 /dev/mapper/loop0p2 -L rootfs

dd if=../Lichee/u-boot/u-boot-sunxi-with-spl.bin of=./V3S-OK.img bs=1024 seek=8 conv=notrunc
mount /dev/mapper/loop0p1 tmpmnt/boot/ &&\
mount /dev/mapper/loop0p2 tmpmnt/rootfs/ &&\
cd tmpmnt/boot/ && \
cp ../../../Lichee/linux/arch/arm/boot/zImage . && \
cp ../../../Lichee/linux/arch/arm/boot/dts/sun8i-v3s-licheepi-zero-dock.dtb . && \
cp ../../../zero_imager/boot.scr .

cd ../rootfs/
tar -xvf ../../../Lichee/buildroot/backuptotalokrootfs_20200922/rootfs.tar -C .

cd ../.. && \
umount ./tmpmnt/boot/ && \
umount ./tmpmnt/rootfs/ && \
kpartx -dv V3S-OK.img 

大致描述一下:

1、生成一个245MB的空固件Img
qemu-img create V3S-OK.img 245M

2、分个区, 4,20,L 代表第一个分区是20M, 4代表20M前面空4MB空间出来, L是个ID,传送门:

http://manpages.ubuntu.com/manpages//trusty/en/man8/sfdisk.8.html

Id is given in hex, without the 0x prefix, or is [E|S|L|X], where L (LINUX_NATIVE (83)) is
       the  default,  S  is LINUX_SWAP (82), E is EXTENDED_PARTITION (5), and X is LINUX_EXTENDED
       (85).

sfdisk --in-order --Linux --unit M ./V3S-OK.img  <<EOF
4,20,L
,,L
EOF

kpartx 把分区挂载到文件系统 , 会在 /dev/mapper/ 下面生成节点loopXpx

kpartx -av V3S-OK.img

格式化一下,按照荔枝派zero的教程,第一个分区是fat16 ,第二个是ext4
mkfs.vfat -F 16 /dev/mapper/loop0p1 -n boot
mkfs.ext4 /dev/mapper/loop0p2 -L rootfs

写入uboot :
dd if=../Lichee/u-boot/u-boot-sunxi-with-spl.bin of=./V3S-OK.img bs=1024 seek=8 conv=notrunc

挂载并拷贝内核和rootfs:

mount /dev/mapper/loop0p1 tmpmnt/boot/ &&\
mount /dev/mapper/loop0p2 tmpmnt/rootfs/ &&\
cd tmpmnt/boot/ && \
cp ../../../Lichee/linux/arch/arm/boot/zImage . && \
cp ../../../Lichee/linux/arch/arm/boot/dts/sun8i-v3s-licheepi-zero-dock.dtb . && \
cp ../../../zero_imager/boot.scr .

cd ../rootfs/
tar -xvf ../../../Lichee/buildroot/backuptotalokrootfs_20200922/rootfs.tar -C .

cd ../.. && \
umount ./tmpmnt/boot/ && \
umount ./tmpmnt/rootfs/ && \

最后解除文件系统挂载:
kpartx -dv V3S-OK.img


然后就可以用win32diskImage 刷入了,起飞!

#94 Re: 全志 SOC » QSPI nor flash相关驱动代码 【转】 » 2020-09-22 22:52:05

挖帖回复:

有没有什么A7芯带QSPI 内置RAM 的U 推荐呢,晕哥

#95 Re: 全志 SOC » 荔枝派zero-V3S搞上bluez5.54+pulseaudio 13.0 来个蓝牙终端播放 » 2020-09-21 11:40:10

控制手机的上一首下一首也搞定了,
了解了一下dbus-send
可以用来发送上一首下一首

播放:

dbus-send --system --print-reply --dest=org.bluez /org/bluez/hci0/dev_C4_86_E9_B9_E3_4C org.bluez.MediaControl1.Play

暂停:
dbus-send --system --print-reply --dest=org.bluez /org/bluez/hci0/dev_C4_86_E9_B9_E3_4C org.bluez.MediaControl1.Pause

下一曲:
dbus-send --system --print-reply --dest=org.bluez /org/bluez/hci0/dev_C4_86_E9_B9_E3_4C org.bluez.MediaControl1.Next

上一曲
dbus-send --system --print-reply --dest=org.bluez /org/bluez/hci0/dev_C4_86_E9_B9_E3_4C org.bluez.MediaControl1.Previous

更多功能细节还在学习和挖掘。

#96 Re: 全志 SOC » 荔枝派zero-V3S搞上bluez5.54+pulseaudio 13.0 来个蓝牙终端播放 » 2020-09-20 17:37:03

搞上了vlc ,本地的mp3和flac 播放都非常OK, 想用来搞个网络收音机,试了下,VLC没问题,遇到新问题,
vlc 播放结束后,pulseaudio 变成idle,自动退出了,
需要: pulseaudio --exit-idle-time=-1
做个标记

#97 Re: 全志 SOC » 荔枝派zero-V3S搞上bluez5.54+pulseaudio 13.0 来个蓝牙终端播放 » 2020-09-19 17:39:59

TeveT 说:

现在有2个地方有点蛋疼,
1、设置蓝牙手机端音量,上一首,下一首,停止,播放 这个的实现应该是要用AVRTP来做,但是似乎这个东西挑安卓和苹果,安卓死活没有看到相关音量的log。
至于操作现在还在摸索。
2、声音听起来有些歌曲会有点偶发的沙沙叫,网抑云的安静的SQ的曲子更容易听出来,不知道是我手机问题还是这个模块要修改驱动? 感觉是丢帧了

求大佬交流起来!

沙沙响的问题,我编译了vlc进文件系统,搞了一波,直接扔flac文件,vlc 播放原来的在手机上的flac 文件,也是有问题的,这个响声像是codec输出的耳机信号有问题! 我接了个小功放,把高频拉低,就很难听到,看来可能是CODEC的输出的问题,研究一下硬件和寄存器先!

#98 Re: 全志 SOC » 郁闷,没有搞定 Ubuntu下用btstack协议栈驱动 RTL8723BS » 2020-09-19 17:37:22

smartcar 说:

没有文档只能一顿瞎改了,笑哭.gif

我搞了一顿下来,我把vlc 搞进文件系统,直接用vlc 播放flac 源文件,也是一样的有沙沙响,看来不是蓝牙的问题了,可能是V3S 内置的CODEC的问题了,奇怪。

那这还咋玩……硬件上有器件要换一下? 感觉像是频率引起的。

#99 Re: 全志 SOC » 郁闷,没有搞定 Ubuntu下用btstack协议栈驱动 RTL8723BS » 2020-09-19 16:46:31

checkout 说:

晕哥有没试过rtl8723bs,3Mbps速率的情况
上传一下portaudio播放的代码,解压到/port/posix-h5/目录下,直接make就行
需要安装portaudio
不会是我连接的杜邦线太长了吧(捂脸.jpg)
test.rar

看到配置文件了,
/lib/firmware/rtl_bt/rtlbt_config

这个东西是可以自己随意改的么?
# cat /lib/firmware/rtl_bt/rtlbt_config | hexdump
0000000 ab55 8723 0031 00f4 0108 0000 0500 0050
0000010 0c00 1000 8002 0492 c550 19ea 1be1 aff1
0000020 015f 0ba4 0027 6301 00fe 0101 015b 0b04
0000030 0b0b e30a 0101 0000
0000037


看到了 0000010 0c00 1000 8002 0492 c550 19ea 1be1 aff1
其中的04928002 我可以自己改? 想设置高一点,一点点排除问题。

#100 Re: 全志 SOC » 郁闷,没有搞定 Ubuntu下用btstack协议栈驱动 RTL8723BS » 2020-09-19 15:14:39

checkout 说:

晕哥有没试过rtl8723bs,3Mbps速率的情况
上传一下portaudio播放的代码,解压到/port/posix-h5/目录下,直接make就行
需要安装portaudio
不会是我连接的杜邦线太长了吧(捂脸.jpg)
test.rar

大佬,如何设置3M的通信波特率? 修改rtl8723bs_bt的驱动代码么,我看波特率设置数值是从芯片那边读过来的。
Realtek Bluetooth :config baud rate to :4928002, hwflowcontrol:5f, 1

对应的:
    {0x04928002, 1500000},

咋改成 3000000 呢? 我这边是这样,高码率流的曲子, 会出现偶发的沙沙响,正在想办法查。

#101 Re: 全志 SOC » 荔枝派zero-V3S搞上bluez5.54+pulseaudio 13.0 来个蓝牙终端播放 » 2020-09-18 21:28:28

秦皇岛岛主 说:

标记,回去测试

交流起来哈,都来一起探索。

#103 Re: 全志 SOC » 荔枝派zero-V3S搞上bluez5.54+pulseaudio 13.0 来个蓝牙终端播放 » 2020-09-17 18:24:12

现在有2个地方有点蛋疼,
1、设置蓝牙手机端音量,上一首,下一首,停止,播放 这个的实现应该是要用AVRTP来做,但是似乎这个东西挑安卓和苹果,安卓死活没有看到相关音量的log。
至于操作现在还在摸索。
2、声音听起来有些歌曲会有点偶发的沙沙叫,网抑云的安静的SQ的曲子更容易听出来,不知道是我手机问题还是这个模块要修改驱动? 感觉是丢帧了

求大佬交流起来!

#104 全志 SOC » 荔枝派zero-V3S搞上bluez5.54+pulseaudio 13.0 来个蓝牙终端播放 » 2020-09-17 18:19:54

TeveT
回复: 11

如题,这个好像比较少人lu顺过?
我也是小白,一上来啥也不知道, 用buildroot2017的版本出来的pulse直接启动不了,也不管那么多了,直接干上buildroot2020.02.6

传个配置文件在附件如下
buildroot-2020_02_6_config.zip


其他的按照荔枝派的文档搞:
https://licheezero.readthedocs.io/zh/latest/%E8%B4%A1%E7%8C%AE/article%205.html?highlight=bt#id2

好,文件系统搞上。

启动,
start_bt.sh ttyS2

pulseaudio -D
/usr/libexec/bluetooth/bluetoothd &
hciconfig hci0 up
hciconfig hci0 class 0x200420

bluetoothctl
pairable on
discoverable on

然后用手机连上,bluetoothctl 可能会提示:[NEW] Device C4:86:E9:B9:E3:4C HUAWEI Mate 9
Request confirmation
[agent] Confirm passkey 075360 (yes/no):
输入yes
后续会提示授权service
Authorize service
[agent] Authorize service 00001108-0000-1000-8000-00805f9b34fb (yes/no):
输入yes
Authorize service
[agent] Authorize service 0000110d-0000-1000-8000-00805f9b34fb (yes/no):
输入yes


然后手机播歌,记得开声卡的播放静音。


amixer -c 0 sset 'Headphone',0 50% unmute

插上耳机,起飞!

#106 全志 SOC » 荔枝派zero-V3S搞上Lvgl7.0带上触摸 » 2020-09-13 23:52:31

TeveT
回复: 1

如题,这玩意儿很多人都lu过成功了。
老规矩上过程:
1、clone
https://github.com/lvgl/lv_port_linux_frame_buffer.git
2、改Makefile
#CC ?= gcc
CC := arm-linux-gnueabihf-gcc

3、make

4、加触摸
荔枝派zero 已经有电阻屏了,直接用 evdev,校准也搞一下,diff一波:

diff --git a/lv_drv_conf.h b/lv_drv_conf.h
index 975c7b4..3623d2d 100644
--- a/lv_drv_conf.h
+++ b/lv_drv_conf.h
@@ -314,18 +314,18 @@
 #endif
 
 /*-------------------------------------------------
  * Mouse or touchpad as evdev interface (for Linux based systems)
  *------------------------------------------------*/
 #ifndef USE_EVDEV
-#  define USE_EVDEV           0
+#  define USE_EVDEV           1
 #endif
 
 #if USE_EVDEV
-#  define EVDEV_NAME   "/dev/input/event0"        /*You can use the "evtest" Linux tool to get the list of devices and test them*/
+#  define EVDEV_NAME   "/dev/input/event1"        /*You can use the "evtest" Linux tool to get the list of devices and test them*/
 #  define EVDEV_SWAP_AXES         0               /*Swap the x and y axes of the touchscreen*/
 
 #  define EVDEV_SCALE             0               /* Scale input, e.g. if touchscreen resolution does not match display resolution */
@@ -334,11 +334,11 @@
 #    define EVDEV_SCALE_VER_RES     (4096)          /* Vertical resolution of touchscreen */
 #  endif  /*EVDEV_SCALE*/
 
-#  define EVDEV_CALIBRATE         0               /*Scale and offset the touchscreen coordinates by using maximum and minimum values for each axis*/
+#  define EVDEV_CALIBRATE         1               /*Scale and offset the touchscreen coordinates by using maximum and minimum values for each axis*/
 #  if EVDEV_CALIBRATE
-#    define EVDEV_HOR_MIN   3800                    /*If EVDEV_XXX_MIN > EVDEV_XXX_MAX the XXX axis is automatically inverted*/
-#    define EVDEV_HOR_MAX   200
-#    define EVDEV_VER_MIN   200
+#    define EVDEV_HOR_MIN   200                    /*If EVDEV_XXX_MIN > EVDEV_XXX_MAX the XXX axis is automatically inverted*/
+#    define EVDEV_HOR_MAX   3800
+#    define EVDEV_VER_MIN   400
 #    define EVDEV_VER_MAX   3800
 #  endif  /*EVDEV_SCALE*/
 #endif  /*USE_EVDEV*/

别忘了初始化加入触摸设备注册一下回调函数:

diff --git a/main.c b/main.c
index d286cc7..317a604 100644
--- a/main.c
+++ b/main.c
@@ -1,6 +1,8 @@
 #include "lvgl/lvgl.h"
 #include "lv_drivers/display/fbdev.h"
 #include "lv_examples/lv_examples.h"
+#include "lv_drivers/indev/evdev.h"
+#include "lvgl/src/lv_hal/lv_hal_indev.h"
 #include <unistd.h>
 #include <pthread.h>
 #include <time.h>
@@ -30,6 +32,14 @@ int main(void)
     disp_drv.flush_cb = fbdev_flush;
     lv_disp_drv_register(&disp_drv);
 
+
+     lv_indev_drv_t indev_drv;
+     lv_indev_drv_init(&indev_drv);          /*Basic initialization*/
+     evdev_init();
+     indev_drv.type = LV_INDEV_TYPE_POINTER; /*See below.*/
+     indev_drv.read_cb = evdev_read;            /*See below.*/
+     lv_indev_drv_register(&indev_drv);      /*Register the driver in LittlevGL*/
+
     /*Create a Demo*/
     lv_demo_widgets();

再编译一下。
起飞!

加图片我还不是很熟悉,lvgl7.0 懂的都懂。

#107 Re: 全志 SOC » 为了V3S不吃灰,移植NES游戏 » 2020-09-05 20:28:33

这投影仪咋这么完美接上? 某宝有?

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn