前言
CPU | 双核 ARM CortexTM-A53, ARM v8 架构,z |
AIPU(NPU) | 搭载周易TZ1AIPU,最大支持0.25TOPS@600MHz |
DRAM | SIP 256MB DDR3 |
存储 | 可使用核心板搭载的 SPINAND (默认空贴)存储 可使用底板搭载的SD卡座 |
video Encoder 视频编码器 | H264/5 &JPEG,最大720p@30fps |
摄像头 | 出厂默认OV9732,最高支持720P@30fps HD 采用USB-C连接器,支持正反插(可分别用作前后摄) |
麦克风 | 两个模拟MEMS麦克风,平均灵敏度91dB SPL@1kHz |
屏幕 | 1.5寸SPI总线屏幕,屏幕接口采用0.5mm 12P FPC,分辨率240*240 |
按键 | 1个复位按键和4个用户按键(ADC按键),1个下载按键(FEL) |
IO引出 | 310P 2.54mm 引出4个电源引脚(5V/GND)11个GPIO引脚 1个4PMX1.25插座(引出2GPIO和5V/GND)s |
以太网接口 | 在核心板以24P 0.5mm间距FPC的形式引出,用于连接相应PHY |
MaixSense 开发板可能是市面上最小的 Linux 卡片电脑, 本套件包含一个搭载全志 R329 的高度集成 SOM 核心板,以及一个多功能 IO 扩展底板,可以运行 Linux 系统, 并具备出色的扩展功能。您可以将它用于搭建个人服务器、开发智能语音助手、设计机器人等场景。它通过内置的周易 AIPU 处理器同时支持智能语音和视频图像处理,开发者可以直接在开发板上跑通相关 CV , NLP 等 AI 模型。
Tina Linux:全志科技基于 Linux 内核开发的针对智能硬件类产品的嵌入式软件系统。Tina Linux基于 openwrt-14.07 版本的软件开发包,包含了Linux系统开发用到的内核源码、驱动、工具、系统中间件与应用程序包。
但是 MaixSense 不只是可以运行 Tina ,还可以运行armbian,这是一个真正完整的 linux 系统,armbian 是基于 debian/ubuntu 进行开发的。
名称 | armbian | Tina |
---|---|---|
简介 | 专门用于ARM开发板的Debian | 全志深度修改OpenWRT1404的系统 |
特点 | 主线化Linux,功能丰富 | 厂商深度修改,软硬件契合度高 |
适用人群 | 极客,嵌入式入门玩家等 | 深度开发,需要自行定制等开发人员 |
官方Debian
- r329-mainline-debian-20210802.img
- 用户名:root
- 密码:sipeed
U-Boot SPL 2021.07-00715-g432f8404c1 (Jul 23 2021 - 14:10:47 +0800)
DRAM: 256 MiB
Trying to boot from MMC1
NOTICE: BL31: v2.5(debug):v2.5-198-g01da1cf09-dirty
NOTICE: BL31: Built : 11:39:03, Jul 23 2021
NOTICE: BL31: Detected Allwinner R329 SoC (1851)
NOTICE: BL31: Found U-Boot DTB at 0xc07ab48, model: Sipeed MaixSense
INFO: ARM GICv2 driver initialized
INFO: Configuring SPC Controller
INFO: BL31: Platform setup done
INFO: BL31: Initializing runtime services
INFO: BL31: cortex_a53: CPU workaround for 855873 was applied
INFO: BL31: cortex_a53: CPU workaround for 1530924 was applied
INFO: PSCI: Suspend is unavailable
INFO: BL31: Preparing for EL3 exit to normal world
INFO: Entry point address = 0x4a000000
INFO: SPSR = 0x3c9
U-Boot 2021.07-00715-g432f8404c1 (Jul 23 2021 - 14:10:47 +0800) Allwinner Technology
CPU: Allwinner R329 (SUN50I)
Model: Sipeed MaixSense
DRAM: 256 MiB
MMC: mmc@4020000: 0, mmc@4021000: 1
Loading Environment from FAT... Unable to read "uboot.env" from mmc0:1... In: serial@2500000
Out: serial@2500000
Err: serial@2500000
Net: No ethernet found.
Hit any key to stop autoboot: 0
switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
Found U-Boot script /boot.scr
286 bytes read in 1 ms (279.3 KiB/s)
## Executing script at 4fc00000
14522376 bytes read in 1204 ms (11.5 MiB/s)
11105 bytes read in 3 ms (3.5 MiB/s)
Moving Image from 0x40080000 to 0x40200000, end=41040000
## Flattened Device Tree blob at 44a00000
Booting using the fdt blob at 0x44a00000
Loading Device Tree to 0000000049ffa000, end 0000000049fffb60 ... OK
Starting kernel ...
[ 0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
[ 0.000000] Linux version 5.14.0-rc3+ (icenowy@ice-390e5) (aarch64-aosc-linux-gnu-gcc (GCC) 9.2.1 20191220, GNU ld (GNU Binutils) 2.33.1) #107 SMP PREEMPT Fri Jul 30 11:42:44 CST 2021
[ 0.000000] Machine model: Sipeed MaixSense
[ 0.000000] earlycon: uart0 at MMIO32 0x0000000002500000 (options '')
[ 0.000000] printk: bootconsole [uart0] enabled
[ 0.000000] Zone ranges:
[ 0.000000] DMA [mem 0x0000000040000000-0x000000004fffffff]
[ 0.000000] DMA32 empty
[ 0.000000] Normal empty
[ 0.000000] Movable zone start for each node
[ 0.000000] Early memory node ranges
[ 0.000000] node 0: [mem 0x0000000040000000-0x000000004fffffff]
[ 0.000000] Initmem setup node 0 [mem 0x0000000040000000-0x000000004fffffff]
[ 0.000000] cma: Reserved 128 MiB at 0x0000000041c00000
[ 0.000000] psci: probing for conduit method from DT.
[ 0.000000] psci: PSCIv1.1 detected in firmware.
[ 0.000000] psci: Using standard PSCI v0.2 function IDs
[ 0.000000] psci: MIGRATE_INFO_TYPE not supported.
[ 0.000000] psci: SMC Calling Convention v1.2
[ 0.000000] percpu: Embedded 22 pages/cpu s51224 r8192 d30696 u90112
[ 0.000000] Detected VIPT I-cache on CPU0
[ 0.000000] CPU features: detected: ARM erratum 845719
[ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 64512
[ 0.000000] Kernel command line: console=ttyS0,115200 root=/dev/mmcblk0p2 rootwait earlycon=uart,mmio32,0x02500000 panic=10 fbcon=font:6x8
[ 0.000000] Dentry cache hash table entries: 32768 (order: 6, 262144 bytes, linear)
[ 0.000000] Inode-cache hash table entries: 16384 (order: 5, 131072 bytes, linear)
[ 0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[ 0.000000] Memory: 111220K/262144K available (8512K kernel code, 998K rwdata, 3108K rodata, 1472K init, 371K bss, 19852K reserved, 131072K cma-reserved)
[ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=2, Nodes=1
[ 0.000000] rcu: Preemptible hierarchical RCU implementation.
[ 0.000000] rcu: RCU event tracing is enabled.
[ 0.000000] rcu: RCU restricting CPUs from NR_CPUS=256 to nr_cpu_ids=2.
[ 0.000000] Trampoline variant of Tasks RCU enabled.
[ 0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
[ 0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=2
[ 0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[ 0.000000] Root IRQ handler: gic_handle_irq
[ 0.000000] GIC: Using split EOI/Deactivate mode
[ 0.000000] random: get_random_bytes called from start_kernel+0x49c/0x604 with crng_init=0
[ 0.000000] arch_timer: cp15 timer(s) running at 24.00MHz (phys).
[ 0.000000] clocksource: arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x588fe9dc0, max_idle_ns: 440795202592 ns
[ 0.000000] sched_clock: 56 bits at 24MHz, resolution 41ns, wraps every 4398046511097ns
[ 0.009015] Console: colour dummy device 80x25
[ 0.013924] Calibrating delay loop (skipped), value calculated using timer frequency.. 48.00 BogoMIPS (lpj=96000)
[ 0.025195] pid_max: default: 32768 minimum: 301
[ 0.030319] LSM: Security Framework initializing
[ 0.034977] Mount-cache hash table entries: 512 (order: 0, 4096 bytes, linear)
[ 0.042197] Mountpoint-cache hash table entries: 512 (order: 0, 4096 bytes, linear)
[ 0.051880] rcu: Hierarchical SRCU implementation.
[ 0.057600] smp: Bringing up secondary CPUs ...
[ 0.063005] Detected VIPT I-cache on CPU1
[ 0.063073] CPU1: Booted secondary processor 0x0000000001 [0x410fd034]
[ 0.063176] smp: Brought up 1 node, 2 CPUs
[ 0.078624] SMP: Total of 2 processors activated.
[ 0.083789] CPU features: detected: 32-bit EL0 Support
[ 0.088938] CPU features: detected: CRC32 instructions
[ 0.094723] CPU: All CPU(s) started at EL2
[ 0.099227] alternatives: patching kernel code
[ 0.104807] devtmpfs: initialized
[ 0.110936] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
[ 0.121662] futex hash table entries: 512 (order: 3, 32768 bytes, linear)
[ 0.133429] pinctrl core: initialized pinctrl subsystem
[ 0.139860] NET: Registered PF_NETLINK/PF_ROUTE protocol family
[ 0.146903] DMA: preallocated 128 KiB GFP_KERNEL pool for atomic allocations
[ 0.154740] DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA pool for atomic allocations
[ 0.163323] DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA32 pool for atomic allocations
[ 0.172093] audit: initializing netlink subsys (disabled)
[ 0.178225] audit: type=2000 audit(0.124:1): state=initialized audit_enabled=0 res=1
[ 0.178581] thermal_sys: Registered thermal governor 'step_wise'
[ 0.186735] thermal_sys: Registered thermal governor 'user_space'
[ 0.193327] thermal_sys: Registered thermal governor 'power_allocator'
[ 0.199760] cpuidle: using governor menu
[ 0.211331] hw-breakpoint: found 6 breakpoint and 4 watchpoint registers.
[ 0.218169] ASID allocator initialised with 65536 entries
[ 0.234916] HugeTLB registered 1.00 GiB page size, pre-allocated 0 pages
[ 0.242200] HugeTLB registered 32.0 MiB page size, pre-allocated 0 pages
[ 0.249559] HugeTLB registered 2.00 MiB page size, pre-allocated 0 pages
[ 0.256913] HugeTLB registered 64.0 KiB page size, pre-allocated 0 pages
[ 0.265721] cryptd: max_cpu_qlen set to 1000
[ 0.273017] SCSI subsystem initialized
[ 0.277499] usbcore: registered new interface driver usbfs
[ 0.283386] usbcore: registered new interface driver hub
[ 0.289247] usbcore: registered new device driver usb
[ 0.294989] mc: Linux media interface: v0.10
[ 0.299696] videodev: Linux video capture interface: v2.00
[ 0.306079] Advanced Linux Sound Architecture Driver Initialized.
[ 0.313302] clocksource: Switched to clocksource arch_sys_counter
[ 0.320190] VFS: Disk quotas dquot_6.6.0
[ 0.324545] VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
[ 0.337208] NET: Registered PF_INET protocol family
[ 0.342678] IP idents hash table entries: 4096 (order: 3, 32768 bytes, linear)
[ 0.351075] tcp_listen_portaddr_hash hash table entries: 256 (order: 0, 4096 bytes, linear)
[ 0.360315] TCP established hash table entries: 2048 (order: 2, 16384 bytes, linear)
[ 0.368849] TCP bind hash table entries: 2048 (order: 3, 32768 bytes, linear)
[ 0.376036] TCP: Hash tables configured (established 2048 bind 2048)
[ 0.383118] UDP hash table entries: 256 (order: 1, 8192 bytes, linear)
[ 0.389661] UDP-Lite hash table entries: 256 (order: 1, 8192 bytes, linear)
[ 0.397426] NET: Registered PF_UNIX/PF_LOCAL protocol family
[ 0.404894] Initialise system trusted keyrings
[ 0.410012] workingset: timestamp_bits=46 max_order=16 bucket_order=0
[ 0.422777] fuse: init (API version 7.34)
[ 0.470674] Key type asymmetric registered
[ 0.475193] Asymmetric key parser 'x509' registered
[ 0.480108] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 249)
[ 0.488234] io scheduler mq-deadline registered
[ 0.492774] io scheduler kyber registered
[ 0.500515] sun50i-r329-r-pinctrl 7022000.pinctrl: initialized sunXi PIO driver
[ 0.508161] pwm-backlight backlight: supply power not found, using dummy regulator
[ 0.526372] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
[ 0.534866] cacheinfo: Unable to detect cache hierarchy for CPU 0
[ 0.548669] loop: module loaded
[ 0.553687] libphy: Fixed MDIO Bus: probed
[ 0.558329] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[ 0.565498] ehci-platform: EHCI generic platform driver
[ 0.571402] ehci-platform 4101000.usb: EHCI Host Controller
[ 0.577552] ehci-platform 4101000.usb: new USB bus registered, assigned bus number 1
[ 0.586158] ehci-platform 4101000.usb: irq 25, io mem 0x04101000
[ 0.605326] ehci-platform 4101000.usb: USB 2.0 started, EHCI 1.00
[ 0.612573] hub 1-0:1.0: USB hub found
[ 0.616413] hub 1-0:1.0: 1 port detected
[ 0.621069] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[ 0.627864] ohci-platform: OHCI generic platform driver
[ 0.633775] ohci-platform 4101400.usb: Generic Platform OHCI controller
[ 0.641043] ohci-platform 4101400.usb: new USB bus registered, assigned bus number 2
[ 0.648907] ohci-platform 4101400.usb: irq 26, io mem 0x04101400
[ 0.717853] hub 2-0:1.0: USB hub found
[ 0.722000] hub 2-0:1.0: 1 port detected
[ 0.726920] usbcore: registered new interface driver usb-storage
[ 0.733827] udc-core: couldn't find an available UDC - added [g_cdc] to list of pending drivers
[ 0.742962] input: 7030800.lradc as /devices/platform/soc/7030800.lradc/input/input0
[ 0.752405] sun6i-rtc 7090000.rtc: registered as rtc0
[ 0.757999] sun6i-rtc 7090000.rtc: setting system clock to 1970-01-02T01:20:32 UTC (91232)
[ 0.767083] sun6i-rtc 7090000.rtc: RTC enabled
[ 0.772040] i2c /dev entries driver
[ 0.776088] usbcore: registered new interface driver uvcvideo
[ 0.783352] sun50i-r329-r-pinctrl 7022000.pinctrl: supply vcc-pm not found, using dummy regulator
[ 0.793518] ledtrig-cpu: registered to indicate activity on CPUs
[ 0.800642] usbcore: registered new interface driver usbhid
[ 0.806770] usbhid: USB HID core driver
[ 0.811749] sun4i-codec 7032000.codec: Failed to register our card
[ 0.819060] Initializing XFRM netlink socket
[ 0.824162] NET: Registered PF_INET6 protocol family
[ 0.830542] Segment Routing with IPv6
[ 0.834654] NET: Registered PF_PACKET protocol family
[ 0.840489] Loading compiled-in X.509 certificates
[ 0.856654] sun50i-r329-pinctrl 2000400.pinctrl: initialized sunXi PIO driver
[ 0.864879] sun50i-r329-pinctrl 2000400.pinctrl: supply vcc-pb not found, using dummy regulator
[ 0.874642] sun50i-r329-pinctrl 2000400.pinctrl: supply vcc-ph not found, using dummy regulator
[ 0.883944] pwm-backlight backlight: supply power not found, using dummy regulator
[ 0.892942] printk: console [ttyS0] disabled
[ 0.917915] 2500000.serial: ttyS0 at MMIO 0x2500000 (irq = 18, base_baud = 1500000) is a 16550A
[ 0.927532] printk: console [ttyS0] enabled
[ 0.927532] printk: console [ttyS0] enabled
[ 0.936299] printk: bootconsole [uart0] disabled
[ 0.936299] printk: bootconsole [uart0] disabled
[ 0.947070] sun50i-r329-r-pinctrl 7022000.pinctrl: supply vcc-pn not found, using dummy regulator
[ 0.956542] [drm] Initialized simple-dbi 1.0.0 20210723 for spi0.0 on minor 0
[ 1.245773] Console: switching to colour frame buffer device 40x30
[ 1.296130] simple-dbi spi0.0: [drm] fb0: simple-dbi frame buffer device
[ 1.303857] sun50i-r329-pinctrl 2000400.pinctrl: supply vcc-pf not found, using dummy regulator
[ 1.304849] debugfs: Directory '7032000.codec' with parent 'R329 Audio Codec' already present!
[ 1.313663] sun50i-r329-pinctrl 2000400.pinctrl: supply vcc-pg not found, using dummy regulator
[ 1.321751] sunxi-mmc 4020000.mmc: Got CD GPIO
[ 1.335427] sunxi-mmc 4021000.mmc: allocated mmc-pwrseq
[ 1.342902] usb_phy_generic usb_phy_generic.1.auto: supply vcc not found, using dummy regulator
[ 1.352308] musb-hdrc musb-hdrc.2.auto: MUSB HDRC host driver
[ 1.358098] musb-hdrc musb-hdrc.2.auto: new USB bus registered, assigned bus number 3
[ 1.359951] sunxi-mmc 4020000.mmc: initialized, max. request size: 2048 KB, uses new timings mode
[ 1.366505] hub 3-0:1.0: USB hub found
[ 1.378788] hub 3-0:1.0: 1 port detected
[ 1.384262] using random self ethernet address
[ 1.388740] using random host ethernet address
[ 1.393849] usb0: HOST MAC 82:05:7d:a5:46:75
[ 1.398233] usb0: MAC fe:98:81:d8:35:fa
[ 1.402122] g_cdc gadget: CDC Composite Gadget, version: King Kamehameha Day 2008
[ 1.409620] g_cdc gadget: g_cdc ready
[ 1.413874] ALSA device list:
[ 1.416852] #0: R329 Audio Codec
[ 1.447451] mmc0: host does not support reading read-only switch, assuming write-enable
[ 1.458839] mmc0: new high speed SDHC card at address aaaa
[ 1.465043] mmcblk0: mmc0:aaaa SD32G 29.7 GiB
[ 1.471453] mmcblk0: p1 p2
[ 1.573865] sunxi-mmc 4021000.mmc: initialized, max. request size: 2048 KB, uses new timings mode
[ 1.588829] sunxi-mmc 4021000.mmc: card claims to support voltages below defined range
[ 1.596087] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null). Quota mode: none.
[ 1.606608] VFS: Mounted root (ext4 filesystem) readonly on device 179:2.
[ 1.614273] devtmpfs: mounted
[ 1.618103] Freeing unused kernel memory: 1472K
[ 1.622770] Run /sbin/init as init process
[ 1.634334] mmc1: new high speed SDIO card at address 0001
[ 1.726777] random: fast init done
[ 1.793349] usb 1-1: new high-speed USB device number 2 using ehci-platform
[ 1.980040] usb 1-1: Found UVC 1.00 device USB 2.0 Camera (0c45:6366)
[ 1.999616] input: USB 2.0 Camera: USB Camera as /devices/platform/soc/4101000.usb/usb1/1-1/1-1:1.0/input/input1
[ 2.126281] systemd[1]: System time before build time, advancing clock.
[ 2.237935] systemd[1]: systemd 247.3-6 running in system mode. (+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +ZSTD +SECCOMP +BLKID +ELFUTILS +KMOD +IDN2 -IDN +PCRE2 default-hierarchy=unified)
[ 2.262041] systemd[1]: Detected architecture arm64.
Welcome to Debian GNU/Linux 11 (bullseye)!
[ 2.290639] systemd[1]: Set hostname to <maixsense>.
[ 2.858997] systemd[1]: Queued start job for default target Graphical Interface.
[ 2.867772] random: systemd: uninitialized urandom read (16 bytes read)
[ 2.874631] systemd[1]: system-getty.slice: unit configures an IP firewall, but the local system does not support BPF/cgroup firewalling.
[ 2.886995] systemd[1]: (This warning is only shown for the first unit using IP firewalling.)
[ 2.898064] systemd[1]: Created slice system-getty.slice.
[ OK ] Created slice system-getty.slice.
[ 2.921507] random: systemd: uninitialized urandom read (16 bytes read)
[ 2.929438] systemd[1]: Created slice system-modprobe.slice.
[ OK ] Created slice system-modprobe.slice.
[ 2.949487] random: systemd: uninitialized urandom read (16 bytes read)
[ 2.957655] systemd[1]: Created slice system-serial\x2dgetty.slice.
[ OK ] Created slice system-serial\x2dgetty.slice.
[ 2.982492] systemd[1]: Created slice User and Session Slice.
[ OK ] Created slice User and Session Slice.
[ 3.005863] systemd[1]: Started Dispatch Password Requests to Console Directory Watch.
[ OK ] Started Dispatch Password …ts to Console Directory Watch.
[ 3.029770] systemd[1]: Started Forward Password Requests to Wall Directory Watch.
[ OK ] Started Forward Password R…uests to Wall Directory Watch.
[ 3.053645] systemd[1]: Condition check resulted in Arbitrary Executable File Formats File System Automount Point being skipped.
[ 3.065482] systemd[1]: Reached target Local Encrypted Volumes.
[ OK ] Reached target Local Encrypted Volumes.
[ 3.085627] systemd[1]: Reached target Paths.
[ OK ] Reached target Paths.
[ 3.105532] systemd[1]: Reached target Remote File Systems.
[ OK ] Reached target Remote File Systems.
[ 3.125507] systemd[1]: Reached target Slices.
[ OK ] Reached target Slices.
[ 3.145544] systemd[1]: Reached target Swap.
[ OK ] Reached target Swap.
[ 3.167080] systemd[1]: Listening on Syslog Socket.
[ OK ] Listening on Syslog Socket.
[ 3.186069] systemd[1]: Listening on fsck to fsckd communication Socket.
[ OK ] Listening on fsck to fsckd communication Socket.
[ 3.209871] systemd[1]: Listening on initctl Compatibility Named Pipe.
[ OK ] Listening on initctl Compatibility Named Pipe.
[ 3.234332] systemd[1]: Listening on Journal Audit Socket.
[ OK ] Listening on Journal Audit Socket.
[ 3.258042] systemd[1]: Listening on Journal Socket (/dev/log).
[ OK ] Listening on Journal Socket (/dev/log).
[ 3.282144] systemd[1]: Listening on Journal Socket.
[ OK ] Listening on Journal Socket.
[ 3.303880] systemd[1]: Listening on udev Control Socket.
[ OK ] Listening on udev Control Socket.
[ 3.326014] systemd[1]: Listening on udev Kernel Socket.
[ OK ] Listening on udev Kernel Socket.
[ 3.348985] systemd[1]: Mounting Huge Pages File System...
Mounting Huge Pages File System...
[ 3.373098] systemd[1]: Mounting POSIX Message Queue File System...
Mounting POSIX Message Queue File System...
[ 3.397112] systemd[1]: Mounting Kernel Debug File System...
Mounting Kernel Debug File System...
[ 3.418005] systemd[1]: Condition check resulted in Kernel Trace File System being skipped.
[ 3.430490] systemd[1]: Starting Create list of static device nodes for the current kernel...
Starting Create list of st…odes for the current kernel...
[ 3.461550] systemd[1]: Starting Load Kernel Module configfs...
Starting Load Kernel Module configfs...
[ 3.485253] systemd[1]: Starting Load Kernel Module drm...
Starting Load Kernel Module drm...
[ 3.509287] systemd[1]: Starting Load Kernel Module fuse...
Starting Load Kernel Module fuse...
[ 3.531362] systemd[1]: Condition check resulted in Set Up Additional Binary Formats being skipped.
[ 3.544135] systemd[1]: Starting File System Check on Root Device...
Starting File System Check on Root Device...
[ 3.573253] systemd[1]: Starting Journal Service...
Starting Journal Service...
[ 3.591487] systemd[1]: Starting Load Kernel Modules...
Starting Load Kernel Modules...
[ 3.603347] systemd[1]: Starting Coldplug All udev Devices...
Starting Coldplug All udev Devices...
[ 3.636512] systemd[1]: Mounted Huge Pages File System.
[ OK 3.646500] systemd[1]: Mounted POSIX Message Queue File System.
0m] Mounted 3.654321] systemd[1]: Mounted Kernel Debug File System.
1;39mHuge Pages File System.
[ OK [ 3.663013] systemd[1]: Finished Create list of static device nodes for the current kernel.
] Mounted POSIX Message Queue File [ 3.676509] systemd[1]: modprobe@configfs.service: Succeeded.
System.
[ OK ] Mounted Kernel Debug F[ 3.686522] systemd[1]: Finished Load Kernel Module configfs.
ile System.
[ OK systemd[1]: modprobe@drm.service: Succeeded.
[0m] Finished Create li[ 3.703403] systemd[1]: Finished Load Kernel Module drm.
st of st… nodes for the curren[ 3.712106] systemd[1]: modprobe@fuse.service: Succeeded.
t kernel.
[ OK 3.719604] systemd[1]: Finished Load Kernel Module fuse.
m] Finished Load Kernel Module configfs.
[ OK ] Finished Load Kernel Module drm.
[ OK ] Finished Load Kernel Module fuse.
[ 3.771390] systemd[1]: Finished File System Check on Root Device.
[ OK ] Finished File System Check on Root Device.
[ 3.807323] systemd[1]: Finished Load Kernel Modules.
[ OK ] Finished Load Kernel Modules.
[ 3.826148] systemd[1]: Started Journal Service.
[ OK ] Started Journal Service.
Mounting FUSE Control File System...
Mounting Kernel Configuration File System...
[ OK ] Started File System Check Daemon to report status.
Starting Remount Root and Kernel File Systems...
Starting Apply Kernel Variables...
[ OK ] Mounted FUSE Control File System.
[ OK ] Mounted Kernel Configuration File System.
[ 3.979214] EXT4-fs (mmcblk0p2): re-mounted. Opts: (null). Quota mode: none.
[ OK ] Finished Remount Root and Kernel File Systems.
[ OK ] Finished Apply Kernel Variables.
Starting Flush Journal to Persistent Storage...
Starting Load/Save Random Seed...
Starting Create System Users...
[ 4.107243] systemd-journald[119]: Received client request to flush runtime journal.
[ OK ] Finished Coldplug All udev Devices.
Starting Helper to synchronize boot up for ifupdown...
[ OK ] Finished Create System Users.
[ OK ] Finished Helper to synchronize boot up for ifupdown.
Starting Create Static Device Nodes in /dev...
[ OK ] Finished Flush Journal to Persistent Storage.
[ OK ] Finished Create Static Device Nodes in /dev.
[ OK ] Reached target Local File Systems (Pre).
[ OK ] Reached target Local File Systems.
Starting Raise network interfaces...
Starting Create Volatile Files and Directories...
Starting Rule-based Manage…for Device Events and Files...
[ OK ] Finished Create Volatile Files and Directories.
Starting Network Time Synchronization...
Starting Update UTMP about System Boot/Shutdown...
[ OK ] Finished Update UTMP about System Boot/Shutdown.
[ OK ] Finished Raise network interfaces.
[ OK ] Started Rule-based Manager for Device Events and Files.
[ OK ] Started Network Time Synchronization.
[ OK ] Reached target System Initialization.
[ OK ] Started Daily Cleanup of Temporary Directories.
[ OK ] Reached target System Time Set.
[ OK ] Reached target System Time Synchronized.
[ OK ] Started Daily apt download activities.
[ OK ] Started Daily apt upgrade and clean activities.
[ OK ] Started Periodic ext4 Onli…ata Check for All Filesystems.
[ OK ] Started Discard unused blocks once a week.
[ OK ] Started Daily rotation of log files.
[ OK ] Reached target Timers.
[ OK ] Listening on D-Bus System Message Bus Socket.
[ OK ] Reached target Sockets.
[ OK ] Reached target Basic System.
[ OK ] Started Regular background program processing daemon.
[ OK ] Started D-Bus System Message Bus.
Starting Network Manager...
Starting Remove Stale Onli…t4 Metadata Check Snapshots...
Starting Authorization Manager...
Starting System Logging Service...
Starting User Login Management...
Starting WPA supplicant...
[ OK ] Created slice system-systemd\x2dbacklight.slice.
Starting Load/Save Screen …ness of backlight:backlight...
[ OK ] Found device /dev/ttyS0.
[ OK ] Started System Logging Service.
[ OK ] Finished Load/Save Screen …htness of backlight:backlight.
[ OK ] Started WPA supplicant.
[ OK ] Started Authorization Manager.
Starting Modem Manager...
[ OK ] Started User Login Management.
[ OK ] Finished Remove Stale Onli…ext4 Metadata Check Snapshots.
[ 6.223842] aipu: loading out-of-tree module taints kernel.
[ OK ] Reached target Hardware activated U[ 6.265270] armchina 3050000.aipu: AIPU KMD probe start...
SB gadget.
[ 6.297377] armchina 3050000.aipu: KMD version: release 3.0.13
[ 6.317387] armchina 3050000.aipu: no interrupts-reg specified
[ 6.369388] random: crng init done
[ 6.372808] random: 7 urandom warning(s) missed due to ratelimiting
[ 6.383692] armchina 3050000.aipu: AIPU is not behind an IOMMU
[ 6.404785] armchina 3050000.aipu: AIPU DRAM mem type is [CMA default]
[ 6.460369] armchina 3050000.aipu: init DRAM region done: pa [0x41e00000, 0x443fffff]
[ 6.468322] armchina 3050000.aipu: AIPU core #0 detected: zhouyi-v1-0600
[ 6.475753] armchina 3050000.aipu: AIPU Initial Status: 0x70000
[ 6.490007] armchina 3050000.aipu: ########## AIPU CORE 0: ZHOUYI V1 ##########
[ 6.498449] armchina 3050000.aipu: # ISA Version Register: 0x0
[ 6.504962] armchina 3050000.aipu: # TPC Feature Register: 0x10101
[ 6.513925] armchina 3050000.aipu: # SPU Feature Register: 0x0
[ 6.562343] armchina 3050000.aipu: # HWA Feature Register: 0x10111
[ OK ] Reached targ[ 6.579756] armchina 3050000.aipu: # Revision ID Register: 0x0
et Sound Card.
[ 6.611023] armchina 3050000.aipu: # Memory Hierarchy Feature Register: 0x170
[ 6.630750] armchina 3050000.aipu: # Instruction RAM Feature Register: 0x0
[ OK ] Finished Load/Save Random Seed.
[ 6.717566] armchina 3050000.aipu: # TEC Local SRAM Feature Register: 0x312
[ 6.735882] armchina 3050000.aipu: # Global SRAM Feature Register: 0x10
[ 6.744607] armchina 3050000.aipu: # Instruction Cache Feature Register:0x233
[ 6.762460] armchina 3050000.aipu: # Data Cache Feature Register: 0x70030
[ 6.775882] armchina 3050000.aipu: # L2 Cache Feature Register: 0x0
[ 6.786730] armchina 3050000.aipu: ############################################
[ 6.800004] armchina 3050000.aipu: initialize AIPU core #0 done
[ 6.835119] cfg80211: Loading compiled-in X.509 certificates for regulatory database
[ OK ] Started Network Manager.
[ OK ] Reached target Network.
[ 6.919707] cfg80211: Loaded X.509 cert 'sforshee: 00b28ddf47aef9cea7'
Starting OpenBSD Secure Shell server...
Starting Permit User Sessions...
[ 7.030823] cfg80211: loaded regulatory.db is malformed or signature is missing/invalid
Starting Hostname Service...
[ OK ] Finished Permit User Sessions.
[ OK ] Started Getty on tty1.
[ OK ] Started Serial Getty on ttyS0.
[ OK ] Reached target Login Prompts.
[FAILED] Failed to start OpenBSD Secure Shell server.
See 'systemctl status ssh.service' for details.
[ OK ] Started Modem Manager.
[ OK ] Stopped OpenBSD Secure Shell server.
Starting OpenBSD Secure Shell server...
[FAILED] Failed to start OpenBSD Secure Shell server.
See 'systemctl status ssh.service' for details.
[ OK ] Reached target Multi-User System.
[ OK ] Reached target Graphical Interface.
Starting Update UTMP about System Runlevel Changes...
[ OK ] Listening on Load/Save RF …itch Status /dev/rfkill Watch.
[ OK ] Started Hostname Service.
[ OK ] Stopped OpenBSD Secure Shell server.
Starting OpenBSD Secure Shell server...
[FAILED] Failed to start OpenBSD Secure Shell server.
See 'systemctl status ssh.service' for details.
[ OK ] Finished Update UTMP about System Runlevel Changes.
Debian GNU/Linux 11 maixsense ttyS0
maixsense login: root
Password:
Linux maixsense 5.14.0-rc3+ #107 SMP PREEMPT Fri Jul 30 11:42:44 CST 2021 aarch64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Wed Jul 14 01:34:24 CST 2021 on ttyS0
root@maixsense:~#
重新划分分区
查看分区
debian镜像默认为2个分区,第一分区是boot分区,第二分区为根文件系统所在分区。
默认第二分区是按照根文件系统大小配置,所以启动后会发现可用空间为0,所以首次启动后要先进行分区扩容。
root@maixsense:~/zhouyi_test# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/root 2.0G 2.0G 0 100% /
devtmpfs 55M 0 55M 0% /dev
tmpfs 120M 0 120M 0% /dev/shm
tmpfs 48M 5.7M 43M 12% /run
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 24M 0 24M 0% /run/user/0
1.fdisk /dev/mmcblk0 d 2 #删除第二分区 n p 2 回车 回车 No #重建第二分区,剩余空间全部给第二分区 w #保存配置 2.partx #查看,高速内核去识别等级硬盘信息 3.resize2fs /dev/mmcblk0p2
再次查看分区,至此根分区扩容完成
root@maixsense:~/zhouyi_test# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/root 30G 2.0G 26G 7% /
devtmpfs 55M 0 55M 0% /dev
tmpfs 120M 0 120M 0% /dev/shm
tmpfs 48M 5.7M 43M 12% /run
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 24M 0 24M 0% /run/user/0
为了主机编译,增加SWAP
没有增加SWAP之前
查看内存
root@maixsense:~# free -h
total used free shared buff/cache available
Mem: 238Mi 80Mi 19Mi 5.0Mi 138Mi 143Mi
Swap: 0B 0B 0B
SWAP分区设置
由于R329内置内存较小,运行debian系统没有问题,但是要进行本地编译的话,就必须开启swap分区。
-
1.设置swapness(可以不用设定)
- 1.swappiness参数值可设置范围在0到100之间。 此参数值越低,就会让Linux系统尽量少用swap分区,多用内存;参数值越高就是反过来,使内核更多的去使用swap空间
- 2.
cat /proc/sys/vm/swappiness
- 3.
echo "vm.swappiness = 50" >> /etc/sysctl.conf
#永久修改 - 4.
sysctl -p
#启用内存阈值设置
-
2.创建swap分区
- 1.
cd /opt && dd if=/dev/zero of=swapfile bs=1M count=1024
#1GB swap空间,约2~3分钟 - 2.
mkswap swapfile
- 1.
-
3.开启关闭swap分区
- 开启swap分区:
swapon swapfile
- 关闭swap分区:
swapoff swapfile
- 开启swap分区:
-
4.开机自动挂载swap分区(可以不用设定)
- 1.在/etc/fstab内加入
- 2./opt/swapfile swap swap defaults 0 0
至此已完成swap分区设置,可使用free查看当前内存情况:
root@maixsense:/opt# free -h
total used free shared buff/cache available
Mem: 238Mi 82Mi 2.0Mi 5.0Mi 152Mi 142Mi
Swap: 1.0Gi
Debian系统下zhouyi AIPU的使用
默认镜像的 ~/zhouyi_test 目录下放置了zhouyi_cam 例程和模型,在此用户可以体验本机编译zhouyi程序:
cd ~/zhouyi_test/build
make clean
cmake ..
time make -j2 #注意必须开启swap才能编译通过
编译zhouyi_cam
root@maixsense:~/zhouyi_test# make clean
root@maixsense:~/zhouyi_test# cmake ..
CMake Error: The source directory "/root" does not appear to contain CMakeLists.txt.
Specify --help for usage, or press the help button on the CMake GUI.
root@maixsense:~/zhouyi_test# time make -j2
make: Warning: File 'Makefile' has modification time 1414376 s in the future
-- The C compiler identification is GNU 10.2.1
-- The CXX compiler identification is GNU 10.2.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /root/zhouyi_test
Scanning dependencies of target zhouyi_cam
make[2]: Warning: File 'zhouyi_cam' has modification time 1415252 s in the future
[ 33%] Building C object CMakeFiles/zhouyi_cam.dir/fb_display.c.o
[ 66%] Building CXX object CMakeFiles/zhouyi_cam.dir/main.cpp.o
make[2]: warning: Clock skew detected. Your build may be incomplete.
[100%] Built target zhouyi_cam
make: warning: Clock skew detected. Your build may be incomplete.
real 1m3.067s
user 0m22.707s
sys 0m4.704s
经过漫长的等待,即可得到zhouyi_cam可执行文件,可以本机执行测试。
运行
root@maixsense:~/zhouyi_test# ./zhouyi_cam
[ WARN:0] global ../modules/videoio/src/cap_gstreamer.cpp (501) isPipelinePlaying OpenCV | GStreamer warning: GStreamer: pipeline have not been created
Zhouyi Cam test program:
Usage:
./zhouyi aipu.bin signed [label_oft]
signed=0, uint8 output; =1, int8 output
real_label_idx = predict_idx-label_oft,
NOTE: default cal with 224x224
argc=1 error
没能运行起来!只能看看代码是怎么写的… …
原来还要加参数
root@maixsense:~/zhouyi_test# ./zhouyi_cam aipu.bin 1 predict_idx-label_oft
官方自带的模型:aipu.bin
该模型在main.cpp中实现,通过OpenCV循环读取摄像头数据,送给推理引擎,对采集到的图像进行分类。其中,推理引擎使用AIPU的相关接口。
- 官方自带的模型(aipu.bin)在R329上的推理速度约为20fps
- 发热量很大,工作一分钟就可以达到60度以上(烫手)
- 官方模型:aipu.bin(大小为4832748Byte–4.6MByte)
root@maixsense:~/zhouyi_test# ./zhouyi_cam aipu.bin 1 predict_idx-label_oft
[ WARN:0] global ../modules/videoio/src/cap_gstreamer.cpp (501) isPipelinePlaying OpenCV | GStreamer warning: GStreamer: pipeline have not been created
Zhouyi Cam test program:
Usage:
./zhouyi aipu.bin signed [label_oft]
signed=0, uint8 output; =1, int8 output
real_label_idx = predict_idx-label_oft,
NOTE: default cal with 224x224
LCD width is 240, height is 240
rate is 25.000000
rate is 25.000000
frame_width is 640.000000, frame_height is 480.000000
###L302
[DEMO INFO] AIPU load graph successfully.
###L309
[ 104.945646] armchina 3050000.aipu: [Job 65536 of Thread 272] trigger job running done
Decode Result:
0: class 558, prob 85; label: flute, transverse flute
1: class 734, prob 68; label: police van, police wagon, paddy wagon, patrol wagon, wagon, black Maria
2: class 518, prob 7; label: crash helmet
3: class 463, prob 6; lab[ 105.015724] armchina 3050000.aipu: [Job 65536 of Thread 272] trigger job running done
el: bucket, pail
4: class 796, prob 5; label: ski mask
Decode Result:
0: class 518, prob 24; label: crash helmet
1: class 558, prob 5; label: flute, transverse flute
2: class 665, prob 2; label: moped
[ 105.077712] armchina 3050000.aipu: [Job 65536 of Thread 272] trigger job running done
3: class 755, prob 2; label: radio telescope, radio reflector
4: class 320, prob 1; label: damselfly
Decode Result:
0: class 734, prob 105; label: police van, police wagon, paddy wagon, patrol wagon, wagon, black Maria
[ 105.139823] armchina 3050000.aipu: [Job 65536 of Thread 272] trigger job running done
2: class 558, prob 23; label: flute, transverse flute
3: class 921, prob 8; label: book jacket, dust cover, dust jacket, dust wrapper
4: class 422, prob 4; label: barbell
Decode Result:
0: class 734, prob 79; label: police van, police wagon, paddy wagon, patrol wagon, wagon, black Maria
1: class 518, prob 46; label: crash helmet
2: class [ 105.202471] armchina 3050000.aipu: [Job 65536 of Thread 272] trigger job running done
558, prob 15; label: flute, transverse flute
3: class 665, prob 12; label: moped
4: class 921, prob 6; label: book jacket, dust cover, dust jacket, dust wrapper
...
周易demo代码
main.cpp
/**
* @file main.cpp
* @brief
*
* Copyright (c) 2021 Sipeed team
*
*
*/
extern "C" {
#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include "fbviewer.h"
#include "label.h"
#include <sys/wait.h>
#include <sys/types.h>
}
#include "standard_api.h"
#include <iostream>
#include <sys/time.h>
#include "opencv2/opencv.hpp"
using namespace cv;
#define DBG_LINE() printf("###L%d\r\n", __LINE__)
int label_oft = 1;
typedef struct {
int index;
int8_t val;
} int8_data_t;
typedef struct {
int index;
uint8_t val;
} uint8_data_t;
int uint8_comp_down(const void*p1, const void*p2) {
//<0, 元素1排在元素2之前;即降序
int tmp = (((uint8_data_t*)p2)->val) - (((uint8_data_t*)p1)->val);
return tmp;
}
int int8_comp_down(const void*p1, const void*p2) {
//<0, 元素1排在元素2之前;即降序
int tmp = (((int8_data_t*)p2)->val) - (((int8_data_t*)p1)->val);
return tmp;
}
static void decode_result_int8(int8_t *result, uint32_t size, int* label_idx, int* prob)
{
int8_data_t* buf = (int8_data_t*)malloc(sizeof(int8_data_t)*size);
if(buf == NULL) return;
for(int i=0; i < size; i++) {
buf[i].index = i;
buf[i].val = result[i];
}
qsort(buf, size, sizeof(int8_data_t), int8_comp_down);
printf("Decode Result:\r\n");
for(int i=0; i < 5; i++) {
printf(" %d: class %4d, prob %3d; label: %s\r\n", i, buf[i].index, buf[i].val, labels[buf[i].index-label_oft]);
}
*label_idx = buf[0].index;
*prob = buf[0].val;
free(buf);
return;
}
static void decode_result_uint8(uint8_t *result, uint32_t size, int* label_idx, int* prob)
{
uint8_data_t* buf = (uint8_data_t*)malloc(sizeof(uint8_data_t)*size);
if(buf == NULL) return;
for(int i=0; i < size; i++) {
buf[i].index = i;
buf[i].val = result[i];
}
qsort(buf, size, sizeof(uint8_data_t), uint8_comp_down);
printf("Decode Result:\r\n");
for(int i=0; i < 5; i++) {
if (!buf[i].index && !buf[i].val) continue;
printf(" %d: class %4d, prob %3u; label: %s\r\n", i, buf[i].index, buf[i].val, labels[buf[i].index-label_oft]);
}
*label_idx = buf[0].index;
*prob = buf[0].val;
free(buf);
return;
}
cv::VideoCapture capture(0);
int init_cam(void)
{
int x,y;
getCurrentRes(&x, &y);
printf("LCD width is %d, height is %d\n", x, y);
cv::Mat img;
VideoCapture cap;
cap.isOpened();
if(!capture.isOpened())
{
std::cout<<"video not open."<<std::endl;
return 1;
}
//get default video fps, set fps to 30fps
double rate = capture.get(CAP_PROP_FPS);
printf("rate is %lf\n", rate);
capture.set(CAP_PROP_FPS, 30);
rate = capture.get(CAP_PROP_FPS);
printf("rate is %lf\n", rate);
//get default video frame info
double frame_width = capture.get(CAP_PROP_FRAME_WIDTH);
double frame_height = capture.get(CAP_PROP_FRAME_HEIGHT);
printf("frame_width is %lf, frame_height is %lf\n", frame_width, frame_height);
//set video frame size to QVGA (then we crop to 224x224)
frame_width = 320;
frame_height = 240;
if(!capture.set(CAP_PROP_FRAME_WIDTH,frame_width))
{
printf("set width failed\n");
return 2;
}
if(!capture.set(CAP_PROP_FRAME_HEIGHT, frame_height))
{
printf("set width failed\n");
return 3;
}
return 0;
}
int init_graph(char* file_model, aipu_ctx_handle_t ** ctx, aipu_graph_desc_t* gdesc, aipu_buffer_alloc_info_t* info)
{
const char* status_msg =NULL;
aipu_status_t status = AIPU_STATUS_SUCCESS;
int ret = 0;
//Step1: init ctx handle
status = AIPU_init_ctx(ctx);
if (status != AIPU_STATUS_SUCCESS) {
AIPU_get_status_msg(status, &status_msg);
printf("[DEMO ERROR] AIPU_init_ctx: %s\n", status_msg);
ret = -1;
//goto out;
}
//Step2: load graph
status = AIPU_load_graph_helper(*ctx, file_model, gdesc);
if (status != AIPU_STATUS_SUCCESS) {
AIPU_get_status_msg(status, &status_msg);
printf("[DEMO ERROR] AIPU_load_graph_helper: %s\n", status_msg);
ret = -2;
//goto deinit_ctx;
}
printf("[DEMO INFO] AIPU load graph successfully.\n");
//Step3: alloc tensor buffers
status = AIPU_alloc_tensor_buffers(*ctx, gdesc, info);
if (status != AIPU_STATUS_SUCCESS) {
AIPU_get_status_msg(status, &status_msg);
printf("[DEMO ERROR] AIPU_alloc_tensor_buffers: %s\n", status_msg);
ret = -3;
//goto unload_graph;
}
return ret;
}
int cap_img(Mat* lcd_frame, Mat* ai_frame)
{
Rect roi(40, 0, 240/4*3, 240); //16/9 -> 4/3
Rect input_roi(8, 8, 224, 224);
Size dsize = Size(240, 240);
if(!capture.read(*lcd_frame))
{
printf("no video frame\r\n");
return -1;
}
*lcd_frame = (*lcd_frame)(roi).clone();
rotate(*lcd_frame, *lcd_frame, ROTATE_180);
resize(*lcd_frame, *lcd_frame, dsize);
cvtColor(*lcd_frame, *lcd_frame, COLOR_BGR2RGB);
*ai_frame = (*lcd_frame)(input_roi).clone() + Scalar(-123, -117,-104);
//imwrite("/tmp/1.bmp", (*lcd_frame)(input_roi).clone());
return 0;
}
int infer_img(Mat* ai_frame, aipu_ctx_handle_t ** ctx, aipu_graph_desc_t* gdesc, aipu_buffer_alloc_info_t* info, int signed_flag, int* label_idx, int* label_prob)
{
uint32_t job_id=0;
const char* status_msg =NULL;
int32_t time_out=-1;
bool finish_job_successfully = true;
aipu_status_t status = AIPU_STATUS_SUCCESS;
int ret = 0;
memcpy(info->inputs.tensors[0].va, ai_frame->data, info->inputs.tensors[0].size);
status = AIPU_create_job(*ctx, gdesc, info->handle, &job_id);
if (status != AIPU_STATUS_SUCCESS) {
AIPU_get_status_msg(status, &status_msg);
printf("[DEMO ERROR] AIPU_create_job: %s\n", status_msg);
ret = -1;
//goto free_tensor_buffers;
}
status = AIPU_finish_job(*ctx, job_id, time_out);
if (status != AIPU_STATUS_SUCCESS) {
AIPU_get_status_msg(status, &status_msg);
printf("[DEMO ERROR] AIPU_finish_job: %s\n", status_msg);
finish_job_successfully = false;
} else {
finish_job_successfully = true;
}
if (finish_job_successfully) {
int8_t *result = (int8_t *)info->outputs.tensors[0].va;
uint32_t size = info->outputs.tensors[0].size;
if(signed_flag == 0) {
decode_result_uint8((uint8_t*)result, size, label_idx, label_prob);
} else {
decode_result_int8(result, size, label_idx, label_prob);
}
}
status = AIPU_clean_job(*ctx, job_id);
if (status != AIPU_STATUS_SUCCESS) {
AIPU_get_status_msg(status, &status_msg);
printf("[TEST ERROR] AIPU_clean_job: %s\n", status_msg);
ret = -2;
//goto free_tensor_buffers;
}
return ret;
}
float cal_fps(struct timeval start, struct timeval end)
{
struct timeval interval;
if (end.tv_usec >= start.tv_usec) {
interval.tv_usec = end.tv_usec - start.tv_usec;
interval.tv_sec = end.tv_sec - start.tv_sec;
} else {
interval.tv_usec = 1000000 + end.tv_usec - start.tv_usec;
interval.tv_sec = end.tv_sec - 1 - start.tv_sec;
}
float fps = 1000000.0 / interval.tv_usec;
return fps;
}
volatile int exit_flag = 0;
void my_handler(int s){
printf("Caught signal %d\n",s);
exit_flag = 1;
return;
}
int main(int argc, char *argv[])
{
int ret = 0;
uint32_t job_id=0;
int32_t time_out=-1;
bool finish_job_successfully = true;
int model_inw, model_inh, model_inch, model_outw, model_outh, model_outch, img_size;
int8_t* bmpbuf;
cv::Mat lcd_frame;
cv::Mat ai_frame;
int label_idx, label_prob;
struct timeval start, end;
signal(SIGINT, my_handler);
printf("Zhouyi Cam test program: \r\n");
printf("Usage: \r\n");
printf(" ./zhouyi aipu.bin signed [label_oft]\r\n");
printf(" signed=0, uint8 output; =1, int8 output\r\n");
printf(" real_label_idx = predict_idx-label_oft, \r\n");
printf(" NOTE: default cal with 224x224\r\n");
aipu_ctx_handle_t * ctx = NULL;
aipu_status_t status = AIPU_STATUS_SUCCESS;
const char* status_msg =NULL;
aipu_graph_desc_t gdesc;
aipu_buffer_alloc_info_t info;
//Step 0: parse input argv
if(argc < 3) {
printf("argc=%d error\r\n", argc);
return -1;
}
if(argc >3) label_oft = atoi(argv[3]);
char* file_model= argv[1];
int signed_flag = atoi(argv[2]);
//Step 1: set USB camera
ret = init_cam();DBG_LINE();
if(ret != 0) {
printf("[DEMO ERROR] init_cam err: %s\n", ret);
goto out;
}
//Step 2: init model graph
ret = init_graph(file_model, &ctx, &gdesc, &info);DBG_LINE();
if(ret == -1) goto out;
else if(ret == -2) goto deinit_ctx;
else if(ret == -3) goto unload_graph;
//MAIN LOOP
while(!exit_flag)
{
//1. cap cam img
if(cap_img(&lcd_frame, &ai_frame) != 0) {
break;
}
//2. infer cam img, get label
gettimeofday(&start, NULL);
ret = infer_img(&ai_frame, &ctx, &gdesc, &info, signed_flag, &label_idx, &label_prob);
if(ret != 0) goto free_tensor_buffers;
gettimeofday(&end, NULL);
//3. draw lcd
putText(lcd_frame, labels[label_idx-label_oft], Point(0, 224), cv::FONT_HERSHEY_PLAIN, 1, Scalar(255,0,0), 2);
float fps = cal_fps(start, end);
char fps_str[16];
sprintf(fps_str, "%.1ffps", fps);
putText(lcd_frame, fps_str, Point(0, 16), cv::FONT_HERSHEY_PLAIN, 1, Scalar(255,0,0), 2);
fb_display(lcd_frame.data, 0, 240, 240, 0, 0, 0, 0);
}
free_tensor_buffers:
status = AIPU_free_tensor_buffers(ctx, info.handle);
if (status != AIPU_STATUS_SUCCESS) {
AIPU_get_status_msg(status, &status_msg);
printf("[DEMO ERROR] AIPU_free_tensor_buffers: %s\n", status_msg);
ret = -1;
}
unload_graph:
status = AIPU_unload_graph(ctx, &gdesc);
if (status != AIPU_STATUS_SUCCESS) {
AIPU_get_status_msg(status, &status_msg);
printf("[DEMO ERROR] AIPU_unload_graph: %s\n", status_msg);
ret = -1;
}
deinit_ctx:
status = AIPU_deinit_ctx(ctx);
if (status != AIPU_STATUS_SUCCESS) {
AIPU_get_status_msg(status, &status_msg);
printf("[DEMO ERROR] AIPU_deinit_ctx: %s\n", status_msg);
ret = -1;
}
out:
return ret;
}
fb_display.c
#define IDSTRING "fbviewer 1.0"
#define DEFAULT_FRAMEBUFFER "/dev/fb0"
#define FBV_SUPPORT_JPEG
#define FBV_SUPPORT_PNG
#define FBV_SUPPORT_BMP
#include <linux/fb.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <asm/types.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Public Use Functions:
*
* extern int fb_display(unsigned char *rgbbuff,
* int x_size, int y_size,
* int x_pan, int y_pan,
* int x_offs, int y_offs);
*
* extern int getCurrentRes(int *x,int *y);
*
*/
__u16 red[256], green[256], blue[256];
struct fb_cmap map332 = {0, 256, red, green, blue, NULL};
__u16 red_b[256], green_b[256], blue_b[256];
struct fb_cmap map_back = {0, 256, red_b, green_b, blue_b, NULL};
int openFB(const char *name);
void closeFB(int fh);
void getVarScreenInfo(int fh, struct fb_var_screeninfo *var);
void setVarScreenInfo(int fh, struct fb_var_screeninfo *var);
void getFixScreenInfo(int fh, struct fb_fix_screeninfo *fix);
void set332map(int fh);
void* convertRGB2FB(int fh, unsigned char *rgbbuff, unsigned long count, int bpp, int *cpp);
void blit2FB(int fh, unsigned char *fbbuff, unsigned char *alpha,
unsigned int pic_xs, unsigned int pic_ys,
unsigned int scr_xs, unsigned int scr_ys,
unsigned int xp, unsigned int yp,
unsigned int xoffs, unsigned int yoffs,
int cpp);
int fb_display(unsigned char *rgbbuff, unsigned char * alpha,
unsigned int x_size, unsigned int y_size,
unsigned int x_pan, unsigned int y_pan,
unsigned int x_offs, unsigned int y_offs)
{
struct fb_var_screeninfo var;
struct fb_fix_screeninfo fix;
unsigned char *fbbuff = NULL;
int fh = -1, bp = 0;
unsigned int x_stride;
/* get the framebuffer device handle */
fh = openFB(NULL);
if(fh == -1)
return -1;
/* read current video mode */
getVarScreenInfo(fh, &var);
getFixScreenInfo(fh, &fix);
x_stride = (fix.line_length * 8) / var.bits_per_pixel;
/* correct panning */
if(x_pan > x_size - x_stride) x_pan = 0;
if(y_pan > y_size - var.yres) y_pan = 0;
/* correct offset */
if(x_offs + x_size > x_stride) x_offs = 0;
if(y_offs + y_size > var.yres) y_offs = 0;
/* blit buffer 2 fb */
fbbuff = (unsigned char*)convertRGB2FB(fh, rgbbuff, x_size * y_size, var.bits_per_pixel, &bp);
#if 0
blit2FB(fh, fbbuff, alpha, x_size, y_size, x_stride, var.yres, x_pan, y_pan, x_offs, y_offs, bp);
#else
blit2FB(fh, fbbuff, alpha, x_size, y_size, x_stride, var.yres_virtual, x_pan, y_pan, x_offs, y_offs + var.yoffset, bp);
#endif
free(fbbuff);
/* close device */
closeFB(fh);
return 0;
}
int getCurrentRes(int *x, int *y)
{
struct fb_var_screeninfo var;
int fh;
fh = openFB(NULL);
if(fh == -1)
return -1;
getVarScreenInfo(fh, &var);
*x = var.xres;
*y = var.yres;
closeFB(fh);
return 0;
}
int openFB(const char *name)
{
int fh;
char *dev;
if(name == NULL)
{
dev = getenv("FRAMEBUFFER");
if(dev) name = dev;
else name = DEFAULT_FRAMEBUFFER;
}
if((fh = open(name, O_RDWR)) == -1)
{
fprintf(stderr, "open %s: %s\n", name, strerror(errno));
return -1;
}
return fh;
}
void closeFB(int fh)
{
close(fh);
}
void getVarScreenInfo(int fh, struct fb_var_screeninfo *var)
{
if(ioctl(fh, FBIOGET_VSCREENINFO, var))
{
fprintf(stderr, "ioctl FBIOGET_VSCREENINFO: %s\n", strerror(errno));
exit(1);
}
}
void setVarScreenInfo(int fh, struct fb_var_screeninfo *var)
{
if(ioctl(fh, FBIOPUT_VSCREENINFO, var))
{
fprintf(stderr, "ioctl FBIOPUT_VSCREENINFO: %s\n", strerror(errno));
exit(1);
}
}
void getFixScreenInfo(int fh, struct fb_fix_screeninfo *fix)
{
if (ioctl(fh, FBIOGET_FSCREENINFO, fix))
{
fprintf(stderr, "ioctl FBIOGET_FSCREENINFO: %s\n", strerror(errno));
exit(1);
}
}
void make332map(struct fb_cmap *map)
{
int rs, gs, bs, i;
int r = 8, g = 8, b = 4;
map->red = red;
map->green = green;
map->blue = blue;
rs = 256 / (r - 1);
gs = 256 / (g - 1);
bs = 256 / (b - 1);
for (i = 0; i < 256; i++)
{
map->red[i] = (rs * ((i / (g * b)) % r)) * 255;
map->green[i] = (gs * ((i / b) % g)) * 255;
map->blue[i] = (bs * ((i) % b)) * 255;
}
}
void set8map(int fh, struct fb_cmap *map)
{
if (ioctl(fh, FBIOPUTCMAP, map) < 0)
{
fprintf(stderr, "Error putting colormap");
exit(1);
}
}
void get8map(int fh, struct fb_cmap *map)
{
if (ioctl(fh, FBIOGETCMAP, map) < 0)
{
fprintf(stderr, "Error getting colormap");
exit(1);
}
}
void set332map(int fh)
{
make332map(&map332);
set8map(fh, &map332);
}
void blit2FB(int fh, unsigned char *fbbuff, unsigned char *alpha,
unsigned int pic_xs, unsigned int pic_ys,
unsigned int scr_xs, unsigned int scr_ys,
unsigned int xp, unsigned int yp,
unsigned int xoffs, unsigned int yoffs,
int cpp)
{
int i, xc, yc;
unsigned char *fb;
unsigned char *fbptr;
unsigned char *imptr;
xc = (pic_xs > scr_xs) ? scr_xs : pic_xs;
yc = (pic_ys > scr_ys) ? scr_ys : pic_ys;
fb = (unsigned char*)mmap(NULL, scr_xs * scr_ys * cpp, PROT_WRITE | PROT_READ, MAP_SHARED, fh, 0);
if(fb == MAP_FAILED)
{
perror("mmap");
return;
}
if(cpp == 1)
{
get8map(fh, &map_back);
set332map(fh);
}
fbptr = fb + (yoffs * scr_xs + xoffs) * cpp;
imptr = fbbuff + (yp * pic_xs + xp) * cpp;
if(alpha)
{
unsigned char * alphaptr;
int from, to, x;
alphaptr = alpha + (yp * pic_xs + xp);
for(i = 0; i < yc; i++, fbptr += scr_xs * cpp, imptr += pic_xs * cpp, alphaptr += pic_xs)
{
for(x = 0; x<xc; x++)
{
int v;
from = to = -1;
for(v = x; v<xc; v++)
{
if(from == -1)
{
if(alphaptr[v] > 0x80) from = v;
}
else
{
if(alphaptr[v] < 0x80)
{
to = v;
break;
}
}
}
if(from == -1)
break;
if(to == -1) to = xc;
memcpy(fbptr + (from * cpp), imptr + (from * cpp), (to - from - 1) * cpp);
x += to - from - 1;
}
}
}
else
for(i = 0; i < yc; i++, fbptr += scr_xs * cpp, imptr += pic_xs * cpp)
memcpy(fbptr, imptr, xc * cpp);
if(cpp == 1)
set8map(fh, &map_back);
munmap(fb, scr_xs * scr_ys * cpp);
}
inline static unsigned char make8color(unsigned char r, unsigned char g, unsigned char b)
{
return (
(((r >> 5) & 7) << 5) |
(((g >> 5) & 7) << 2) |
((b >> 6) & 3) );
}
inline static unsigned short make15color(unsigned char r, unsigned char g, unsigned char b)
{
return (
(((r >> 3) & 31) << 10) |
(((g >> 3) & 31) << 5) |
((b >> 3) & 31) );
}
inline static unsigned short make16color(unsigned char r, unsigned char g, unsigned char b)
{
return (
(((r >> 3) & 31) << 11) |
(((g >> 2) & 63) << 5) |
((b >> 3) & 31) );
}
void* convertRGB2FB(int fh, unsigned char *rgbbuff, unsigned long count, int bpp, int *cpp)
{
unsigned long i;
void *fbbuff = NULL;
u_int8_t *c_fbbuff;
u_int16_t *s_fbbuff;
u_int32_t *i_fbbuff;
switch(bpp)
{
case 8:
*cpp = 1;
c_fbbuff = (unsigned char *) malloc(count * sizeof(unsigned char));
for(i = 0; i < count; i++)
c_fbbuff[i] = make8color(rgbbuff[i*3], rgbbuff[i*3+1], rgbbuff[i*3+2]);
fbbuff = (void *) c_fbbuff;
break;
case 15:
*cpp = 2;
s_fbbuff = (unsigned short *) malloc(count * sizeof(unsigned short));
for(i = 0; i < count ; i++)
s_fbbuff[i] = make15color(rgbbuff[i*3], rgbbuff[i*3+1], rgbbuff[i*3+2]);
fbbuff = (void *) s_fbbuff;
break;
case 16:
*cpp = 2;
s_fbbuff = (unsigned short *) malloc(count * sizeof(unsigned short));
for(i = 0; i < count ; i++)
s_fbbuff[i] = make16color(rgbbuff[i*3], rgbbuff[i*3+1], rgbbuff[i*3+2]);
fbbuff = (void *) s_fbbuff;
break;
case 24:
case 32:
*cpp = 4;
i_fbbuff = (unsigned int *) malloc(count * sizeof(unsigned int));
for(i = 0; i < count ; i++)
i_fbbuff[i] = ((0xFF << 24) & 0xFF000000) |
((rgbbuff[i*3] << 16) & 0xFF0000) |
((rgbbuff[i*3+1] << 8) & 0xFF00) |
(rgbbuff[i*3+2] & 0xFF);
fbbuff = (void *) i_fbbuff;
break;
default:
fprintf(stderr, "Unsupported video mode! You've got: %dbpp\n", bpp);
exit(1);
}
return fbbuff;
}