Regular readers will know that Firefly team sent me several of their Rockchip boards for evaluation, and I started with a review of ROC-RK3328-CC development board powered by Rockchip RK3328 processor. This time, I went with the high-end AIO-3399J board comprised of a features-packed baseboard and a Rockchip RK3399 system-on-module.
Just like with the previous review, I’ve decided to focus on Linux support, in this case Xunbuntu 16.04, and I’ll do an Android review on the company releases Android 8.1 for Firefly-RK3399 board.
First Boot with AIO-3399J Board
Before booting the board, I inserted the heatsink, and connected the provided WiFi antennas. I also connected some devices and cables, including a mouse, the male to male USB cable to the top USB 3.0 (OTG) port for firmware update, a HDMI cable to my TV, and Ethernet cable, as well as the serial debug board.
The final step was to connect the 12V power supply, and I immediately got output to the serial console (/dev/ttyUSB0 configured with 1,500,000 bps 8N1, no hardware flow control), and a few seconds later the Android 7.1 launcher showed up.
But I wanted to run a Linux distributions, so I went over the download page, and selected the latest Ubuntu 16.04 image (AIO-3399J_xubuntu1604_20180119.7z), which actually happens to be Xubuntu 16.04 (Ubuntu + Xfce desktop environment). Just make sure you select “Google Drive” instead of “Official” if you are outside of China, as the download speed should be much higher that way.
Now that we have out firmware file, we just need to follow the upgrade instructions for Linux or Windows with respectively Linux_Upgrade_Tool or AndroidTool.
My computer is running Ubuntu 18.04, so I went with the Linux method. First you need to make you’ve connected your male to male USB cable between your computer and the board with power connected.
We need to enter “loader mode” as follows: keep pressing the recovery button, press and release the reset button, and about two seconds later, release the recovery button.
If everything is working as expected, the serial console output should look like:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
DDR Version 1.08 20170320 In Channel 0: DDR3, 800MHz Bus Width=32 Col=10 Bank=8 Row=15 CS=1 Die Bus-Width=16 Size=1024MB Channel 1: DDR3, 800MHz Bus Width=32 Col=10 Bank=8 Row=15 CS=1 Die Bus-Width=16 Size=1024MB 256B stride ch 0 ddrconfig = 0x101, ddrsize = 0x20 ch 1 ddrconfig = 0x101, ddrsize = 0x20 pmugrf_os_reg[2] = 0x32817281, stride = 0x9 OUT Boot1: 2017-06-09, version: 1.09 CPUId = 0x0 ChipType = 0x10, 1836 SdmmcInit=2 0 BootCapSize=100000 UserCapSize=14910MB FwPartOffset=2000 , 100000 SdmmcInit=0 20 StorageInit ok = 66829 LoadTrustBL No find bl30.bin Load uboot, ReadLba = 2000 Load OK, addr=0x200000, size=0x77d6c RunBL31 0x10000 NOTICE: BL31: v1.3(debug):9f93abc NOTICE: BL31: Built : 10:18:20, Jul 27 2017 NOTICE: BL31: Rockchip release version: v1.1 INFO: GICv3 with legacy support detected. ARM GICV3 driver initialized in EL3 INFO: plat_rockchip_pmu_init(1089): pd status 3e INFO: BL31: Initializing runtime services INFO: BL31: Initializing BL32 INF [0x0] TEE-CORE:init_primary_helper:337: Initializing (1.1.0-96-g3fbe315-dev) INF [0x0] TEE-CORE:init_primary_helper:338: Release version: 1.1 INF [0x0] TEE-CORE:init_teecore:83: teecore inits done INFO: BL31: Preparing for EL3 exit to normal world INFO: Entry point address = 0x200000 INFO: SPSR = 0x3c9 U-Boot 2014.10-RK3399-06 (Mar 13 2018 - 09:22:52) CPU: rk3399 cpu version = 0 CPU's clock information: aplll = 816000000HZ apllb = 24000000HZ gpll = 800000000HZ aclk_periph_h = 133333333HZ, hclk_periph_h = 66666666HZ, pclk_peZ aclk_periph_l0 = 100000000HZ, hclk_periph_l0 = 100000000HZ, pclkZ hclk_periph_l1 = 100000000HZ, pclk_periph_l1 = 50000000HZ cpll = 800000000HZ dpll = 800000000HZ vpll = 24000000HZ npll = 24000000HZ ppll = 676000000HZ Board: Rockchip platform Board Uboot as second level loader DRAM: Found dram banks: 1 Adding bank:0000000000200000(000000007fe00000) Reserve memory for trust os. dram reserve bank: base = 0x08400000, size = 0x01000000 128 MiB SdmmcInit = 0 20 storage init OK! Using default environment GetParam remotectl v0.1 pwm freq=0xb8320 pwm_freq_nstime=0x52d Load FDT from resource image. power key: bank-0 pin-5 can't find dts node for fixed usb bc: can find node by path: /dwc-control-usb/usb_bc pmic:rk808 can't find dts node for pwm1 set pwm voltage ok,pwm_id =2 vol=1000000,pwm_value=66 CPU's clock information: aplll = 816000000HZ apllb = 24000000HZ gpll = 800000000HZ aclk_periph_h = 133333333HZ, hclk_periph_h = 66666666HZ, pclk_peZ aclk_periph_l0 = 100000000HZ, hclk_periph_l0 = 100000000HZ, pclkZ hclk_periph_l1 = 100000000HZ, pclk_periph_l1 = 50000000HZ cpll = 800000000HZ dpll = 800000000HZ vpll = 24000000HZ npll = 24000000HZ ppll = 676000000HZ SecureBootEn = 0, SecureBootLock = 0 #Boot ver: 2018-03-13#1.09 empty serial no. normal boot. checkKey vbus = 1 rockusb key pressed. |
If you have not setup the serial console, that should not be a problem, and after uncompressing the firmware, we can flash it as follows:
|
1 |
sudo upgrade_tool uf AIO-3399J_xubuntu1604_20170119.img |
This normally take about a minute or so, and that’s the output from the command upon success:
|
1 2 3 4 |
Loading firmware... Support Type:RK330C FW Ver:6.0.01 FW Time:2018-01-19 11:39:11 Loader ver:1.05 Loader Time:2017-04-25 15:10:44 Upgrade firmware ok. |
The board will be automatically reboot, and Xubuntu desktop should show on your HDMI TV/monitor after a few seconds.
I then remove the male to male USB cable, and instead added a USB keyboard, and a USB 3.0 drive. You may notice I had some overscan issues (edges cut) in the photo above, but setting aspect ratio to “Just Scan” in my LG television fixed the issue.
Here’s the very first boot serial log for reference:
|
1 |
The kernel booted in about 20 seconds.
Some system info with the usual commands:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
root@firefly:~# cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=16.04 DISTRIB_CODENAME=xenial DISTRIB_DESCRIPTION="Ubuntu 16.04.2 LTS" root@firefly:~# uname -a Linux firefly 4.4.77 #836 SMP Fri Jan 19 10:37:54 HKT 2018 aarch64 aarch64 aarcx root@firefly:~# df -h Filesystem Size Used Avail Use% Mounted on /dev/root 15G 2.1G 12G 15% / devtmpfs 955M 0 955M 0% /dev tmpfs 956M 172K 956M 1% /dev/shm tmpfs 956M 9.1M 947M 1% /run tmpfs 5.0M 4.0K 5.0M 1% /run/lock tmpfs 956M 0 956M 0% /sys/fs/cgroup tmpfs 192M 44K 192M 1% /run/user/1000 tmpfs 192M 0 192M 0% /run/user/0 /dev/sda1 245G 182G 63G 75% /media/firefly/USB3_NTFS /dev/sda2 241G 181G 48G 80% /media/firefly/USB3_EXT4 root@firefly:~# free -mh total used free shared buff/cache available Mem: 1.9G 577M 894M 27M 438M 1.2G Swap: 0B 0B 0B |
It’s not exactly the most recent Ubuntu version, but everything else is as expected with a 15GB rootfs, and around 1.9GB total RAM. I won’t update Ubuntu at first, in case this breaks a few things, but I’ll do it later in this review. The board detect all four partitions on my drives, but can only mount NTFS and EXT4 partition, since exFAT and BTRFS are not enabled in the kernel.
No modules are loaded since they are built-in the kernel like with ROC-RK3328-C, and gpios appears to be enable:
|
1 2 3 4 |
root@firefly:~# lsmod Module Size Used by root@firefly:~# ls /sys/class/gpio/ export gpiochip0 gpiochip128 gpiochip32 gpiochip64 gpiochip96 unexport |
Firefly has one of the best documentation for drivers and I/Os I’ve seen so far, and they explain how to define the behavior in device tree files, program the drivers in C language, and debug with sysfs.
For example, we can see more details about the pins with the following commands:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
cat /sys/kernel/debug/gpio GPIOs 0-31, platform/pinctrl, gpio0: gpio-4 ( |bt_default_wake_host) in hi gpio-5 ( |GPIO Key Power ) in hi gpio-9 ( |bt_default_reset ) out hi gpio-10 ( |reset ) out hi gpio-13 ( |vcc3v3_pcie ) out hi GPIOs 32-63, platform/pinctrl, gpio1: gpio-32 ( |vcc5v0_host ) out hi gpio-33 ( |vcc_lcd ) out hi gpio-34 ( |irq-gpio ) in hi gpio-35 ( |vbus_5v ) out hi gpio-42 ( |cs-gpio ) out hi gpio-45 ( |pmic-hold-gpio ) out hi gpio-46 ( |vsel ) out lo gpio-49 ( |reset-gpio ) out hi gpio-52 ( |sdpwr-gpio ) out hi gpio-56 ( |pmic-stby-gpio ) out hi GPIOs 64-95, platform/pinctrl, gpio2: gpio-66 ( |? ) out lo gpio-68 ( |power-gpio ) out hi gpio-70 ( |vcc3v3_3g ) out hi gpio-71 ( |? ) out hi gpio-83 ( |bt_default_rts ) out lo gpio-90 ( |bt_default_wake ) out hi GPIOs 96-127, platform/pinctrl, gpio3: gpio-111 ( |mdio-reset ) out hi GPIOs 128-159, platform/pinctrl, gpio4: gpio-149 ( |hp-con-gpio ) out lo |
Commands to turn off and on again one of the Blue LED close to the DC jack:
|
1 2 |
echo 0 >/sys/class/leds/firefly:blue:power/brightness echo 1 >/sys/class/leds/firefly:blue:power/brightness |
Command to read ADC values using sysfs:
|
1 2 3 4 5 6 7 |
cat /sys/bus/iio/devices/iio\:device0/in_voltage*_raw 1023 1022 3 808 6 717 |
and some PWM info:
|
1 2 3 4 5 6 7 8 9 |
cat /sys/kernel/debug/pwm platform/ff420020.pwm, 1 PWM device pwm-0 (vdd-log ): requested enabled period: 24997 ns duty: 16754 ns pe platform/ff420010.pwm, 1 PWM device pwm-0 ((null) ): period: 0 ns duty: 0 ns polarity: normal platform/ff420000.pwm, 1 PWM device pwm-0 ((null) ): period: 0 ns duty: 0 ns polarity: normal |
AIo-3399J has many I/O headers, and all marked on the other side of the board.
3D Graphics (OpenGL ES) on AIO3399-J with Ubuntu 16.04
Let’s move to test whether 3D graphics acceleration is enabled by installating the usual tools:
|
1 |
apt install mesa-utils-extra glmark2-es2 |
es2_info reports Arm Midgard r13p0 GPU driver is indeed loaded:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
es2_info EGL_VERSION: 1.4 Midgard-"r13p0-00rel0" EGL_VENDOR: ARM EGL_EXTENSIONS: EGL_KHR_image_pixmap, EGL_KHR_partial_update, EGL_KHR_config_attribs, EGL_KHR_image, EGL_KHR_image_base, EGL_KHR_fence_sync, EGL_KHR_wait_sync, EGL_KHR_gl_colorspace, EGL_KHR_get_all_proc_addresses, EGL_IMG_context_priority, EGL_ARM_pixmap_multisample_discard, EGL_KHR_gl_texture_2D_image, EGL_KHR_gl_renderbuffer_image, EGL_KHR_create_context, EGL_KHR_surfaceless_context, EGL_KHR_gl_texture_cubemap_image, EGL_EXT_create_context_robustness, EGL_KHR_cl_event2 EGL_CLIENT_APIS: OpenGL_ES GL_VERSION: OpenGL ES 3.2 v1.r13p0-00rel0-git(a4271c9).31ba04af2d3c01618138bef3aed66c2c GL_RENDERER: Mali-T860 GL_EXTENSIONS: GL_ARM_rgba8, GL_ARM_mali_shader_binary, GL_OES_depth24, GL_OES_depth_texture, GL_OES_depth_texture_cube_map, GL_OES_packed_depth_stencil, GL_OES_rgb8_rgba8, GL_EXT_read_format_bgra, GL_OES_compressed_paletted_texture, GL_OES_compressed_ETC1_RGB8_texture, GL_OES_standard_derivatives, GL_OES_EGL_image, GL_OES_EGL_image_external, GL_OES_EGL_image_external_essl3, GL_OES_EGL_sync, GL_OES_texture_npot, GL_OES_vertex_half_float, GL_OES_required_internalformat, GL_OES_vertex_array_object, GL_OES_mapbuffer, GL_EXT_texture_format_BGRA8888, GL_EXT_texture_rg, GL_EXT_texture_type_2_10_10_10_REV, GL_OES_fbo_render_mipmap, GL_OES_element_index_uint, GL_EXT_shadow_samplers, GL_OES_texture_compression_astc, GL_KHR_texture_compression_astc_ldr, GL_KHR_texture_compression_astc_hdr, GL_KHR_texture_compression_astc_sliced_3d, GL_KHR_debug, GL_EXT_occlusion_query_boolean, GL_EXT_disjoint_timer_query, GL_EXT_blend_minmax, GL_EXT_discard_framebuffer, GL_OES_get_program_binary, GL_OES_texture_3D, GL_EXT_texture_storage, GL_EXT_multisampled_render_to_texture, GL_OES_surfaceless_context, GL_OES_texture_stencil8, GL_EXT_shader_pixel_local_storage, GL_ARM_shader_framebuffer_fetch, GL_ARM_shader_framebuffer_fetch_depth_stencil, GL_ARM_mali_program_binary, GL_EXT_sRGB, GL_EXT_sRGB_write_control, GL_EXT_texture_sRGB_decode, GL_KHR_blend_equation_advanced, GL_KHR_blend_equation_advanced_coherent, GL_OES_texture_storage_multisample_2d_array, GL_OES_shader_image_atomic, GL_EXT_robustness, GL_EXT_draw_buffers_indexed, GL_OES_draw_buffers_indexed, GL_EXT_texture_border_clamp, GL_OES_texture_border_clamp, GL_EXT_texture_cube_map_array, GL_OES_texture_cube_map_array, GL_OES_sample_variables, GL_OES_sample_shading, GL_OES_shader_multisample_interpolation, GL_EXT_shader_io_blocks, GL_OES_shader_io_blocks, GL_EXT_tessellation_shader, GL_OES_tessellation_shader, GL_EXT_primitive_bounding_box, GL_OES_primitive_bounding_box, GL_EXT_geometry_shader, GL_OES_geometry_shader, GL_ANDROID_extension_pack_es31a, GL_EXT_gpu_shader5, GL_OES_gpu_shader5, GL_EXT_texture_buffer, GL_OES_texture_buffer, GL_EXT_copy_image, GL_OES_copy_image, GL_EXT_color_buffer_half_float, GL_EXT_color_buffer_float, GL_EXT_YUV_target, GL_OVR_multiview, GL_OVR_multiview2, GL_OVR_multiview_multisampled_render_to_texture, GL_KHR_robustness, GL_KHR_robust_buffer_access_behavior, GL_EXT_draw_elements_base_vertex, GL_OES_draw_elements_base_vertex |
es2gears works OK with Midgard driver at around 55 fps.
glmark2-es2 could also run just fine, and with more sample than on ROC-RK3328-CC since OpenGL ES 3.2 is supported (and not just version 2.0),
glmark2-es2 output:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
glmark2-es2 ======================================================= glmark2 2014.03+git20150611.fa71af2d ======================================================= OpenGL Information GL_VENDOR: ARM GL_RENDERER: Mali-T860 GL_VERSION: OpenGL ES 3.2 v1.r13p0-00rel0-git(a4271c9).31ba04af2d3c01618138bef3aed66c2c ======================================================= [build] use-vbo=false: FPS: 47 FrameTime: 21.277 ms [build] use-vbo=true: FPS: 51 FrameTime: 19.608 ms [texture] texture-filter=nearest: FPS: 55 FrameTime: 18.182 ms [texture] texture-filter=linear: FPS: 57 FrameTime: 17.544 ms [texture] texture-filter=mipmap: FPS: 56 FrameTime: 17.857 ms [shading] shading=gouraud: FPS: 56 FrameTime: 17.857 ms [shading] shading=blinn-phong-inf: FPS: 57 FrameTime: 17.544 ms [shading] shading=phong: FPS: 56 FrameTime: 17.857 ms [shading] shading=cel: FPS: 55 FrameTime: 18.182 ms [bump] bump-render=high-poly: FPS: 49 FrameTime: 20.408 ms [bump] bump-render=normals: FPS: 55 FrameTime: 18.182 ms [bump] bump-render=height: FPS: 56 FrameTime: 17.857 ms [effect2d] kernel=0,1,0;1,-4,1;0,1,0;: FPS: 52 FrameTime: 19.231 ms [effect2d] kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;: FPS: 33 FrameTime: 30.303 ms [pulsar] light=false:quads=5:texture=false: FPS: 57 FrameTime: 17.544 ms [desktop] blur-radius=5:effect=blur:passes=1:separable=true:windows=4: FPS: 34 FrameTime: 29.412 ms [desktop] effect=shadow:windows=4: FPS: 57 FrameTime: 17.544 ms [buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=map: FPS: 29 FrameTime: 34.483 ms [buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=subdata: FPS: 30 FrameTime: 33.333 ms [buffer] columns=200:interleave=true:update-dispersion=0.9:update-fraction=0.5:update-method=map: FPS: 33 FrameTime: 30.303 ms [ideas] speed=duration: FPS: 44 FrameTime: 22.727 ms [jellyfish] <default>: FPS: 48 FrameTime: 20.833 ms [terrain] <default>: FPS: 18 FrameTime: 55.556 ms [shadow] <default>: FPS: 43 FrameTime: 23.256 ms [refract] <default>: FPS: 32 FrameTime: 31.250 ms [conditionals] fragment-steps=0:vertex-steps=0: FPS: 57 FrameTime: 17.544 ms [conditionals] fragment-steps=5:vertex-steps=0: FPS: 55 FrameTime: 18.182 ms [conditionals] fragment-steps=0:vertex-steps=5: FPS: 55 FrameTime: 18.182 ms [function] fragment-complexity=low:fragment-steps=5: FPS: 56 FrameTime: 17.857 ms [function] fragment-complexity=medium:fragment-steps=5: FPS: 52 FrameTime: 19.231 ms [loop] fragment-loop=false:fragment-steps=5:vertex-steps=5: FPS: 55 FrameTime: 18.182 ms [loop] fragment-steps=5:fragment-uniform=false:vertex-steps=5: FPS: 55 FrameTime: 18.182 ms [loop] fragment-steps=5:fragment-uniform=true:vertex-steps=5: FPS: 53 FrameTime: 18.868 ms ======================================================= glmark2 Score: 48 ======================================================= |
The score is 48, which is higher than Mali-450MP platform, but still not very high. But as on other Arm platfoms, performance is greatly limited by X11 calls, and if you run the sample offscreen, the score is much higher:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
glmark2-es2 --off-screen ======================================================= glmark2 2014.03+git20150611.fa71af2d ======================================================= OpenGL Information GL_VENDOR: ARM GL_RENDERER: Mali-T860 GL_VERSION: OpenGL ES 3.2 v1.r13p0-00rel0-git(a4271c9).31ba04af2d3c01618c ======================================================= [build] use-vbo=false: FPS: 229 FrameTime: 4.367 ms [build] use-vbo=true: FPS: 306 FrameTime: 3.268 ms [texture] texture-filter=nearest: FPS: 366 FrameTime: 2.732 ms [texture] texture-filter=linear: FPS: 349 FrameTime: 2.865 ms [texture] texture-filter=mipmap: FPS: 335 FrameTime: 2.985 ms [shading] shading=gouraud: FPS: 253 FrameTime: 3.953 ms [shading] shading=blinn-phong-inf: FPS: 247 FrameTime: 4.049 ms [shading] shading=phong: FPS: 229 FrameTime: 4.367 ms [shading] shading=cel: FPS: 287 FrameTime: 3.484 ms [bump] bump-render=high-poly: FPS: 145 FrameTime: 6.897 ms [bump] bump-render=normals: FPS: 323 FrameTime: 3.096 ms [bump] bump-render=height: FPS: 315 FrameTime: 3.175 ms [effect2d] kernel=0,1,0;1,-4,1;0,1,0;: FPS: 197 FrameTime: 5.076 ms [effect2d] kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;: FPS: 260 FrameTime: 3.846 ms [pulsar] light=false:quads=5:texture=false: FPS: 320 FrameTime: 3.125 ms [desktop] blur-radius=5:effect=blur:passes=1:separable=true:windows=4: FPS: 206s [desktop] effect=shadow:windows=4: FPS: 208 FrameTime: 4.808 ms [buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5s [buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5s [buffer] columns=200:interleave=true:update-dispersion=0.9:update-fraction=0.5:s [ideas] speed=duration: FPS: 80 FrameTime: 12.500 ms [jellyfish] <default>: FPS: 171 FrameTime: 5.848 ms [terrain] <default>: FPS: 45 FrameTime: 22.222 ms [shadow] <default>: FPS: 256 FrameTime: 3.906 ms [refract] <default>: FPS: 85 FrameTime: 11.765 ms [conditionals] fragment-steps=0:vertex-steps=0: FPS: 327 FrameTime: 3.058 ms [conditionals] fragment-steps=5:vertex-steps=0: FPS: 204 FrameTime: 4.902 ms [conditionals] fragment-steps=0:vertex-steps=5: FPS: 320 FrameTime: 3.125 ms [function] fragment-complexity=low:fragment-steps=5: FPS: 257 FrameTime: 3.891 s [function] fragment-complexity=medium:fragment-steps=5: FPS: 184 FrameTime: 5.4s [loop] fragment-loop=false:fragment-steps=5:vertex-steps=5: FPS: 253 FrameTime:s [loop] fragment-steps=5:fragment-uniform=false:vertex-steps=5: FPS: 254 FrameTis [loop] fragment-steps=5:fragment-uniform=true:vertex-steps=5: FPS: 200 FrameTims ======================================================= glmark2 Score: 222 ======================================================= |
Anyway, there used to be a time where most boards did not support 3D graphics acceleration, but in recent times, it appears most now do.
In the past, I’ve also found out that upgrading the OS might overwrite some files and break support for 3D graphics, so I upgraded the system to Ubuntu 16.04.5:
|
1 2 |
sudo apt update sudo apt dist-upgrade |
and both samples could still work. So all good.
I also tried WebGL, and the WebGL Quake demo worked at about 50 fps, but some other would failed complaining about missing extension.
Video Playback on AIO3399-J with Ubuntu 16.04
Hardware video decoding support is a given in Android, but not so in Linux distributions. I could not find any pre-installed video player, so I installed ffmpeg, and tried to play some 1080p videos with ffplay and it does work.
Ignore the tearing in the screenshot above, as it’s just an effect of taking a screenshot. Sadly that also means hardware video decoding is not enabled, since it would normally rely on a separate hardware buffer that does not show in screenshot (a black area is normally shown). I could play H.264, H.265, and MPEG2 1080p videos reasonably smoothly with software video decoding, except in some scenes, especially when panning when the video is not as smooth as it could be.
Since the video play relies on software video decoding it takes a fair amount of resources. I’ve also tried to play 4K H.264 / H.265 videos but unsurprinslgy the processor is not fast enough for this tasks, and the videos just play in slow motion with many audio cuts. We’ll need to wait for hardware video decoding support, or switch to Android OS.
Browsing the Web with Chromium
Browsing the web works well, pages load fast, and scrolling is about as smooth as on my main PC. However, you still have to take into account the amount of RAM, especially if you have the 2GB RAM version like I do.
For example, when I tried to play Candy Crush Saga (Facebook) in Chromium would end up with “Aw, Snap!” page meaning the current tab crashed. The kernel log explains why:
|
1 2 |
[ 6227.723347] Out of memory: Kill process 3370 (chromium-browse) score 547 or sacrifice child [ 6227.724084] Killed process 3370 (chromium-browse) total-vm:2212980kB, anon-rss:1028564kB, file-rss:47172kB |
So not enough memory even if a single tab, and no other program launched. That means it’s time to enable ZRAM:
|
1 2 3 4 |
sudo apt install zram-config zramctl /dev/zram0 -s 512M mkwap /dev/zram0 mkwap /dev/zram0 |
Let’s double check we now have ZRAM (swap):
|
1 2 3 4 |
free -h total used free shared buff/cache available Mem: 1.9G 586M 1.0G 44M 280M 1.2G Swap: 511M 0B 511M |
and try again.
Yes! Success. The RAM is still on the limit with 512MB ZRAM, but at least I could play, and performance was very good. I could not see any difference against playing on my main PC (FX8350 program + NVIDIA GTX750 graphics card).
I would also play YouTube videos smoothly up to 720p, but 1080p video may have problems playing smoothly like in ODROID-XU4Q board.
Testing eMMC and USB 3.0 Storage Performance
I normally test storage performance with iozone (3), and installation is just one line.
|
1 2 3 4 5 |
sudo apt install iozone3 Reading package lists... Done Building dependency tree Reading state information... Done E: Unable to locate package iozone3 |
The only problem is that installation would not work here. Iozone is part of multiverse repo, and it’s missing in /etc/apt/sources.list. So edit the files and add four following lines:
|
1 2 3 4 |
deb http://ports.ubuntu.com/ubuntu-ports/ xenial multiverse deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial multiverse deb http://ports.ubuntu.com/ubuntu-ports/ xenial-updates multiverse deb-src http://ports.ubuntu.com/ubuntu-ports/ xenial-updates multiverse |
Now installation can be completed:
|
1 2 |
sudo apt update sudo apt install iozone3 |
Another workaround would have been to use snaps, but there’s configuration problem with snaps in the provided Ubuntu image:
|
1 2 |
sudo snap install iozone3 error: cannot communicate with server: Post http://localhost/v2/snaps/iozone3: dial unix /run/snapd.socket: connect: connection refused |
Anyway, we can start by testing the eMMC flash performance:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
sudo iozone -e -I -a -s 1000M -r 4k -r 16k -r 512k -r 1024k -r 16384k -i 0 -i 1 -i 2 Iozone: Performance Test of File I/O Version $Revision: 3.429 $ Compiled for 64 bit mode. Build: linux Output is in kBytes/sec Time Resolution = 0.000001 seconds. Processor cache size set to 1024 kBytes. Processor cache line size set to 32 bytes. File stride size set to 17 * record size. random random bkwd record stride kB reclen write rewrite read reread read write read rewrite read fwrite frewrite fread freread 1024000 4 27137 32018 26651 27368 21334 26919 1024000 16 53037 53023 75339 75604 61510 49689 1024000 512 54460 55266 240715 238180 228771 54066 1024000 1024 55115 54838 263255 251719 245114 53762 1024000 16384 54634 55292 296379 295641 292336 54952 iozone test complete. |
The write numbers looks normal and fairly good, but at first, I thought getting around 296MB/s read speeds on a 16GB eMMC flash is way too high. But actually the chip is a Samsung KLMAG1JETD-B041 eMMC flash 5.1 capable of HS400 speeds, and based on data for older Samsung chips it is indeed possible to get close to 300 MB/s with a 16GB flash, at least in theory.
I switched to USB3 NTFS performance:
|
1 2 3 4 5 6 7 8 9 |
cd /media/firefly/USB3_NTFS/ sudo iozone -e -I -a -s 1000M -r 4k -r 16k -r 512k -r 1024k -r 16384k -i 0 -i 1 random random bkwd record stride kB reclen write rewrite read reread read write read rewrite read fwrite frewrite fread freread 1024000 4 16468 30254 72420 72888 1024000 16 56010 58684 381819 207400 1024000 512 70702 53748 310350 425884 1024000 1024 73372 63357 632738 367912 1024000 16384 85725 88068 678924 328447 |
Write numbers look normal considering I’m using mechanical drives, and even a little low since I can normally get around 100MB/s write on that drive. However,read speed are 6 times faster than the typical performance from the drive, so let’s ignore them.
With that in mind, I’ve re-run the test on the EXT-4 partition of my drive, but this time with a 4GB file (twice the RAM):
|
1 2 3 4 5 6 7 8 9 10 11 |
cd ../USB3_EXT4/ sudo iozone -e -I -a -s 4000M -r 4k -r 16k -r 512k -r 1024k -r 16384k -i 0 -i 1 random random bkwd record stride kB reclen write rewrite read reread read write read rewrite read fwrite frewrite fread freread 4096000 4 17374 21294 22436 29755 4096000 16 74487 79492 77171 77137 4096000 512 89448 93158 96351 96484 4096000 1024 72869 89283 94067 94233 4096000 16384 86170 91713 93765 93863 iozone test complete. |
It took fairly long time, but at least all numbers are believable, and performance is roughly as expected, i.e. close to 100MB/s for sequential read and write operation.
This got me curious, so I repeated the eMMC flash test with a 4GB file:
|
1 2 3 4 5 6 7 8 9 10 |
Command line used: iozone -e -I -a -s 4000M -r 4k -r 16k -r 512k -r 1024k -r 16384k -i 0 -i 1 -i 2 random random bkwd record stride kB reclen write rewrite read reread read write read rewrite read fwrite frewrite fread freread 4096000 4 22712 31390 19925 22540 15893 8822 4096000 16 33129 50269 63731 66480 56315 14149 4096000 512 21231 48961 242603 238690 226344 14997 4096000 1024 19047 49522 257641 260358 247429 15565 4096000 16384 24047 50874 281959 279561 278128 26270 iozone test complete. |
But the results still look the same, so Firefly must have combined a high-end 16GB eMMC flash in their module together with proper implementation to achived those amazing read speeds. Random read values still appear to be too high though.
AIO-3399J also comes with M.2 NVMe SSD socket, which would have been interesting to test, but unfortunately I have no such SSD lying around.
Network performance – Gigabit Ethernet and 802.11ac WiFi
Gigabit Ethernet full duplex using iperf:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
iperf -s ------------------------------------------------------------ Server listening on TCP port 5001 TCP window size: 85.3 KByte (default) ------------------------------------------------------------ [ 4] local 192.168.1.16 port 5001 connected with 192.168.1.21 port 58628 ------------------------------------------------------------ Client connecting to 192.168.1.21, TCP port 5001 TCP window size: 170 KByte (default) ------------------------------------------------------------ [ 6] local 192.168.1.16 port 36282 connected with 192.168.1.21 port 5001 [ ID] Interval Transfer Bandwidth [ 6] 0.0-60.0 sec 2.77 GBytes 396 Mbits/sec [ 4] 0.0-60.0 sec 5.84 GBytes 835 Mbits/sec |
835 Mbps and 396 Mbps, so there’s an asymmetry while doing transfers in both direction at the same time.
But the number look better testing one direction at a time
- Upload only:
|
1 |
[ 3] 0.0-60.0 sec 6.40 GBytes 917 Mbits/sec |
- Download only:
|
1 |
[ 3] 0.0-60.0 sec 6.57 GBytes 940 Mbits/sec |
Gigabit Ethernet is almost maxed out in either direction.
I repeated the test for 802.11ac WiFi performance
- upload only:
|
1 |
[ 4] 0.0-60.1 sec 714 MBytes 99.6 Mbits/sec |
- download only:
|
1 |
[ 3] 0.0-60.0 sec 1.60 GBytes 229 Mbits/sec |
Download performance is good, but for some reasons upload could be better.
Final words
The provided Xubuntu 16.04 image works relatively well on AIO-3399J, and I’m pleased with overall performance, 3D graphics support, and good documentation for I/Os. However, hardware video decoding is not implemented, and there are few minor issues with the image such as problems with snap support, and some common apt repositories are not enabled by default. Android is probably a better option if you need 1080p or 4K video decoding.
AIO-3399J board is ideal if you need a development platform with many I/Os, and plan to use the company’s RK3399 Core-3399J system-on-module with your own custom carrier board.
AIO-3399J is sold for $165 on Firefly store with a power supply, the male to male USB cable, and two WiFi antennas. You should howevr consideing adding the heatsink to your order as well, and/or if your project requires it go with the 4GB RAM/16GB version for $235 instead. Sample price for Core-3399J SoM is respectively $95 and $119 for the 2GB and 4GB version.

Jean-Luc started CNX Software in 2010 as a part-time endeavor, before quitting his job as a software engineering manager, and starting to write daily news, and reviews full time later in 2011.
Support CNX Software! Donate via cryptocurrencies, become a Patron on Patreon, or purchase goods on Amazon or Aliexpress. We also use affiliate links in articles to earn commissions if you make a purchase after clicking on those links.










