页次: 1
大佬, 温度湿度的功能,能不能用/tmp下的一个文件获取数据,第一行温度,第二行湿度,没有文件则默认值
我想搞个esp单片机广播温湿度值,然后写个app放屏幕板子后台,读取到后就保存到tmp
我以前遇到的error
error1
c-stack.c:55:26: error: missing binary operator before token "("
55 | #elif HAVE_LIBSIGSEGV && SIGSTKSZ < 16384
vim ./output/build/host-m4-1.4.18/lib/c-stack.c 注释三行代码
//#elif HAVE_LIBSIGSEGV && SIGSTKSZ < 16384
/* libsigsegv 2.6 through 2.8 have a bug where some architectures use
more than the Linux default of an 8k alternate stack when deciding
if a fault was caused by stack overflow. */
//# undef SIGSTKSZ
//# define SIGSTKSZ 16384
error2
‘_STAT_VER’ undeclared (first use in this function) 100 | #define INT_NEXT_LSTAT(a,b) NEXT_LSTAT64(_STAT_VER,a,b)
vim ./output/build/host-fakeroot-1.20.2/libfakeroot.c 添加三行代码
diff --git a/libfakeroot.c b/libfakeroot.c
index 3e80e38..14e56bc 100644
--- a/libfakeroot.c
+++ b/libfakeroot.c
@@ -90,6 +90,10 @@
#define SEND_GET_XATTR64(a,b,c) send_get_xattr64(a,b)
#endif
+#ifndef _STAT_VER
+#define _STAT_VER 0
+#endif
+
/*
These INT_* (which stands for internal) macros should always be used when
the fakeroot library owns the storage of the stat variable.
error3
/worktmp/Mwatch/buildroot-2020.02.6/output/build/qt5base-5.12.8/include/QtCore/../../src/corelib/global/qendian.h:333:35: error: ‘numeric_limits’ is not a member of ‘std’
333 | { return QSpecialInteger(std::numeric_limits::min()); }
vim /worktmp/Mwatch/buildroot-2020.02.6/output/build/qt5base-5.12.8/include/QtCore/../../src/corelib/global/qendian.h
加入#include <limits>
其他文件遇到这种错误,都加入#include <limits>
/worktmp/Mwatch/buildroot-2020.02.6/output/build/qt5base-5.12.8/src/corelib/tools/qbytearraymatcher.h
./output/build/qt5base-5.12.8/util/lexgen/generator.cpp
./output/build/qt5base-5.12.8/src/tools/moc/generator.cpp
#define N (PIN_N % 8 * 4) //引脚x : x % 8 * 4
请问这个引脚怎么得来的? 比如我用的是PG6引脚,请问PIN_N应该怎么设置?
#define PB_CFG0_REG 0x01C20800 + 1 * 0x24 //PB配置寄存器 A:0 B:1 C:2 ....
#define PB_DATA_REG 0x01C20800 + 1 * 0x34 //PB数据寄存器 A:0 B:1 C:2 ....
#define PIN_N 5 //第5个引脚
PG6
==>
#define PG_CFG0_REG 0x01C20800 + 6 * 0x24 //PG配置寄存器 A:0 B:1 C:2 D3 E4 F5 G6 ....
#define PG_DATA_REG 0x01C20800 + 6 * 0x34 //PG数据寄存器 A:0 B:1 C:2 ....
#define PIN_N 6 //第6个引脚
Linux下推流教程
安装ffmpeg
ffmpeg -re -i "/home/user/ikun.mp4" -vcodec copy -acodec aac -b:a 192k -f flv "rtmp://live-push.bilivideo.com/live-bvc/?streamname=live_434575063_32470690&key=2b9c8044be0a954aac15e4f09128c8a5&schedule=rtmp&pflag=1"
创建测试脚本
#!/bin/bash
# 读取配置文件
config_file="config.txt"
input_file=$(sed -n '1p' "$config_file")
rtmp_url=$(sed -n '2p' "$config_file")
echo $input_file
while :
do
ffmpeg -re -i "$input_file" -vcodec copy -acodec aac -b:a 192k -f flv "$rtmp_url"
done
创建config.txt配置文件(供参考)
/home/user/ikun.mp4
rtmp://live-push.bilivideo.com/live-bvc/?streamname=live_434575063_32470690&key=xxxxxxxxxxe4f09128c8a5&schedule=rtmp&pflag=1
9.9元 高铁410wifi棒子测试OK
修改CONFIG_BOOTCOMMAND相关参数,修改uboot读取kernel的大小(2.2m)
开机优化到2.5s进终端
#define CONFIG_BOOTCOMMAND "sf probe 0 100000000; sf read 0x80C00000 0x100000 0x4000; \
sf read 0x80008000 0x110000 0x215000; bootz 0x80008000 - 0x80C00000"
最新log
[消耗时间] log
[0.002] DRAM: 32 MiB
[0.009] SPL: Unsupported Boot Device!
[0.000] Trying to boot from sunxi SPI
[0.279]
[0.000]
[0.000] U-Boot 2018.01-05682-gd83b2fefcf-dirty (Sep 05 2023 - 01:22:50 +0800) Allwinner Technology
[0.002]
[0.000] DRAM: 32 MiB
[0.517] CONFIG_ENV_SPI_MAX_HZ: 100000000
[0.001] SF: Detected xt25f128b with page size 256 Bytes, erase size 4 KiB, total 16 MiB
[0.000] spi_flash_read
[0.001] --
[0.000] *** Warning0 - bad CRC, using default environment
[0.001]
[0.000] In: serial@1c25000
[0.000] Out: serial@1c25000
[0.000] Err: serial@1c25000
[0.000] starting USB...
[0.000] No controllers found
[0.001] Hit any key to stop autoboot: 0
[0.000] SF: Detected xt25f128b with page size 256 Bytes, erase size 4 KiB, total 16 MiB
[0.000] device 0 offset 0x100000, size 0x4000
[0.003] SF: 16384 bytes @ 0x100000 Read: OK
[0.000] device 0 offset 0x110000, size 0x215000
[0.345] SF: 2183168 bytes @ 0x110000 Read: OK
[0.000] ## Flattened Device Tree blob at 80c00000
[0.000] Booting using the fdt blob at 0x80c00000
[0.000] Loading Device Tree to 816fa000, end 816ff085 ... OK
[0.007]
[0.000] Starting kernel ...
[0.000]
[0.479] [ 0.000000] Booting Linux on physical CPU 0x0
[0.019] [ 0.000000] Linux version 4.15.0-rc8-licheepi-nano+ (lv129@Lv-Ubuntu) (gcc version 7.2.1 20171011 (Linaro GCC 7.2-2017.11)) #41 Tue Sep 5 01:17:06 CST 2023
[0.001] [ 0.000000] CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=0005317f
[0.001] [ 0.000000] CPU: VIVT data cache, VIVT instruction cache
[0.000] [ 0.000000] OF: fdt: Machine model: Lichee Pi Nano
[0.000] [ 0.000000] Memory policy: Data cache writeback
[0.000] [ 0.000000] random: fast init done
[0.000] [ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 8128
[0.000] [ 0.000000] Kernel command line: console=ttyS0,921600 earlyprintk panic=5 rootwait; mtdparts=spi32766.0:220k(uboot)ro,64k(dtb)ro,2.5M(kernel)ro,-(rootfs) root=/dev/mtdblock3 rw rootfstype=squs
[0.002] [ 0.000000] Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
[0.000] [ 0.000000] Inode-cache hash table entries: 2048 (order: 1, 8192 bytes)
[0.000] [ 0.000000] Memory: 27928K/32768K available (3008K kernel code, 164K rwdata, 800K rodata, 176K init, 193K bss, 4840K reserved, 0K cma-reserved, 0K highmem)
[0.001] [ 0.000000] Virtual kernel memory layout:
[0.000] [ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB)
[0.000] [ 0.000000] fixmap : 0xffc00000 - 0xfff00000 (3072 kB)
[0.000] [ 0.000000] vmalloc : 0xc2800000 - 0xff800000 ( 976 MB)
[0.000] [ 0.000000] lowmem : 0xc0000000 - 0xc2000000 ( 32 MB)
[0.000] [ 0.000000] pkmap : 0xbfe00000 - 0xc0000000 ( 2 MB)
[0.000] [ 0.000000] modules : 0xbf000000 - 0xbfe00000 ( 14 MB)
[0.000] [ 0.000000] .text : 0x(ptrval) - 0x(ptrval) (3010 kB)
[0.000] [ 0.000000] .init : 0x(ptrval) - 0x(ptrval) ( 176 kB)
[0.000] [ 0.000000] .data : 0x(ptrval) - 0x(ptrval) ( 165 kB)
[0.000] [ 0.000000] .bss : 0x(ptrval) - 0x(ptrval) ( 194 kB)
[0.001] [ 0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[0.000] [ 0.000000] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
[0.000] [ 0.000061] sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 89478484971ns
[0.001] [ 0.000138] clocksource: timer: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 79635851949 ns
[0.001] [ 0.000715] Console: colour dummy device 80x30
[0.000] [ 0.000821] Calibrating delay loop... 383.38 BogoMIPS (lpj=1916928)
[0.000] [ 0.050301] pid_max: default: 32768 minimum: 301
[0.000] [ 0.050581] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[0.001] [ 0.050622] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[0.000] [ 0.052119] CPU: Testing write buffer coherency: ok
[0.000] [ 0.054359] Setting up static identity map for 0x80008400 - 0x80008458
[0.000] [ 0.056763] devtmpfs: initialized
[0.000] [ 0.061779] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[0.001] [ 0.061860] futex hash table entries: 256 (order: -1, 3072 bytes)
[0.000] [ 0.062186] pinctrl core: initialized pinctrl subsystem
[0.000] [ 0.064912] DMA: preallocated 256 KiB pool for atomic coherent allocations
[0.001] [ 0.066720] cpuidle: using governor menu
[0.000] [ 0.086121] SCSI subsystem initialized
[0.000] [ 0.086492] usbcore: registered new interface driver usbfs
[0.000] [ 0.086644] usbcore: registered new interface driver hub
[0.000] [ 0.086902] usbcore: registered new device driver usb
[0.000] [ 0.087395] pps_core: LinuxPPS API ver. 1 registered
[0.000] [ 0.087422] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[0.001] [ 0.088044] clocksource: Switched to clocksource timer
[0.000] [ 0.097043] NetWinder Floating Point Emulator V0.97 (double precision)
[0.000] [ 0.099863] workingset: timestamp_bits=30 max_order=13 bucket_order=0
[0.001] [ 0.108231] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[0.000] [ 0.108837] jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
[0.000] [ 0.110300] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 252)
[0.001] [ 0.110356] io scheduler noop registered
[0.000] [ 0.110372] io scheduler deadline registered
[0.000] [ 0.111032] io scheduler cfq registered (default)
[0.000] [ 0.111070] io scheduler mq-deadline registered
[0.000] [ 0.111083] io scheduler kyber registered
[0.000] [ 0.122354] suniv-pinctrl 1c20800.pinctrl: initialized sunXi PIO driver
[0.001] [ 0.127990] Serial: 8250/16550 driver, 2 ports, IRQ sharing disabled
[0.000] [ 0.131749] console [ttyS0] disabled
[0.000] [ 0.152137] 1c25000.serial: ttyS0 at MMIO 0x1c25000 (irq = 24, base_baud = 6250000) is a 16550A
[0.001] [ 0.202468] console [ttyS0] enabled
[0.003] [ 0.205117] SCSI Media Changer driver v0.25
[0.004] [ 0.209795] m25p80 spi0.0: xt25f128b (16384 Kbytes)
[0.000] [ 0.210531] mtd: bad character after partition (.)
[0.000] [ 0.211227] 5 ofpart partitions found on MTD device spi0.0
[0.001] [ 0.211955] Creating 5 MTD partitions on "spi0.0":
[0.000] [ 0.212615] 0x000000000000-0x000000032000 : "u-boot"
[0.004] [ 0.216379] 0x000000100000-0x000000110000 : "dtb"
[0.003] [ 0.220060] 0x000000110000-0x000000360000 : "kernel"
[0.003] [ 0.223501] 0x000000510000-0x000000725000 : "rootfs"
[0.000] [ 0.224196] mtd: partition "rootfs" doesn't end on an erase/write block -- force read-only
[0.004] [ 0.228013] 0x000000800000-0x000000d00000 : "overlayfs"
[0.004] [ 0.232104] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[0.000] [ 0.233002] ehci-platform: EHCI generic platform driver
[0.001] [ 0.233957] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[0.000] [ 0.234851] ohci-platform: OHCI generic platform driver
[0.001] [ 0.236764] usb_phy_generic usb_phy_generic.0.auto: usb_phy_generic.0.auto supply vcc not found, using dummy regulator
[0.005] [ 0.241833] g_serial gadget: Gadget Serial v2.4
[0.000] [ 0.242480] g_serial gadget: g_serial ready
[0.001] [ 0.243514] i2c /dev entries driver
[0.064] [ 0.308211] sunxi-mmc 1c0f000.mmc: base:0x21230d20 irq:20
[0.002] [ 0.310634] usbcore: registered new interface driver usbhid
[0.000] [ 0.311399] usbhid: USB HID core driver
[0.023] [ 0.333849] VFS: Mounted root (squashfs filesystem) readonly on device 31:3.
[0.006] [ 0.340321] devtmpfs: mounted
[0.001] [ 0.341928] Freeing unused kernel memory: 176K
[0.000] [ 0.342532] This architecture does not have kernel memory protection.
[0.105] [ 0.447269] random: crng init done
[0.273] [ 0.721136] g_serial gadget: high-speed config #2: CDC ACM config
[0.226] Starting logging: OK
[0.079] read-only file system detected...done
[0.121]
[0.000] Welcome to Buildroot
buildroot login:
最耗费时间的
[0.000] Trying to boot from sunxi SPI
[0.279]
[0.517] CONFIG_ENV_SPI_MAX_HZ: 100000000
[0.001] SF: Detected xt25f128b with page size 256 Bytes, erase size 4 KiB, total 16 MiB
[0.000] device 0 offset 0x110000, size 0x215000
[0.345] SF: 2183168 bytes @ 0x110000 Read: OK
[0.007]
[0.000] Starting kernel ...
[0.479] [ 0.000000] Booting Linux on physical CPU 0x0
[0.105] [ 0.447269] random: crng init done
[0.273] [ 0.721136] g_serial gadget: high-speed config #2: CDC ACM config
[0.226] Starting logging: OK
[0.079] read-only file system detected...done
[0.121]
[0.000] Welcome to Buildroot
buildroot login:
uboot SPI默认1M速度设置100M 可加快0.3 0.4s
https://whycan.com/t_8172.html
#ifndef CONFIG_ENV_SPI_MAX_HZ
//# define CONFIG_ENV_SPI_MAX_HZ CONFIG_SF_DEFAULT_SPEED
# define CONFIG_ENV_SPI_MAX_HZ 100000000
#endif
#ifndef CONFIG_ENV_SPI_MODE
# define CONFIG_ENV_SPI_MODE CONFIG_SF_DEFAULT_MODE
#endif
#ifndef CONFIG_SPL_BUILD
#define CMD_SAVEENV
#endif
#ifdef CONFIG_ENV_OFFSET_REDUND
#ifdef CMD_SAVEENV
static ulong env_offset = CONFIG_ENV_OFFSET;
static ulong env_new_offset = CONFIG_ENV_OFFSET_REDUND;
#endif
#define ACTIVE_FLAG 1
#define OBSOLETE_FLAG 0
#endif /* CONFIG_ENV_OFFSET_REDUND */
DECLARE_GLOBAL_DATA_PTR;
static struct spi_flash *env_flash;
static int setup_flash_device(void)
{
#ifdef ONFIG_DM_SPI_FLASH_lzq
struct udevice *new;
int ret;
/* speed and mode will be read from DT */
ret = spi_flash_probe_bus_cs(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS,
0, 0, &new);
if (ret) {
set_default_env("!spi_flash_probe_bus_cs() failed");
return ret;
}
env_flash = dev_get_uclass_priv(new);
#else
printf("CONFIG_ENV_SPI_MAX_HZ: %d\n", CONFIG_ENV_SPI_MAX_HZ);
if (!env_flash) {
env_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS,
CONFIG_ENV_SPI_CS,
CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE);
if (!env_flash) {
set_default_env("!spi_flash_probe() failed");
return -EIO;
}
}
#endif
return 0;
}
[2023-09-04 23:45:57.021] U-Boot SPL 2018.01-05682-gd83b2fefcf-dirty (Sep 04 2023 - 23:44:43)
[2023-09-04 23:45:57.023] DRAM: 32 MiB
[2023-09-04 23:45:57.032] SPL: Unsupported Boot Device!
[2023-09-04 23:45:57.033] Trying to boot from sunxi SPI
[2023-09-04 23:45:57.312]
[2023-09-04 23:45:57.312]
[2023-09-04 23:45:57.312] U-Boot 2018.01-05682-gd83b2fefcf-dirty (Sep 04 2023 - 23:44:43 +0800) Allwinner Technology
[2023-09-04 23:45:57.315]
[2023-09-04 23:45:57.315] DRAM: 32 MiB
[2023-09-04 23:45:57.832] CONFIG_ENV_SPI_MAX_HZ: 100000000
[2023-09-04 23:45:57.833] SF: Detected xt25f128b with page size 256 Bytes, erase size 4 KiB, total 16 MiB
[2023-09-04 23:45:57.833] spi_flash_read
[2023-09-04 23:45:57.835] --
[2023-09-04 23:45:57.835] *** Warning0 - bad CRC, using default environment
[2023-09-04 23:45:57.837]
[2023-09-04 23:45:57.837] In: serial@1c25000
[2023-09-04 23:45:57.837] Out: serial@1c25000
[2023-09-04 23:45:57.837] Err: serial@1c25000
[2023-09-04 23:45:57.837] starting USB...
[2023-09-04 23:45:57.837] No controllers found
[2023-09-04 23:45:57.839] Hit any key to stop autoboot: 0
[2023-09-04 23:45:57.839] SF: Detected xt25f128b with page size 256 Bytes, erase size 4 KiB, total 16 MiB
[2023-09-04 23:45:57.840] device 0 offset 0x100000, size 0x4000
[2023-09-04 23:45:57.845] SF: 16384 bytes @ 0x100000 Read: OK
[2023-09-04 23:45:57.845] device 0 offset 0x110000, size 0x400000
[2023-09-04 23:45:58.883] SF: 4194304 bytes @ 0x110000 Read: OK
[2023-09-04 23:45:58.884] ## Flattened Device Tree blob at 80c00000
[2023-09-04 23:45:58.884] Booting using the fdt blob at 0x80c00000
[2023-09-04 23:45:58.884] Loading Device Tree to 816fa000, end 816ff085 ... OK
[2023-09-04 23:45:58.892]
[2023-09-04 23:45:58.892] Starting kernel ...
[2023-09-04 23:45:58.892]
[2023-09-04 23:45:59.419] [ 0.000000] Booting Linux on physical CPU 0x0
[2023-09-04 23:45:59.438] [ 0.000000] Linux version 4.15.0-rc8-licheepi-nano+ (lv129@Lv-Ubuntu) (gcc version 7.2.1 20171011 (Linaro GCC 7.2-2017.11)) #37 Sun Sep 3 18:02:14 CST 2023
[2023-09-04 23:45:59.440] [ 0.000000] CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=0005317f
[2023-09-04 23:45:59.441] [ 0.000000] CPU: VIVT data cache, VIVT instruction cache
[2023-09-04 23:45:59.442] [ 0.000000] OF: fdt: Machine model: Lichee Pi Nano
[2023-09-04 23:45:59.442] [ 0.000000] Memory policy: Data cache writeback
[2023-09-04 23:45:59.443] [ 0.000000] random: fast init done
[2023-09-04 23:45:59.443] [ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 8128
[2023-09-04 23:45:59.444] [ 0.000000] Kernel command line: console=ttyS0,921600 earlyprintk panic=5 rootwait; mtdparts=spi32766.0:220k(uboot)ro,64k(dtb)ro,2.5M(kernel)ro,-(rootfs) root=/dev/mtdblock3s
[2023-09-04 23:45:59.447] [ 0.000000] Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
[2023-09-04 23:45:59.447] [ 0.000000] Inode-cache hash table entries: 2048 (order: 1, 8192 bytes)
[2023-09-04 23:45:59.448] [ 0.000000] Memory: 27652K/32768K available (3171K kernel code, 191K rwdata, 860K rodata, 188K init, 202K bss, 5116K reserved, 0K cma-reserved, 0K highmem)
[2023-09-04 23:45:59.450] [ 0.000000] Virtual kernel memory layout:
[2023-09-04 23:45:59.451] [ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB)
[2023-09-04 23:45:59.452] [ 0.000000] fixmap : 0xffc00000 - 0xfff00000 (3072 kB)
[2023-09-04 23:45:59.452] [ 0.000000] vmalloc : 0xc2800000 - 0xff800000 ( 976 MB)
[2023-09-04 23:45:59.453] [ 0.000000] lowmem : 0xc0000000 - 0xc2000000 ( 32 MB)
[2023-09-04 23:45:59.454] [ 0.000000] pkmap : 0xbfe00000 - 0xc0000000 ( 2 MB)
[2023-09-04 23:45:59.454] [ 0.000000] modules : 0xbf000000 - 0xbfe00000 ( 14 MB)
[2023-09-04 23:45:59.455] [ 0.000000] .text : 0x(ptrval) - 0x(ptrval) (3173 kB)
[2023-09-04 23:45:59.456] [ 0.000000] .init : 0x(ptrval) - 0x(ptrval) ( 188 kB)
[2023-09-04 23:45:59.456] [ 0.000000] .data : 0x(ptrval) - 0x(ptrval) ( 192 kB)
[2023-09-04 23:45:59.457] [ 0.000000] .bss : 0x(ptrval) - 0x(ptrval) ( 203 kB)
[2023-09-04 23:45:59.458] [ 0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[2023-09-04 23:45:59.459] [ 0.000000] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
[2023-09-04 23:45:59.460] [ 0.000060] sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 89478484971ns
[2023-09-04 23:45:59.461] [ 0.000134] clocksource: timer: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 79635851949 ns
[2023-09-04 23:45:59.462] [ 0.000721] Console: colour dummy device 80x30
[2023-09-04 23:45:59.463] [ 0.000824] Calibrating delay loop... 380.92 BogoMIPS (lpj=1904640)
[2023-09-04 23:45:59.463] [ 0.060173] pid_max: default: 32768 minimum: 301
[2023-09-04 23:45:59.464] [ 0.060506] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[2023-09-04 23:45:59.465] [ 0.060556] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[2023-09-04 23:45:59.465] [ 0.062106] CPU: Testing write buffer coherency: ok
[2023-09-04 23:45:59.466] [ 0.064395] Setting up static identity map for 0x80008400 - 0x80008458
[2023-09-04 23:45:59.467] [ 0.066845] devtmpfs: initialized
[2023-09-04 23:45:59.468] [ 0.072161] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[2023-09-04 23:45:59.469] [ 0.072243] futex hash table entries: 256 (order: -1, 3072 bytes)
[2023-09-04 23:45:59.470] [ 0.072566] pinctrl core: initialized pinctrl subsystem
[2023-09-04 23:45:59.470] [ 0.075325] DMA: preallocated 256 KiB pool for atomic coherent allocations
[2023-09-04 23:45:59.471] [ 0.077163] cpuidle: using governor menu
[2023-09-04 23:45:59.472] [ 0.097818] SCSI subsystem initialized
[2023-09-04 23:45:59.472] [ 0.098241] usbcore: registered new interface driver usbfs
[2023-09-04 23:45:59.473] [ 0.098409] usbcore: registered new interface driver hub
[2023-09-04 23:45:59.474] [ 0.098632] usbcore: registered new device driver usb
[2023-09-04 23:45:59.474] [ 0.099114] pps_core: LinuxPPS API ver. 1 registered
[2023-09-04 23:45:59.475] [ 0.099146] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[2023-09-04 23:45:59.476] [ 0.099814] clocksource: Switched to clocksource timer
[2023-09-04 23:45:59.477] [ 0.108785] NetWinder Floating Point Emulator V0.97 (double precision)
[2023-09-04 23:45:59.477] [ 0.111063] Initialise system trusted keyrings
[2023-09-04 23:45:59.478] [ 0.111786] workingset: timestamp_bits=30 max_order=13 bucket_order=0
[2023-09-04 23:45:59.479] [ 0.120461] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[2023-09-04 23:45:59.480] [ 0.121020] jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
[2023-09-04 23:45:59.481] [ 0.136077] Key type asymmetric registered
[2023-09-04 23:45:59.481] [ 0.136136] Asymmetric key parser 'x509' registered
[2023-09-04 23:45:59.482] [ 0.136396] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 252)
[2023-09-04 23:45:59.483] [ 0.136436] io scheduler noop registered
[2023-09-04 23:45:59.483] [ 0.136449] io scheduler deadline registered
[2023-09-04 23:45:59.484] [ 0.137193] io scheduler cfq registered (default)
[2023-09-04 23:45:59.484] [ 0.137242] io scheduler mq-deadline registered
[2023-09-04 23:45:59.485] [ 0.137259] io scheduler kyber registered
[2023-09-04 23:45:59.486] [ 0.148785] suniv-pinctrl 1c20800.pinctrl: initialized sunXi PIO driver
[2023-09-04 23:45:59.487] [ 0.154811] Serial: 8250/16550 driver, 2 ports, IRQ sharing disabled
[2023-09-04 23:45:59.487] [ 0.158256] console [ttyS0] disabled
[2023-09-04 23:45:59.488] [ 0.178515] 1c25000.serial: ttyS0 at MMIO 0x1c25000 (irq = 24, base_baud = 6250000) is a 16550A
[2023-09-04 23:45:59.489] [ 0.230784] console [ttyS0] enabled
[2023-09-04 23:45:59.492] [ 0.233506] SCSI Media Changer driver v0.25
[2023-09-04 23:45:59.497] [ 0.238030] m25p80 spi0.0: xt25f128b (16384 Kbytes)
[2023-09-04 23:45:59.497] [ 0.238788] mtd: bad character after partition (.)
[2023-09-04 23:45:59.498] [ 0.239486] 5 ofpart partitions found on MTD device spi0.0
[2023-09-04 23:45:59.499] [ 0.240383] Creating 5 MTD partitions on "spi0.0":
[2023-09-04 23:45:59.499] [ 0.241061] 0x000000000000-0x000000037000 : "u-boot"
[2023-09-04 23:45:59.504] [ 0.244885] 0x000000100000-0x000000110000 : "dtb"
[2023-09-04 23:45:59.507] [ 0.248372] 0x000000110000-0x000000360000 : "kernel"
[2023-09-04 23:45:59.511] [ 0.252105] 0x000000510000-0x000000760000 : "rootfs"
[2023-09-04 23:45:59.514] [ 0.255589] 0x000000800000-0x000000d00000 : "overlayfs"
[2023-09-04 23:45:59.518] [ 0.259421] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[2023-09-04 23:45:59.519] [ 0.260503] ehci-platform: EHCI generic platform driver
[2023-09-04 23:45:59.520] [ 0.261545] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[2023-09-04 23:45:59.521] [ 0.262444] ohci-platform: OHCI generic platform driver
[2023-09-04 23:45:59.522] [ 0.263513] usbcore: registered new interface driver usb-storage
[2023-09-04 23:45:59.524] [ 0.265330] usb_phy_generic usb_phy_generic.0.auto: usb_phy_generic.0.auto supply vcc not found, using dummy regulator
[2023-09-04 23:45:59.529] [ 0.270436] g_serial gadget: Gadget Serial v2.4
[2023-09-04 23:45:59.529] [ 0.271084] g_serial gadget: g_serial ready
[2023-09-04 23:45:59.530] [ 0.272102] i2c /dev entries driver
[2023-09-04 23:45:59.589] [ 0.329997] sunxi-mmc 1c0f000.mmc: base:0x448d286f irq:20
[2023-09-04 23:45:59.591] [ 0.332691] usbcore: registered new interface driver usbhid
[2023-09-04 23:45:59.592] [ 0.333459] usbhid: USB HID core driver
[2023-09-04 23:45:59.596] [ 0.336761] Loading compiled-in X.509 certificates
[2023-09-04 23:45:59.615] [ 0.356606] VFS: Mounted root (squashfs filesystem) readonly on device 31:3.
[2023-09-04 23:45:59.622] [ 0.363135] devtmpfs: mounted
[2023-09-04 23:45:59.623] [ 0.364813] Freeing unused kernel memory: 188K
[2023-09-04 23:45:59.624] [ 0.365413] This architecture does not have kernel memory protection.
[2023-09-04 23:45:59.736] [ 0.477057] random: crng init done
[2023-09-04 23:46:00.019] [ 0.760662] g_serial gadget: high-speed config #2: CDC ACM config
[2023-09-04 23:46:00.243] Starting logging: OK
[2023-09-04 23:46:00.318] read-only file system detected...done
[2023-09-04 23:46:00.449]
[2023-09-04 23:46:00.449] Welcome to Buildroot
buildroot login: :00.449]
3.7s进终端
最新log
uboot->kernel 2.2s
kernel解压0.5s
kernel启动到登陆花费1s
[2023-09-03 23:00:32.628] U-Boot SPL 2018.01-05682-gd83b2fefcf-dirty (Sep 03 2023 - 22:35:29)
[2023-09-03 23:00:32.630] DRAM: 32 MiB
[2023-09-03 23:00:32.640] SPL: Unsupported Boot Device!
[2023-09-03 23:00:32.640] Trying to boot from sunxi SPI
[2023-09-03 23:00:32.918]
[2023-09-03 23:00:32.918]
[2023-09-03 23:00:32.918] U-Boot 2018.01-05682-gd83b2fefcf-dirty (Sep 03 2023 - 22:35:29 +0800) Allwinner Technology
[2023-09-03 23:00:32.921]
[2023-09-03 23:00:32.921] DRAM: 32 MiB
[2023-09-03 23:00:33.440] SF: Detected xt25f128b with page size 256 Bytes, erase size 4 KiB, total 16 MiB
[2023-09-03 23:00:33.440] spi_flash_read
[2023-09-03 23:00:33.783] --
[2023-09-03 23:00:33.783] <test>----0
[2023-09-03 23:00:33.783] *** Warning0 - bad CRC, using default environment
[2023-09-03 23:00:33.785]
[2023-09-03 23:00:33.785] In: serial@1c25000
[2023-09-03 23:00:33.785] Out: serial@1c25000
[2023-09-03 23:00:33.785] Err: serial@1c25000
[2023-09-03 23:00:33.786] starting USB...
[2023-09-03 23:00:33.786] No controllers found
[2023-09-03 23:00:33.787] Hit any key to stop autoboot: 0
[2023-09-03 23:00:33.789] SF: Detected xt25f128b with page size 256 Bytes, erase size 4 KiB, total 16 MiB
[2023-09-03 23:00:33.789] device 0 offset 0x100000, size 0x4000
[2023-09-03 23:00:33.794] SF: 16384 bytes @ 0x100000 Read: OK
[2023-09-03 23:00:33.794] device 0 offset 0x110000, size 0x400000
[2023-09-03 23:00:34.809] SF: 4194304 bytes @ 0x110000 Read: OK
[2023-09-03 23:00:34.809] ## Flattened Device Tree blob at 80c00000
[2023-09-03 23:00:34.809] Booting using the fdt blob at 0x80c00000
[2023-09-03 23:00:34.810] Loading Device Tree to 816fa000, end 816ff085 ... OK
[2023-09-03 23:00:34.817]
[2023-09-03 23:00:34.817] Starting kernel ...
[2023-09-03 23:00:34.817]
[2023-09-03 23:00:35.346] [ 0.000000] Booting Linux on physical CPU 0x0
[2023-09-03 23:00:35.347] [ 0.000000] Linux version 4.15.0-rc8-licheepi-nano+ (lv129@Lv-Ubuntu) (gcc version 7.2.1 20171011 (Linaro GCC 7.2-2017.11)) #37 Sun Sep 3 18:02:14 CST 2023
[2023-09-03 23:00:35.349] [ 0.000000] CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=0005317f
[2023-09-03 23:00:35.350] [ 0.000000] CPU: VIVT data cache, VIVT instruction cache
[2023-09-03 23:00:35.350] [ 0.000000] OF: fdt: Machine model: Lichee Pi Nano
[2023-09-03 23:00:35.351] [ 0.000000] Memory policy: Data cache writeback
[2023-09-03 23:00:35.351] [ 0.000000] random: fast init done
[2023-09-03 23:00:35.352] [ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 8128
[2023-09-03 23:00:35.353] [ 0.000000] Kernel command line: console=ttyS0,921600 earlyprintk panic=5 rootwait; mtdparts=spi32766.0:220k(uboot)ro,64k(dtb)ro,2.5M(kernel)ro,-(rootfs) root=/dev/mtdblock3s
[2023-09-03 23:00:35.355] [ 0.000000] Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
[2023-09-03 23:00:35.356] [ 0.000000] Inode-cache hash table entries: 2048 (order: 1, 8192 bytes)
[2023-09-03 23:00:35.356] [ 0.000000] Memory: 27652K/32768K available (3171K kernel code, 191K rwdata, 860K rodata, 188K init, 202K bss, 5116K reserved, 0K cma-reserved, 0K highmem)
[2023-09-03 23:00:35.358] [ 0.000000] Virtual kernel memory layout:
[2023-09-03 23:00:35.359] [ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB)
[2023-09-03 23:00:35.360] [ 0.000000] fixmap : 0xffc00000 - 0xfff00000 (3072 kB)
[2023-09-03 23:00:35.361] [ 0.000000] vmalloc : 0xc2800000 - 0xff800000 ( 976 MB)
[2023-09-03 23:00:35.361] [ 0.000000] lowmem : 0xc0000000 - 0xc2000000 ( 32 MB)
[2023-09-03 23:00:35.362] [ 0.000000] pkmap : 0xbfe00000 - 0xc0000000 ( 2 MB)
[2023-09-03 23:00:35.363] [ 0.000000] modules : 0xbf000000 - 0xbfe00000 ( 14 MB)
[2023-09-03 23:00:35.363] [ 0.000000] .text : 0x(ptrval) - 0x(ptrval) (3173 kB)
[2023-09-03 23:00:35.364] [ 0.000000] .init : 0x(ptrval) - 0x(ptrval) ( 188 kB)
[2023-09-03 23:00:35.365] [ 0.000000] .data : 0x(ptrval) - 0x(ptrval) ( 192 kB)
[2023-09-03 23:00:35.366] [ 0.000000] .bss : 0x(ptrval) - 0x(ptrval) ( 203 kB)
[2023-09-03 23:00:35.367] [ 0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[2023-09-03 23:00:35.367] [ 0.000000] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
[2023-09-03 23:00:35.368] [ 0.000060] sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 89478484971ns
[2023-09-03 23:00:35.369] [ 0.000129] clocksource: timer: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 79635851949 ns
[2023-09-03 23:00:35.370] [ 0.000700] Console: colour dummy device 80x30
[2023-09-03 23:00:35.371] [ 0.000800] Calibrating delay loop... 393.21 BogoMIPS (lpj=1966080)
[2023-09-03 23:00:35.372] [ 0.050249] pid_max: default: 32768 minimum: 301
[2023-09-03 23:00:35.372] [ 0.050532] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[2023-09-03 23:00:35.373] [ 0.050575] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[2023-09-03 23:00:35.374] [ 0.052096] CPU: Testing write buffer coherency: ok
[2023-09-03 23:00:35.375] [ 0.054362] Setting up static identity map for 0x80008400 - 0x80008458
[2023-09-03 23:00:35.375] [ 0.056764] devtmpfs: initialized
[2023-09-03 23:00:35.376] [ 0.061981] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[2023-09-03 23:00:35.377] [ 0.062057] futex hash table entries: 256 (order: -1, 3072 bytes)
[2023-09-03 23:00:35.378] [ 0.062367] pinctrl core: initialized pinctrl subsystem
[2023-09-03 23:00:35.379] [ 0.065067] DMA: preallocated 256 KiB pool for atomic coherent allocations
[2023-09-03 23:00:35.380] [ 0.066893] cpuidle: using governor menu
[2023-09-03 23:00:35.380] [ 0.087277] SCSI subsystem initialized
[2023-09-03 23:00:35.380] [ 0.087696] usbcore: registered new interface driver usbfs
[2023-09-03 23:00:35.381] [ 0.087880] usbcore: registered new interface driver hub
[2023-09-03 23:00:35.382] [ 0.088105] usbcore: registered new device driver usb
[2023-09-03 23:00:35.383] [ 0.088574] pps_core: LinuxPPS API ver. 1 registered
[2023-09-03 23:00:35.383] [ 0.088604] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[2023-09-03 23:00:35.384] [ 0.089271] clocksource: Switched to clocksource timer
[2023-09-03 23:00:35.385] [ 0.098105] NetWinder Floating Point Emulator V0.97 (double precision)
[2023-09-03 23:00:35.386] [ 0.100351] Initialise system trusted keyrings
[2023-09-03 23:00:35.387] [ 0.101075] workingset: timestamp_bits=30 max_order=13 bucket_order=0
[2023-09-03 23:00:35.387] [ 0.109434] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[2023-09-03 23:00:35.388] [ 0.110034] jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
[2023-09-03 23:00:35.389] [ 0.124934] Key type asymmetric registered
[2023-09-03 23:00:35.390] [ 0.124984] Asymmetric key parser 'x509' registered
[2023-09-03 23:00:35.390] [ 0.125246] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 252)
[2023-09-03 23:00:35.391] [ 0.125281] io scheduler noop registered
[2023-09-03 23:00:35.392] [ 0.125295] io scheduler deadline registered
[2023-09-03 23:00:35.392] [ 0.126028] io scheduler cfq registered (default)
[2023-09-03 23:00:35.393] [ 0.126070] io scheduler mq-deadline registered
[2023-09-03 23:00:35.394] [ 0.126082] io scheduler kyber registered
[2023-09-03 23:00:35.394] [ 0.137382] suniv-pinctrl 1c20800.pinctrl: initialized sunXi PIO driver
[2023-09-03 23:00:35.395] [ 0.143280] Serial: 8250/16550 driver, 2 ports, IRQ sharing disabled
[2023-09-03 23:00:35.396] [ 0.146684] console [ttyS0] disabled
[2023-09-03 23:00:35.396] [ 0.166963] 1c25000.serial: ttyS0 at MMIO 0x1c25000 (irq = 24, base_baud = 6250000) is a 16550A
[2023-09-03 23:00:35.397] [ 0.219054] console [ttyS0] enabled
[2023-09-03 23:00:35.400] [ 0.221870] SCSI Media Changer driver v0.25
[2023-09-03 23:00:35.405] [ 0.226325] m25p80 spi0.0: xt25f128b (16384 Kbytes)
[2023-09-03 23:00:35.405] [ 0.227084] mtd: bad character after partition (.)
[2023-09-03 23:00:35.406] [ 0.227783] 5 ofpart partitions found on MTD device spi0.0
[2023-09-03 23:00:35.407] [ 0.228510] Creating 5 MTD partitions on "spi0.0":
[2023-09-03 23:00:35.408] [ 0.229172] 0x000000000000-0x000000037000 : "u-boot"
[2023-09-03 23:00:35.412] [ 0.233057] 0x000000100000-0x000000110000 : "dtb"
[2023-09-03 23:00:35.415] [ 0.236517] 0x000000110000-0x000000360000 : "kernel"
[2023-09-03 23:00:35.419] [ 0.240179] 0x000000510000-0x000000760000 : "rootfs"
[2023-09-03 23:00:35.422] [ 0.243656] 0x000000800000-0x000000d00000 : "overlayfs"
[2023-09-03 23:00:35.426] [ 0.247442] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[2023-09-03 23:00:35.427] [ 0.248343] ehci-platform: EHCI generic platform driver
[2023-09-03 23:00:35.428] [ 0.249523] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[2023-09-03 23:00:35.429] [ 0.250426] ohci-platform: OHCI generic platform driver
[2023-09-03 23:00:35.430] [ 0.251521] usbcore: registered new interface driver usb-storage
[2023-09-03 23:00:35.432] [ 0.253338] usb_phy_generic usb_phy_generic.0.auto: usb_phy_generic.0.auto supply vcc not found, using dummy regulator
[2023-09-03 23:00:35.437] [ 0.258189] g_serial gadget: Gadget Serial v2.4
[2023-09-03 23:00:35.437] [ 0.258837] g_serial gadget: g_serial ready
[2023-09-03 23:00:35.438] [ 0.260024] i2c /dev entries driver
[2023-09-03 23:00:35.498] [ 0.319448] sunxi-mmc 1c0f000.mmc: base:0xe3ef672b irq:20
[2023-09-03 23:00:35.501] [ 0.322130] usbcore: registered new interface driver usbhid
[2023-09-03 23:00:35.501] [ 0.322896] usbhid: USB HID core driver
[2023-09-03 23:00:35.505] [ 0.326180] Loading compiled-in X.509 certificates
[2023-09-03 23:00:35.524] [ 0.345893] VFS: Mounted root (squashfs filesystem) readonly on device 31:3.
[2023-09-03 23:00:35.531] [ 0.352389] devtmpfs: mounted
[2023-09-03 23:00:35.533] [ 0.354059] Freeing unused kernel memory: 188K
[2023-09-03 23:00:35.533] [ 0.354664] This architecture does not have kernel memory protection.
[2023-09-03 23:00:35.642] [ 0.463421] random: crng init done
[2023-09-03 23:00:35.916] [ 0.737182] g_serial gadget: high-speed config #2: CDC ACM config
[2023-09-03 23:00:36.148] Starting logging: OK
[2023-09-03 23:00:36.226] read-only file system detected...done
[2023-09-03 23:00:36.349]
[2023-09-03 23:00:36.349] Welcome to Buildroot
buildroot login: login[62]: root login on 'ttyGS0'
问题1
uboot启动打log发现主要时间在D2--D3
static int env_sf_load(void)
{
pr_err("<test>----D\n");
int ret;
char *buf = NULL;
buf = (char *)memalign(ARCH_DMA_MINALIGN, CONFIG_ENV_SIZE);
if (!buf) {
set_default_env("!malloc() failed");
return -EIO;
}
pr_err("<test>----D1\n");
ret = setup_flash_device();
if (ret)
goto out;
pr_err("<test>----D2\n");
ret = spi_flash_read(env_flash,
CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, buf);
pr_err("<test>----D3\n");
if (ret) {
set_default_env("!spi_flash_read() failed");
goto err_read;
}
pr_err("<test>----B\n");
ret = env_import(buf, 1);
if (ret)
gd->env_valid = ENV_VALID;
err_read:
spi_flash_free(env_flash);
env_flash = NULL;
out:
free(buf);
return ret;
}
修改 Environment Size 即可
│
│ │ Select the location of the environment (Environment is in SPI flash) ---> │ │
│ │ (0x35000) Environment Offset │ │
│ │ (0x1000) Environment Size
修改前D2->D3花费2.7s
修改后D2->D3花费0.3s
[2023-09-03 21:57:23.790] U-Boot 2018.01-05682-gd83b2fefcf-dirty (Sep 03 2023 - 21:57:02 +0800) Allwinner Techy
[2023-09-03 21:57:23.791]
[2023-09-03 21:57:23.791] CPU: Allwinner F Series (SUNIV)
[2023-09-03 21:57:23.791] Model: Lichee Pi Nano
[2023-09-03 21:57:23.791] DRAM: 32 MiB
[2023-09-03 21:57:24.313] <test>----D
[2023-09-03 21:57:24.313] <test>----D1
[2023-09-03 21:57:24.313] SF: Detected xt25f128b with page size 256 Bytes, erase size 4 KiB, total 16 MiB
[2023-09-03 21:57:24.315] <test>----D2
[2023-09-03 21:57:24.656] <test>----D3
[2023-09-03 21:57:24.656] <test>----B
[2023-09-03 21:57:24.656] <test>----0
[2023-09-03 21:57:24.656] *** Warning0 - bad CRC, using default environment
最新log
uboot->kernel 4.5s
主要花费在
2023-09-03 21:07:59.239] CPU: Allwinner F Series (SUNIV)
[2023-09-03 21:07:59.240] Model: Lichee Pi Nano
[2023-09-03 21:07:59.240] DRAM: 32 MiB
[2023-09-03 21:07:59.761] SF: Detected xt25f128b with page size 256 Bytes, erase size 4 KiB, total 16 MiB
[2023-09-03 21:08:02.495] *** Warning - bad CRC, using default environment
kernel解压0.5s
kernel启动到登陆花费1s
[2023-09-03 21:07:58.948] U-Boot SPL 2018.01-05682-gd83b2fefcf-dirty (Sep 03 2023 - 19:52:25)
[2023-09-03 21:07:58.951] DRAM: 32 MiB
[2023-09-03 21:07:58.960] SPL: Unsupported Boot Device!
[2023-09-03 21:07:58.960] Trying to boot from sunxi SPI
[2023-09-03 21:07:59.239]
[2023-09-03 21:07:59.239]
[2023-09-03 21:07:59.239] U-Boot 2018.01-05682-gd83b2fefcf-dirty (Sep 03 2023 - 19:52:25 +0800) Allwinner Technology
[2023-09-03 21:07:59.239]
[2023-09-03 21:07:59.239] CPU: Allwinner F Series (SUNIV)
[2023-09-03 21:07:59.240] Model: Lichee Pi Nano
[2023-09-03 21:07:59.240] DRAM: 32 MiB
[2023-09-03 21:07:59.761] SF: Detected xt25f128b with page size 256 Bytes, erase size 4 KiB, total 16 MiB
[2023-09-03 21:08:02.495] *** Warning - bad CRC, using default environment
[2023-09-03 21:08:02.497]
[2023-09-03 21:08:02.497] In: serial@1c25000
[2023-09-03 21:08:02.497] Out: serial@1c25000
[2023-09-03 21:08:02.497] Err: serial@1c25000
[2023-09-03 21:08:02.497] starting USB...
[2023-09-03 21:08:02.498] No controllers found
[2023-09-03 21:08:02.500] Hit any key to stop autoboot: 0
[2023-09-03 21:08:02.501] SF: Detected xt25f128b with page size 256 Bytes, erase size 4 KiB, total 16 MiB
[2023-09-03 21:08:02.501] device 0 offset 0x100000, size 0x4000
[2023-09-03 21:08:02.506] SF: 16384 bytes @ 0x100000 Read: OK
[2023-09-03 21:08:02.506] device 0 offset 0x110000, size 0x400000
[2023-09-03 21:08:03.533] SF: 4194304 bytes @ 0x110000 Read: OK
[2023-09-03 21:08:03.534] ## Flattened Device Tree blob at 80c00000
[2023-09-03 21:08:03.534] Booting using the fdt blob at 0x80c00000
[2023-09-03 21:08:03.534] Loading Device Tree to 816fa000, end 816ff085 ... OK
[2023-09-03 21:08:03.541]
[2023-09-03 21:08:03.541] Starting kernel ...
[2023-09-03 21:08:03.541]
[2023-09-03 21:08:04.071] [ 0.000000] Booting Linux on physical CPU 0x0
[2023-09-03 21:08:04.071] [ 0.000000] Linux version 4.15.0-rc8-licheepi-nano+ (lv129@Lv-Ubuntu) (gcc version 7.2.1 20171011 (Linaro GCC 7.2-2017.11)) #37 Sun Sep 3 18:02:14 CST 2023
[2023-09-03 21:08:04.073] [ 0.000000] CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=0005317f
[2023-09-03 21:08:04.074] [ 0.000000] CPU: VIVT data cache, VIVT instruction cache
[2023-09-03 21:08:04.075] [ 0.000000] OF: fdt: Machine model: Lichee Pi Nano
[2023-09-03 21:08:04.076] [ 0.000000] Memory policy: Data cache writeback
[2023-09-03 21:08:04.076] [ 0.000000] random: fast init done
[2023-09-03 21:08:04.077] [ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 8128
[2023-09-03 21:08:04.077] [ 0.000000] Kernel command line: console=ttyS0,921600 earlyprintk panic=5 rootwait; mtdparts=spi32766.0:220k(uboot)ro,64k(dtb)ro,2M(kernel)ro,-(rootfs) root=/dev/mtdblock3 rs
[2023-09-03 21:08:04.080] [ 0.000000] Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
[2023-09-03 21:08:04.081] [ 0.000000] Inode-cache hash table entries: 2048 (order: 1, 8192 bytes)
[2023-09-03 21:08:04.081] [ 0.000000] Memory: 27652K/32768K available (3171K kernel code, 191K rwdata, 860K rodata, 188K init, 202K bss, 5116K reserved, 0K cma-reserved, 0K highmem)
[2023-09-03 21:08:04.083] [ 0.000000] Virtual kernel memory layout:
[2023-09-03 21:08:04.084] [ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB)
[2023-09-03 21:08:04.085] [ 0.000000] fixmap : 0xffc00000 - 0xfff00000 (3072 kB)
[2023-09-03 21:08:04.085] [ 0.000000] vmalloc : 0xc2800000 - 0xff800000 ( 976 MB)
[2023-09-03 21:08:04.086] [ 0.000000] lowmem : 0xc0000000 - 0xc2000000 ( 32 MB)
[2023-09-03 21:08:04.087] [ 0.000000] pkmap : 0xbfe00000 - 0xc0000000 ( 2 MB)
[2023-09-03 21:08:04.087] [ 0.000000] modules : 0xbf000000 - 0xbfe00000 ( 14 MB)
[2023-09-03 21:08:04.088] [ 0.000000] .text : 0x(ptrval) - 0x(ptrval) (3173 kB)
[2023-09-03 21:08:04.089] [ 0.000000] .init : 0x(ptrval) - 0x(ptrval) ( 188 kB)
[2023-09-03 21:08:04.090] [ 0.000000] .data : 0x(ptrval) - 0x(ptrval) ( 192 kB)
[2023-09-03 21:08:04.090] [ 0.000000] .bss : 0x(ptrval) - 0x(ptrval) ( 203 kB)
[2023-09-03 21:08:04.091] [ 0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[2023-09-03 21:08:04.092] [ 0.000000] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
[2023-09-03 21:08:04.093] [ 0.000060] sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 89478484971ns
[2023-09-03 21:08:04.094] [ 0.000129] clocksource: timer: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 79635851949 ns
[2023-09-03 21:08:04.095] [ 0.000701] Console: colour dummy device 80x30
[2023-09-03 21:08:04.096] [ 0.000802] Calibrating delay loop... 393.21 BogoMIPS (lpj=1966080)
[2023-09-03 21:08:04.097] [ 0.050249] pid_max: default: 32768 minimum: 301
[2023-09-03 21:08:04.097] [ 0.050533] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[2023-09-03 21:08:04.098] [ 0.050576] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[2023-09-03 21:08:04.099] [ 0.052098] CPU: Testing write buffer coherency: ok
[2023-09-03 21:08:04.099] [ 0.054361] Setting up static identity map for 0x80008400 - 0x80008458
[2023-09-03 21:08:04.100] [ 0.056763] devtmpfs: initialized
[2023-09-03 21:08:04.101] [ 0.061968] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[2023-09-03 21:08:04.102] [ 0.062045] futex hash table entries: 256 (order: -1, 3072 bytes)
[2023-09-03 21:08:04.103] [ 0.062351] pinctrl core: initialized pinctrl subsystem
[2023-09-03 21:08:04.103] [ 0.065051] DMA: preallocated 256 KiB pool for atomic coherent allocations
[2023-09-03 21:08:04.105] [ 0.066886] cpuidle: using governor menu
[2023-09-03 21:08:04.105] [ 0.087228] SCSI subsystem initialized
[2023-09-03 21:08:04.105] [ 0.087656] usbcore: registered new interface driver usbfs
[2023-09-03 21:08:04.106] [ 0.087826] usbcore: registered new interface driver hub
[2023-09-03 21:08:04.107] [ 0.088050] usbcore: registered new device driver usb
[2023-09-03 21:08:04.107] [ 0.088526] pps_core: LinuxPPS API ver. 1 registered
[2023-09-03 21:08:04.108] [ 0.088557] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[2023-09-03 21:08:04.109] [ 0.089213] clocksource: Switched to clocksource timer
[2023-09-03 21:08:04.110] [ 0.098054] NetWinder Floating Point Emulator V0.97 (double precision)
[2023-09-03 21:08:04.111] [ 0.100305] Initialise system trusted keyrings
[2023-09-03 21:08:04.111] [ 0.101031] workingset: timestamp_bits=30 max_order=13 bucket_order=0
[2023-09-03 21:08:04.112] [ 0.109525] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[2023-09-03 21:08:04.113] [ 0.110105] jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
[2023-09-03 21:08:04.114] [ 0.124928] Key type asymmetric registered
[2023-09-03 21:08:04.114] [ 0.124981] Asymmetric key parser 'x509' registered
[2023-09-03 21:08:04.115] [ 0.125240] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 252)
[2023-09-03 21:08:04.116] [ 0.125279] io scheduler noop registered
[2023-09-03 21:08:04.117] [ 0.125294] io scheduler deadline registered
[2023-09-03 21:08:04.117] [ 0.126025] io scheduler cfq registered (default)
[2023-09-03 21:08:04.118] [ 0.126075] io scheduler mq-deadline registered
[2023-09-03 21:08:04.118] [ 0.126091] io scheduler kyber registered
[2023-09-03 21:08:04.119] [ 0.137359] suniv-pinctrl 1c20800.pinctrl: initialized sunXi PIO driver
[2023-09-03 21:08:04.120] [ 0.143266] Serial: 8250/16550 driver, 2 ports, IRQ sharing disabled
[2023-09-03 21:08:04.121] [ 0.146705] console [ttyS0] disabled
[2023-09-03 21:08:04.121] [ 0.166980] 1c25000.serial: ttyS0 at MMIO 0x1c25000 (irq = 24, base_baud = 6250000) is a 16550A
[2023-09-03 21:08:04.122] [ 0.219039] console [ttyS0] enabled
[2023-09-03 21:08:04.125] [ 0.221839] SCSI Media Changer driver v0.25
[2023-09-03 21:08:04.130] [ 0.226318] m25p80 spi0.0: xt25f128b (16384 Kbytes)
[2023-09-03 21:08:04.130] [ 0.227143] 5 ofpart partitions found on MTD device spi0.0
[2023-09-03 21:08:04.131] [ 0.227876] Creating 5 MTD partitions on "spi0.0":
[2023-09-03 21:08:04.132] [ 0.228539] 0x000000000000-0x000000037000 : "u-boot"
[2023-09-03 21:08:04.136] [ 0.232451] 0x000000100000-0x000000110000 : "dtb"
[2023-09-03 21:08:04.140] [ 0.235930] 0x000000110000-0x000000360000 : "kernel"
[2023-09-03 21:08:04.143] [ 0.239619] 0x000000510000-0x000000760000 : "rootfs"
[2023-09-03 21:08:04.147] [ 0.243120] 0x000000800000-0x000000d00000 : "overlayfs"
[2023-09-03 21:08:04.150] [ 0.246902] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[2023-09-03 21:08:04.151] [ 0.247800] ehci-platform: EHCI generic platform driver
[2023-09-03 21:08:04.152] [ 0.248790] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[2023-09-03 21:08:04.153] [ 0.249856] ohci-platform: OHCI generic platform driver
[2023-09-03 21:08:04.154] [ 0.250986] usbcore: registered new interface driver usb-storage
[2023-09-03 21:08:04.156] [ 0.252804] usb_phy_generic usb_phy_generic.0.auto: usb_phy_generic.0.auto supply vcc not found, using dummy regulator
[2023-09-03 21:08:04.161] [ 0.257627] g_serial gadget: Gadget Serial v2.4
[2023-09-03 21:08:04.161] [ 0.258276] g_serial gadget: g_serial ready
[2023-09-03 21:08:04.163] [ 0.259469] i2c /dev entries driver
[2023-09-03 21:08:04.223] [ 0.319388] sunxi-mmc 1c0f000.mmc: base:0xe3ef672b irq:20
[2023-09-03 21:08:04.225] [ 0.322061] usbcore: registered new interface driver usbhid
[2023-09-03 21:08:04.226] [ 0.322828] usbhid: USB HID core driver
[2023-09-03 21:08:04.229] [ 0.326082] Loading compiled-in X.509 certificates
[2023-09-03 21:08:04.248] [ 0.344877] VFS: Mounted root (squashfs filesystem) readonly on device 31:3.
[2023-09-03 21:08:04.256] [ 0.352320] devtmpfs: mounted
[2023-09-03 21:08:04.257] [ 0.353997] Freeing unused kernel memory: 188K
[2023-09-03 21:08:04.258] [ 0.354602] This architecture does not have kernel memory protection.
[2023-09-03 21:08:04.367] [ 0.463255] random: crng init done
[2023-09-03 21:08:04.642] [ 0.738377] g_serial gadget: high-speed config #2: CDC ACM config
[2023-09-03 21:08:04.873] Starting logging: OK
[2023-09-03 21:08:04.952] read-only file system detected...done
[2023-09-03 21:08:04.977] Starting network: ip: socket: Function not implemented
[2023-09-03 21:08:05.058] ip: socket: Function not implemented
[2023-09-03 21:08:05.065] FAIL
[2023-09-03 21:08:05.183]
[2023-09-03 21:08:05.183] Welcome to Buildroot
buildroot login: :05.183]
[2023-09-03 21:08:06.149] Welcome to Buildroot
buildroot login: root149]
[2023-09-03 21:08:07.906] login[71]: root login on 'console'
# ls /dev/
[2023-09-03 21:08:09.896] console mtd4ro tty1
[2023-09-03 21:08:09.897] cpu_dma_latency mtdblock0 tty2
[2023-09-03 21:08:09.897] full mtdblock1 tty3
[2023-09-03 21:08:09.899] gpiochip0 mtdblock2 tty4
[2023-09-03 21:08:09.899] i2c-0 mtdblock3 ttyGS0
[2023-09-03 21:08:09.900] kmsg mtdblock4 ttyS0
[2023-09-03 21:08:09.901] mem network_latency ttyS1
[2023-09-03 21:08:09.902] memory_bandwidth network_throughput ttyp0
[2023-09-03 21:08:09.903] mtd0 null ttyp1
[2023-09-03 21:08:09.904] mtd0ro ptmx urandom
[2023-09-03 21:08:09.905] mtd1 pts vcs
[2023-09-03 21:08:09.906] mtd1ro ptyp0 vcs1
[2023-09-03 21:08:09.907] mtd2 ptyp1 vcsa
[2023-09-03 21:08:09.908] mtd2ro random vcsa1
[2023-09-03 21:08:09.908] mtd3 shm zero
[2023-09-03 21:08:09.909] mtd3ro tty
[2023-09-03 21:08:09.910] mtd4 tty0
[2023-09-03 21:08:09.912] #
问题2解决了
之前是kernel压缩方式是XZ(1.5s zImge 1.7m)
改成GZIP (0.53s zImge 2.2m)
改成LZO(0.45s zImage 2.5m)
linux kernel
General setup --->
Kernel compression mode (Gzip) --->
GZIP 0.53s
[2023-09-03 20:50:37.548] Starting kernel ...
[2023-09-03 20:50:37.548]
[2023-09-03 20:50:38.077] [ 0.000000] Booting Linux on physical CPU 0x0
LZO 0.45s
[2023-09-03 20:59:24.485] Starting kernel ...
[2023-09-03 20:59:24.485]
[2023-09-03 20:59:24.936] [ 0.000000] Booting Linux on physical CPU 0x0
https://whycan.com/t_3010.html
mark下
测试squashfs文件系统挂载速度很快,问题3解决了
[2023-09-03 18:18:06.336] [ 0.326070] Loading compiled-in X.509 certificates
[2023-09-03 18:18:06.355] [ 0.344888] VFS: Mounted root (squashfs filesystem) readonly on device 31:3.
[2023-09-03 18:18:06.363] [ 0.352311] devtmpfs: mounted
[2023-09-03 18:18:06.364] [ 0.353985] Freeing unused kernel memory: 188K
[2023-09-03 18:18:06.364] [ 0.354592] This architecture does not have kernel memory protection.
[2023-09-03 18:18:06.474] [ 0.463208] random: crng init done
[2023-09-03 18:18:06.754] [ 0.743375] g_serial gadget: high-speed config #2: CDC ACM config
[2023-09-03 18:18:06.966] Starting logging: OK
[2023-09-03 18:18:07.039] read-only file system detected...done
[2023-09-03 18:18:07.069] Starting network: ip: socket: Function not implemented
[2023-09-03 18:18:07.148] ip: socket: Function not implemented
[2023-09-03 18:18:07.154] FAIL
[2023-09-03 18:18:07.268]
[2023-09-03 18:18:07.268] Welcome to Buildroot
buildroot login: :07.268]
[2023-09-03 16:27:01.088] U-Boot SPL 2018.01-05682-gd83b2fefcf-dirty (Sep 03 2023 - 14:43:12)
[2023-09-03 16:27:01.090] DRAM: 32 MiB
[2023-09-03 16:27:01.099] Trying to boot from MMC1
[2023-09-03 16:27:01.099] MMC Device 0 not found
[2023-09-03 16:27:01.099] spl: could not find mmc device. error: -19
[2023-09-03 16:27:01.100] Trying to boot from sunxi SPI
[2023-09-03 16:27:01.399]
[2023-09-03 16:27:01.399]
[2023-09-03 16:27:01.399] U-Boot 2018.01-05682-gd83b2fefcf-dirty (Sep 03 2023 - 14:43:12 +0800) Allwinner Technology
[2023-09-03 16:27:01.400]
[2023-09-03 16:27:01.400] CPU: Allwinner F Series (SUNIV)
[2023-09-03 16:27:01.400] Model: Lichee Pi Nano
[2023-09-03 16:27:01.400] DRAM: 32 MiB
[2023-09-03 16:27:01.922] MMC:
[2023-09-03 16:27:01.922] SF: Detected xt25f128b with page size 256 Bytes, erase size 4 KiB, total 16 MiB
[2023-09-03 16:27:04.656] *** Warning - bad CRC, using default environment
[2023-09-03 16:27:04.658]
[2023-09-03 16:27:04.658] In: serial@1c25000
[2023-09-03 16:27:04.658] Out: serial@1c25000
[2023-09-03 16:27:04.658] Err: serial@1c25000
[2023-09-03 16:27:04.658] starting USB...
[2023-09-03 16:27:04.659] No controllers found
[2023-09-03 16:27:04.660] Hit any key to stop autoboot: 0
[2023-09-03 16:27:04.662] SF: Detected xt25f128b with page size 256 Bytes, erase size 4 KiB, total 16 MiB
[2023-09-03 16:27:04.662] device 0 offset 0x100000, size 0x4000
[2023-09-03 16:27:04.667] SF: 16384 bytes @ 0x100000 Read: OK
[2023-09-03 16:27:04.667] device 0 offset 0x110000, size 0x400000
[2023-09-03 16:27:05.698] SF: 4194304 bytes @ 0x110000 Read: OK
[2023-09-03 16:27:05.698] ## Flattened Device Tree blob at 80c00000
[2023-09-03 16:27:05.699] Booting using the fdt blob at 0x80c00000
[2023-09-03 16:27:05.699] Loading Device Tree to 816fa000, end 816ff03d ... OK
[2023-09-03 16:27:05.706]
[2023-09-03 16:27:05.706] Starting kernel ...
[2023-09-03 16:27:05.706]
[2023-09-03 16:27:07.259] [ 0.000000] Booting Linux on physical CPU 0x0
[2023-09-03 16:27:07.259] [ 0.000000] Linux version 4.15.0-rc8-licheepi-nano+ (lv129@Lv-Ubuntu) (gcc version 7.2.1 20171011 (Linaro GCC 7.2-2017.11)) #36 Sat Sep 2 23:56:49 CST 2023
[2023-09-03 16:27:07.261] [ 0.000000] CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=0005317f
[2023-09-03 16:27:07.262] [ 0.000000] CPU: VIVT data cache, VIVT instruction cache
[2023-09-03 16:27:07.262] [ 0.000000] OF: fdt: Machine model: Lichee Pi Nano
[2023-09-03 16:27:07.263] [ 0.000000] Memory policy: Data cache writeback
[2023-09-03 16:27:07.264] [ 0.000000] random: fast init done
[2023-09-03 16:27:07.264] [ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 8128
[2023-09-03 16:27:07.265] [ 0.000000] Kernel command line: console=ttyS0,921600 earlyprintk panic=5 rootwait; mtdparts=spi32766.0:220k(uboot)ro,64k(dtb)ro,2M(kernel)ro,-(rootfs) root=/dev/mtdblock3 r2
[2023-09-03 16:27:07.267] [ 0.000000] Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
[2023-09-03 16:27:07.268] [ 0.000000] Inode-cache hash table entries: 2048 (order: 1, 8192 bytes)
[2023-09-03 16:27:07.269] [ 0.000000] Memory: 27676K/32768K available (3157K kernel code, 191K rwdata, 856K rodata, 184K init, 202K bss, 5092K reserved, 0K cma-reserved, 0K highmem)
[2023-09-03 16:27:07.271] [ 0.000000] Virtual kernel memory layout:
[2023-09-03 16:27:07.271] [ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB)
[2023-09-03 16:27:07.272] [ 0.000000] fixmap : 0xffc00000 - 0xfff00000 (3072 kB)
[2023-09-03 16:27:07.273] [ 0.000000] vmalloc : 0xc2800000 - 0xff800000 ( 976 MB)
[2023-09-03 16:27:07.273] [ 0.000000] lowmem : 0xc0000000 - 0xc2000000 ( 32 MB)
[2023-09-03 16:27:07.274] [ 0.000000] pkmap : 0xbfe00000 - 0xc0000000 ( 2 MB)
[2023-09-03 16:27:07.275] [ 0.000000] modules : 0xbf000000 - 0xbfe00000 ( 14 MB)
[2023-09-03 16:27:07.276] [ 0.000000] .text : 0x(ptrval) - 0x(ptrval) (3159 kB)
[2023-09-03 16:27:07.276] [ 0.000000] .init : 0x(ptrval) - 0x(ptrval) ( 184 kB)
[2023-09-03 16:27:07.277] [ 0.000000] .data : 0x(ptrval) - 0x(ptrval) ( 192 kB)
[2023-09-03 16:27:07.278] [ 0.000000] .bss : 0x(ptrval) - 0x(ptrval) ( 203 kB)
[2023-09-03 16:27:07.278] [ 0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[2023-09-03 16:27:07.280] [ 0.000000] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
[2023-09-03 16:27:07.280] [ 0.000060] sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 89478484971ns
[2023-09-03 16:27:07.281] [ 0.000131] clocksource: timer: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 79635851949 ns
[2023-09-03 16:27:07.283] [ 0.000704] Console: colour dummy device 80x30
[2023-09-03 16:27:07.283] [ 0.000808] Calibrating delay loop... 395.67 BogoMIPS (lpj=1978368)
[2023-09-03 16:27:07.284] [ 0.120299] pid_max: default: 32768 minimum: 301
[2023-09-03 16:27:07.284] [ 0.120582] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[2023-09-03 16:27:07.285] [ 0.120626] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[2023-09-03 16:27:07.286] [ 0.122154] CPU: Testing write buffer coherency: ok
[2023-09-03 16:27:07.287] [ 0.124381] Setting up static identity map for 0x80008400 - 0x80008458
[2023-09-03 16:27:07.288] [ 0.126796] devtmpfs: initialized
[2023-09-03 16:27:07.288] [ 0.131861] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[2023-09-03 16:27:07.289] [ 0.131933] futex hash table entries: 256 (order: -1, 3072 bytes)
[2023-09-03 16:27:07.290] [ 0.132258] pinctrl core: initialized pinctrl subsystem
[2023-09-03 16:27:07.291] [ 0.134986] DMA: preallocated 256 KiB pool for atomic coherent allocations
[2023-09-03 16:27:07.292] [ 0.136765] cpuidle: using governor menu
[2023-09-03 16:27:07.292] [ 0.156412] SCSI subsystem initialized
[2023-09-03 16:27:07.293] [ 0.156785] usbcore: registered new interface driver usbfs
[2023-09-03 16:27:07.293] [ 0.156980] usbcore: registered new interface driver hub
[2023-09-03 16:27:07.294] [ 0.157200] usbcore: registered new device driver usb
[2023-09-03 16:27:07.295] [ 0.157671] pps_core: LinuxPPS API ver. 1 registered
[2023-09-03 16:27:07.296] [ 0.157700] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[2023-09-03 16:27:07.297] [ 0.158327] clocksource: Switched to clocksource timer
[2023-09-03 16:27:07.297] [ 0.167295] NetWinder Floating Point Emulator V0.97 (double precision)
[2023-09-03 16:27:07.298] [ 0.169524] Initialise system trusted keyrings
[2023-09-03 16:27:07.299] [ 0.170249] workingset: timestamp_bits=30 max_order=13 bucket_order=0
[2023-09-03 16:27:07.300] [ 0.178859] jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
[2023-09-03 16:27:07.300] [ 0.193685] Key type asymmetric registered
[2023-09-03 16:27:07.301] [ 0.193736] Asymmetric key parser 'x509' registered
[2023-09-03 16:27:07.302] [ 0.193995] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 252)
[2023-09-03 16:27:07.302] [ 0.194034] io scheduler noop registered
[2023-09-03 16:27:07.303] [ 0.194049] io scheduler deadline registered
[2023-09-03 16:27:07.304] [ 0.194748] io scheduler cfq registered (default)
[2023-09-03 16:27:07.304] [ 0.194790] io scheduler mq-deadline registered
[2023-09-03 16:27:07.305] [ 0.194802] io scheduler kyber registered
[2023-09-03 16:27:07.305] [ 0.205862] suniv-pinctrl 1c20800.pinctrl: initialized sunXi PIO driver
[2023-09-03 16:27:07.306] [ 0.211773] Serial: 8250/16550 driver, 2 ports, IRQ sharing disabled
[2023-09-03 16:27:07.307] [ 0.215212] console [ttyS0] disabled
[2023-09-03 16:27:07.308] [ 0.235604] 1c25000.serial: ttyS0 at MMIO 0x1c25000 (irq = 24, base_baud = 6250000) is a 16550A
[2023-09-03 16:27:07.309] [ 0.286873] console [ttyS0] enabled
[2023-09-03 16:27:07.312] [ 0.289729] SCSI Media Changer driver v0.25
[2023-09-03 16:27:07.317] [ 0.294387] m25p80 spi0.0: xt25f128b (16384 Kbytes)
[2023-09-03 16:27:07.317] [ 0.295211] 4 ofpart partitions found on MTD device spi0.0
[2023-09-03 16:27:07.318] [ 0.295952] Creating 4 MTD partitions on "spi0.0":
[2023-09-03 16:27:07.318] [ 0.296620] 0x000000000000-0x000000037000 : "u-boot"
[2023-09-03 16:27:07.322] [ 0.300369] 0x000000100000-0x000000110000 : "dtb"
[2023-09-03 16:27:07.326] [ 0.303803] 0x000000110000-0x000000310000 : "kernel"
[2023-09-03 16:27:07.329] [ 0.307194] 0x000000510000-0x000000a60000 : "rootfs"
[2023-09-03 16:27:07.333] [ 0.311234] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[2023-09-03 16:27:07.334] [ 0.312134] ehci-platform: EHCI generic platform driver
[2023-09-03 16:27:07.335] [ 0.313071] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[2023-09-03 16:27:07.336] [ 0.313956] ohci-platform: OHCI generic platform driver
[2023-09-03 16:27:07.337] [ 0.315046] usbcore: registered new interface driver usb-storage
[2023-09-03 16:27:07.339] [ 0.316799] usb_phy_generic usb_phy_generic.0.auto: usb_phy_generic.0.auto supply vcc not found, using dummy regulator
[2023-09-03 16:27:07.344] [ 0.321855] g_serial gadget: Gadget Serial v2.4
[2023-09-03 16:27:07.344] [ 0.322502] g_serial gadget: g_serial ready
[2023-09-03 16:27:07.346] [ 0.323494] i2c /dev entries driver
[2023-09-03 16:27:07.411] [ 0.388495] sunxi-mmc 1c0f000.mmc: base:0x079d1269 irq:20
[2023-09-03 16:27:07.413] [ 0.391014] usbcore: registered new interface driver usbhid
[2023-09-03 16:27:07.413] [ 0.391780] usbhid: USB HID core driver
[2023-09-03 16:27:07.418] [ 0.395115] Loading compiled-in X.509 certificates
[2023-09-03 16:27:07.473] [ 0.450938] random: crng init done
[2023-09-03 16:27:07.829] [ 0.806504] g_serial gadget: high-speed config #2: CDC ACM config
[2023-09-03 16:27:07.843] [ 0.821018] VFS: Mounted root (jffs2 filesystem) on device 31:3.
[2023-09-03 16:27:07.846] [ 0.824061] devtmpfs: mounted
[2023-09-03 16:27:07.848] [ 0.825690] Freeing unused kernel memory: 184K
[2023-09-03 16:27:07.848] [ 0.826296] This architecture does not have kernel memory protection.
[2023-09-03 16:27:12.891] 1
[2023-09-03 16:27:13.215] Starting logging: OK
[2023-09-03 16:27:13.491] Initializing random number generator... done.
[2023-09-03 16:27:13.797]
[2023-09-03 16:27:13.797] Welcome to Buildroot
(none) login: root13.797]
主要是3个部分
1.uboot --> 花费了2.7s
[2023-09-03 16:27:01.922] SF: Detected xt25f128b with page size 256 Bytes, erase size 4 KiB, total 16 MiB
[2023-09-03 16:27:04.656] *** Warning - bad CRC, using default environment
2.kernel此处花费了1.55s
[2023-09-03 16:27:05.706] Starting kernel ...
[2023-09-03 16:27:05.706]
[2023-09-03 16:27:07.259] [ 0.000000] Booting Linux on physical CPU 0x0
3.kernel到inittab花费了5s之久
[2023-09-03 16:27:07.848] [ 0.826296] This architecture does not have kernel memory protection.
[2023-09-03 16:27:12.891] 1
[2023-09-03 16:32:46.170] # /etc/inittab
[2023-09-03 16:32:46.170] ::sysinit:/bin/echo 1
[2023-09-03 16:32:46.170] # Startup the system
[2023-09-03 16:32:46.170] #::sysinit:/bin/mount -t proc proc /proc
[2023-09-03 16:32:46.171] #::sysinit:/bin/mount -o remount,rw /
[2023-09-03 16:32:46.171] #::sysinit:/bin/mkdir -p /dev/pts
[2023-09-03 16:32:46.172] #::sysinit:/bin/mkdir -p /dev/shm
[2023-09-03 16:32:46.172] #::sysinit:/bin/mount -a
[2023-09-03 16:32:46.172] #::sysinit:/bin/hostname -F /etc/hostname
[2023-09-03 16:32:46.173] # now run any rc scripts
[2023-09-03 16:32:46.173] ::sysinit:/etc/init.d/rcS
麻烦大佬们帮忙看看如何优化
@pldjn_V3S
In file included from /usr/include/signal.h:328,
from ./signal.h:52,
from c-stack.c:49:
c-stack.c:55:26: error: missing binary operator before token "("
55 | #elif HAVE_LIBSIGSEGV && SIGSTKSZ < 16384
| ^~~~~~~~
make[5]: *** [Makefile:1915: c-stack.o] Error 1
make[5]: *** Waiting for unfinished jobs....
make[4]: *** [Makefile:1674: all] Error 2
make[3]: *** [Makefile:1572: all-recursive] Error 1
make[2]: *** [Makefile:1528: all] Error 2
我把c-stack.c的这部分代码注掉,又会出新的错误。所以感觉是版本问题。
#elif HAVE_LIBSIGSEGV && SIGSTKSZ < 16384
/* libsigsegv 2.6 through 2.8 have a bug where some architectures use
more than the Linux default of an 8k alternate stack when deciding
if a fault was caused by stack overflow. */
# undef SIGSTKSZ
# define SIGSTKSZ 16384
新的错误是一堆的_STAT_VER相关
libfakeroot.c: In function ‘chown’:
libfakeroot.c:99:40: error: ‘_STAT_VER’ undeclared (first use in this function)
99 | #define INT_NEXT_STAT(a,b) NEXT_STAT64(_STAT_VER,a,b)
c-stack.c:55:26: error: missing binary operator before token "("
使用如下m4文件夹===>
https://github.com/buildroot/buildroot/tree/master/package/m4
libfakeroot.c: In function ‘chown’:
libfakeroot.c:99:40: error: ‘_STAT_VER’ undeclared (first use in this function)
下载替换整个fakeroot
https://blog.csdn.net/weixin_41489977/article/details/119962326
@muxi01
高通410 wifi棒子?
我已经用它推流直播了😂
【wifi棒B站24h推流测试-哔哩哔哩直播】 https://b23.tv/XG4CODS
&spi1{
status = "okay";
st7789v: st7789v@0{
compatible = "sitronix,st7789v";
reg = <0>;
status = "okay";
spi-max-frequency = <24000000>;//点不亮适量降
spi-cpol;
spi-cpha;
rotate = <270>;
fps = <60>;
buswidth = <8>;
dc-gpios = <&pio 4 4 GPIO_ACTIVE_HIGH>; // PE4 PB0
reset-gpios = <&pio 4 5 GPIO_ACTIVE_HIGH>; // PE5
//led-gpios = <&pio 0 0 GPIO_ACTIVE_LOW>; // PA0
debug = <0x0>;
};
};
fbtft-io.c
// SPDX-License-Identifier: GPL-2.0
#include <linux/export.h>
#include <linux/errno.h>
#include <linux/gpio/consumer.h>
#include <linux/spi/spi.h>
#include "fbtft.h"
int fbtft_write_spi(struct fbtft_par *par, void *buf, size_t len)
{
struct spi_transfer t = {
.tx_buf = buf,
.len = len,
};
struct spi_message m;
fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
"%s(len=%zu): ", __func__, len);
if (!par->spi) {
dev_err(par->info->device,
"%s: par->spi is unexpectedly NULL\n", __func__);
return -1;
}
spi_message_init(&m);
spi_message_add_tail(&t, &m);
return spi_sync(par->spi, &m);
}
EXPORT_SYMBOL(fbtft_write_spi);
/**
* fbtft_write_spi_emulate_9() - write SPI emulating 9-bit
* @par: Driver data
* @buf: Buffer to write
* @len: Length of buffer (must be divisible by 8)
*
* When 9-bit SPI is not available, this function can be used to emulate that.
* par->extra must hold a transformation buffer used for transfer.
*/
int fbtft_write_spi_emulate_9(struct fbtft_par *par, void *buf, size_t len)
{
u16 *src = buf;
u8 *dst = par->extra;
size_t size = len / 2;
size_t added = 0;
int bits, i, j;
u64 val, dc, tmp;
fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
"%s(len=%zu): ", __func__, len);
if (!par->extra) {
dev_err(par->info->device, "%s: error: par->extra is NULL\n",
__func__);
return -EINVAL;
}
if ((len % 8) != 0) {
dev_err(par->info->device,
"error: len=%zu must be divisible by 8\n", len);
return -EINVAL;
}
for (i = 0; i < size; i += 8) {
tmp = 0;
bits = 63;
for (j = 0; j < 7; j++) {
dc = (*src & 0x0100) ? 1 : 0;
val = *src & 0x00FF;
tmp |= dc << bits;
bits -= 8;
tmp |= val << bits--;
src++;
}
tmp |= ((*src & 0x0100) ? 1 : 0);
*(__be64 *)dst = cpu_to_be64(tmp);
dst += 8;
*dst++ = (u8)(*src++ & 0x00FF);
added++;
}
return spi_write(par->spi, par->extra, size + added);
}
EXPORT_SYMBOL(fbtft_write_spi_emulate_9);
int fbtft_read_spi(struct fbtft_par *par, void *buf, size_t len)
{
int ret;
u8 txbuf[32] = { 0, };
struct spi_transfer t = {
.speed_hz = 2000000,
.rx_buf = buf,
.len = len,
};
struct spi_message m;
if (!par->spi) {
dev_err(par->info->device,
"%s: par->spi is unexpectedly NULL\n", __func__);
return -ENODEV;
}
if (par->startbyte) {
if (len > 32) {
dev_err(par->info->device,
"len=%zu can't be larger than 32 when using 'startbyte'\n",
len);
return -EINVAL;
}
txbuf[0] = par->startbyte | 0x3;
t.tx_buf = txbuf;
fbtft_par_dbg_hex(DEBUG_READ, par, par->info->device, u8,
txbuf, len, "%s(len=%zu) txbuf => ",
__func__, len);
}
spi_message_init(&m);
spi_message_add_tail(&t, &m);
ret = spi_sync(par->spi, &m);
fbtft_par_dbg_hex(DEBUG_READ, par, par->info->device, u8, buf, len,
"%s(len=%zu) buf <= ", __func__, len);
return ret;
}
EXPORT_SYMBOL(fbtft_read_spi);
/*
* Optimized use of gpiolib is twice as fast as no optimization
* only one driver can use the optimized version at a time
*/
int fbtft_write_gpio8_wr(struct fbtft_par *par, void *buf, size_t len)
{
u8 data;
int i;
#ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
static u8 prev_data;
#endif
fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
"%s(len=%zu): ", __func__, len);
while (len--) {
data = *(u8 *)buf;
/* Start writing by pulling down /WR */
gpiod_set_value(par->gpio.wr, 0);
/* Set data */
#ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
if (data == prev_data) {
gpiod_set_value(par->gpio.wr, 0); /* used as delay */
} else {
for (i = 0; i < 8; i++) {
if ((data & 1) != (prev_data & 1))
gpiod_set_value(par->gpio.db[i],
data & 1);
data >>= 1;
prev_data >>= 1;
}
}
#else
for (i = 0; i < 8; i++) {
gpiod_set_value(par->gpio.db[i], data & 1);
data >>= 1;
}
#endif
/* Pullup /WR */
gpiod_set_value(par->gpio.wr, 1);
#ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
prev_data = *(u8 *)buf;
#endif
buf++;
}
return 0;
}
EXPORT_SYMBOL(fbtft_write_gpio8_wr);
int fbtft_write_gpio16_wr(struct fbtft_par *par, void *buf, size_t len)
{
u16 data;
int i;
#ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
static u16 prev_data;
#endif
fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len,
"%s(len=%zu): ", __func__, len);
while (len) {
data = *(u16 *)buf;
/* Start writing by pulling down /WR */
gpiod_set_value(par->gpio.wr, 0);
/* Set data */
#ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
if (data == prev_data) {
gpiod_set_value(par->gpio.wr, 0); /* used as delay */
} else {
for (i = 0; i < 16; i++) {
if ((data & 1) != (prev_data & 1))
gpiod_set_value(par->gpio.db[i],
data & 1);
data >>= 1;
prev_data >>= 1;
}
}
#else
for (i = 0; i < 16; i++) {
gpiod_set_value(par->gpio.db[i], data & 1);
data >>= 1;
}
#endif
/* Pullup /WR */
gpiod_set_value(par->gpio.wr, 1);
#ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO
prev_data = *(u16 *)buf;
#endif
buf += 2;
len -= 2;
}
return 0;
}
EXPORT_SYMBOL(fbtft_write_gpio16_wr);
int fbtft_write_gpio16_wr_latched(struct fbtft_par *par, void *buf, size_t len)
{
dev_err(par->info->device, "%s: function not implemented\n", __func__);
return -1;
}
EXPORT_SYMBOL(fbtft_write_gpio16_wr_latched);
fbtft-core.c
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2013 Noralf Tronnes
*
* This driver is inspired by:
* st7735fb.c, Copyright (C) 2011, Matt Porter
* broadsheetfb.c, Copyright (C) 2008, Jaya Kumar
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/fb.h>
#include <linux/gpio/consumer.h>
#include <linux/spi/spi.h>
#include <linux/delay.h>
#include <linux/uaccess.h>
#include <linux/backlight.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/spinlock.h>
#include <video/mipi_display.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include "fbtft.h"
#include "internal.h"
static unsigned long debug;
module_param(debug, ulong, 0000);
MODULE_PARM_DESC(debug, "override device debug level");
int fbtft_write_buf_dc(struct fbtft_par *par, void *buf, size_t len, int dc)
{
int ret;
if (par->gpio.dc)
gpiod_set_value(par->gpio.dc, dc);
ret = par->fbtftops.write(par, buf, len);
if (ret < 0)
dev_err(par->info->device,
"write() failed and returned %d\n", ret);
return ret;
}
EXPORT_SYMBOL(fbtft_write_buf_dc);
void fbtft_dbg_hex(const struct device *dev, int groupsize,
void *buf, size_t len, const char *fmt, ...)
{
va_list args;
static char textbuf[512];
char *text = textbuf;
size_t text_len;
va_start(args, fmt);
text_len = vscnprintf(text, sizeof(textbuf), fmt, args);
va_end(args);
hex_dump_to_buffer(buf, len, 32, groupsize, text + text_len,
512 - text_len, false);
if (len > 32)
dev_info(dev, "%s ...\n", text);
else
dev_info(dev, "%s\n", text);
}
EXPORT_SYMBOL(fbtft_dbg_hex);
// static int fbtft_request_one_gpio(struct fbtft_par *par,
// const char *name, int index,
// struct gpio_desc **gpiop)
// {
// struct device *dev = par->info->device;
// int ret = 0;
// *gpiop = devm_gpiod_get_index_optional(dev, name, index,
// GPIOD_OUT_HIGH);
// if (IS_ERR(*gpiop)) {
// ret = PTR_ERR(*gpiop);
// dev_err(dev,
// "Failed to request %s GPIO: %d\n", name, ret);
// return ret;
// }
// fbtft_par_dbg(DEBUG_REQUEST_GPIOS, par, "%s: '%s' GPIO\n",
// __func__, name);
// return ret;
// }
static int fbtft_request_one_gpio(struct fbtft_par *par,
const char *name, int index,
struct gpio_desc **gpiop)
{
struct device *dev = par->info->device;
struct device_node *node = dev->of_node;
int gpio, flags, ret = 0;
enum of_gpio_flags of_flags;
if (of_find_property(node, name, NULL)) {
gpio = of_get_named_gpio_flags(node, name, index, &of_flags);
if (gpio == -ENOENT)
return 0;
if (gpio == -EPROBE_DEFER)
return gpio;
if (gpio < 0) {
dev_err(dev,
"failed to get '%s' from DT\n", name);
return gpio;
}
//active low translates to initially low
flags = (of_flags & OF_GPIO_ACTIVE_LOW) ? GPIOF_OUT_INIT_LOW :
GPIOF_OUT_INIT_HIGH;
ret = devm_gpio_request_one(dev, gpio, flags,
dev->driver->name);
if (ret) {
dev_err(dev,
"gpio_request_one('%s'=%d) failed with %d\n",
name, gpio, ret);
return ret;
}
*gpiop = gpio_to_desc(gpio);
fbtft_par_dbg(DEBUG_REQUEST_GPIOS, par, "%s: '%s' = GPIO%d\n",
__func__, name, gpio);
}
return ret;
}
static int fbtft_request_gpios(struct fbtft_par *par)
{
int i;
int ret;
ret = fbtft_request_one_gpio(par, "reset-gpios", 0, &par->gpio.reset);
if (ret)
return ret;
ret = fbtft_request_one_gpio(par, "dc-gpios", 0, &par->gpio.dc);
if (ret)
return ret;
ret = fbtft_request_one_gpio(par, "reset", 0, &par->gpio.reset);
if (ret)
return ret;
ret = fbtft_request_one_gpio(par, "dc", 0, &par->gpio.dc);
if (ret)
return ret;
ret = fbtft_request_one_gpio(par, "rd", 0, &par->gpio.rd);
if (ret)
return ret;
ret = fbtft_request_one_gpio(par, "wr", 0, &par->gpio.wr);
if (ret)
return ret;
ret = fbtft_request_one_gpio(par, "cs", 0, &par->gpio.cs);
if (ret)
return ret;
ret = fbtft_request_one_gpio(par, "latch", 0, &par->gpio.latch);
if (ret)
return ret;
for (i = 0; i < 16; i++) {
ret = fbtft_request_one_gpio(par, "db", i,
&par->gpio.db[i]);
if (ret)
return ret;
ret = fbtft_request_one_gpio(par, "led", i,
&par->gpio.led[i]);
if (ret)
return ret;
ret = fbtft_request_one_gpio(par, "aux", i,
&par->gpio.aux[i]);
if (ret)
return ret;
}
return 0;
}
#ifdef CONFIG_FB_BACKLIGHT
static int fbtft_backlight_update_status(struct backlight_device *bd)
{
struct fbtft_par *par = bl_get_data(bd);
bool polarity = par->polarity;
fbtft_par_dbg(DEBUG_BACKLIGHT, par,
"%s: polarity=%d, power=%d, fb_blank=%d\n",
__func__, polarity, bd->props.power, bd->props.fb_blank);
if ((bd->props.power == FB_BLANK_UNBLANK) &&
(bd->props.fb_blank == FB_BLANK_UNBLANK))
gpiod_set_value(par->gpio.led[0], polarity);
else
gpiod_set_value(par->gpio.led[0], !polarity);
return 0;
}
static int fbtft_backlight_get_brightness(struct backlight_device *bd)
{
return bd->props.brightness;
}
void fbtft_unregister_backlight(struct fbtft_par *par)
{
if (par->info->bl_dev) {
par->info->bl_dev->props.power = FB_BLANK_POWERDOWN;
backlight_update_status(par->info->bl_dev);
backlight_device_unregister(par->info->bl_dev);
par->info->bl_dev = NULL;
}
}
static const struct backlight_ops fbtft_bl_ops = {
.get_brightness = fbtft_backlight_get_brightness,
.update_status = fbtft_backlight_update_status,
};
void fbtft_register_backlight(struct fbtft_par *par)
{
struct backlight_device *bd;
struct backlight_properties bl_props = { 0, };
if (!par->gpio.led[0]) {
fbtft_par_dbg(DEBUG_BACKLIGHT, par,
"%s(): led pin not set, exiting.\n", __func__);
return;
}
bl_props.type = BACKLIGHT_RAW;
/* Assume backlight is off, get polarity from current state of pin */
bl_props.power = FB_BLANK_POWERDOWN;
if (!gpiod_get_value(par->gpio.led[0]))
par->polarity = true;
bd = backlight_device_register(dev_driver_string(par->info->device),
par->info->device, par,
&fbtft_bl_ops, &bl_props);
if (IS_ERR(bd)) {
dev_err(par->info->device,
"cannot register backlight device (%ld)\n",
PTR_ERR(bd));
return;
}
par->info->bl_dev = bd;
if (!par->fbtftops.unregister_backlight)
par->fbtftops.unregister_backlight = fbtft_unregister_backlight;
}
#else
void fbtft_register_backlight(struct fbtft_par *par) { };
void fbtft_unregister_backlight(struct fbtft_par *par) { };
#endif
EXPORT_SYMBOL(fbtft_register_backlight);
EXPORT_SYMBOL(fbtft_unregister_backlight);
static void fbtft_set_addr_win(struct fbtft_par *par, int xs, int ys, int xe,
int ye)
{
write_reg(par, MIPI_DCS_SET_COLUMN_ADDRESS,
(xs >> 8) & 0xFF, xs & 0xFF, (xe >> 8) & 0xFF, xe & 0xFF);
write_reg(par, MIPI_DCS_SET_PAGE_ADDRESS,
(ys >> 8) & 0xFF, ys & 0xFF, (ye >> 8) & 0xFF, ye & 0xFF);
write_reg(par, MIPI_DCS_WRITE_MEMORY_START);
}
static void fbtft_reset(struct fbtft_par *par)
{
if (!par->gpio.reset)
return;
fbtft_par_dbg(DEBUG_RESET, par, "%s()\n", __func__);
gpiod_set_value_cansleep(par->gpio.reset, 1);
usleep_range(20, 40);
gpiod_set_value_cansleep(par->gpio.reset, 0);
msleep(120);
gpiod_set_value_cansleep(par->gpio.reset, 1);
msleep(10);
gpiod_set_value_cansleep(par->gpio.reset, 0);
msleep(200);
gpiod_set_value_cansleep(par->gpio.reset, 1);
msleep(10);
}
static void fbtft_update_display(struct fbtft_par *par, unsigned int start_line,
unsigned int end_line)
{
size_t offset, len;
ktime_t ts_start, ts_end;
long fps, throughput;
bool timeit = false;
int ret = 0;
if (unlikely(par->debug & (DEBUG_TIME_FIRST_UPDATE |
DEBUG_TIME_EACH_UPDATE))) {
if ((par->debug & DEBUG_TIME_EACH_UPDATE) ||
((par->debug & DEBUG_TIME_FIRST_UPDATE) &&
!par->first_update_done)) {
ts_start = ktime_get();
timeit = true;
}
}
/* Sanity checks */
if (start_line > end_line) {
dev_warn(par->info->device,
"%s: start_line=%u is larger than end_line=%u. Shouldn't happen, will do full display update\n",
__func__, start_line, end_line);
start_line = 0;
end_line = par->info->var.yres - 1;
}
if (start_line > par->info->var.yres - 1 ||
end_line > par->info->var.yres - 1) {
dev_warn(par->info->device,
"%s: start_line=%u or end_line=%u is larger than max=%d. Shouldn't happen, will do full display update\n",
__func__, start_line,
end_line, par->info->var.yres - 1);
start_line = 0;
end_line = par->info->var.yres - 1;
}
fbtft_par_dbg(DEBUG_UPDATE_DISPLAY, par, "%s(start_line=%u, end_line=%u)\n",
__func__, start_line, end_line);
if (par->fbtftops.set_addr_win)
par->fbtftops.set_addr_win(par, 0, start_line,
par->info->var.xres - 1, end_line);
offset = start_line * par->info->fix.line_length;
len = (end_line - start_line + 1) * par->info->fix.line_length;
ret = par->fbtftops.write_vmem(par, offset, len);
if (ret < 0)
dev_err(par->info->device,
"%s: write_vmem failed to update display buffer\n",
__func__);
if (unlikely(timeit)) {
ts_end = ktime_get();
if (!ktime_to_ns(par->update_time))
par->update_time = ts_start;
fps = ktime_us_delta(ts_start, par->update_time);
par->update_time = ts_start;
fps = fps ? 1000000 / fps : 0;
throughput = ktime_us_delta(ts_end, ts_start);
throughput = throughput ? (len * 1000) / throughput : 0;
throughput = throughput * 1000 / 1024;
dev_info(par->info->device,
"Display update: %ld kB/s, fps=%ld\n",
throughput, fps);
par->first_update_done = true;
}
}
static void fbtft_mkdirty(struct fb_info *info, int y, int height)
{
struct fbtft_par *par = info->par;
struct fb_deferred_io *fbdefio = info->fbdefio;
/* special case, needed ? */
if (y == -1) {
y = 0;
height = info->var.yres;
}
/* Mark display lines/area as dirty */
spin_lock(&par->dirty_lock);
if (y < par->dirty_lines_start)
par->dirty_lines_start = y;
if (y + height - 1 > par->dirty_lines_end)
par->dirty_lines_end = y + height - 1;
spin_unlock(&par->dirty_lock);
/* Schedule deferred_io to update display (no-op if already on queue)*/
schedule_delayed_work(&info->deferred_work, fbdefio->delay);
}
static void fbtft_deferred_io(struct fb_info *info, struct list_head *pagelist)
{
struct fbtft_par *par = info->par;
unsigned int dirty_lines_start, dirty_lines_end;
struct page *page;
unsigned long index;
unsigned int y_low = 0, y_high = 0;
int count = 0;
spin_lock(&par->dirty_lock);
dirty_lines_start = par->dirty_lines_start;
dirty_lines_end = par->dirty_lines_end;
/* set display line markers as clean */
par->dirty_lines_start = par->info->var.yres - 1;
par->dirty_lines_end = 0;
spin_unlock(&par->dirty_lock);
/* Mark display lines as dirty */
list_for_each_entry(page, pagelist, lru) {
count++;
index = page->index << PAGE_SHIFT;
y_low = index / info->fix.line_length;
y_high = (index + PAGE_SIZE - 1) / info->fix.line_length;
dev_dbg(info->device,
"page->index=%lu y_low=%d y_high=%d\n",
page->index, y_low, y_high);
if (y_high > info->var.yres - 1)
y_high = info->var.yres - 1;
if (y_low < dirty_lines_start)
dirty_lines_start = y_low;
if (y_high > dirty_lines_end)
dirty_lines_end = y_high;
}
par->fbtftops.update_display(info->par,
dirty_lines_start, dirty_lines_end);
}
static void fbtft_fb_fillrect(struct fb_info *info,
const struct fb_fillrect *rect)
{
struct fbtft_par *par = info->par;
dev_dbg(info->dev,
"%s: dx=%d, dy=%d, width=%d, height=%d\n",
__func__, rect->dx, rect->dy, rect->width, rect->height);
sys_fillrect(info, rect);
par->fbtftops.mkdirty(info, rect->dy, rect->height);
}
static void fbtft_fb_copyarea(struct fb_info *info,
const struct fb_copyarea *area)
{
struct fbtft_par *par = info->par;
dev_dbg(info->dev,
"%s: dx=%d, dy=%d, width=%d, height=%d\n",
__func__, area->dx, area->dy, area->width, area->height);
sys_copyarea(info, area);
par->fbtftops.mkdirty(info, area->dy, area->height);
}
static void fbtft_fb_imageblit(struct fb_info *info,
const struct fb_image *image)
{
struct fbtft_par *par = info->par;
dev_dbg(info->dev,
"%s: dx=%d, dy=%d, width=%d, height=%d\n",
__func__, image->dx, image->dy, image->width, image->height);
sys_imageblit(info, image);
par->fbtftops.mkdirty(info, image->dy, image->height);
}
static ssize_t fbtft_fb_write(struct fb_info *info, const char __user *buf,
size_t count, loff_t *ppos)
{
struct fbtft_par *par = info->par;
ssize_t res;
dev_dbg(info->dev,
"%s: count=%zd, ppos=%llu\n", __func__, count, *ppos);
res = fb_sys_write(info, buf, count, ppos);
/* TODO: only mark changed area update all for now */
par->fbtftops.mkdirty(info, -1, 0);
return res;
}
/* from pxafb.c */
static unsigned int chan_to_field(unsigned int chan, struct fb_bitfield *bf)
{
chan &= 0xffff;
chan >>= 16 - bf->length;
return chan << bf->offset;
}
static int fbtft_fb_setcolreg(unsigned int regno, unsigned int red,
unsigned int green, unsigned int blue,
unsigned int transp, struct fb_info *info)
{
unsigned int val;
int ret = 1;
dev_dbg(info->dev,
"%s(regno=%u, red=0x%X, green=0x%X, blue=0x%X, trans=0x%X)\n",
__func__, regno, red, green, blue, transp);
switch (info->fix.visual) {
case FB_VISUAL_TRUECOLOR:
if (regno < 16) {
u32 *pal = info->pseudo_palette;
val = chan_to_field(red, &info->var.red);
val |= chan_to_field(green, &info->var.green);
val |= chan_to_field(blue, &info->var.blue);
pal[regno] = val;
ret = 0;
}
break;
}
return ret;
}
static int fbtft_fb_blank(int blank, struct fb_info *info)
{
struct fbtft_par *par = info->par;
int ret = -EINVAL;
dev_dbg(info->dev, "%s(blank=%d)\n",
__func__, blank);
if (!par->fbtftops.blank)
return ret;
switch (blank) {
case FB_BLANK_POWERDOWN:
case FB_BLANK_VSYNC_SUSPEND:
case FB_BLANK_HSYNC_SUSPEND:
case FB_BLANK_NORMAL:
ret = par->fbtftops.blank(par, true);
break;
case FB_BLANK_UNBLANK:
ret = par->fbtftops.blank(par, false);
break;
}
return ret;
}
static void fbtft_merge_fbtftops(struct fbtft_ops *dst, struct fbtft_ops *src)
{
if (src->write)
dst->write = src->write;
if (src->read)
dst->read = src->read;
if (src->write_vmem)
dst->write_vmem = src->write_vmem;
if (src->write_register)
dst->write_register = src->write_register;
if (src->set_addr_win)
dst->set_addr_win = src->set_addr_win;
if (src->reset)
dst->reset = src->reset;
if (src->mkdirty)
dst->mkdirty = src->mkdirty;
if (src->update_display)
dst->update_display = src->update_display;
if (src->init_display)
dst->init_display = src->init_display;
if (src->blank)
dst->blank = src->blank;
if (src->request_gpios_match)
dst->request_gpios_match = src->request_gpios_match;
if (src->request_gpios)
dst->request_gpios = src->request_gpios;
if (src->verify_gpios)
dst->verify_gpios = src->verify_gpios;
if (src->register_backlight)
dst->register_backlight = src->register_backlight;
if (src->unregister_backlight)
dst->unregister_backlight = src->unregister_backlight;
if (src->set_var)
dst->set_var = src->set_var;
if (src->set_gamma)
dst->set_gamma = src->set_gamma;
}
/**
* fbtft_framebuffer_alloc - creates a new frame buffer info structure
*
* @display: pointer to structure describing the display
* @dev: pointer to the device for this fb, this can be NULL
* @pdata: platform data for the display in use
*
* Creates a new frame buffer info structure.
*
* Also creates and populates the following structures:
* info->fbops
* info->fbdefio
* info->pseudo_palette
* par->fbtftops
* par->txbuf
*
* Returns the new structure, or NULL if an error occurred.
*
*/
struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display,
struct device *dev,
struct fbtft_platform_data *pdata)
{
struct fb_info *info;
struct fbtft_par *par;
struct fb_ops *fbops = NULL;
struct fb_deferred_io *fbdefio = NULL;
u8 *vmem = NULL;
void *txbuf = NULL;
void *buf = NULL;
unsigned int width;
unsigned int height;
int txbuflen = display->txbuflen;
unsigned int bpp = display->bpp;
unsigned int fps = display->fps;
int vmem_size;
const s16 *init_sequence = display->init_sequence;
char *gamma = display->gamma;
u32 *gamma_curves = NULL;
/* sanity check */
if (display->gamma_num * display->gamma_len >
FBTFT_GAMMA_MAX_VALUES_TOTAL) {
dev_err(dev, "FBTFT_GAMMA_MAX_VALUES_TOTAL=%d is exceeded\n",
FBTFT_GAMMA_MAX_VALUES_TOTAL);
return NULL;
}
/* defaults */
if (!fps)
fps = 20;
if (!bpp)
bpp = 16;
if (!pdata) {
dev_err(dev, "platform data is missing\n");
return NULL;
}
/* override driver values? */
if (pdata->fps)
fps = pdata->fps;
if (pdata->txbuflen)
txbuflen = pdata->txbuflen;
if (pdata->display.init_sequence)
init_sequence = pdata->display.init_sequence;
if (pdata->gamma)
gamma = pdata->gamma;
if (pdata->display.debug)
display->debug = pdata->display.debug;
if (pdata->display.backlight)
display->backlight = pdata->display.backlight;
if (pdata->display.width)
display->width = pdata->display.width;
if (pdata->display.height)
display->height = pdata->display.height;
if (pdata->display.buswidth)
display->buswidth = pdata->display.buswidth;
if (pdata->display.regwidth)
display->regwidth = pdata->display.regwidth;
display->debug |= debug;
fbtft_expand_debug_value(&display->debug);
switch (pdata->rotate) {
case 90:
case 270:
width = display->height;
height = display->width;
break;
default:
width = display->width;
height = display->height;
}
vmem_size = display->width * display->height * bpp / 8;
vmem = vzalloc(vmem_size);
if (!vmem)
goto alloc_fail;
fbops = devm_kzalloc(dev, sizeof(struct fb_ops), GFP_KERNEL);
if (!fbops)
goto alloc_fail;
fbdefio = devm_kzalloc(dev, sizeof(struct fb_deferred_io), GFP_KERNEL);
if (!fbdefio)
goto alloc_fail;
buf = devm_kzalloc(dev, 128, GFP_KERNEL);
if (!buf)
goto alloc_fail;
if (display->gamma_num && display->gamma_len) {
gamma_curves = devm_kcalloc(dev,
display->gamma_num *
display->gamma_len,
sizeof(gamma_curves[0]),
GFP_KERNEL);
if (!gamma_curves)
goto alloc_fail;
}
info = framebuffer_alloc(sizeof(struct fbtft_par), dev);
if (!info)
goto alloc_fail;
info->screen_buffer = vmem;
info->fbops = fbops;
info->fbdefio = fbdefio;
fbops->owner = dev->driver->owner;
fbops->fb_read = fb_sys_read;
fbops->fb_write = fbtft_fb_write;
fbops->fb_fillrect = fbtft_fb_fillrect;
fbops->fb_copyarea = fbtft_fb_copyarea;
fbops->fb_imageblit = fbtft_fb_imageblit;
fbops->fb_setcolreg = fbtft_fb_setcolreg;
fbops->fb_blank = fbtft_fb_blank;
fbdefio->delay = HZ / fps;
fbdefio->deferred_io = fbtft_deferred_io;
fb_deferred_io_init(info);
snprintf(info->fix.id, sizeof(info->fix.id), "%s", dev->driver->name);
info->fix.type = FB_TYPE_PACKED_PIXELS;
info->fix.visual = FB_VISUAL_TRUECOLOR;
info->fix.xpanstep = 0;
info->fix.ypanstep = 0;
info->fix.ywrapstep = 0;
info->fix.line_length = width * bpp / 8;
info->fix.accel = FB_ACCEL_NONE;
info->fix.smem_len = vmem_size;
info->var.rotate = pdata->rotate;
info->var.xres = width;
info->var.yres = height;
info->var.xres_virtual = info->var.xres;
info->var.yres_virtual = info->var.yres;
info->var.bits_per_pixel = bpp;
info->var.nonstd = 1;
/* RGB565 */
info->var.red.offset = 11;
info->var.red.length = 5;
info->var.green.offset = 5;
info->var.green.length = 6;
info->var.blue.offset = 0;
info->var.blue.length = 5;
info->var.transp.offset = 0;
info->var.transp.length = 0;
info->flags = FBINFO_FLAG_DEFAULT | FBINFO_VIRTFB;
par = info->par;
par->info = info;
par->pdata = pdata;
par->debug = display->debug;
par->buf = buf;
spin_lock_init(&par->dirty_lock);
par->bgr = pdata->bgr;
par->startbyte = pdata->startbyte;
par->init_sequence = init_sequence;
par->gamma.curves = gamma_curves;
par->gamma.num_curves = display->gamma_num;
par->gamma.num_values = display->gamma_len;
mutex_init(&par->gamma.lock);
info->pseudo_palette = par->pseudo_palette;
if (par->gamma.curves && gamma) {
if (fbtft_gamma_parse_str(par, par->gamma.curves, gamma,
strlen(gamma)))
goto release_framebuf;
}
/* Transmit buffer */
if (txbuflen == -1)
txbuflen = vmem_size + 2; /* add in case startbyte is used */
if (txbuflen >= vmem_size + 2)
txbuflen = 0;
#ifdef __LITTLE_ENDIAN
if ((!txbuflen) && (bpp > 8))
txbuflen = PAGE_SIZE; /* need buffer for byteswapping */
#endif
if (txbuflen > 0) {
txbuf = devm_kzalloc(par->info->device, txbuflen, GFP_KERNEL);
if (!txbuf)
goto release_framebuf;
par->txbuf.buf = txbuf;
par->txbuf.len = txbuflen;
}
/* default fbtft operations */
par->fbtftops.write = fbtft_write_spi;
par->fbtftops.read = fbtft_read_spi;
par->fbtftops.write_vmem = fbtft_write_vmem16_bus8;
par->fbtftops.write_register = fbtft_write_reg8_bus8;
par->fbtftops.set_addr_win = fbtft_set_addr_win;
par->fbtftops.reset = fbtft_reset;
par->fbtftops.mkdirty = fbtft_mkdirty;
par->fbtftops.update_display = fbtft_update_display;
if (display->backlight)
par->fbtftops.register_backlight = fbtft_register_backlight;
/* use driver provided functions */
fbtft_merge_fbtftops(&par->fbtftops, &display->fbtftops);
return info;
release_framebuf:
framebuffer_release(info);
alloc_fail:
vfree(vmem);
return NULL;
}
EXPORT_SYMBOL(fbtft_framebuffer_alloc);
/**
* fbtft_framebuffer_release - frees up all memory used by the framebuffer
*
* @info: frame buffer info structure
*
*/
void fbtft_framebuffer_release(struct fb_info *info)
{
fb_deferred_io_cleanup(info);
vfree(info->screen_buffer);
framebuffer_release(info);
}
EXPORT_SYMBOL(fbtft_framebuffer_release);
/**
* fbtft_register_framebuffer - registers a tft frame buffer device
* @fb_info: frame buffer info structure
*
* Sets SPI driverdata if needed
* Requests needed gpios.
* Initializes display
* Updates display.
* Registers a frame buffer device @fb_info.
*
* Returns negative errno on error, or zero for success.
*
*/
int fbtft_register_framebuffer(struct fb_info *fb_info)
{
int ret;
char text1[50] = "";
char text2[50] = "";
struct fbtft_par *par = fb_info->par;
struct spi_device *spi = par->spi;
/* sanity checks */
if (!par->fbtftops.init_display) {
dev_err(fb_info->device, "missing fbtftops.init_display()\n");
return -EINVAL;
}
if (spi)
spi_set_drvdata(spi, fb_info);
if (par->pdev)
platform_set_drvdata(par->pdev, fb_info);
ret = par->fbtftops.request_gpios(par);
if (ret < 0)
goto reg_fail;
if (par->fbtftops.verify_gpios) {
ret = par->fbtftops.verify_gpios(par);
if (ret < 0)
goto reg_fail;
}
ret = par->fbtftops.init_display(par);
if (ret < 0)
goto reg_fail;
if (par->fbtftops.set_var) {
ret = par->fbtftops.set_var(par);
if (ret < 0)
goto reg_fail;
}
/* update the entire display */
par->fbtftops.update_display(par, 0, par->info->var.yres - 1);
if (par->fbtftops.set_gamma && par->gamma.curves) {
ret = par->fbtftops.set_gamma(par, par->gamma.curves);
if (ret)
goto reg_fail;
}
if (par->fbtftops.register_backlight)
par->fbtftops.register_backlight(par);
ret = register_framebuffer(fb_info);
if (ret < 0)
goto reg_fail;
fbtft_sysfs_init(par);
if (par->txbuf.buf && par->txbuf.len >= 1024)
sprintf(text1, ", %zu KiB buffer memory", par->txbuf.len >> 10);
if (spi)
sprintf(text2, ", spi%d.%d at %d MHz", spi->master->bus_num,
spi->chip_select, spi->max_speed_hz / 1000000);
dev_info(fb_info->dev,
"%s frame buffer, %dx%d, %d KiB video memory%s, fps=%lu%s\n",
fb_info->fix.id, fb_info->var.xres, fb_info->var.yres,
fb_info->fix.smem_len >> 10, text1,
HZ / fb_info->fbdefio->delay, text2);
#ifdef CONFIG_FB_BACKLIGHT
/* Turn on backlight if available */
if (fb_info->bl_dev) {
fb_info->bl_dev->props.power = FB_BLANK_UNBLANK;
fb_info->bl_dev->ops->update_status(fb_info->bl_dev);
}
#endif
return 0;
reg_fail:
if (par->fbtftops.unregister_backlight)
par->fbtftops.unregister_backlight(par);
return ret;
}
EXPORT_SYMBOL(fbtft_register_framebuffer);
/**
* fbtft_unregister_framebuffer - releases a tft frame buffer device
* @fb_info: frame buffer info structure
*
* Frees SPI driverdata if needed
* Frees gpios.
* Unregisters frame buffer device.
*
*/
int fbtft_unregister_framebuffer(struct fb_info *fb_info)
{
struct fbtft_par *par = fb_info->par;
if (par->fbtftops.unregister_backlight)
par->fbtftops.unregister_backlight(par);
fbtft_sysfs_exit(par);
unregister_framebuffer(fb_info);
return 0;
}
EXPORT_SYMBOL(fbtft_unregister_framebuffer);
/**
* fbtft_init_display_from_property() - Device Tree init_display() function
* @par: Driver data
*
* Return: 0 if successful, negative if error
*/
static int fbtft_init_display_from_property(struct fbtft_par *par)
{
struct device *dev = par->info->device;
int buf[64], count, index, i, j, ret;
u32 *values;
u32 val;
count = device_property_count_u32(dev, "init");
if (count < 0)
return count;
if (count == 0)
return -EINVAL;
values = kmalloc_array(count + 1, sizeof(*values), GFP_KERNEL);
if (!values)
return -ENOMEM;
ret = device_property_read_u32_array(dev, "init", values, count);
if (ret)
goto out_free;
par->fbtftops.reset(par);
if (par->gpio.cs)
gpiod_set_value(par->gpio.cs, 0); /* Activate chip */
index = -1;
val = values[++index];
while (index < count) {
if (val & FBTFT_OF_INIT_CMD) {
val &= 0xFFFF;
i = 0;
while ((index < count) && !(val & 0xFFFF0000)) {
if (i > 63) {
dev_err(dev,
"%s: Maximum register values exceeded\n",
__func__);
ret = -EINVAL;
goto out_free;
}
buf[i++] = val;
val = values[++index];
}
/* make debug message */
fbtft_par_dbg(DEBUG_INIT_DISPLAY, par,
"init: write_register:\n");
for (j = 0; j < i; j++)
fbtft_par_dbg(DEBUG_INIT_DISPLAY, par,
"buf[%d] = %02X\n", j, buf[j]);
par->fbtftops.write_register(par, i,
buf[0], buf[1], buf[2], buf[3],
buf[4], buf[5], buf[6], buf[7],
buf[8], buf[9], buf[10], buf[11],
buf[12], buf[13], buf[14], buf[15],
buf[16], buf[17], buf[18], buf[19],
buf[20], buf[21], buf[22], buf[23],
buf[24], buf[25], buf[26], buf[27],
buf[28], buf[29], buf[30], buf[31],
buf[32], buf[33], buf[34], buf[35],
buf[36], buf[37], buf[38], buf[39],
buf[40], buf[41], buf[42], buf[43],
buf[44], buf[45], buf[46], buf[47],
buf[48], buf[49], buf[50], buf[51],
buf[52], buf[53], buf[54], buf[55],
buf[56], buf[57], buf[58], buf[59],
buf[60], buf[61], buf[62], buf[63]);
} else if (val & FBTFT_OF_INIT_DELAY) {
fbtft_par_dbg(DEBUG_INIT_DISPLAY, par,
"init: msleep(%u)\n", val & 0xFFFF);
msleep(val & 0xFFFF);
val = values[++index];
} else {
dev_err(dev, "illegal init value 0x%X\n", val);
ret = -EINVAL;
goto out_free;
}
}
out_free:
kfree(values);
return ret;
}
/**
* fbtft_init_display() - Generic init_display() function
* @par: Driver data
*
* Uses par->init_sequence to do the initialization
*
* Return: 0 if successful, negative if error
*/
int fbtft_init_display(struct fbtft_par *par)
{
int buf[64];
char msg[128];
char str[16];
int i = 0;
int j;
/* sanity check */
if (!par->init_sequence) {
dev_err(par->info->device,
"error: init_sequence is not set\n");
return -EINVAL;
}
/* make sure stop marker exists */
for (i = 0; i < FBTFT_MAX_INIT_SEQUENCE; i++)
if (par->init_sequence[i] == -3)
break;
if (i == FBTFT_MAX_INIT_SEQUENCE) {
dev_err(par->info->device,
"missing stop marker at end of init sequence\n");
return -EINVAL;
}
par->fbtftops.reset(par);
if (par->gpio.cs)
gpiod_set_value(par->gpio.cs, 0); /* Activate chip */
i = 0;
while (i < FBTFT_MAX_INIT_SEQUENCE) {
if (par->init_sequence[i] == -3) {
/* done */
return 0;
}
if (par->init_sequence[i] >= 0) {
dev_err(par->info->device,
"missing delimiter at position %d\n", i);
return -EINVAL;
}
if (par->init_sequence[i + 1] < 0) {
dev_err(par->info->device,
"missing value after delimiter %d at position %d\n",
par->init_sequence[i], i);
return -EINVAL;
}
switch (par->init_sequence[i]) {
case -1:
i++;
/* make debug message */
strcpy(msg, "");
j = i + 1;
while (par->init_sequence[j] >= 0) {
sprintf(str, "0x%02X ", par->init_sequence[j]);
strcat(msg, str);
j++;
}
fbtft_par_dbg(DEBUG_INIT_DISPLAY, par,
"init: write(0x%02X) %s\n",
par->init_sequence[i], msg);
/* Write */
j = 0;
while (par->init_sequence[i] >= 0) {
if (j > 63) {
dev_err(par->info->device,
"%s: Maximum register values exceeded\n",
__func__);
return -EINVAL;
}
buf[j++] = par->init_sequence[i++];
}
par->fbtftops.write_register(par, j,
buf[0], buf[1], buf[2], buf[3],
buf[4], buf[5], buf[6], buf[7],
buf[8], buf[9], buf[10], buf[11],
buf[12], buf[13], buf[14], buf[15],
buf[16], buf[17], buf[18], buf[19],
buf[20], buf[21], buf[22], buf[23],
buf[24], buf[25], buf[26], buf[27],
buf[28], buf[29], buf[30], buf[31],
buf[32], buf[33], buf[34], buf[35],
buf[36], buf[37], buf[38], buf[39],
buf[40], buf[41], buf[42], buf[43],
buf[44], buf[45], buf[46], buf[47],
buf[48], buf[49], buf[50], buf[51],
buf[52], buf[53], buf[54], buf[55],
buf[56], buf[57], buf[58], buf[59],
buf[60], buf[61], buf[62], buf[63]);
break;
case -2:
i++;
fbtft_par_dbg(DEBUG_INIT_DISPLAY, par,
"init: mdelay(%d)\n",
par->init_sequence[i]);
mdelay(par->init_sequence[i++]);
break;
default:
dev_err(par->info->device,
"unknown delimiter %d at position %d\n",
par->init_sequence[i], i);
return -EINVAL;
}
}
dev_err(par->info->device,
"%s: something is wrong. Shouldn't get here.\n", __func__);
return -EINVAL;
}
EXPORT_SYMBOL(fbtft_init_display);
/**
* fbtft_verify_gpios() - Generic verify_gpios() function
* @par: Driver data
*
* Uses @spi, @pdev and @buswidth to determine which GPIOs is needed
*
* Return: 0 if successful, negative if error
*/
static int fbtft_verify_gpios(struct fbtft_par *par)
{
struct fbtft_platform_data *pdata = par->pdata;
int i;
fbtft_par_dbg(DEBUG_VERIFY_GPIOS, par, "%s()\n", __func__);
if (pdata->display.buswidth != 9 && par->startbyte == 0 &&
!par->gpio.dc) {
dev_err(par->info->device,
"Missing info about 'dc' gpio. Aborting.\n");
return -EINVAL;
}
if (!par->pdev)
return 0;
if (!par->gpio.wr) {
dev_err(par->info->device, "Missing 'wr' gpio. Aborting.\n");
return -EINVAL;
}
for (i = 0; i < pdata->display.buswidth; i++) {
if (!par->gpio.db[i]) {
dev_err(par->info->device,
"Missing 'db%02d' gpio. Aborting.\n", i);
return -EINVAL;
}
}
return 0;
}
/* returns 0 if the property is not present */
static u32 fbtft_property_value(struct device *dev, const char *propname)
{
int ret;
u32 val = 0;
ret = device_property_read_u32(dev, propname, &val);
if (ret == 0)
dev_info(dev, "%s: %s = %u\n", __func__, propname, val);
return val;
}
static struct fbtft_platform_data *fbtft_properties_read(struct device *dev)
{
struct fbtft_platform_data *pdata;
if (!dev_fwnode(dev)) {
dev_err(dev, "Missing platform data or properties\n");
return ERR_PTR(-EINVAL);
}
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return ERR_PTR(-ENOMEM);
pdata->display.width = fbtft_property_value(dev, "width");
pdata->display.height = fbtft_property_value(dev, "height");
pdata->display.regwidth = fbtft_property_value(dev, "regwidth");
pdata->display.buswidth = fbtft_property_value(dev, "buswidth");
pdata->display.backlight = fbtft_property_value(dev, "backlight");
pdata->display.bpp = fbtft_property_value(dev, "bpp");
pdata->display.debug = fbtft_property_value(dev, "debug");
pdata->rotate = fbtft_property_value(dev, "rotate");
pdata->bgr = device_property_read_bool(dev, "bgr");
pdata->fps = fbtft_property_value(dev, "fps");
pdata->txbuflen = fbtft_property_value(dev, "txbuflen");
pdata->startbyte = fbtft_property_value(dev, "startbyte");
device_property_read_string(dev, "gamma", (const char **)&pdata->gamma);
if (device_property_present(dev, "led-gpios"))
pdata->display.backlight = 1;
if (device_property_present(dev, "init"))
pdata->display.fbtftops.init_display =
fbtft_init_display_from_property;
pdata->display.fbtftops.request_gpios = fbtft_request_gpios;
return pdata;
}
/**
* fbtft_probe_common() - Generic device probe() helper function
* @display: Display properties
* @sdev: SPI device
* @pdev: Platform device
*
* Allocates, initializes and registers a framebuffer
*
* Either @sdev or @pdev should be NULL
*
* Return: 0 if successful, negative if error
*/
int fbtft_probe_common(struct fbtft_display *display,
struct spi_device *sdev,
struct platform_device *pdev)
{
struct device *dev;
struct fb_info *info;
struct fbtft_par *par;
struct fbtft_platform_data *pdata;
int ret;
if (sdev)
dev = &sdev->dev;
else
dev = &pdev->dev;
if (unlikely(display->debug & DEBUG_DRIVER_INIT_FUNCTIONS))
dev_info(dev, "%s()\n", __func__);
pdata = dev->platform_data;
if (!pdata) {
pdata = fbtft_properties_read(dev);
if (IS_ERR(pdata))
return PTR_ERR(pdata);
}
info = fbtft_framebuffer_alloc(display, dev, pdata);
if (!info)
return -ENOMEM;
par = info->par;
par->spi = sdev;
par->pdev = pdev;
if (display->buswidth == 0) {
dev_err(dev, "buswidth is not set\n");
return -EINVAL;
}
/* write register functions */
if (display->regwidth == 8 && display->buswidth == 8)
par->fbtftops.write_register = fbtft_write_reg8_bus8;
else if (display->regwidth == 8 && display->buswidth == 9 && par->spi)
par->fbtftops.write_register = fbtft_write_reg8_bus9;
else if (display->regwidth == 16 && display->buswidth == 8)
par->fbtftops.write_register = fbtft_write_reg16_bus8;
else if (display->regwidth == 16 && display->buswidth == 16)
par->fbtftops.write_register = fbtft_write_reg16_bus16;
else
dev_warn(dev,
"no default functions for regwidth=%d and buswidth=%d\n",
display->regwidth, display->buswidth);
/* write_vmem() functions */
if (display->buswidth == 8)
par->fbtftops.write_vmem = fbtft_write_vmem16_bus8;
else if (display->buswidth == 9)
par->fbtftops.write_vmem = fbtft_write_vmem16_bus9;
else if (display->buswidth == 16)
par->fbtftops.write_vmem = fbtft_write_vmem16_bus16;
/* GPIO write() functions */
if (par->pdev) {
if (display->buswidth == 8)
par->fbtftops.write = fbtft_write_gpio8_wr;
else if (display->buswidth == 16)
par->fbtftops.write = fbtft_write_gpio16_wr;
}
/* 9-bit SPI setup */
if (par->spi && display->buswidth == 9) {
if (par->spi->master->bits_per_word_mask & SPI_BPW_MASK(9)) {
par->spi->bits_per_word = 9;
} else {
dev_warn(&par->spi->dev,
"9-bit SPI not available, emulating using 8-bit.\n");
/* allocate buffer with room for dc bits */
par->extra = devm_kzalloc(par->info->device,
par->txbuf.len +
(par->txbuf.len / 8) + 8,
GFP_KERNEL);
if (!par->extra) {
ret = -ENOMEM;
goto out_release;
}
par->fbtftops.write = fbtft_write_spi_emulate_9;
}
}
if (!par->fbtftops.verify_gpios)
par->fbtftops.verify_gpios = fbtft_verify_gpios;
/* make sure we still use the driver provided functions */
fbtft_merge_fbtftops(&par->fbtftops, &display->fbtftops);
/* use init_sequence if provided */
if (par->init_sequence)
par->fbtftops.init_display = fbtft_init_display;
/* use platform_data provided functions above all */
fbtft_merge_fbtftops(&par->fbtftops, &pdata->display.fbtftops);
ret = fbtft_register_framebuffer(info);
if (ret < 0)
goto out_release;
return 0;
out_release:
fbtft_framebuffer_release(info);
return ret;
}
EXPORT_SYMBOL(fbtft_probe_common);
/**
* fbtft_remove_common() - Generic device remove() helper function
* @dev: Device
* @info: Framebuffer
*
* Unregisters and releases the framebuffer
*
* Return: 0 if successful, negative if error
*/
int fbtft_remove_common(struct device *dev, struct fb_info *info)
{
struct fbtft_par *par;
if (!info)
return -EINVAL;
par = info->par;
if (par)
fbtft_par_dbg(DEBUG_DRIVER_INIT_FUNCTIONS, par,
"%s()\n", __func__);
fbtft_unregister_framebuffer(info);
fbtft_framebuffer_release(info);
return 0;
}
EXPORT_SYMBOL(fbtft_remove_common);
MODULE_LICENSE("GPL");
fb_st7789v.c
// SPDX-License-Identifier: GPL-2.0+
/*
* FB driver for the ST7789V LCD Controller
*
* Copyright (C) 2015 Dennis Menschel
*/
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <video/mipi_display.h>
#include "fbtft.h"
#define DRVNAME "fb_st7789v"
#define DEFAULT_GAMMA \
"70 2C 2E 15 10 09 48 33 53 0B 19 18 20 25\n" \
"70 2C 2E 15 10 09 48 33 53 0B 19 18 20 25"
#define HSD20_IPS_GAMMA \
"D0 05 0A 09 08 05 2E 44 45 0F 17 16 2B 33\n" \
"D0 05 0A 09 08 05 2E 43 45 0F 16 16 2B 33"
#define HSD20_IPS 1
/**
* enum st7789v_command - ST7789V display controller commands
*
* @PORCTRL: porch setting
* @GCTRL: gate control
* @VCOMS: VCOM setting
* @VDVVRHEN: VDV and VRH command enable
* @VRHS: VRH set
* @VDVS: VDV set
* @VCMOFSET: VCOM offset set
* @PWCTRL1: power control 1
* @PVGAMCTRL: positive voltage gamma control
* @NVGAMCTRL: negative voltage gamma control
*
* The command names are the same as those found in the datasheet to ease
* looking up their semantics and usage.
*
* Note that the ST7789V display controller offers quite a few more commands
* which have been omitted from this list as they are not used at the moment.
* Furthermore, commands that are compliant with the MIPI DCS have been left
* out as well to avoid duplicate entries.
*/
enum st7789v_command {
PORCTRL = 0xB2,
GCTRL = 0xB7,
VCOMS = 0xBB,
VDVVRHEN = 0xC2,
VRHS = 0xC3,
VDVS = 0xC4,
VCMOFSET = 0xC5,
PWCTRL1 = 0xD0,
PVGAMCTRL = 0xE0,
NVGAMCTRL = 0xE1,
};
#define MADCTL_BGR BIT(3) /* bitmask for RGB/BGR order */
#define MADCTL_MV BIT(5) /* bitmask for page/column order */
#define MADCTL_MX BIT(6) /* bitmask for column address order */
#define MADCTL_MY BIT(7) /* bitmask for page address order */
/**
* init_display() - initialize the display controller
*
* @par: FBTFT parameter object
*
* Most of the commands in this init function set their parameters to the
* same default values which are already in place after the display has been
* powered up. (The main exception to this rule is the pixel format which
* would default to 18 instead of 16 bit per pixel.)
* Nonetheless, this sequence can be used as a template for concrete
* displays which usually need some adjustments.
*
* Return: 0 on success, < 0 if error occurred.
*/
static int init_display(struct fbtft_par *par)
{
par->fbtftops.reset(par);
/* turn off sleep mode */
write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE);
mdelay(120);
/* set pixel format to RGB-565 */
write_reg(par, MIPI_DCS_SET_PIXEL_FORMAT, MIPI_DCS_PIXEL_FMT_16BIT);
if (HSD20_IPS)
write_reg(par, PORCTRL, 0x05, 0x05, 0x00, 0x33, 0x33);
else
write_reg(par, PORCTRL, 0x08, 0x08, 0x00, 0x22, 0x22);
/*
* VGH = 13.26V
* VGL = -10.43V
*/
if (HSD20_IPS)
write_reg(par, GCTRL, 0x75);
else
write_reg(par, GCTRL, 0x35);
/*
* VDV and VRH register values come from command write
* (instead of NVM)
*/
write_reg(par, VDVVRHEN, 0x01, 0xFF);
/*
* VAP = 4.1V + (VCOM + VCOM offset + 0.5 * VDV)
* VAN = -4.1V + (VCOM + VCOM offset + 0.5 * VDV)
*/
if (HSD20_IPS)
write_reg(par, VRHS, 0x13);
else
write_reg(par, VRHS, 0x0B);
/* VDV = 0V */
write_reg(par, VDVS, 0x20);
/* VCOM = 0.9V */
if (HSD20_IPS)
write_reg(par, VCOMS, 0x22);
else
write_reg(par, VCOMS, 0x20);
/* VCOM offset = 0V */
write_reg(par, VCMOFSET, 0x20);
/*
* AVDD = 6.8V
* AVCL = -4.8V
* VDS = 2.3V
*/
write_reg(par, PWCTRL1, 0xA4, 0xA1);
write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
if (HSD20_IPS)
write_reg(par, MIPI_DCS_ENTER_INVERT_MODE);
return 0;
// par->fbtftops.reset(par);
// mdelay(50);
// write_reg(par,0x36,0x00);
// write_reg(par,0x3A,0x05);
// write_reg(par,0xB2,0x0C,0x0C,0x00,0x33,0x33);
// write_reg(par,0xB7,0x35);
// write_reg(par,0xBB,0x19);
// write_reg(par,0xC0,0x2C);
// write_reg(par,0xC2,0x01);
// write_reg(par,0xC3,0x12);
// write_reg(par,0xC4,0x20);
// write_reg(par,0xC6,0x0F);
// write_reg(par,0xD0,0xA4,0xA1);
// write_reg(par,0xE0,0xD0,0x04,0x0D,0x11,0x13,0x2B,0x3F,0x54,0x4C,0x18,0x0D,0x0B,0x1F,0x23);
// write_reg(par,0xE1,0xD0,0x04,0x0C,0x11,0x13,0x2C,0x3F,0x44,0x51,0x2F,0x1F,0x1F,0x20,0x23);
// write_reg(par,0x21);
// write_reg(par,0x11);
// mdelay(50);
// write_reg(par,0x29);
// mdelay(200);
// return 0;
}
/**
* set_var() - apply LCD properties like rotation and BGR mode
*
* @par: FBTFT parameter object
*
* Return: 0 on success, < 0 if error occurred.
*/
static int set_var(struct fbtft_par *par)
{
u8 madctl_par = 0;
if (par->bgr)
madctl_par |= MADCTL_BGR;
switch (par->info->var.rotate) {
case 0:
break;
case 90:
madctl_par |= (MADCTL_MV | MADCTL_MY);
break;
case 180:
madctl_par |= (MADCTL_MX | MADCTL_MY);
break;
case 270:
madctl_par |= (MADCTL_MV | MADCTL_MX);
break;
default:
return -EINVAL;
}
write_reg(par, MIPI_DCS_SET_ADDRESS_MODE, madctl_par);
return 0;
}
/**
* set_gamma() - set gamma curves
*
* @par: FBTFT parameter object
* @curves: gamma curves
*
* Before the gamma curves are applied, they are preprocessed with a bitmask
* to ensure syntactically correct input for the display controller.
* This implies that the curves input parameter might be changed by this
* function and that illegal gamma values are auto-corrected and not
* reported as errors.
*
* Return: 0 on success, < 0 if error occurred.
*/
static int set_gamma(struct fbtft_par *par, u32 *curves)
{
int i;
int j;
int c; /* curve index offset */
/*
* Bitmasks for gamma curve command parameters.
* The masks are the same for both positive and negative voltage
* gamma curves.
*/
static const u8 gamma_par_mask[] = {
0xFF, /* V63[3:0], V0[3:0]*/
0x3F, /* V1[5:0] */
0x3F, /* V2[5:0] */
0x1F, /* V4[4:0] */
0x1F, /* V6[4:0] */
0x3F, /* J0[1:0], V13[3:0] */
0x7F, /* V20[6:0] */
0x77, /* V36[2:0], V27[2:0] */
0x7F, /* V43[6:0] */
0x3F, /* J1[1:0], V50[3:0] */
0x1F, /* V57[4:0] */
0x1F, /* V59[4:0] */
0x3F, /* V61[5:0] */
0x3F, /* V62[5:0] */
};
for (i = 0; i < par->gamma.num_curves; i++) {
c = i * par->gamma.num_values;
for (j = 0; j < par->gamma.num_values; j++)
curves[c + j] &= gamma_par_mask[j];
write_reg(par, PVGAMCTRL + i,
curves[c + 0], curves[c + 1], curves[c + 2],
curves[c + 3], curves[c + 4], curves[c + 5],
curves[c + 6], curves[c + 7], curves[c + 8],
curves[c + 9], curves[c + 10], curves[c + 11],
curves[c + 12], curves[c + 13]);
}
return 0;
}
/**
* blank() - blank the display
*
* @par: FBTFT parameter object
* @on: whether to enable or disable blanking the display
*
* Return: 0 on success, < 0 if error occurred.
*/
static int blank(struct fbtft_par *par, bool on)
{
if (on)
write_reg(par, MIPI_DCS_SET_DISPLAY_OFF);
else
write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
return 0;
}
static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
{
// switch(par->info->var.rotate)
// {
// case 0: xs+=53;xe+=53;ys+=40;ye+=40;
// break;
// // case 90: xs+=40;xe+=40;ys+=53;ye+=53;
// case 90: xs+=80;xe+=80;
// break;
// case 180: xs+=53;xe+=53;ys+=40;ye+=40;
// break;
// case 270: xs+=40;xe+=40;ys+=53;ye+=53;
// break;
// default :
// break;
// }
write_reg(par, MIPI_DCS_SET_COLUMN_ADDRESS,
xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF);
write_reg(par, MIPI_DCS_SET_PAGE_ADDRESS,
ys >> 8, ys & 0xFF, ye >> 8, ye & 0xFF);
write_reg(par, MIPI_DCS_WRITE_MEMORY_START);
}
static struct fbtft_display display = {
.regwidth = 8,
.width = 240,
.height = 240,
.gamma_num = 2,
.gamma_len = 14,
.gamma = HSD20_IPS_GAMMA,
.fbtftops = {
.init_display = init_display,
.set_addr_win = set_addr_win,
.set_var = set_var,
.set_gamma = set_gamma,
.blank = blank,
},
};
FBTFT_REGISTER_DRIVER(DRVNAME, "sitronix,st7789v", &display);
MODULE_ALIAS("spi:" DRVNAME);
MODULE_ALIAS("platform:" DRVNAME);
MODULE_ALIAS("spi:st7789v");
MODULE_ALIAS("platform:st7789v");
MODULE_DESCRIPTION("FB driver for the ST7789V LCD Controller");
MODULE_AUTHOR("Dennis Menschel");
MODULE_LICENSE("GPL");
就在两地方,毫无问题
.config - Linux/arm 5.4.99 Kernel Configuration
> Device Drivers > I2C support > I2C Hardware Bus support ────────────────────
┌─────────────────────── I2C Hardware Bus support ────────────────────────┐
│ Arrow keys navigate the menu. <Enter> selects submenus ---> (or empty │
│ submenus ----). Highlighted letters are hotkeys. Pressing <Y> │
│ includes, <N> excludes, <M> modularizes features. Press <Esc><Esc> to │
│ exit, <?> for Help, </> for Search. Legend: [*] built-in [ ] │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ *** I2C system bus drivers (mostly embedded / system-on-chip)│ │
│ │ < > CBUS I2C driver │ │
│ │ < > Synopsys DesignWare Platform │ │
│ │ < > EMMA Mobile series I2C adapter │ │
│ │ <*> GPIO-based bitbanging I2C
i2c_gpio0: i2c-gpio-0 {
compatible = "i2c-gpio";
sda-gpios = <&pio 4 0 GPIO_ACTIVE_HIGH>;
scl-gpios = <&pio 4 1 GPIO_ACTIVE_HIGH>;
i2c-gpio,delay-us = <5>;
#address-cells = <1>;
#size-cells = <0>;
ft6x06@38 {
compatible = "focaltech,ft6236";
reg = <0x38>;
interrupt-parent = <&pio>;
interrupts = <4 2 IRQ_TYPE_LEVEL_LOW>;
reset-gpios = <&pio 4 3 GPIO_ACTIVE_LOW>;
touchscreen-size-x = <240>;
touchscreen-size-y = <240>;
};
};
opencv图传
服务端
#include <unistd.h>//Linux系统下网络通讯的头文件集合
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <malloc.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <stdarg.h>
#include <fcntl.h>
#include <fcntl.h>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;
enum
{
PORT = 8888
};
int main(int argc, char** argv)
{
int m_sockClient;
if ((m_sockClient = socket(AF_INET, SOCK_DGRAM, 0)) < 0) //创建socket句柄,采用UDP协议
{
printf("create socket error: %s(errno: %d)\n", strerror(errno), errno);
return -1;
}
sockaddr_in m_servaddr;
memset(&m_servaddr, 0, sizeof(m_servaddr)); //初始化结构体
m_servaddr.sin_family = AF_INET; //设置通信方式
m_servaddr.sin_port = htons(PORT); //设置端口号
m_servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
int len = sizeof(m_servaddr);
bind(m_sockClient, (sockaddr*)&m_servaddr, sizeof(m_servaddr));//绑定套接字
Mat image;
unsigned char buf[426672];
struct sockaddr_in addr_client;
while (true)
{
std::vector<uchar> decode;
int n = recvfrom(m_sockClient, buf, sizeof(buf), 0,(struct sockaddr *)&addr_client, (socklen_t *)&len);//接受缓存
int pos = 0;
while (pos < n)
{
decode.push_back(buf[pos++]);//存入vector
}
buf[n] = 0;
image = imdecode(decode, CV_LOAD_IMAGE_COLOR);//图像解码
imshow("image", image);
waitKey(10);
}
return 0;
}
客户端
#include <unistd.h>//Linux系统下网络通讯的头文件集合
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <malloc.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <stdarg.h>
#include <fcntl.h>
#include <fcntl.h>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;
enum
{
PORT = 8888
};
int main(int argc, char** argv)
{
int m_sockClient;
if ((m_sockClient = socket(AF_INET, SOCK_DGRAM, 0)) < 0) //创建socket句柄,采用UDP协议
{
printf("create socket error: %s(errno: %d)\n", strerror(errno), errno);
return -1;
}
sockaddr_in m_servaddr;
memset(&m_servaddr, 0, sizeof(m_servaddr)); //初始化结构体
m_servaddr.sin_family = AF_INET; //设置通信方式
m_servaddr.sin_port = htons(PORT); //设置端口号
m_servaddr.sin_addr.s_addr = inet_addr(argv[1]);
//m_servaddr.sin_port = htons(8888);//设置需要发送的IP和端口号
bind(m_sockClient, (sockaddr*)&m_servaddr, sizeof(m_servaddr));//绑定端口号
VideoCapture capture(cv::String("/dev/video0"));//打开摄像头
Mat image;
while (true)
{
capture >> image;//读入图片
if (image.empty()) //如果照片为空则退出
{
printf("empty image\n\n");
return -1;
}
std::vector<uchar> data_encode;
std::vector<int> quality;
quality.push_back(CV_IMWRITE_JPEG_QUALITY);
quality.push_back(10);//进行50%的压缩
imencode(".jpg", image, data_encode,quality);//将图像编码
//char encodeImg[426672];
int nSize = data_encode.size();
unsigned char *encodeImg = new unsigned char[nSize];
printf("%d\n", nSize);
for (int i = 0; i < nSize; i++)
{
encodeImg[i] = data_encode[i];
}
sendto(m_sockClient, encodeImg, nSize, 0, (const sockaddr*)& m_servaddr, sizeof(m_servaddr));
memset(&encodeImg, 0, sizeof(encodeImg)); //初始化结构体
}
return 0;
}
opencv交叉编译挺坑的,分享一下个人编译好的库
包含适用于 PC端 A7架构(V3s/V3X H2 H3等) A53架构(H5 H6)的opencv动态库
链接:
https://pan.baidu.com/s/19ia2QO9gtlHLV82U27WCmg
提取码:7ur9
【PC端】
将PC opencv和ARM opencv库解压到自定义路径下(PC用于调试,调试后成功后切换arm编译)
【ARM端】
将lib文件下的所有文件复制到板子/usr/lib下 (如果在arm端编译还需复制include下的文件)
【Qt】
INCLUDEPATH += /usr/local/include \
/usr/local/arm_opencv/include/opencv \
/usr/local/arm_opencv/include/opencv2
LIBS += /usr/local/arm_opencv/lib/libopencv*.so
【GCC】
g++ test.cpp -o test -I/home/lzq/opencv/PC_opencv/include -L/home/lzq/opencv/PC_opencv/lib -lopencv_highgui -lopencv_imgproc -lopencv_core -lopencv_imgcodecs -lopencv_videoio -lpthread -ldl
这个屏幕是mipi接口的吗 能上个链接吗
spi屏幕
MIPI只是小电脑名字,并不是屏幕接口
https://whycan.com/t_7281.html
https://whycan.com/t_7522.html
重点重点重点
瓦片坐标换算(输入转换后的经度纬度)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define PI 3.14159265359
int main(int argc , char **argv)
{
if(argc != 4)
{
printf("error! such as: ./test 1 2 3\r\n");
return -1;
}
double longitude = atof(argv[1]); //经度
double latitude = atof(argv[2]); //纬度
int zoom = atoi(argv[3]); //级别
double xtile, ytile;
printf("%f %f %d \r\n", longitude, latitude, zoom);
latitude = latitude / 180.0 * PI; //角度转弧度
xtile = (longitude + 180.0) / 360.0 * pow(2.0, zoom); //计算地图瓦片坐标x
ytile = (1.0 - asinh(tan(latitude)) / PI) / 2.0 * pow(2.0, zoom); //计算地图瓦片坐标y
printf("\r\nxtile: %f \r\nytile: %f \r\nzoom: %d \r\n", xtile, ytile, zoom);
return 0;
}
高德地图查经度纬度网站
https://lbs.amap.com/tools/picker
记住这个圆心
lzq@lzq:~/desktop$ ./map 113.865221 29.714519 18
113.865221 29.714519 18
xtile: 213986.123594
ytile: 108393.812937
zoom: 18
lzq@lzq:~/desktop$
根据输出寻找瓦片地图图片,非常准
换个等级试试
离线地图下载
使用https://gitee.com/CrimsonHu/java_map_download里的地图下载器
划定需要的区域
下载
桌面镜像已上传,链接跟一楼一样,记得建立swap分区
链接:
https://pan.baidu.com/s/1GhGtAKwBWQI940ZrbjnovA
提取码:pjs3
led驱动编译到内核
在如图路径中放入led.c驱动代码 Kconfig Makefile
led.c
查看一楼
Kconfig
menu "led driver"
config LED
tristate"myled"
default y
endmenu
Makefile
obj-$(CONFIG_LED)+=led.o
修改char路径下的Kconfig和Makefile
在endmenu前加入
source "drivers/char/led/Kconfig"
obj-$(CONFIG_LED) += led/
make menuconfig ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j12
替换原来的zImage
启动系统查看加载的模块 200 myled
root@lzq:~# cat /proc/devices
Character devices:
1 mem
2 pty
3 ttyp
4 /dev/vc/0
4 tty
4 ttyS
5 /dev/tty
5 /dev/console
5 /dev/ptmx
7 vcs
10 misc
13 input
29 fb
81 video4linux
89 i2c
90 mtd
116 alsa
128 ptm
136 pts
180 usb
189 usb_device
200 myled
212 DVB
226 drm
248 rpmb
249 ttyGS
250 bsg
251 watchdog
252 media
253 rtc
254 gpiochip
Block devices:
8 sd
65 sd
66 sd
67 sd
68 sd
69 sd
70 sd
71 sd
128 sd
129 sd
130 sd
131 sd
132 sd
133 sd
134 sd
135 sd
179 mmc
259 blkext
最后手动创建myled的设备(代码里可自动创建),参考帖子里的教程
@twzy
https://releases.linaro.org/debian/images/alip-armhf/
这里是带桌面的文件系统,换掉原来的文件系统就行
记得启动交换分区,不然很卡
V3X和V3S就uboot有点差异,内核文件系统通用
应用层pwm点灯
PB5引脚有pwm功能,我们可以通过它来调节背光灯亮度
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <string.h>
#define PIO_BASE_ADDR 0x01C20000
#define PIO_ADDR_OFF 0x800
#define PIO_CFG_OFF 0x24 //配置
#define PIO_DAT_OFF 0x34 //数据
#define PWM_ADDR_OFF 0x1400
#define PWM_CH1_OFF 0x08 //pwm1
#define Page_Size (4096 * 2)
uint32_t *base_map = NULL;
uint32_t *gpio_map = NULL;
uint32_t *gpio_cfg = NULL;
uint32_t *gpio_dat = NULL;
uint32_t *pwm_base_map = NULL;
uint32_t *pwm1_period = NULL;
uint32_t T = 1000; //周期
int main(int argc , char **argv)
{
int mem_fd;
int duty=200;
if (argc!=2)
{
printf("./backlight level (level:0~100)\n");
exit(-1);
}
duty = T - atol(argv[1])*10;
if ((mem_fd = open("/dev/mem", O_RDWR)) < 0)
{
//printf("open error\r\n");
exit(-1);
}
//mmap(系统自动分配内存地址,映射区长度“内存页的整数倍”,选择可读可写,MAP_SHARED=与其他所有映射到这个对象的进程共享空间,文件句柄,被映射内容的起点)
//offest 映射物理内存的话,必须页对其!!! 所以这个起始地址应该是0x1000的整数倍,那么明显0x01C20800需要减去0x800才是整数倍!
if ((base_map = (uint32_t *)mmap(NULL, Page_Size, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, PIO_BASE_ADDR)) == NULL)
{
//printf("mmap error\r\n");
close(mem_fd);
exit(-1);
}
//printf("base_map:0x%.8X\n", (uint32_t)base_map);
close(mem_fd); //映射好之后就可以关闭文件?
//这里已经将0x1c20000的地址映射到了内存中,但是我们需要的地址是0x01C20800,所以要再加上地址偏移量~
gpio_map = (uint32_t)base_map + PIO_ADDR_OFF; //加上偏移量必选先把他转化成unsigend int才可以相加
//printf("gpio_map:0x%.8X\n", (uint32_t)gpio_map);
gpio_cfg = (uint32_t)gpio_map + PIO_CFG_OFF; //gpioB控制寄存器地址
//printf("gpio_cfg:0x%.8X\n", (uint32_t)gpio_cfg);
gpio_dat = (uint32_t)gpio_map + PIO_DAT_OFF; //gpioB数据寄存器地址
//printf("gpio_dat:0x%.8X\n", (uint32_t)gpio_dat);
/*PB5点灯*/
(*gpio_cfg) &= ~((unsigned int)7 << 20); //先将对应位置0 //
(*gpio_cfg) |= ((unsigned int)1 << 20); //PB5 设定out //模式in out pwm
// (*gpio_dat) &= ~(1 << 5); //开灯
// sleep(1);
// (*gpio_dat) |= (1<<5);
// sleep(1);
/**
* PWM波配置顺序
* 1.GPIO 配置PWM输出模式
* 2.PWM 预分頻
* 3.PWM 总周期
* 4.PWM 活跃周期
* 5.PWM 使能
*/
//PB5设定PWM输出
(*gpio_cfg) &= ~((unsigned int)7 << 20); //置20:22 000
(*gpio_cfg) |= ((unsigned int)2 << 20); //PB5 2=010 设定20:22 010 pwm1模式
//我们需要的地址是0x01C21400,所以要再加上地址偏移量
pwm_base_map = (uint32_t)base_map + PWM_ADDR_OFF; //pwm_base_map也是pwm控制寄存器 初始值是0x00000000
//printf("pwm_base_map:0x%.8X\n", (uint32_t)pwm_base_map);
/*首先设置pwm1 预分頻*/ //PWM_CH1_PRESCAL
(*pwm_base_map) &= ~((uint32_t)15 << 15); //先将15~18位置0
(*pwm_base_map) |= (uint32_t)0 << 15; //将15~18位设置为 0000 ---> 对应分頻120 24m/120=200k
/*可能要设置SCLK_CH1_GATING为mask*/
(*pwm_base_map) &= ~((uint32_t)1 << 21); //先将第21位置0
(*pwm_base_map) |= (uint32_t)1 << 21; //将第21位置1 ---> 设置为自定义预分頻系数
/**
* 具体的总周期时间的作用需要进一步测试
* 注意:要活动周期设置好之后使能PWM通道
* 这样才会有正确输出,并且之后直接修改寄存器的值就可以修改占空比。
* */
/*再设置pwm1占空比*/
pwm1_period = (uint32_t)pwm_base_map + PWM_CH1_OFF; //pwm1_period设置pwm_CH1的占空比寄存器
//printf("pwm1_period:0x%.8X\n", (uint32_t)pwm1_period);
/*先设置总周期*/ //PWM周期的计算应该是这样 OSC 24MHz / Pre-scalar / (entire cycles + 1)
(*pwm1_period) &= ~((uint32_t)65535 << 16); //将31~16位置零
(*pwm1_period) |= (uint32_t)T << 16; // 现在设置整个周期65535
/*再设置活跃周期 活跃周期要小于总周期*/
(*pwm1_period) &= ~((uint32_t)65535 << 0); //将15~0位置零
(*pwm1_period) |= (uint32_t)duty << 0; //将15~0位置为2500 现在设置活跃周期为35535
/*最后应该设置PWM_CH1_EN为enable*/
(*pwm_base_map) &= ~((uint32_t)1 << 19); //先将第4位置0 ---> disable
(*pwm_base_map) |= (uint32_t)1 << 19; //将第4位置1 ---> enable pwm1
//printf("PWM ENABLE DUTY:%d\n",duty);
munmap(base_map, Page_Size);
//printf("munmap success!\n");
return 0;
}
0.配置
1.分频
pass自定义
2.周期
3.使能
测试
#!/bin/bash
t=0
while(true)
do
#sleep 0.001
.backlight $t
echo $((t++))
if [ $t == 101 ];then
t=0
echo "ok"
fi
done
效果
另一种驱动代码(用到了GPIO的函数),会自动在/dev下创建设备
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <mach/gpio.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/poll.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/device.h> // 内核源码里创建/移除设备,产生热插拔事件的函数class
#define MYMA 200
#define MYMI 3333
#define COUNT 1
#define LED_IO GPIOB(5)//注意修改! 对应开发板上的led灯引脚
dev_t devid; //用于存放设备号
struct cdev mycdev;
static struct class *mycls;
//打开设备文件时开启中断
static int myopen(struct inode *ind,struct file *fl)
{
int ret;
ret = gpio_request(LED_IO, "led_0"); //请求gpio口,tldev则是为其取一个名字。
if(ret<0)
goto err0;
gpio_direction_output(LED_IO, 0); //配置gpio口为输出,先输出低电平
return 0;
err0:
return ret;
}
static ssize_t mywrite(struct file *fl,const char *__user buf,size_t len,loff_t *off)
{
char stat;
copy_from_user(&stat,buf,sizeof(char));
if(stat)
gpio_set_value(LED_IO,1);
else
gpio_set_value(LED_IO,0);
return 0;
}
//关闭设备文件时释放中断
static int myclose(struct inode *inode,struct file *fl)
{
gpio_set_value(LED_IO,0);
gpio_free(LED_IO);
return 0;
}
static struct file_operations fops= {
.owner = THIS_MODULE,
.open = myopen,
.write = mywrite,
.release= myclose,
};
static int __init test_init(void)
{
int ret;
devid = MKDEV(MYMA, MYMI); //生成一个设备号
ret = register_chrdev_region(devid, COUNT, DEVNAME); //name设备名(用于查看用, 长度不能超过64字节 )
if (ret < 0)
goto err0;
cdev_init(&mycdev, &fops);
mycdev.owner = THIS_MODULE;
ret = cdev_add(&mycdev, devid, COUNT);
if (ret < 0)
goto err1;
mycls= class_create(THIS_MODULE,"mykeycls");
if(mycls== NULL)
goto err2;
device_create(mycls,NULL,devid,NULL,DEVNAME);
return 0;
err2:
cdev_del(&mycdev);
err1:
unregister_chrdev_region(devid, COUNT);
err0:
return ret;
}
static void __exit test_exit(void)
{
device_destroy(mycls,devid);
class_destroy(mycls);
unregister_chrdev_region(devid, COUNT);
cdev_del(&mycdev);
gpio_free(LED_IO); //释放gpio
}
module_init(test_init);
module_exit(test_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("xxx");
MODULE_DESCRIPTION("led");
MODULE_VERSION("v0.0");
Makefile 和一楼的一样
make报错出现无#include <mach/gpio.h>
解决:
1.将内核源码中的如图文件夹复制到arch/arm/include/
这是linux3.4中的,我的是linux5.10,没有该文件夹
2.在内核源码arch/arm/include/下创建mach文件夹
创建gpio.h
/*
* arch/arm/mach-sunxi/include/mach/gpio.h
*
* Copyright(c) 2013-2015 Allwinnertech Co., Ltd.
* http://www.allwinnertech.com
*
* Author: sunny <sunny@allwinnertech.com>
*
* allwinner sunxi gpio defines.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/slab.h>
#ifndef __SUNXI_MACH_GPIO_H
#define __SUNXI_MACH_GPIO_H
/* pin group base number name space,
* the max pin number : 26*32=832.
*/
#define SUNXI_PINCTRL "sunxi-pinctrl"
#define SUNXI_BANK_SIZE 32
#define SUNXI_PA_BASE 0
#define SUNXI_PB_BASE 32
#define SUNXI_PC_BASE 64
#define SUNXI_PD_BASE 96
#define SUNXI_PE_BASE 128
#define SUNXI_PF_BASE 160
#define SUNXI_PG_BASE 192
#define SUNXI_PH_BASE 224
#define SUNXI_PI_BASE 256
#define SUNXI_PJ_BASE 288
#define SUNXI_PK_BASE 320
#define SUNXI_PL_BASE 352
#define SUNXI_PM_BASE 384
#define SUNXI_PN_BASE 416
#define SUNXI_PO_BASE 448
#define AXP_PIN_BASE 1024
#define SUNXI_PIN_NAME_MAX_LEN 8
/* sunxi gpio name space */
#define GPIOA(n) (SUNXI_PA_BASE + (n))
#define GPIOB(n) (SUNXI_PB_BASE + (n))
#define GPIOC(n) (SUNXI_PC_BASE + (n))
#define GPIOD(n) (SUNXI_PD_BASE + (n))
#define GPIOE(n) (SUNXI_PE_BASE + (n))
#define GPIOF(n) (SUNXI_PF_BASE + (n))
#define GPIOG(n) (SUNXI_PG_BASE + (n))
#define GPIOH(n) (SUNXI_PH_BASE + (n))
#define GPIOI(n) (SUNXI_PI_BASE + (n))
#define GPIOJ(n) (SUNXI_PJ_BASE + (n))
#define GPIOK(n) (SUNXI_PK_BASE + (n))
#define GPIOL(n) (SUNXI_PL_BASE + (n))
#define GPIOM(n) (SUNXI_PM_BASE + (n))
#define GPION(n) (SUNXI_PN_BASE + (n))
#define GPIOO(n) (SUNXI_PO_BASE + (n))
#define GPIO_AXP(n) (AXP_PIN_BASE + (n))
/* sunxi specific input/output/eint functions */
#define SUNXI_PIN_INPUT_FUNC (0)
#define SUNXI_PIN_OUTPUT_FUNC (1)
#define SUNXI_PIN_EINT_FUNC (6)
#define SUNXI_PIN_IO_DISABLE (7)
/* axp group base number name space,
* axp pinctrl number space coherent to sunxi-pinctrl.
*/
#define AXP_PINCTRL "axp-pinctrl"
#define AXP_CFG_GRP (0xFFFF)
#define AXP_PIN_INPUT_FUNC (0)
#define AXP_PIN_OUTPUT_FUNC (1)
#define IS_AXP_PIN(pin) (pin >= AXP_PIN_BASE)
/* sunxi specific pull up/down */
enum sunxi_pull_up_down {
SUNXI_PULL_DISABLE = 0,
SUNXI_PULL_UP,
SUNXI_PULL_DOWN,
};
/* sunxi specific data types */
enum sunxi_data_type {
SUNXI_DATA_LOW = 0,
SUNXI_DATA_HIGH = 0,
};
/* sunxi specific pull status */
enum sunxi_pin_pull {
SUNXI_PIN_PULL_DISABLE = 0x00,
SUNXI_PIN_PULL_UP = 0x01,
SUNXI_PIN_PULL_DOWN = 0x02,
SUNXI_PIN_PULL_RESERVED = 0x03,
};
/* sunxi specific driver levels */
enum sunxi_pin_drv_level {
SUNXI_DRV_LEVEL0 = 10,
SUNXI_DRV_LEVEL1 = 20,
SUNXI_DRV_LEVEL2 = 30,
SUNXI_DRV_LEVEL3 = 40,
};
/* sunxi specific data bit status */
enum sunxi_pin_data_status {
SUNXI_PIN_DATA_LOW = 0x00,
SUNXI_PIN_DATA_HIGH = 0x01,
};
/* sunxi pin interrupt trigger mode */
enum sunxi_pin_int_trigger_mode {
SUNXI_PIN_EINT_POSITIVE_EDGE = 0x0,
SUNXI_PIN_EINT_NEGATIVE_EDGE = 0x1,
SUNXI_PIN_EINT_HIGN_LEVEL = 0x2,
SUNXI_PIN_EINT_LOW_LEVEL = 0x3,
SUNXI_PIN_EINT_DOUBLE_EDGE = 0x4
};
/* the source clock of pin int */
enum sunxi_pin_int_source_clk {
SUNXI_PIN_INT_SRC_CLK_32K = 0x0,
SUNXI_PIN_INT_SRC_CLK_24M = 0x1
};
static inline int sunxi_gpio_to_name(int gpio, char *name)
{
int bank, index;
if (!name) {
return -EINVAL;
}
if (IS_AXP_PIN(gpio)) {
/* axp gpio name like this : GPIO0/GPIO1/.. */
index = gpio - AXP_PIN_BASE;
sprintf(name, "GPIO%d", index);
} else {
/* sunxi gpio name like this : PA0/PA1/PB0 */
bank = gpio / SUNXI_BANK_SIZE;
index = gpio % SUNXI_BANK_SIZE;
sprintf(name, "P%c%d", ('A' + bank), index);
}
return 0;
}
#endif /* __SUNXI_MACH_GPIO_H */
测试代码
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
int main(int argc, char** argv)
{
int fd;
char LED_ON=1,LED_OFF=0,flag=0;
fd = open("/dev/tldev", O_RDWR);
if (fd < 0)
{
perror("open");
}
while (1)
{
write(fd,&LED_ON,1); //led灯亮
sleep(1);
write(fd,&LED_OFF,1); //led灯灭
sleep(1);
}
return 0;
}
运行后LED交替亮灭1s
本人已经验证成功
应用点灯
应用层直接用C操作
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
#define GPIO_REG_BASE 0x01C20800 //GPIO物理基地址 (小页4kb)
#define MAP_SIZE 0x400 //MMU页大小
#define GPIO_BASE_OFFSET (GPIO_REG_BASE & 0X00000FFF) //GPIO基地址偏移计算
#define GPIO_PAGE_OFFSET (GPIO_REG_BASE & 0XFFFFF000) //获得页偏移
/**********************修改的************************/
#define rPB_CFG0 0X24 //PB_CFG0寄存器地址偏移
#define rPB_DAT 0X34 //PB_DAT寄存器地址偏移
/***************************************************/
int led_on(unsigned char *MAP_BASE);
int led_off(unsigned char *MAP_BASE);
int main(int argc, char **argv)
{
static int dev_fd;
unsigned char *map_base;
if(argc!=2 || (strcmp(argv[1],"on") && strcmp(argv[1],"off"))){
printf("argv_error!please input 'on' or 'off'!\n");
exit (0);
}
dev_fd = open("/dev/mem", O_RDWR );
if (dev_fd < 0){
printf("open(/dev/mem) failed.\n");
return 0;
}
map_base = (unsigned char *)mmap(NULL, 0x400,PROT_READ | PROT_WRITE, MAP_SHARED,dev_fd, GPIO_PAGE_OFFSET); //把物理地址映射到虚拟地址
if(!strcmp(argv[1],"on")) led_on(map_base); //点亮LED
if(!strcmp(argv[1],"off")) led_off(map_base);//关闭LED
if(dev_fd) close(dev_fd);
munmap(map_base,MAP_SIZE);//解除映射关系
return 0;
}
//led_on
int led_on(unsigned char *MAP_BASE)
{
unsigned int PB_CFG0,PB_DAT;
PB_CFG0=*(volatile unsigned int *)(MAP_BASE+GPIO_BASE_OFFSET+rPB_CFG0);
PB_DAT=*(volatile unsigned int *)(MAP_BASE+GPIO_BASE_OFFSET+rPB_DAT);
*(volatile unsigned int *)(MAP_BASE+GPIO_BASE_OFFSET+rPB_CFG0)=((PB_CFG0 & 0XFF0FFFFF)|0X00100000);//PB5 第6个引脚
*(volatile unsigned int *)(MAP_BASE+GPIO_BASE_OFFSET+rPB_DAT)=((PB_DAT & 0XFFFFFFDF)|0X00000020);
}
//led_off
int led_off(unsigned char *MAP_BASE)
{
unsigned int PB_CFG0,PB_DAT;
PB_CFG0=*(volatile unsigned int *)(MAP_BASE+GPIO_BASE_OFFSET+rPB_CFG0);
PB_DAT=*(volatile unsigned int *)(MAP_BASE+GPIO_BASE_OFFSET+rPB_DAT);
*(volatile unsigned int *)(MAP_BASE+GPIO_BASE_OFFSET+rPB_CFG0)=((PB_CFG0 & 0XFF0FFFFF)|0X00100000);//PB5 第6个引脚
*(volatile unsigned int *)(MAP_BASE+GPIO_BASE_OFFSET+rPB_DAT)=((PB_DAT & 0XFFFFFFDF));
}
编译运行
arm-linux-gnueabihf-gcc led.c -o led
./led on
./led off
make 获取led.ko 和可执行的led_test 弄到板子上
先查看已经注册的设备号 发现里面没有200
root@lzq:/test# cat /proc/devices
Character devices:
1 mem
2 pty
3 ttyp
4 /dev/vc/0
4 tty
4 ttyS
5 /dev/tty
5 /dev/console
5 /dev/ptmx
7 vcs
10 misc
13 input
14 sound
29 fb
81 video4linux
89 i2c
90 mtd
116 alsa
128 ptm
136 pts
180 usb
189 usb_device
212 DVB
226 drm
248 rpmb
249 ttyGS
250 bsg
251 watchdog
252 media
253 rtc
254 gpiochip
Block devices:
8 sd
65 sd
66 sd
67 sd
68 sd
69 sd
70 sd
71 sd
128 sd
129 sd
130 sd
131 sd
132 sd
133 sd
134 sd
135 sd
179 mmc
259 blkext
root@lzq:/test#
加载内核驱动 再次查看 出现200 myled
root@lzq:/test# insmod led.ko
root@lzq:/test# cat /proc/devices
Character devices:
1 mem
2 pty
3 ttyp
4 /dev/vc/0
4 tty
4 ttyS
5 /dev/tty
5 /dev/console
5 /dev/ptmx
7 vcs
10 misc
13 input
14 sound
29 fb
81 video4linux
89 i2c
90 mtd
116 alsa
128 ptm
136 pts
180 usb
189 usb_device
200 myled
212 DVB
226 drm
248 rpmb
249 ttyGS
250 bsg
251 watchdog
252 media
253 rtc
254 gpiochip
创建设备
root@lzq:/test# mknod /dev/myled c 200 0
root@lzq:/test# ls /dev/myled
/dev/myled
root@lzq:/test#
测试
root@lzq:/test# ./led_test /dev/myled on
root@lzq:/test# ./led_test /dev/myled off
root@lzq:/test#
创建脚本测试
vim run.sh
chmod +x run.sh
./run.sh
run.sh
#!/bin/bash
while(true)
do
./led_test /dev/myled on
sleep 0.3
./led_test /dev/myled off
sleep 0.3
done
效果(PB5是屏幕背光的引脚)
卸载驱动 删除设备
rmmod myled
rm /dev/myled
全志V3s V3x F1C200S等都适用
驱动点灯
led.c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#define DEV_MAJOR 200 /* 主设备号 */
#define DEV_NAME "myled" /* 设备名 */
#define PB_CFG0_REG 0x01C20800 + 1 * 0x24 //PB配置寄存器 A:0 B:1 C:2 ....
#define PB_DATA_REG 0x01C20800 + 1 * 0x34 //PB数据寄存器 A:0 B:1 C:2 ....
#define PIN_N 5 //第5个引脚
#define N (PIN_N % 8 * 4) //引脚x : x % 8 * 4
volatile unsigned int *gpio_con = NULL;
volatile unsigned int *gpio_dat = NULL;
/*打开设备*/
static int led_open (struct inode *node, struct file *filp)
{
if (gpio_con) {
/*打开成功*/
}
else {
return -1;
}
return 0;
}
/*写设备*/
static ssize_t led_write (struct file *filp, const char __user *buf, size_t size, loff_t *off)
{
unsigned char val;
copy_from_user(&val, buf, 1);
if (val)
{
*gpio_dat |= (1 << PIN_N);//引脚5设置1
}
else
{
*gpio_dat &= ~(1 << PIN_N);//引脚5设置0
}
return 1;
}
/*关闭设备*/
static int led_release (struct inode *node, struct file *filp)
{
return 0;
}
/*
* 设备操作函数结构体
*/
static struct file_operations myled_oprs = {
.owner = THIS_MODULE,
.open = led_open,
.write = led_write,
.release = led_release,
};
/* 设备初始化 */
static int myled_init(void)
{
int ret;
ret = register_chrdev(DEV_MAJOR, DEV_NAME, &myled_oprs);
if (ret < 0) {
printk(KERN_ERR "fail\n");
return -1;
}
printk(KERN_ERR "init \n");
gpio_con = (volatile unsigned int *)ioremap(PB_CFG0_REG, 1);
//选择1
gpio_dat = (volatile unsigned int *)ioremap(PB_DATA_REG, 1);
//选择2
//gpio_dat = gpio_con + 4; //数据寄存器 指针+4是移动了4*4=16个字节 原来是0x24 现在是0x34
*gpio_con &= ~(7 << N); //7=111 取反000 20:22设置000 默认是0x7=111 失能
*gpio_con |= (1 << N); //设置输出 20:22设置001
*gpio_dat &= ~(1 << PIN_N); //第5个引脚初始化设置0
return 0;
}
static void __exit myled_exit(void)
{
/* 注销字符设备驱动 */
unregister_chrdev(DEV_MAJOR, DEV_NAME);
printk("exit!\r\n");
}
//注册模块加载函数
module_init(myled_init);
//卸载模块加载函数
module_exit(myled_exit);
//开源信息
MODULE_LICENSE("GPL");
//作者
MODULE_AUTHOR("Lv129");
Makefile
ifneq ($(KERNELRELEASE),)
#kbuild syntax. dependency relationshsip of files and target modules are listed here.
obj-m := led.o
else
PWD:= $(shell pwd)
KDIR := /home/lzq/desktop/129/linux-5.10
all:
$(MAKE) -C $(KDIR) M=$(PWD) modules
rm -rf .*.cmd *.o *.mod.c .tmp_versions *.mod *.symvers *.order
clean:
rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions *.mod *.symvers *.order
endif
测试应用
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
/* ledtest on
* * ledtest off
* */
int main(int argc, char **argv)
{
int fd;
int a;
unsigned char val = 1;
if (argc != 3)
{
printf("Usage :\n");
printf("%s your_dev <on|off>\n", argv[0]);
return 0;
}
fd = open(argv[1], O_RDWR);
if (fd < 0)
{
printf("can't open!\n");
}
if (strcmp(argv[2], "on") == 0)
{
val = 1;
}
else
{
val = 0;
}
write(fd, &val, 1);
/* 关闭设备 */
a = close(fd);
if(a < 0){
printf("Can't\r\n");
return -1;
}
return 0;
}
Makefile
EXEC = led_test
OBJS = led_test.o
CROSS = arm-linux-gnueabihf-
CC = $(CROSS)gcc
STRIP = $(CROSS)strip
CFLAGS = -Wall -g -O2
all: clean $(EXEC)
$(EXEC):$(OBJS)
$(CC) $(CFLAGS) -o $@ $(OBJS)
$(STRIP) $@
clean:
-rm -f $(EXEC) *.o
uboot
https://gitee.com/byleefei/uboot-2021.07-v3x
make ARCH=arm mipi-v3x_defconfig
make ARCH=arm menuconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j12
时钟源码
clock.zip
#ifndef WIDGET_H
#define WIDGET_H
#include <QMainWindow>
#include<QPainter>
#include <QTimer>
#include <QTime>
#include <QWidget>
#include <QtMath>
namespace Ui {
class Widget;
}
class Widget : public QMainWindow
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr);
~Widget();
void paintEvent(QPaintEvent *);
//定义文本区域
QRectF textRectF(double r,int pointSize,double angle);
private slots:
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));//更新界面
timer->start(1000);//每秒更新一次界面
}
Widget::~Widget()
{
delete ui;
}
void Widget::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
//获取系统时间
QTime time = QTime::currentTime();
// 时针、分针、秒针位置 - 多边形
static const QPoint hourHand[3] = {
QPoint(7, 8),
QPoint(-7, 8),
QPoint(0, -30)
};
static const QPoint minuteHand[3] = {
QPoint(7, 8),
QPoint(-7, 8),
QPoint(0, -65)
};
static const QPoint secondHand[3] = {
QPoint(7, 8),
QPoint(-7, 8),
QPoint(0, -80)
};
// 时针、分针、秒针颜色
QColor hourColor(200, 100, 0, 200);
QColor minuteColor(0, 127, 127, 150);
QColor secondColor(0, 160, 230, 150);
int side = qMin(width(), height());
//获取窗口信息
QPainter painter(this);
//设置抗锯齿,精度越高,效率越低
painter.setRenderHint(QPainter::Antialiasing);
// 平移坐标系原点至中心点
painter.translate(width() / 2, height() / 2);
// 缩放
painter.scale(side / 200.0, side / 200.0);
// 绘制时针
painter.setPen(Qt::NoPen);
painter.setBrush(hourColor);
painter.save();
// 每圈360° = 12h 即:旋转角度 = 小时数 * 30°
painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0)));
painter.drawConvexPolygon(hourHand, 3);
painter.restore();
// 绘制小时线 (360度 / 12 = 30度)
painter.setPen(hourColor);
for (int i = 0; i < 12; ++i) {
painter.drawLine(88, 0, 96, 0);
painter.rotate(30.0);
}
int radius = 100;
QFont font = painter.font();
font.setBold(true);//字体加粗
painter.setFont(font);
int pointSize = font.pointSize();
// 绘制小时文本
int nHour = 0;
for (int i = 0; i < 12; ++i) {
nHour = i + 3;//原点变了,从3绘制(旋转0°)
if (nHour > 12) nHour -= 12;//13 14 -> 1 2
//在中心绘制
painter.drawText(textRectF(radius*0.8, pointSize, i * 30), Qt::AlignCenter, QString::number(nHour));
}
painter.setPen(Qt::NoPen);
// 绘制分针
painter.setBrush(minuteColor);
painter.save();
// 每圈360° = 60m 即:旋转角度 = 分钟数 * 6°
painter.rotate(6.0 * (time.minute() + time.second() / 60.0));
painter.drawConvexPolygon(minuteHand, 3);
painter.restore();
// 绘制分钟线 (360度 / 60 = 6度)
painter.setPen(minuteColor);
for (int j = 0; j < 60; ++j) {
if ((j % 5) != 0)
painter.drawLine(92, 0, 96, 0);
painter.rotate(6.0);
}
// 绘制秒针
painter.setPen(Qt::NoPen);
painter.setBrush(secondColor);
painter.save();
// 每圈360° = 60s 即:旋转角度 = 秒数 * 6°
painter.rotate(6.0 * time.second());//旋转图像
painter.drawConvexPolygon(secondHand, 3);
painter.restore();
}
//绘制文本区域
//输入半径,区域大小,角度
QRectF Widget::textRectF(double r, int pointSize, double angle)
{
QRectF rectF;
rectF.setX(r*qCos(angle*M_PI/180.0) - pointSize*2);
rectF.setY(r*qSin(angle*M_PI/180.0) - pointSize/2.0);
rectF.setWidth(pointSize*4);
rectF.setHeight(pointSize);
return rectF;
}
百度语音识别Qt源码
baiduSpeech.zip
usb摄像头源码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <ctype.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <asm/types.h>
#include <linux/videodev2.h>
#include <linux/fb.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <poll.h>
#include <math.h>
#include <wchar.h>
#include <time.h>
#include <stdbool.h>
#define CAM_WIDTH 320
#define CAM_HEIGHT 240
static char *dev_video;
static char *dev_fb0;
static char *yuv_buffer;
static char *rgb_buffer;
typedef unsigned int u32;
typedef unsigned short u16;
typedef unsigned char u8;
#define YUVToRGB(Y) \
((u16)((((u8)(Y) >> 3) << 11) | (((u8)(Y) >> 2) << 5) | ((u8)(Y) >> 3)))
struct v4l2_buffer video_buffer;
/*全局变量*/
int lcd_fd;
int video_fd;
unsigned char *lcd_mem_p = NULL; //保存LCD屏映射到进程空间的首地址
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
char *video_buff_buff[4]; /*保存摄像头缓冲区的地址*/
int video_height = 0;
int video_width = 0;
unsigned char *lcd_display_buff; //LCD显存空间
unsigned char *lcd_display_buff2; //LCD显存空间
static void errno_exit(const char *s)
{
fprintf(stderr, "%s error %d, %s\n", s, errno, strerror(errno));
exit(EXIT_FAILURE);
}
static int xioctl(int fh, int request, void *arg)
{
int r;
do {
r = ioctl(fh, request, arg);
} while (-1 == r && EINTR == errno);
return r;
}
static int video_init(void)
{
struct v4l2_capability cap;
ioctl(video_fd, VIDIOC_QUERYCAP, &cap);
struct v4l2_fmtdesc dis_fmtdesc;
dis_fmtdesc.index = 0;
dis_fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
// printf("-----------------------支持格式---------------------\n");
// while (ioctl(video_fd, VIDIOC_ENUM_FMT, &dis_fmtdesc) != -1) {
// printf("\t%d.%s\n", dis_fmtdesc.index + 1,
// dis_fmtdesc.description);
// dis_fmtdesc.index++;
// }
struct v4l2_format video_format;
video_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
video_format.fmt.pix.width = CAM_WIDTH;
video_format.fmt.pix.height = CAM_HEIGHT;
video_format.fmt.pix.pixelformat =
V4L2_PIX_FMT_YUYV; //使用JPEG格式帧,用于静态图像采集
ioctl(video_fd, VIDIOC_S_FMT, &video_format);
printf("当前摄像头支持的分辨率:%dx%d\n", video_format.fmt.pix.width,
video_format.fmt.pix.height);
if (video_format.fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV) {
printf("当前摄像头不支持YUYV格式输出.\n");
video_height = video_format.fmt.pix.height;
video_width = video_format.fmt.pix.width;
//return -3;
} else {
video_height = video_format.fmt.pix.height;
video_width = video_format.fmt.pix.width;
printf("当前摄像头支持YUYV格式输出.width %d height %d\n",
video_height, video_height);
}
/*3. 申请缓冲区*/
struct v4l2_requestbuffers video_requestbuffers;
memset(&video_requestbuffers, 0, sizeof(struct v4l2_requestbuffers));
video_requestbuffers.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
video_requestbuffers.count = 4;
video_requestbuffers.memory = V4L2_MEMORY_MMAP;
if (ioctl(video_fd, VIDIOC_REQBUFS, &video_requestbuffers))
return -4;
printf("成功申请的缓冲区数量:%d\n", video_requestbuffers.count);
/*4. 得到每个缓冲区的地址: 将申请的缓冲区映射到进程空间*/
struct v4l2_buffer video_buffer;
memset(&video_buffer, 0, sizeof(struct v4l2_buffer));
int i;
for (i = 0; i < video_requestbuffers.count; i++) {
video_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
video_buffer.index = i;
video_buffer.memory = V4L2_MEMORY_MMAP;
if (ioctl(video_fd, VIDIOC_QUERYBUF, &video_buffer))
return -5;
/*映射缓冲区的地址到进程空间*/
video_buff_buff[i] =
mmap(NULL, video_buffer.length, PROT_READ | PROT_WRITE,
MAP_SHARED, video_fd, video_buffer.m.offset);
printf("第%d个缓冲区地址:%#X\n", i, video_buff_buff[i]);
}
/*5. 将缓冲区放入到采集队列*/
memset(&video_buffer, 0, sizeof(struct v4l2_buffer));
for (i = 0; i < video_requestbuffers.count; i++) {
video_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
video_buffer.index = i;
video_buffer.memory = V4L2_MEMORY_MMAP;
if (ioctl(video_fd, VIDIOC_QBUF, &video_buffer)) {
printf("VIDIOC_QBUF error\n");
return -6;
}
}
printf("启动摄像头采集\n");
/*6. 启动摄像头采集*/
int opt_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (ioctl(video_fd, VIDIOC_STREAMON, &opt_type)) {
printf("VIDIOC_STREAMON error\n");
return -7;
}
return 0;
}
int lcd_init(void)
{
/*2. 获取可变参数*/
if (ioctl(lcd_fd, FBIOGET_VSCREENINFO, &vinfo))
return -2;
printf("屏幕X:%d 屏幕Y:%d 像素位数:%d\n", vinfo.xres, vinfo.yres,
vinfo.bits_per_pixel);
//分配显存空间,完成图像显示
lcd_display_buff =
malloc(vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8);
/*3. 获取固定参数*/
if (ioctl(lcd_fd, FBIOGET_FSCREENINFO, &finfo))
return -3;
printf("smem_len=%d Byte,line_length=%d Byte\n", finfo.smem_len,
finfo.line_length);
/*4. 映射LCD屏物理地址到进程空间*/
lcd_mem_p = (unsigned char *)mmap(0, finfo.smem_len,
PROT_READ | PROT_WRITE, MAP_SHARED,
lcd_fd, 0); //从文件的那个地方开始映射
memset(lcd_mem_p, 0xFFFFFFFF, finfo.smem_len);
printf("映射LCD屏物理地址到进程空间\n");
return 0;
}
static void close_device(void)
{
if (-1 == close(video_fd))
errno_exit("close");
video_fd = -1;
if (-1 == close(lcd_fd))
errno_exit("close");
lcd_fd = -1;
}
static void open_device(void)
{
video_fd = open(dev_video, O_RDWR /* required */ | O_NONBLOCK, 0);
if (-1 == video_fd) {
fprintf(stderr, "Cannot open '%s': %d, %s\n", dev_video, errno,
strerror(errno));
exit(EXIT_FAILURE);
}
lcd_fd = open(dev_fb0, O_RDWR, 0);
if (-1 == lcd_fd) {
fprintf(stderr, "Cannot open '%s': %d, %s\n", dev_fb0, errno,
strerror(errno));
exit(EXIT_FAILURE);
}
}
/*
将YUV格式数据转为RGB
*/
void yuv_to_rgb(unsigned char *yuv_buffer, unsigned char *rgb_buffer,
int iWidth, int iHeight)
{
int x;
int z = 0;
unsigned char *ptr = rgb_buffer;
unsigned char *yuyv = yuv_buffer;
for (x = 0; x < iWidth * iHeight; x++) {
int r, g, b;
int y, u, v;
if (!z)
y = yuyv[0] << 8;
else
y = yuyv[2] << 8;
u = yuyv[1] - 128;
v = yuyv[3] - 128;
r = (y + (359 * v)) >> 8;
g = (y - (88 * u) - (183 * v)) >> 8;
b = (y + (454 * u)) >> 8;
*(ptr++) = (b > 255) ? 255 : ((b < 0) ? 0 : b);
*(ptr++) = (g > 255) ? 255 : ((g < 0) ? 0 : g);
*(ptr++) = (r > 255) ? 255 : ((r < 0) ? 0 : r);
if (z++) {
z = 0;
yuyv += 4;
}
}
}
void rgb24_to_rgb565(char *rgb24, char *rgb16)
{
int i = 0, j = 0;
for (i = 0; i < 320 * 240 * 3; i += 3) {
rgb16[j] = rgb24[i] >> 3; // B
rgb16[j] |= ((rgb24[i + 1] & 0x1C) << 3); // G
rgb16[j + 1] = rgb24[i + 2] & 0xF8; // R
rgb16[j + 1] |= (rgb24[i + 1] >> 5); // G
j += 2;
}
}
int main(int argc, char **argv)
{
dev_video = argv[1];
dev_fb0 = "/dev/fb0";
open_device();
video_init();
lcd_init();
/*3. 读取摄像头的数据*/
struct pollfd video_fds;
video_fds.events = POLLIN;
video_fds.fd = video_fd;
memset(&video_buffer, 0, sizeof(struct v4l2_buffer));
rgb_buffer = malloc(CAM_WIDTH * CAM_HEIGHT * 3);
yuv_buffer = malloc(CAM_WIDTH * CAM_HEIGHT * 3);
unsigned char *rgb_p;
int w, h, i, j;
unsigned char r, g, b;
unsigned int c;
while (1) {
/*等待摄像头采集数据*/
poll(&video_fds, 1, -1);
/*得到缓冲区的编号*/
video_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
video_buffer.memory = V4L2_MEMORY_MMAP;
ioctl(video_fd, VIDIOC_DQBUF, &video_buffer);
//printf("当前采集OK的缓冲区编号:%d,地址:%#X num:%d\n",
// video_buffer.index, video_buff_buff[video_buffer.index],
// strlen(video_buff_buff[video_buffer.index]));
/*对缓冲区数据进行处理*/
yuv_to_rgb(video_buff_buff[video_buffer.index], yuv_buffer,
video_height, video_width);
rgb24_to_rgb565(yuv_buffer, rgb_buffer);
//printf("显示屏进行显示\n");
//显示屏进行显示: 将显存空间的数据拷贝到LCD屏进行显示
memcpy(lcd_mem_p, rgb_buffer,
vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8);
/*将缓冲区放入采集队列*/
ioctl(video_fd, VIDIOC_QBUF, &video_buffer);
//printf("将缓冲区放入采集队列\n");
}
/*4. 关闭视频设备*/
close(video_fd);
return 0;
}
@twzy
另问V3x目前有没有比较容易上手的TF卡镜像呢?
自制的,有问题麻烦说一下
适用于 https://whycan.com/t_7522.html 中的mipi-v3x
链接:
https://pan.baidu.com/s/1GhGtAKwBWQI940ZrbjnovA
提取码:pjs3
注意:
镜像连不上wifi会一直卡在那里
建议烧录完镜像后,在虚拟机里改下wifi名称和密码,顺便扩容
或者把手机热点wifi的名称密码改成楼下图里的
我也根据大佬的思路做了一个V3s的小电脑,大佬可以说说那个EDX桌面操作怎么处理吗,我弄了一个太卡了
试试这个程序?
armgcc编译弄到板子上运行
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/fb.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <stdlib.h>
static int fd_fb;
static struct fb_var_screeninfo var; /* Current var */
static struct fb_fix_screeninfo finfo;
static int screen_size;
static unsigned char *fb_base;
static unsigned int line_width;
static unsigned int pixel_width;
/**********************************************************************
* 函数名称: lcd_put_pixel
* 功能描述: 在LCD指定位置上输出指定颜色(描点)
* 输入参数: x坐标,y坐标,颜色
* 输出参数: 无
* 返 回 值: 会
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2020/05/12 V1.0 zh(angenao) 创建
***********************************************************************/
void lcd_put_pixel(int x, int y, unsigned int color)
{
unsigned char *pen_8 = fb_base+y*line_width+x*pixel_width;
unsigned short *pen_16;
unsigned int *pen_32;
unsigned int red, green, blue;
pen_16 = (unsigned short *)pen_8;
pen_32 = (unsigned int *)pen_8;
switch (var.bits_per_pixel)
{
case 8:
{
*pen_8 = color;
break;
}
case 16:
{
/* 565 */
red = (color >> 16) & 0xff;
green = (color >> 8) & 0xff;
blue = (color >> 0) & 0xff;
color = ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3);
*pen_16 = color;
break;
}
case 24:
{
*pen_32=color;
break;
}
case 32:
{
*pen_32 = color;
break;
}
default:
{
printf("can't surport %dbpp\n", var.bits_per_pixel);
break;
}
}
}
int main(int argc, char **argv)
{
int i,j;
fd_fb = open("/dev/fb0", O_RDWR);
if (fd_fb < 0)
{
printf("can't open /dev/fb0\n");
return -1;
}
if (ioctl(fd_fb, FBIOGET_VSCREENINFO, &var))
{
printf("can't get var\n");
return -1;
}
if (ioctl(fd_fb,FBIOGET_FSCREENINFO,&finfo))
{
printf("Error reading fixed information\n");
exit(-1);
}
//显示结构体信息
printf("The mem is :%d\n",finfo.smem_len);
printf("The line_length is :%d\n",finfo.line_length);
printf("The xres is :%d\n",var.xres);
printf("The yres is :%d\n",var.yres);
printf("bits_per_pixel is :%d\n",var.bits_per_pixel);
line_width = var.xres * var.bits_per_pixel / 8;
pixel_width = var.bits_per_pixel / 8;
//计算显存大小
screen_size = var.xres * var.yres * var.bits_per_pixel / 8;
/*这就是把fp所指的文件中从开始到screensize大小的内容给映射出来,得到一个指向这块空间的指针*/
fb_base = (unsigned char *)mmap(NULL , screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);
if (fb_base == (unsigned char *)-1)
{
printf("can't mmap\n");
return -1;
}
/* 清屏: 全部设为白色 */
memset(fb_base, 0xff, screen_size);
for(i = 0 ; i < var.xres/2 ; i++)
for(j = 0 ; j < var.yres/2 ; j++)
lcd_put_pixel(i,j, 0xFF0000); //设为红色
for(i = var.xres/2 ; i < var.xres ; i++)
for(j = var.yres/2 ; j < var.yres ; j++)
lcd_put_pixel(i,j, 0xFF0000); //设为红色
munmap(fb_base , screen_size);/*解除映射*/
close(fd_fb); /*关闭文件*/
return 0;
}
@夜阑卧听
chmod +x qmake
qmake -v看看
lzq@lzq:/opt$ cd qt5.12
lzq@lzq:/opt/qt5.12$ cd bin/
lzq@lzq:/opt/qt5.12/bin$ ls
canbusutil qlalr qmlcachegen qmlmin qmltestrunner syncqt.pl
fixqt4headers.pl qmake qmlimportscanner qmlpreview qvkgen uic
moc qml qmllint qmlscene rcc
lzq@lzq:/opt/qt5.12/bin$ ./qmake -v
QMake version 3.1
Using Qt version 5.12.9 in /opt/qt5.12/lib
lzq@lzq:/opt/qt5.12/bin$
问题:
荔枝派nano/全志F1C100S/F1C200S无法运行官方交叉编译工具编译出的可执行程序
解决:
sudo apt-get install gcc-arm-linux-gnueabi g++-arm-linux-gnueabi
arm-linux-gnueabi-gcc Framebuffer.c -o Framebuffer
结果:
root@ubuntu-VirtualBox:/# rz
root@ubuntu-VirtualBox:/# chmod 777 Framebuffer
root@ubuntu-VirtualBox:/# ./Framebuffer
The mem is :1536000
The line_length is :3200
The xres is :800
The yres is :480
bits_per_pixel is :32
root@ubuntu-VirtualBox:/#
0.获取源码
下载linux5.2:https://github.com/Lichee-Pi/linux/archive/nano-5.2-tf.zip
解压:
unzip nano-5.2-tf.zip
进入linux目录下:
cd linux-nano-5.2-tf
1.打补丁
usb.patch 20楼
vim usb.patch
patch -p1 < usb.patch
2.替换config文件
不替换make不生成设备树
config文件 24楼
vim .config
删除所有,复制24楼的config,保存
3.编译
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j12
资本家大善人 说:@树莓学LINUX
印象里好像不用,只设置了个控制台,7楼
这个很详细
https://blog.csdn.net/qq_28877125/article/details/120007416开启双端显示后 屏幕能正常显示了 难道在使用串口的时候 屏幕默认不显示吗
能的,双端显示,双端控制
报错
binman: Node '/binman/u-boot-img': Entry contents size is 0xa6fb1 (683953) but entry size is 0x76000 (483328)
Makefile:1148: recipe for target 'u-boot-sunxi-with-spl.bin' failed
make: *** [u-boot-sunxi-with-spl.bin] Error 1
解决
make ARCH=arm menuconfig
Environment --->
Select the location of the environment (Environment in an MMC│
(0xf0000) Environment Offset
(0x8000) Environment Size
结果
OBJCOPY spl/u-boot-spl-nodtb.bin
COPY spl/u-boot-spl.bin
MKSUNXI spl/sunxi-spl.bin
BINMAN u-boot-sunxi-with-spl.bin
正常
USB已搞定,device模式是ACM + ETH复合设备,放上SDKhttps://pan.baidu.com/s/1mJl7M4W3RvlqyHt26JgpVA
百度云失效了能重新发一个吗
连不上,呜呜呜
# ifconfig wlan0 up
# ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
wlan0 Link encap:Ethernet HWaddr AC:D0:74:D3:F8:A8
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
# wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant.conf
Successfully initialized wpa_supplicant
rfkill: Cannot open RFKILL control device
@树莓学LINUX
印象里好像不用,只设置了个控制台,7楼
这个很详细
https://blog.csdn.net/qq_28877125/article/details/120007416
@摸鱼moyu
https://whycan.com/p_70521.html#p70521
我也遇到了,以及解决了
lzq@lzq:~/desktop/nano$ sudo sunxi-fel ver
AWUSBFEX soc=00001663(unknown) 00000001 ver=0001 44 08 scratchpad=00007e00 00000000 00000000
使用官方提供的sunxi-tools-f1c100s-spiflash工具即可解决
lzq@lzq:~/desktop/nano$ sudo sunxi-fel ver
AWUSBFEX soc=00001663(F1C100s) 00000001 ver=0001 44 08 scratchpad=00007e00 00000000 00000000
lzq@lzq:~/desktop/nano$ sudo sunxi-fel -p spiflash-write 0 Nano_flash_800480.bin
100% [================================================] 16777 kB, 53.1 kB/s
sunxi-tools-f1c100s-spiflash工具如下
sunxi-tools-f1c100s-spiflash.zip
@thanksgivingday
// SPDX-License-Identifier: GPL-2.0+
/*
* FB driver for the ST7789V LCD Controller
*
* Copyright (C) 2015 Dennis Menschel
*/
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <video/mipi_display.h>
#include "fbtft.h"
#define DRVNAME "fb_st7789v"
#define DEFAULT_GAMMA \
"70 2C 2E 15 10 09 48 33 53 0B 19 18 20 25\n" \
"70 2C 2E 15 10 09 48 33 53 0B 19 18 20 25"
#define HSD20_IPS_GAMMA \
"D0 05 0A 09 08 05 2E 44 45 0F 17 16 2B 33\n" \
"D0 05 0A 09 08 05 2E 43 45 0F 16 16 2B 33"
#define HSD20_IPS 1
/**
* enum st7789v_command - ST7789V display controller commands
*
* @PORCTRL: porch setting
* @GCTRL: gate control
* @VCOMS: VCOM setting
* @VDVVRHEN: VDV and VRH command enable
* @VRHS: VRH set
* @VDVS: VDV set
* @VCMOFSET: VCOM offset set
* @PWCTRL1: power control 1
* @PVGAMCTRL: positive voltage gamma control
* @NVGAMCTRL: negative voltage gamma control
*
* The command names are the same as those found in the datasheet to ease
* looking up their semantics and usage.
*
* Note that the ST7789V display controller offers quite a few more commands
* which have been omitted from this list as they are not used at the moment.
* Furthermore, commands that are compliant with the MIPI DCS have been left
* out as well to avoid duplicate entries.
*/
enum st7789v_command {
PORCTRL = 0xB2,
GCTRL = 0xB7,
VCOMS = 0xBB,
VDVVRHEN = 0xC2,
VRHS = 0xC3,
VDVS = 0xC4,
VCMOFSET = 0xC5,
PWCTRL1 = 0xD0,
PVGAMCTRL = 0xE0,
NVGAMCTRL = 0xE1,
};
#define MADCTL_BGR BIT(3) /* bitmask for RGB/BGR order */
#define MADCTL_MV BIT(5) /* bitmask for page/column order */
#define MADCTL_MX BIT(6) /* bitmask for column address order */
#define MADCTL_MY BIT(7) /* bitmask for page address order */
/**
* init_display() - initialize the display controller
*
* @par: FBTFT parameter object
*
* Most of the commands in this init function set their parameters to the
* same default values which are already in place after the display has been
* powered up. (The main exception to this rule is the pixel format which
* would default to 18 instead of 16 bit per pixel.)
* Nonetheless, this sequence can be used as a template for concrete
* displays which usually need some adjustments.
*
* Return: 0 on success, < 0 if error occurred.
*/
static int init_display(struct fbtft_par *par)
{
par->fbtftops.reset(par);
/* turn off sleep mode */
write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE);
mdelay(120);
/* set pixel format to RGB-565 */
write_reg(par, MIPI_DCS_SET_PIXEL_FORMAT, MIPI_DCS_PIXEL_FMT_16BIT);
if (HSD20_IPS)
write_reg(par, PORCTRL, 0x05, 0x05, 0x00, 0x33, 0x33);
else
write_reg(par, PORCTRL, 0x08, 0x08, 0x00, 0x22, 0x22);
/*
* VGH = 13.26V
* VGL = -10.43V
*/
if (HSD20_IPS)
write_reg(par, GCTRL, 0x75);
else
write_reg(par, GCTRL, 0x35);
/*
* VDV and VRH register values come from command write
* (instead of NVM)
*/
write_reg(par, VDVVRHEN, 0x01, 0xFF);
/*
* VAP = 4.1V + (VCOM + VCOM offset + 0.5 * VDV)
* VAN = -4.1V + (VCOM + VCOM offset + 0.5 * VDV)
*/
if (HSD20_IPS)
write_reg(par, VRHS, 0x13);
else
write_reg(par, VRHS, 0x0B);
/* VDV = 0V */
write_reg(par, VDVS, 0x20);
/* VCOM = 0.9V */
if (HSD20_IPS)
write_reg(par, VCOMS, 0x22);
else
write_reg(par, VCOMS, 0x20);
/* VCOM offset = 0V */
write_reg(par, VCMOFSET, 0x20);
/*
* AVDD = 6.8V
* AVCL = -4.8V
* VDS = 2.3V
*/
write_reg(par, PWCTRL1, 0xA4, 0xA1);
write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
if (HSD20_IPS)
write_reg(par, MIPI_DCS_ENTER_INVERT_MODE);
return 0;
// par->fbtftops.reset(par);
// mdelay(50);
// write_reg(par,0x36,0x00);
// write_reg(par,0x3A,0x05);
// write_reg(par,0xB2,0x0C,0x0C,0x00,0x33,0x33);
// write_reg(par,0xB7,0x35);
// write_reg(par,0xBB,0x19);
// write_reg(par,0xC0,0x2C);
// write_reg(par,0xC2,0x01);
// write_reg(par,0xC3,0x12);
// write_reg(par,0xC4,0x20);
// write_reg(par,0xC6,0x0F);
// write_reg(par,0xD0,0xA4,0xA1);
// write_reg(par,0xE0,0xD0,0x04,0x0D,0x11,0x13,0x2B,0x3F,0x54,0x4C,0x18,0x0D,0x0B,0x1F,0x23);
// write_reg(par,0xE1,0xD0,0x04,0x0C,0x11,0x13,0x2C,0x3F,0x44,0x51,0x2F,0x1F,0x1F,0x20,0x23);
// write_reg(par,0x21);
// write_reg(par,0x11);
// mdelay(50);
// write_reg(par,0x29);
// mdelay(200);
// return 0;
}
/**
* set_var() - apply LCD properties like rotation and BGR mode
*
* @par: FBTFT parameter object
*
* Return: 0 on success, < 0 if error occurred.
*/
static int set_var(struct fbtft_par *par)
{
u8 madctl_par = 0;
if (par->bgr)
madctl_par |= MADCTL_BGR;
switch (par->info->var.rotate) {
case 0:
break;
case 90:
madctl_par |= (MADCTL_MV | MADCTL_MY);
break;
case 180:
madctl_par |= (MADCTL_MX | MADCTL_MY);
break;
case 270:
madctl_par |= (MADCTL_MV | MADCTL_MX);
break;
default:
return -EINVAL;
}
write_reg(par, MIPI_DCS_SET_ADDRESS_MODE, madctl_par);
return 0;
}
/**
* set_gamma() - set gamma curves
*
* @par: FBTFT parameter object
* @curves: gamma curves
*
* Before the gamma curves are applied, they are preprocessed with a bitmask
* to ensure syntactically correct input for the display controller.
* This implies that the curves input parameter might be changed by this
* function and that illegal gamma values are auto-corrected and not
* reported as errors.
*
* Return: 0 on success, < 0 if error occurred.
*/
static int set_gamma(struct fbtft_par *par, u32 *curves)
{
int i;
int j;
int c; /* curve index offset */
/*
* Bitmasks for gamma curve command parameters.
* The masks are the same for both positive and negative voltage
* gamma curves.
*/
static const u8 gamma_par_mask[] = {
0xFF, /* V63[3:0], V0[3:0]*/
0x3F, /* V1[5:0] */
0x3F, /* V2[5:0] */
0x1F, /* V4[4:0] */
0x1F, /* V6[4:0] */
0x3F, /* J0[1:0], V13[3:0] */
0x7F, /* V20[6:0] */
0x77, /* V36[2:0], V27[2:0] */
0x7F, /* V43[6:0] */
0x3F, /* J1[1:0], V50[3:0] */
0x1F, /* V57[4:0] */
0x1F, /* V59[4:0] */
0x3F, /* V61[5:0] */
0x3F, /* V62[5:0] */
};
for (i = 0; i < par->gamma.num_curves; i++) {
c = i * par->gamma.num_values;
for (j = 0; j < par->gamma.num_values; j++)
curves[c + j] &= gamma_par_mask[j];
write_reg(par, PVGAMCTRL + i,
curves[c + 0], curves[c + 1], curves[c + 2],
curves[c + 3], curves[c + 4], curves[c + 5],
curves[c + 6], curves[c + 7], curves[c + 8],
curves[c + 9], curves[c + 10], curves[c + 11],
curves[c + 12], curves[c + 13]);
}
return 0;
}
/**
* blank() - blank the display
*
* @par: FBTFT parameter object
* @on: whether to enable or disable blanking the display
*
* Return: 0 on success, < 0 if error occurred.
*/
static int blank(struct fbtft_par *par, bool on)
{
if (on)
write_reg(par, MIPI_DCS_SET_DISPLAY_OFF);
else
write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
return 0;
}
static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
{
// switch(par->info->var.rotate)
// {
// case 0: xs+=53;xe+=53;ys+=40;ye+=40;
// break;
// // case 90: xs+=40;xe+=40;ys+=53;ye+=53;
// case 90: xs+=80;xe+=80;
// break;
// case 180: xs+=53;xe+=53;ys+=40;ye+=40;
// break;
// case 270: xs+=40;xe+=40;ys+=53;ye+=53;
// break;
// default :
// break;
// }
write_reg(par, MIPI_DCS_SET_COLUMN_ADDRESS,
xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF);
write_reg(par, MIPI_DCS_SET_PAGE_ADDRESS,
ys >> 8, ys & 0xFF, ye >> 8, ye & 0xFF);
write_reg(par, MIPI_DCS_WRITE_MEMORY_START);
}
static struct fbtft_display display = {
.regwidth = 8,
.width = 240,
.height = 320,
.gamma_num = 2,
.gamma_len = 14,
.gamma = HSD20_IPS_GAMMA,
.fbtftops = {
.init_display = init_display,
.set_addr_win = set_addr_win,
.set_var = set_var,
.set_gamma = set_gamma,
.blank = blank,
},
};
FBTFT_REGISTER_DRIVER(DRVNAME, "sitronix,st7789v", &display);
MODULE_ALIAS("spi:" DRVNAME);
MODULE_ALIAS("platform:" DRVNAME);
MODULE_ALIAS("spi:st7789v");
MODULE_ALIAS("platform:st7789v");
MODULE_DESCRIPTION("FB driver for the ST7789V LCD Controller");
MODULE_AUTHOR("Dennis Menschel");
MODULE_LICENSE("GPL");
附个Framebuffer程序
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/fb.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <stdlib.h>
static int fd_fb;
static struct fb_var_screeninfo var; /* Current var */
static struct fb_fix_screeninfo finfo;
static int screen_size;
static unsigned char *fb_base;
static unsigned int line_width;
static unsigned int pixel_width;
/**********************************************************************
* 函数名称: lcd_put_pixel
* 功能描述: 在LCD指定位置上输出指定颜色(描点)
* 输入参数: x坐标,y坐标,颜色
* 输出参数: 无
* 返 回 值: 会
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2020/05/12 V1.0 zh(angenao) 创建
***********************************************************************/
void lcd_put_pixel(int x, int y, unsigned int color)
{
unsigned char *pen_8 = fb_base+y*line_width+x*pixel_width;
unsigned short *pen_16;
unsigned int *pen_32;
unsigned int red, green, blue;
pen_16 = (unsigned short *)pen_8;
pen_32 = (unsigned int *)pen_8;
switch (var.bits_per_pixel)
{
case 8:
{
*pen_8 = color;
break;
}
case 16:
{
/* 565 */
red = (color >> 16) & 0xff;
green = (color >> 8) & 0xff;
blue = (color >> 0) & 0xff;
color = ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3);
*pen_16 = color;
break;
}
case 24:
{
*pen_32=color;
break;
}
case 32:
{
*pen_32 = color;
break;
}
default:
{
printf("can't surport %dbpp\n", var.bits_per_pixel);
break;
}
}
}
int main(int argc, char **argv)
{
int i,j;
fd_fb = open("/dev/fb0", O_RDWR);
if (fd_fb < 0)
{
printf("can't open /dev/fb0\n");
return -1;
}
if (ioctl(fd_fb, FBIOGET_VSCREENINFO, &var))
{
printf("can't get var\n");
return -1;
}
if (ioctl(fd_fb,FBIOGET_FSCREENINFO,&finfo))
{
printf("Error reading fixed information\n");
exit(-1);
}
//显示结构体信息
printf("The mem is :%d\n",finfo.smem_len);
printf("The line_length is :%d\n",finfo.line_length);
printf("The xres is :%d\n",var.xres);
printf("The yres is :%d\n",var.yres);
printf("bits_per_pixel is :%d\n",var.bits_per_pixel);
line_width = var.xres * var.bits_per_pixel / 8;
pixel_width = var.bits_per_pixel / 8;
//计算显存大小
screen_size = var.xres * var.yres * var.bits_per_pixel / 8;
/*这就是把fp所指的文件中从开始到screensize大小的内容给映射出来,得到一个指向这块空间的指针*/
fb_base = (unsigned char *)mmap(NULL , screen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);
if (fb_base == (unsigned char *)-1)
{
printf("can't mmap\n");
return -1;
}
/* 清屏: 全部设为白色 */
memset(fb_base, 0xff, screen_size);
for(i = 0 ; i < var.xres/2 ; i++)
for(j = 0 ; j < var.yres/2 ; j++)
lcd_put_pixel(i,j, 0xFF0000); //设为红色
for(i = var.xres/2 ; i < var.xres ; i++)
for(j = var.yres/2 ; j < var.yres ; j++)
lcd_put_pixel(i,j, 0xFF0000); //设为红色
munmap(fb_base , screen_size);/*解除映射*/
close(fd_fb); /*关闭文件*/
return 0;
}
./configure -prefix /opt/A53_qt5.12.9 \
-opensource -confirm-license \
-release \
-strip \
-shared \
-xplatform aarch64 \
-optimized-qmake \
-c++std c++11 \
--rpath=no \
-pch \
-skip qt3d \
-skip qtactiveqt \
-skip qtandroidextras \
-skip qtcanvas3d \
-skip qtconnectivity \
-skip qtdatavis3d \
-skip qtdoc \
-skip qtgamepad \
-skip qtlocation \
-skip qtmacextras \
-skip qtnetworkauth \
-skip qtpurchasing \
-skip qtremoteobjects \
-skip qtscript \
-skip qtscxml \
-skip qtsensors \
-skip qtspeech \
-skip qtsvg \
-skip qttools \
-skip qttranslations \
-skip qtwayland \
-skip qtwebengine \
-skip qtwebview \
-skip qtwinextras \
-skip qtx11extras \
-skip qtxmlpatterns \
-make libs \
-make examples \
-nomake tools -nomake tests \
-gui \
-widgets \
-dbus-runtime \
--glib=no \
--iconv=no \
--pcre=qt \
--zlib=qt \
-no-openssl \
--freetype=qt \
--harfbuzz=qt \
-no-opengl \
-linuxfb \
--xcb=no \
--libpng=qt \
--libjpeg=qt \
--sqlite=qt \
-plugin-sql-sqlite \
-recheck-all
make -jn(n为内核数,如:make -j12)
make install
我12核编译花了半小时,先编译麻烦的可以用我编译好的,见4.Qt移植
H6Qt交叉编译配置
#
# qmake configuration for building with aarch64-linux-gnu-g++
#
MAKEFILE_GENERATOR = UNIX
CONFIG += incremental
QMAKE_INCREMENTAL_STYLE = sublib
QT_QPA_DEFAULT_PLATFORM=linuxfb
QMAKE_CFLAGS_RELEASE += -O2 -march=armv8-a -lts
QMAKE_CXXFLAGS_RELEASE += -O2 -march=armv8-a -lts
include(../common/linux.conf)
include(../common/gcc-base-unix.conf)
include(../common/g++-unix.conf)
# modifications to g++.conf
QMAKE_CC =/opt/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-gcc
QMAKE_CXX =/opt/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-g++
QMAKE_LINK =/opt/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-g++
QMAKE_LINK_SHLIB =/opt/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-g++
# modifications to linux.conf
QMAKE_AR =/opt/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-ar cqs
QMAKE_OBJCOPY =/opt/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-objcopy
QMAKE_NM =/opt/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-nm -P
QMAKE_STRIP =/opt/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-strip
load(qt_config)
5.opencv移植
Qt交叉编译包/opencv包:链接:https://pan.baidu.com/s/1h5EzGjsm0M2pSvjQdO6Z2A 提取码:0jsl
将opencv包分别解压到Ubuntu和泰奇猫(全志H6)的/usr/local下
创建Qt工程,在pro文件里加入
CONFIG += c++11
INCLUDEPATH += /usr/local/include \
/usr/local/A53_opencv/include/opencv \
/usr/local/A53_opencv/include/opencv2
LIBS += /usr/local/A53_opencv/lib/libopencv*.so
用x86的opencv就改成x86的opencv库路径,这个自己去百度学习如何编译,很简单
将编译好的文件传输到泰奇猫(全志H6)上运行
结果如下:
人脸检测Qt工程(包含模型):
人脸检测.zip
注意路径:
4.Qt移植
泰奇猫(全志H6)下
将烧录好的SD卡插入电脑,在Ubuntu下挂载
fdisk -l
然后将Qt交叉编译包解压到/mnt/opt下,即SD卡下的opt目录
取消挂载1)cd / 2)umount /mnt
拔出SD卡,插到泰奇猫(全志H6)上,上电
1)root模式 sudo -s
2)vi /etc/bash.bashrc
在前面添加如下代码
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0
export TSLIB_TSDEVICE=/dev/input/event1
export TSLIB_CONFFILE=/opt/tslib/etc/ts.conf
export TSLIB_PLUGINDIR=/opt/tslib/lib/ts
export TSLIB_CALIBFILE=/etc/pointercal
export LD_LIBRARY_PATH=/lib:/usr/lib:/opt/tslib/lib:/opt/A53_qt5.12.9/lib
export PATH=/bin:/sbin:/usr/bin/:/usr/sbin:/opt/tslib/bin
export QT_QPA_PLATFORM_PLUGIN_PATH=/opt/A53_qt5.12.9/plugins
export QT_QPA_PLATFORM=linuxfb:tty=/dev/fb0
export QT_QPA_FONTDIR=/opt/A53_qt5.12.9/lib/fonts
#export QT_QPA_GENERIC_PLUGINS=tslib:$TSLIB_TSDEVICE
3)source /etc/bash.bashrc
4.Qt移植
我用的Qt5.12(linux下的)
链接:https://pan.baidu.com/s/1H7BDKXv_6QtNnhcyKJ1qaA 提取码:e4w2
安装:1)chmod +x 软件.run 2)./软件.run
Qt交叉编译包/opencv包:链接:https://pan.baidu.com/s/1h5EzGjsm0M2pSvjQdO6Z2A 提取码:0jsl
用tar指令将Qt交叉编译包解压到/opt目录下
照着图片敲指令,结果如图所示,表示以及安装好
linux下Qt交叉编译配置
1.打开Qt,点击实例时钟工程
2.点击Manage Kits...
3.添加全志H6的GCC G++ GDB
4.添加交叉编译好的Qmake
5.创建设备
6.选择我们的设备,编译,无错误即可
3.安装交叉编译工具
Ubuntu下的
地址:https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads
我选的是gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu.tar.xz
解压tar.xz文件:先 xz -d xxx.tar.xz 将 xxx.tar.xz解压成 xxx.tar 然后,再用 tar xvf xxx.tar来解包。
或者 tar -Jxf xxx.tar.xz
root下将gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu移动到/opt目录下
mv gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu /opt
vim /etc/bash.bashrc
最后加入PATH="$PATH:/opt/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin"
source /etc/bash.bashrc
aarch64-none-linux-gnu-gcc -v
如图显示,说明交叉编译工具以及安装成功
st7789 LCD +1
https://whycan.com/t_7024.html
效果
我使用的是Linux-5.10内核
当时驱动不了屏幕,后来发现驱动程序有点问题,就照着STM32的程序改了一下
路径为linux-5.10/drivers/staging/fbtft/
改好的fb_st7789v程序如下
fb_st7789v.zip
内核配置
Device Drivers --->
【*】 Staging drivers --->
<*> Support for small TFT LCD display modules --->
<*> FB driver for the ST7789V LCD Controller
设备树
路径为linux-5.10/arch/arm/boot/dts/
sun8i-v3s-licheepi-zero-dock.dts
chosen {
/delete-node/ framebuffer@0;
};
&spi0{
status = "okay";
st7789v: st7789v@0{
compatible = "sitronix,st7789v";
reg = <0>;
status = "okay";
spi-max-frequency = <96000000>;
spi-cpol;
spi-cpha;
rotate = <270>;
fps = <60>;
buswidth = <8>;
dc-gpios = <&pio 1 4 GPIO_ACTIVE_HIGH>; // PB4 PB0
reset-gpios = <&pio 1 5 GPIO_ACTIVE_HIGH>; // PB5
//led-gpios = <&pio 0 0 GPIO_ACTIVE_LOW>; // PA0
debug = <0x0>;
};
};
简单的内核驱动
helloworld.c
-------------------------------------------------------------------------------------------------
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
static int hello_init(void)
{
printk(KERN_INFO " Hello World enter\n");//打印级别+打印信息
return 0;
}
static void hello_exit(void)
{
printk(KERN_INFO " Hello World exit\n");//打印级别+打印信息
}
//安装模块做什么
module_init(hello_init);
//卸载模块做什么
module_exit(hello_exit);
//模块信息
MODULE_AUTHOR("ephraim");
MODULE_DESCRIPTION("A simple Hello World Module");
MODULE_ALIAS("a simplest module");
-------------------------------------------------------------------------------------------------
Makefile
-------------------------------------------------------------------------------------------------
ifneq ($(KERNELRELEASE),)
#kbuild syntax. dependency relationshsip of files and target modules are listed here.
obj-m := helloworld.o
else
PWD:= $(shell pwd)
KDIR := /home/lzq/desktop/linux-5.10
all:
$(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions
endif
-------------------------------------------------------------------------------------------------
make一下生成helloworld.ko
结果
全志v3s荔枝派zero对usb声卡的支持
淘宝7元买的usb声卡
_____________________________________________________________________
效果
视频声音小了,请将电脑声音调置最大
_____________________________________________________________________
内核
Device Drivers -->
Sound card support -->
--- Sound card support Preclaim OSS device numbers
<*> Advanced Linux Sound Architecture -->
--- Advanced Linux Sound Architecture
[ *] Enable OSS Emulation
< *> OSS Mixer API
< *> OSS PCM (digital audio) API
[ *] OSS PCM (digital audio) API - Include plugin system
[ *] USB sound devices --->
<*>USB Audio /MIDI drive
_____________________________________________________________________
设备树
/*
&codec {
allwinner,audio-routing =
"Headphone", "HP",
"Headphone", "HPCOM",
"MIC1", "Mic",
"Mic", "HBIAS";
status = "okay";
};
*/
我去除了原来的声卡配置,因为用不上,自己画的板子,耳机口还没焊接
_____________________________________________________________________
根文件
开启alsa
_____________________________________________________________________
验证
ls/dev
查看有没有audio设备
root@lzq:/129# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Device [USB PnP Sound Device], device 0: USB Audio [USB Audio]
Subdevices: 1/1
Subdevice #0: subdevice #0
root@lzq:/129#
_____________________________________________________________________
问题
mp3格式无法用aplay播放(都是噪声),估计是采样率不匹配,用mplayer就好了
aplay只能播放wav格式的音乐
太大了,论坛传不了
链接: https://pan.baidu.com/s/1aQcvVj-iQ7w89xaz5GpO6w
提取码:k9o3
直接解压到opt
包含
Qt5-5.12Linux安装包
交叉编译
Qt5.12-arm
Qt-5.91-arm(就是qte5.5.1,Ubuntu不能改名,v3s下可以)
Qt-5.91-x11
tslib-触屏软件库
sqlite3
目标板步骤(环境变量要改)
拷贝qt5.9.1-arm, sqlite3,tslib(内含ts_calibrate) 到/opt下
拷贝字体到/opt/qt5.9.1-arm/lib/fonts下
之前交叉编译qt的工具链里的/usr/lib/arm-linux-gnueabihf/lib/libstdc++.so.6.0.22 覆盖当前的so
编辑/etc/bash.bashrc, 加入环境变量:
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0
export TSLIB_TSDEVICE=/dev/input/event1
export TSLIB_CONFFILE=/opt/tslib/etc/ts.conf
export TSLIB_PLUGINDIR=/opt/tslib/lib/ts
export TSLIB_CALIBFILE=/etc/pointercal
export LD_LIBRARY_PATH=/lib:/usr/lib:/opt/tslib/lib:/opt/qt5.9.1-arm/lib
export PATH=/bin:/sbin:/usr/bin/:/usr/sbin:/opt/tslib/bin
export QT_QPA_PLATFORM_PLUGIN_PATH=/opt/qt5.9.1-arm/plugins
export QT_QPA_PLATFORM=linuxfb:tty=/dev/fb0
export QT_QPA_FONTDIR=/opt/qt5.9.1-arm/lib/fonts
export QT_QPA_GENERIC_PLUGINS=tslib:$TSLIB_TSDEVICE
拷贝编译好的基于qt的应用程序到自定义目录下
报错如下:
# insmod r8723bs.ko
[ 26.170222] r8723bs: module is from the staging directory, the quality is unknown, you have been warned.
[ 26.192103] r8723bs: Unknown symbol cfg80211_inform_bss_frame_data (err -2)
[ 26.199306] r8723bs: Unknown symbol cfg80211_scan_done (err -2)
[ 26.205321] r8723bs: Unknown symbol cfg80211_new_sta (err -2)
[ 26.211127] r8723bs: Unknown symbol cfg80211_disconnected (err -2)
[ 26.217350] r8723bs: Unknown symbol wiphy_new_nm (err -2)
[ 26.222757] r8723bs: Unknown symbol wiphy_register (err -2)
[ 26.228381] r8723bs: Unknown symbol cfg80211_put_bss (err -2)
[ 26.234126] r8723bs: Unknown symbol cfg80211_roamed (err -2)
[ 26.239823] r8723bs: Unknown symbol ieee80211_get_channel_khz (err -2)
[ 26.246387] r8723bs: Unknown symbol cfg80211_ibss_joined (err -2)
[ 26.252495] r8723bs: Unknown symbol cfg80211_michael_mic_failure (err -2)
[ 26.259299] r8723bs: Unknown symbol wiphy_apply_custom_regulatory (err -2)
[ 26.266178] r8723bs: Unknown symbol cfg80211_rx_mgmt_khz (err -2)
[ 26.272287] r8723bs: Unknown symbol cfg80211_del_sta_sinfo (err -2)
[ 26.278585] r8723bs: Unknown symbol wiphy_unregister (err -2)
[ 26.284351] r8723bs: Unknown symbol cfg80211_get_bss (err -2)
[ 26.290123] r8723bs: Unknown symbol ieee80211_freq_khz_to_channel (err -2)
[ 26.297019] r8723bs: Unknown symbol rfc1042_header (err -2)
[ 26.302607] r8723bs: Unknown symbol cfg80211_mgmt_tx_status (err -2)
[ 26.309067] r8723bs: Unknown symbol bridge_tunnel_header (err -2)
[ 26.315169] r8723bs: Unknown symbol cfg80211_connect_done (err -2)
[ 26.321371] r8723bs: Unknown symbol cfg80211_unlink_bss (err -2)
[ 26.327391] r8723bs: Unknown symbol wiphy_free (err -2)
[ 26.341109] r8723bs: module is from the staging directory, the quality is unknown, you have been warned.
[ 26.362850] r8723bs: Unknown symbol cfg80211_inform_bss_frame_data (err -2)
[ 26.370064] r8723bs: Unknown symbol cfg80211_scan_done (err -2)
[ 26.376076] r8723bs: Unknown symbol cfg80211_new_sta (err -2)
[ 26.381912] r8723bs: Unknown symbol cfg80211_disconnected (err -2)
[ 26.388140] r8723bs: Unknown symbol wiphy_new_nm (err -2)
[ 26.393550] r8723bs: Unknown symbol wiphy_register (err -2)
[ 26.399141] r8723bs: Unknown symbol cfg80211_put_bss (err -2)
[ 26.404883] r8723bs: Unknown symbol cfg80211_roamed (err -2)
[ 26.410573] r8723bs: Unknown symbol ieee80211_get_channel_khz (err -2)
[ 26.417134] r8723bs: Unknown symbol cfg80211_ibss_joined (err -2)
[ 26.423241] r8723bs: Unknown symbol cfg80211_michael_mic_failure (err -2)
[ 26.430070] r8723bs: Unknown symbol wiphy_apply_custom_regulatory (err -2)
[ 26.436975] r8723bs: Unknown symbol cfg80211_rx_mgmt_khz (err -2)
[ 26.443068] r8723bs: Unknown symbol cfg80211_del_sta_sinfo (err -2)
[ 26.449366] r8723bs: Unknown symbol wiphy_unregister (err -2)
[ 26.455133] r8723bs: Unknown symbol cfg80211_get_bss (err -2)
[ 26.460908] r8723bs: Unknown symbol ieee80211_freq_khz_to_channel (err -2)
[ 26.467804] r8723bs: Unknown symbol rfc1042_header (err -2)
[ 26.473393] r8723bs: Unknown symbol cfg80211_mgmt_tx_status (err -2)
[ 26.479853] r8723bs: Unknown symbol bridge_tunnel_header (err -2)
[ 26.485952] r8723bs: Unknown symbol cfg80211_connect_done (err -2)
[ 26.492156] r8723bs: Unknown symbol cfg80211_unlink_bss (err -2)
[ 26.498177] r8723bs: Unknown symbol wiphy_free (err -2)
insmod: can't insert 'r8723bs.ko': unknown symbol in module, or unknown parameter
解决:
--- Networking support
-*- Wireless --->
<*> cfg80211 - wireless configuration API
<*> Generic IEEE 802.11 Networking Stack (mac80211)
结果:
# insmod r8723bs.ko
[ 30.986029] r8723bs: module is from the staging directory, the quality is unknown, you have been warned.
[ 31.012525] RTL8723BS: module init start
[ 31.016478] RTL8723BS: rtl8723bs v4.3.5.5_12290.20140916_BTCOEX20140507-4E40
[ 31.023645] RTL8723BS: rtl8723bs BT-Coex version = BTCOEX20140507-4E40
[ 31.031477] pnetdev = 681b2ddb
[ 31.067274] RTL8723BS: rtw_ndev_init(wlan0)
[ 31.072883] RTL8723BS: module init ret =0
页次: 1