Jump to content
Electronics-Lab.com Community

Forlinx

Members
  • Posts

    100
  • Joined

  • Last visited

  • Days Won

    1

Forlinx last won the day on March 21 2024

Forlinx had the most liked content!

2 Followers

Contact Methods

  • Website URL
    https://www.forlinx.net/

Recent Profile Visitors

10,683 profile views

Forlinx's Achievements

  1. FET3562J-C SoM based on Rockchip RK3562 series processor is a product designed for industrial automation and consumer electronics equipment. With its powerful functions and flexibility, it has attracted wide attention from customers in various industries since its launch. This article will introduce in detail how to start and test the MCU of RK3562J processor, and help engineers better understand this chip through practical operation steps. RK3562J Processor Overview RK3562J processor uses a 4*[email protected] + Cortex-M0 @ 200MHz architecture. Among them, the four Cortex-A53 cores are the main cores responsible for handling complex operating system tasks and applications. In contrast, the Cortex-M0 cores serve as auxiliary cores running a bare-core system capable of fast response and control for tasks with high real-time requirements. Preparations for Launching the M0 Core Firmware At present, the M0 kernel firmware is not started by default on the embedded OK3562J-C development board. Therefore, we need to go through a series of steps to configure and start the M0 core. The following are the specific steps. 1.U-Boot Modification In theory, we need to open the AMP (Asymmetric Multiprocessing) compilation macro, but because the U-Boot of the embedded OK3562J-C development board has been configured with the AMP function by default, the user does not need to modify any U-Boot. 2. Kernel Modification (1) Toolkit Installation First, we need to install the SCons toolkit for later compilation. It can be installed with the following command: forlinx@ubuntu:~$ sudo apt-get install scons (2) Add AMP Device Tree Calls OK3562J-C board has been added with a call to the AMP device tree. It's content can be viewed through the relevant configuration files. forlinx@ubuntu:~$ cd /home/forlinx/work/OK3562-linux-source/ forlinx@ubuntu:~/work/OK3562-linux-source$ vi kernel-5.10/arch/arm64/boot/dts/rockchip/OK3562-C-common.dtsi +include "rk3562-amp.dtsi" rk3562-amp.dtsi includes: / { /* Device description */ rockchip_amp: rockchip-amp { compatible = "rockchip,amp"; clocks = <&cru FCLK_BUS_CM0_CORE>, <&cru CLK_BUS_CM0_RTC>, <&cru PCLK_MAILBOX>, <&cru PCLK_INTC>, // <&cru SCLK_UART7>, <&cru PCLK_UART7>, <&cru PCLK_TIMER>, <&cru CLK_TIMER4>, <&cru CLK_TIMER5>; //pinctrl-names = "default"; //pinctrl-0 = <&uart7m1_xfer>; amp-cpu-aff-maskbits = /bits/ 64; amp-irqs = /bits/ 64 ; status = "okay"; }; /*Some reserved memory areas are defined */ reserved-memory { #address-cells =; #size-cells =; ranges; /* remote amp core address */ amp_shmem_reserved: amp-shmem@7800000 { reg =; no-map; }; rpmsg_reserved: rpmsg@7c00000 { reg =; no-map; }; rpmsg_dma_reserved: rpmsg-dma@8000000 { compatible = "shared-dma-pool"; reg =; no-map; }; /* mcu address */ mcu_reserved: mcu@8200000 { reg =; no-map; }; }; /* Implementing the Rockchip RPMsg function */ rpmsg: rpmsg@7c00000 { compatible = "rockchip,rpmsg"; mbox-names = "rpmsg-rx", "rpmsg-tx"; mboxes = <&mailbox 0 &mailbox 3>; rockchip,vdev-nums =; /* CPU3: link-id 0x03; MCU: link-id 0x04; */ rockchip,link-id =; reg =; memory-region = <&rpmsg_dma_reserved>; status = "okay"; }; }; 3. Generating Configuration Files Next, we need to generate a configuration file for the M0 core firmware. In the RTOS source directory, generate the required configuration file by copying the default configuration file and running the SCons menu configuration interface. Although no additional configuration is required in this example, the user can configure it as needed. forlinx@ubuntu:~/work/OK3562-linux-source$ cd rtos/bsp/rockchip/rk3562-32 forlinx@ubuntu:~/work/OK3562-linux-source/rtos/bsp/rockchip/rk3562-32$ cp board/rk3562_evb1_lp4x/defconfig .config forlinx@ubuntu:~/work/OK3562-linux-source/rtos/bsp/rockchip/rk3562-32$ scons --menuconfig After opening the graphical configuration interface, you can exit directly without configuration. If there are other functional requirements, you can exit and save after corresponding configuration. forlinx@ubuntu:~/work/OK3562-linux-source/rtos/bsp/rockchip/rk3562-32$ cp .config board/rk3562_evb1_lp4x/defconfig forlinx@ubuntu:~/work/OK3562-linux-source/rtos/bsp/rockchip/rk3562-32$ cp rtconfig.h board/rk3562_evb1_lp4x/defconfig.h 4. Source Code Compilation After generating the configuration file, we can start compiling the source code. By running the build script, select the appropriate defconfig configuration and compile the Linux system and M0 core firmware separately. After successful compilation, amp. img image files will be generated in the specified directory. forlinx@ubuntu:~/work/OK3562-linux-source/rtos/bsp/rockchip/rk3562-32$ cd ../../../../ forlinx@ubuntu:~/work/OK3562-linux-source$ ./build.sh chip Log colors: message notice warning error fatal Log saved at /home/forlinx/work/3562/git/OK3562-linux-source/output/sessions/2024-08-27_15-48-21 Switching to chip: ok3562 Pick a defconfig: 1. forlinx_defconfig 2. forlinx_ok3562_linux_defconfig 3. forlinx_ok3562_linux_mcu_defconfig 4. forlinx_ok3562_linux_rtos_defconfig Which would you like? [1]: 4 //Select the fourth forlinx@ubuntu:~/work/OK3562-linux-source$ ./build.sh rtos forlinx@ubuntu:~/work/OK3562-linux-source$ ./build.sh mcu After compilation, generate a amp. img in the rockdev directory: forlinx@ubuntu:~/work/OK3562-linux-source$ ls rockdev/ amp.img boot.img linux-headers.tar MiniLoaderAll.bin misc.img oem.img parameter.txt recovery.img rootfs.img uboot.img update.img userdata.img Flashing Image Copy the generated amp. img image file to the computer, and switch the development board to the flashing mode. Use the flash tool to configure the path to amp.img. Click "Device Partition Table" and click "Execute" after successful reading. Startup Validation Press the spacebar to enter the U-Boot menu when restarting the board. In the U-Boot menu, enter 3 to configure amp start on. Enter 1 to restart the development board. During the boot process, observe the printouts of the U-Boot stage, if printouts related to the M0 core firmware boot are seen, the M0 core firmware has been successfully booted using U-Boot. Summary The above operation is simply to start the M0 core and print the information. In fact, the M0 core is very powerful, supporting UART, PWM, I2C, SPI and other peripheral interfaces. (At present, Forlinx Embedded has no more M0 core interface test routines. If there are relevant requirements,please contact the technical support to obtain the official information of Rockchip for in-depth study and development.) Hope this article can give you a better understanding of the M0 core of the RK3562J processor and help you in your subsequent development work. Click on the image below to learn more about the FET3562J-C SoM.
  2. As we all know, the Linux system is a non-real-time system based on time-slice scheduling, and its real-time performance is difficult to meet the timing requirements of industrial applications. Therefore, in many scenarios, the Linux operating system cannot be used. Of course, this limitation has been improved. Currently, the Linux community has added many versions of real-time patches. By applying these real-time patches to the Linux kernel, its real-time performance can be significantly enhanced. 1. Download the patch Download the real-time patch corresponding to the Linux version. We need to download the real-time patch for Linux 4.1.15. Index of /pub/linux/kernel/projects/rt/6.1/ The kernel version we are using is Linux 6.1.36. Find a similar patch in the “older” section: patches-6.1.33-rt11.tar.gz. 2. Type into the kernel unpack patches-6.1.33-rt11.tar.gz to the sdk path, which is the upper layer of the kernel source code. $ ls OKMX93-linux-fs OKMX93-linux-kernel appsrc build.sh environment-setup-aarch64-toolchain extra images patches patches-6.1.33-rt11.tar.gz tools Since more than 200 patches are in the extracted patch, use a script in the kernel directory to merge the patches. $ cd OKMX93-linux-kernel The script reads as follows: #!/bin/sh cat ../patches/series | while read line do patch -p1 < ../patches/$line done After executing this script, compile the kernel make Image -j16 3. Test real-time 3.1 cross-compiling cyctest git clone git://git.kernel.org/pub/scm/utils/rt-tests/rt-tests.git cd rt-tests/ git checkout -b v1.0 origin/stable/v1.0 Modify Makefile #CC?=$(CROSS_COMPILE)gcc #AR?=$(CROSS_COMPILE)ar Compile make 3.2 cyclictest test method Load the compiled cyclictest onto the board and increase its executable permissions, you can use the cyclictest command to carry out real-time performance testing of the Linux kernel, the test command is: root@fl-imx6ull:~# ./cyclictest -t8 -p 80 -n -i 10000 -l 10000 Specific parameters can be used as a reference: -p --prio = thread with PRIO ordinal 0 The priority usage method for the highest priority thread is: -p 90 / --prio=90 -m --mlockall thread priority is 0 Lock current and future memory allocation -c --clock=CLOCK Counter. Every time interval of the thread is reached, the counter is increased by 1. Select clock cyclictest -C 1 0 = CLOCK _ MONOTONIC (default) 1 = CLOCK _ REALTIME -i --interval=INTV Basic thread interval, default is 1000 (unit is us) -l --loops=LOOPS The number of cycles, which is 0 (infinite) by default, can be combined with the number of -I intervals to roughly calculate the time of the entire test, for example, -I 1000-l 1000000, the total cycle time is 1000 * 1000000 = 1000000000 us = 1000s, so it is roughly more than 16 minutes -n --nanosleep Use clock_nanosleep -h --histogram=US Draw a histogram of the delay on a standard output device after execution (many threads have the same permissions) US is the maximum trace time limit. -q --quiet The -q parameter prints no information at runtime, only a summary on exit, which in combination with the -h HISTNUM parameter prints HISTNUM line statistics and a general summary on exit. -f --ftrace The ftrace function traces (usually used with -b, in fact -b is usually used without -f) -b --breaktrace=USEC Sends a stop trace when the delay exceeds the value specified by the USEC. USEC, in milliseconds (us) Run Result Meaning: T:0 Serial number is 0 P:0 Thread priority is 0 C:1000 Counter. Every time interval of the thread is reached, the counter is increased by 1. I: 1000 Time interval is 1000 microseconds (us) Min: Minimum Delay (us) Act: Last Delay (us) Avg: Everyrage Delay (us) Max: Maximum Delay (us) 3.3 Testing unpatched kernels First Test root@ok-mx93:~# ./cyclictest -t8 -p 80 -n -i 10000 -l 10000 # /dev/cpu_dma_latency set to 0us policy: fifo: loadavg: 0.04 0.04 0.04 1/127 996 T: 0 ( 917) P:80 I:10000 C: 10000 Min: 5 Act: 7 Avg: 7 Max: 65 T: 1 ( 918) P:80 I:10500 C: 9533 Min: 5 Act: 8 Avg: 7 Max: 126 T: 2 ( 919) P:80 I:11000 C: 9100 Min: 5 Act: 7 Avg: 7 Max: 78 T: 3 ( 920) P:80 I:11500 C: 8704 Min: 5 Act: 9 Avg: 7 Max: 80 T: 4 ( 921) P:80 I:12000 C: 8341 Min: 5 Act: 8 Avg: 6 Max: 72 T: 5 ( 922) P:80 I:12500 C: 8008 Min: 5 Act: 6 Avg: 7 Max: 75 T: 6 ( 923) P:80 I:13000 C: 7700 Min: 5 Act: 7 Avg: 7 Max: 73 T: 7 ( 924) P:80 I:13500 C: 7414 Min: 5 Act: 7 Avg: 7 Max: 71 Second test root@ok-mx93:~# ./cyclictest -t8 -p 80 -n -i 10000 -l 10000 # /dev/cpu_dma_latency set to 0us policy: fifo: loadavg: 0.00 0.00 0.00 1/128 1410 T: 0 ( 1329) P:80 I:10000 C: 10000 Min: 5 Act: 8 Avg: 7 Max: 102 T: 1 ( 1330) P:80 I:10500 C: 9531 Min: 5 Act: 6 Avg: 7 Max: 113 T: 2 ( 1331) P:80 I:11000 C: 9097 Min: 5 Act: 8 Avg: 7 Max: 79 T: 3 ( 1332) P:80 I:11500 C: 8702 Min: 5 Act: 8 Avg: 7 Max: 61 T: 4 ( 1333) P:80 I:12000 C: 8339 Min: 5 Act: 7 Avg: 6 Max: 78 T: 5 ( 1334) P:80 I:12500 C: 8006 Min: 5 Act: 7 Avg: 7 Max: 89 T: 6 ( 1335) P:80 I:13000 C: 7698 Min: 5 Act: 7 Avg: 7 Max: 55 T: 7 ( 1336) P:80 I:13500 C: 7413 Min: 5 Act: 9 Avg: 7 Max: 54 Third test root@ok-mx93:~# ./cyclictest -t8 -p 80 -n -i 10000 -l 10000 # /dev/cpu_dma_latency set to 0us policy: fifo: loadavg: 0.00 0.00 0.00 1/127 1488 T: 0 ( 1414) P:80 I:10000 C: 10000 Min: 5 Act: 7 Avg: 6 Max: 60 T: 1 ( 1415) P:80 I:10500 C: 9531 Min: 5 Act: 6 Avg: 6 Max: 65 T: 2 ( 1416) P:80 I:11000 C: 9097 Min: 5 Act: 7 Avg: 6 Max: 64 T: 3 ( 1417) P:80 I:11500 C: 8702 Min: 5 Act: 7 Avg: 7 Max: 60 T: 4 ( 1418) P:80 I:12000 C: 8339 Min: 5 Act: 7 Avg: 6 Max: 63 T: 5 ( 1419) P:80 I:12500 C: 8006 Min: 5 Act: 6 Avg: 7 Max: 51 T: 6 ( 1420) P:80 I:13000 C: 7698 Min: 5 Act: 6 Avg: 6 Max: 50 T: 7 ( 1421) P:80 I:13500 C: 7413 Min: 5 Act: 7 Avg: 7 Max: 60 3.4 Testing the kernel With Real-time Patching First test root@ok-mx93:~# ./cyclictest -t8 -p 80 -n -i 10000 -l 10000 # /dev/cpu_dma_latency set to 0us policy: fifo: loadavg: 0.06 0.08 0.03 1/126 654 T: 0 ( 579) P:80 I:10000 C: 10000 Min: 5 Act: 8 Avg: 6 Max: 47 T: 1 ( 580) P:80 I:10500 C: 9532 Min: 5 Act: 6 Avg: 6 Max: 48 T: 2 ( 581) P:80 I:11000 C: 9099 Min: 5 Act: 6 Avg: 6 Max: 56 T: 3 ( 582) P:80 I:11500 C: 8703 Min: 5 Act: 7 Avg: 6 Max: 67 T: 4 ( 583) P:80 I:12000 C: 8341 Min: 5 Act: 7 Avg: 6 Max: 48 T: 5 ( 584) P:80 I:12500 C: 8007 Min: 5 Act: 7 Avg: 6 Max: 48 T: 6 ( 585) P:80 I:13000 C: 7699 Min: 5 Act: 7 Avg: 6 Max: 50 T: 7 ( 586) P:80 I:13500 C: 7414 Min: 5 Act: 6 Avg: 6 Max: 59 Second test root@ok-mx93:~# ./cyclictest -t8 -p 80 -n -i 10000 -l 10000 # /dev/cpu_dma_latency set to 0us policy: fifo: loadavg: 0.00 0.02 0.00 1/127 753 T: 0 ( 678) P:80 I:10000 C: 10000 Min: 5 Act: 7 Avg: 6 Max: 54 T: 1 ( 679) P:80 I:10500 C: 9532 Min: 5 Act: 9 Avg: 8 Max: 56 T: 2 ( 680) P:80 I:11000 C: 9099 Min: 5 Act: 6 Avg: 6 Max: 50 T: 3 ( 681) P:80 I:11500 C: 8703 Min: 5 Act: 7 Avg: 6 Max: 48 T: 4 ( 682) P:80 I:12000 C: 8341 Min: 5 Act: 7 Avg: 6 Max: 55 T: 5 ( 683) P:80 I:12500 C: 8007 Min: 5 Act: 6 Avg: 7 Max: 71 T: 6 ( 684) P:80 I:13000 C: 7699 Min: 5 Act: 7 Avg: 7 Max: 51 T: 7 ( 685) P:80 I:13500 C: 7414 Min: 5 Act: 6 Avg: 6 Max: 54 Third test root@ok-mx93:~# ./cyclictest -t8 -p 80 -n -i 10000 -l 10000 # /dev/cpu_dma_latency set to 0us policy: fifo: loadavg: 0.00 0.01 0.00 1/117 835 T: 0 ( 759) P:80 I:10000 C: 10000 Min: 5 Act: 9 Avg: 6 Max: 63 T: 1 ( 760) P:80 I:10500 C: 9532 Min: 5 Act: 8 Avg: 8 Max: 77 T: 2 ( 761) P:80 I:11000 C: 9099 Min: 5 Act: 6 Avg: 7 Max: 79 T: 3 ( 762) P:80 I:11500 C: 8703 Min: 5 Act: 7 Avg: 6 Max: 61 T: 4 ( 763) P:80 I:12000 C: 8341 Min: 5 Act: 7 Avg: 6 Max: 67 T: 5 ( 764) P:80 I:12500 C: 8007 Min: 5 Act: 16 Avg: 6 Max: 65 T: 6 ( 765) P:80 I:13000 C: 7699 Min: 5 Act: 8 Avg: 6 Max: 89 T: 7 ( 766) P:80 I:13500 C: 7414 Min: 5 Act: 7 Avg: 7 Max: 76
  3. With the rapid development of Internet of Things (IoT) technology, efficient and stable development platforms have become key to driving project success. iMX6UL series processors, with high performance, low power consumption, and compact size, have become the ideal choice for many IoT applications. Combined with the Linux 4.1.15 operating system, we provide developers with a complete technical solution designed to help you easily install and use Node-RED on the iMX6UL series, thereby accelerating the development of IoT projects. Node-RED is a flow-based flashing tool that offers a browser-based flow editor. Users can create automation tasks and applications by dragging and dropping nodes and connecting them. It features a rich library of nodes, supports various protocol conversions, and allows users to create custom nodes to extend functionality. It is particularly suitable for building and deploying IoT applications, enabling easy integration of various hardware devices and sensors. Installation Steps: 1. Install Node.js Node.js is the foundational environment for running Node-RED. Here are the detailed installation steps: 1.1 Download the source code: Download link: https://registry.npmmirror.com/binary.html?path=node/v11.1.0/ Version:node-v11.1.0-linux-armv7l.tar.gz 1.2 Copy the file: Copy the downloaded source package to the iMX6UL development board and extract it: $ cp /run/media/sda1/node-v11.1.0-linux-armv7l.tar.gz ./ $ tar -xvf node-v11.1.0-linux-armv7l.tar.gz $ mv node-v11.1.0-linux-armv7l nodejs 1.3 Create symbolic links: To facilitate global access, create symbolic links for Node.js and npm: $ ln -s /home/root/nodejs/bin/node /usr/bin/ $ ln -s /home/root/nodejs/bin/npm /usr/bin/ 1.4 Check the version: Verify if Node.js and npm are installed successfully: node -v npm -v If the version numbers are printed, the environment setup is correct. Otherwise, please set the executable permissions and check again. chmod 777 nodejs/bin/* chmod 777 nodejs/bin/* 2. Install Node-RED 2.1 Install Node-RED: Ensure the development board can access the internet normally, then enter the following command to install Node-RED: npm install -g --unsafe-perm node-red If you encounter the following error: please execute: npm config set strict-ssl false Then try the installation again. npm install -g --unsafe-perm node-red If it gets stuck at this point: please execute: npm install -g node-gyp Then try the installation again. npm install -g --unsafe-perm node-red 2.2 Install pm2: pm2 is a powerful process management tool for Node.js applications, which can help you better manage the Node-RED service. The installation command is as follows: npm install -g pm2 2.3 Set a symbolic link: For ease of use, you can create a symbolic link for pm2 (path subject to actual conditions). ln -s /home/root/nodejs/bin/pm2 /usr/bin 2.4 Manage and start Node-RED: Use pm2 to start the Node-RED service and set it to start automatically on boot: pm2 start /home/root/nodejs/bin/node-red -- -v pm2 save pm2 startup Use Node-RED After installation, you can access the Node-RED user interface via a browser at http://:1880. Node-RED provides a rich library of nodes, supporting functions such as data acquisition, device control, event handling, etc. By dragging and connecting nodes, you can easily build complex IoT application flows. Notes: This technical solution is primarily applicable to the Forlinx MCU FETMX6ULL and FETMX6UL platforms with the Linux 4.1.15 operating system. For other platforms, please refer to the corresponding documentation for modification; If you encounter any issues during installation, please check network connectivity, file permissions, and other settings; Node-RED's node library is continuously updated, so it is recommended to regularly visit the official website for the latest nodes and examples. Conclusion With this technical solution, developers can easily install and use Node-RED on the iMX6UL series processors, thus accelerating the development of IoT projects. The high performance and low power consumption of the iMX6UL series, combined with the stability of the Linux 4.1.15 operating system and the ease of use of Node-RED, provide powerful technical support for IoT applications. We look forward to exploring the limitless possibilities of IoT with developers!
  4. In the management and interaction of embedded devices, the application based on Web mode has become the mainstream. This kind of server not only occupies small resources and runs efficiently, but also can dynamically generate page content according to actual needs. For users, they can realize the remote management, status monitoring and function control of embedded devices only through the commonly used Web browser, without installing additional software or complex configuration. BOA is a lightweight, efficient, and embedded Web server known for its minimal resource consumption and straightforward configuration. It is particularly suited for devices with limited memory and processing capabilities, providing essential Web functionalities. This article describes how to port the boa server on the FET-MX9352-C platform. How to Compile Source Code? Download address: http://www.boa.org/ 1. Install dependent libraries sudo apt-get install bison flex Unzip the source code in Ubuntu $ tar xvf boa-0.94.14rc21.tar cd boa-0.94.14rc21/ Modify the boa source code Modify src/compat.h find #define TIMEZONE_OFFSET(foo) foo##->tm_gmtoff Modify to #define TIMEZONE_OFFSET(foo) (foo)->tm_gmtoff Otherwise, an error occurs: util.c:100:1: error: pasting "t" and "->" does not give a valid preprocessing token make: *** [util.o] error 1 Modify src/log.c find if (dup2(error_log, STDERR_FILENO) == -1) { DIE("unable to dup2 the error log"); } Modify to /*if (dup2(error_log, STDERR_FILENO) == -1) { DIE("unable to dup2 the error log"); }*/ Otherwise, an error occurs: log.c:73 unable to dup2 the error log:bad file descriptor Modify src/boa.c find if (passwdbuf == NULL) { DIE(”getpwuid”); } if (initgroups(passwdbuf->pw_name, passwdbuf->pw_gid) == -1) { DIE(”initgroups”); } Modify to #if 0 if (passwdbuf == NULL) { DIE(”getpwuid”); } if (initgroups(passwdbuf->pw_name, passwdbuf->pw_gid) == -1) { DIE(”initgroups”); } #endif Otherwise, an error occurs: boa.c:211 - getpwuid: No such file or directory Set environment variables and compile . /opt/fsl-imx-xwayland/6.1-mickledore/environment-setup-armv8a-poky-linux ./configure --host=arm-linux make aarch64-poky-linux-strip src/boa At this point, the boa has been cross-compiled Expected file path examples/boa. conf and SRC/boa 2. Modify boa.conf vi boa.conf (1) Group modification Modify Group nogroup to Group root (2) User modification Modify User nobody to User root (3) Modify DocumentRoot DocumentRoot /var/www (4) Modify ScriptAlias ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ (5) ServerName settings Modify #ServerName www.your.org.here ServerName www.your.org.here Otherwise, an error will occur “gethostbyname::No such file or directory 3. Compile the test file Unzip the source code in Ubuntu tar xvf cgi_app.tar.gz cd cgi_app/ Clean up the files make clean Set environment variables and compile . /opt/fsl-imx-xwayland/6.1-mickledore/environment-setup-armv8a-poky-linux $CC -o app.cgi cgi_app.c cJSON/cJSON.c Generate app.cgi 4.Arrange to the development board To create the directory, enter the following command on the development board. mkdir /usr/lib/cgi-bin mkdir /var/www mkdir /etc/boa mkdir /usr/lib/cgi-bin/ Table of ContentsPut app.cgi in the /usr/lib/cgi-bin/ directory Put index.html, xmlhttpreq.js to /var/www/ folder Put boa.conf in the/etc/boa/directory Place boa in the/usr/bin/directory Place the mime. Types in the/etc/directory Modify permissions chown root:root /var/www/* chown root:root /usr/lib/cgi-bin/app.cgi chmod o+x /usr/lib/cgi-bin/app.cgi chmod o+r /usr/lib/cgi-bin/app.cgi Turn off the original network services Because 9352 self-started lighttpd services, ps aux | grep http can see his process ID. To disable the startup of the Lighttpd service, vi /lib/systemd/system/lighttpd.service change line 8 and 9 to #ExecStartPre=/usr/sbin/lighttpd -tt -f /etc/lighttpd/lighttpd.conf #ExecStart=/usr/sbin/lighttpd -D -f /etc/lighttpd/lighttpd.conf Create a log file Vi/etc/autorun. sh Write this in mkdir/var/log/boa and restart Start the boa by entering the following command on the development board. boa The computer and the development board are directly connected through the network cable, and the computer opens the browser to access the IP of the development board. http://192.168.0.232/
  5. fw _ printenv is a tool for reading the U-boot environment variable. It provides the configuration information stored in the U-boot environment variable to the Linux system. These environment variables are typically used to configure and control the boot loading process, such as boot commands, kernel parameters, device tree file paths, and more. This article shows how to use fw_printenv on OKMX6UL boards, mainly for Forlinx OKMX6UL with Linux 4.1.15. Other platforms can also reference this guide, but adjustments may be required. 1. Compile the fw_printenv Tool Execute the following commands under the U-boot source code path, and then the tool will be generated under tools/env. $ . /opt/fsl-imx-x11/4.1.15-2.0.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi $ make env If you encounter the following error: ...... In file included from tools/env/aes.c:1:0: tools/env/../../lib/aes.c:28:20: fatal error: string.h: No such file or directory compilation terminated. scripts/Makefile.host:111: recipe for target 'tools/env/aes.o' failed make[1]: *** [tools/env/aes.o] Error 1 Makefile:1372: recipe for target 'env' failed make: *** [env] Error 2 Then modify the uboot top-level Makefile to comment out CC #CC = $(CROSS_COMPILE)gcc Then compile $ make env Compile to generate the following two files under the tools/env/ path: fw_printenv fw_env.config fw_printenv used for reading and writing environment variables fw_env.config used to describe the partition, address, etc. where the variable is located. 2. Configuration File modify the fw_env.config file under tools/env in the uboot source directory according to the mtd partition, the location and size of the UBOOT environment variables, etc. See the instructions in the fw_env.config file and the /tools/env/README file for specific modifications. Device offset, Env size, and Flash sector size should correspond to the three macro definitions in the include/configs/xxxx. H files in the uboot source directory. CONFIG_ENV_OFFSET CONFIG_ENV_SIZE CONFIG_ENV_SECT_SIZE Note: The following is based on the 2024 image, and it is recommended to double-check the exact address in uboot. (1) OKMX6ULL The header file for the OKMX6ULL-S and OKMX6ULL-C series is include/configs/mx6ullevk.h, which is configured as follows: #define CONFIG_ENV_SIZE SZ_8K #if defined(CONFIG_ENV_IS_IN_MMC) #define CONFIG_ENV_OFFSET (12 * SZ_64K) #elif defined(CONFIG_ENV_IS_IN_SPI_FLASH) #define CONFIG_ENV_OFFSET (768 * 1024) #define CONFIG_ENV_SECT_SIZE (64 * 1024) #define CONFIG_ENV_SPI_BUS CONFIG_SF_DEFAULT_BUS #define CONFIG_ENV_SPI_CS CONFIG_SF_DEFAULT_CS #define CONFIG_ENV_SPI_MODE CONFIG_SF_DEFAULT_MODE #define CONFIG_ENV_SPI_MAX_HZ CONFIG_SF_DEFAULT_SPEED #elif defined(CONFIG_SYS_BOOT_NAND) #undef CONFIG_ENV_SIZE #define CONFIG_ENV_OFFSET (0x6 << 20) /* 60 -> 06 */ #define CONFIG_ENV_SECT_SIZE (128 << 10) #define CONFIG_ENV_SIZE CONFIG_ENV_SECT_SIZE #elif defined(CONFIG_SYS_BOOT_NAND_1G) #undef CONFIG_ENV_SIZE #define CONFIG_ENV_OFFSET (0xa << 20) #define CONFIG_ENV_SECT_SIZE (256 << 10) #define CONFIG_ENV_SIZE CONFIG_ENV_SECT_SIZE #endif Some of the macros used above can be found in the./include/Linux/sizes. h. #define SZ_8K 0x00002000 #define SZ_16K 0x00004000 #define SZ_32K 0x00008000 #define SZ_64K 0x00010000 ...... It follows that: CONFIG_ENV_OFFSET CONFIG_ENV_SIZE CONFIG_ENV_SECT_SIZE EMMC 0x80000 0x2000 / 256 Nand 0x600000 0x20000 0x20000 1G Nand 0xA00000 0x40000 0x40000 Therefore, the configuration files for each version of the SoM are as follows: emmc ...... # Block device example /dev/mmcblk1 0x80000 0x2000 ...... 256 nand ...... # NAND example /dev/mtd2 0x00000 0x20000 0x20000 1 ...... 1G nand ...... # NAND example /dev/mtd2 0x00000 0x40000 0x40000 1 ...... (2) OKMX6UL OKMX6UL-C Environment Variables #define CONFIG_ENV_SIZE SZ_8K #if defined(CONFIG_ENV_IS_IN_MMC) #define CONFIG_ENV_OFFSET (8 * SZ_64K) #elif defined(CONFIG_ENV_IS_IN_SPI_FLASH) #define CONFIG_ENV_OFFSET (768 * 1024) #define CONFIG_ENV_SECT_SIZE (64 * 1024) #define CONFIG_ENV_SPI_BUS CONFIG_SF_DEFAULT_BUS #define CONFIG_ENV_SPI_CS CONFIG_SF_DEFAULT_CS #define CONFIG_ENV_SPI_MODE CONFIG_SF_DEFAULT_MODE #define CONFIG_ENV_SPI_MAX_HZ CONFIG_SF_DEFAULT_SPEED #elif defined(CONFIG_SYS_BOOT_NAND) #undef CONFIG_ENV_SIZE #if defined(CONFIG_ FCU1101 ) /*#define CONFIG_ENV_OFFSET (60 << 20)*/ #define CONFIG_ENV_OFFSET (0x4 << 20) #else #define CONFIG_ENV_OFFSET (0x6 << 20) #endif /*#define CONFIG_ENV_OFFSET (0x6 << 20) */ #define CONFIG_ENV_SECT_SIZE (128 << 10) #define CONFIG_ENV_SIZE CONFIG_ENV_SECT_SIZE #elif defined(CONFIG_SYS_BOOT_NAND_1G) #undef CONFIG_ENV_SIZE #define CONFIG_ENV_OFFSET (0xa << 20) #define CONFIG_ENV_SECT_SIZE (256 << 10) #define CONFIG_ENV_SIZE CONFIG_ENV_SECT_SIZE Some of the macros used above can be found in the./include/Linux/sizes. h. ...... #define SZ_8K 0x00002000 #define SZ_16K 0x00004000 #define SZ_32K 0x00008000 #define SZ_64K 0x00010000 ...... We can get CONFIG_ENV_OFFSET CONFIG_ENV_SIZE CONFIG_ENV_SECT_SIZE EMMC 0xc0000 0x2000 / 256 Nand 0x600000 0x20000 0x20000 1G Nand 0xA00000 0x40000 0x40000 Therefore, the configuration files for each version of the SoM are as follows: emmc. ...... # Block device example /dev/mmcblk1 0xc0000 0x2000 ...... 256nand ...... # NAND example /dev/mtd2 0x00000 0x20000 0x20000 1 ...... 1G nand ...... # NAND example /dev/mtd2 0x00000 0x40000 0x40000 1 ...... Deploy to the Development Board Copy tools/env/fw_env.config to the /etc path of the development board; Copy tools/env/fw_printenv to the root file system of the development board under the path /usr/bin. Create a soft link so that fw_setenv links to /usr/bin/fw_printenv Create a soft link method: $ ln -s /usr/bin/fw_printenv /usr/bin/fw_setenv 3. Use & Method Read Environment Variables root@fl-imx6ull:~# fw_printenv baudrate=115200 board_name=EVK board_rev=14X14 bootcmd=if test ${bootdev} = sd1; then run erase_env;mmc dev 0;if fatload mmc 0:1 83200000 target/env.txt;then echo burn default env from sdcard......;setenv_sdcard mmc 0:1 83200000 target/env.txt;fi;echo update from sd ...;run update_from_sd;else echo boot from nand ...;run nandargs;run bootnand; fi; bootcmd_mfg=run erase_env;run setenv_mfgtool;run mfgtool_args;bootz ${loadaddr} ${initrd_addr} ${fdt_addr}; bootdelay=1 bootdev=mmc2 bootnand=nand read ${loadaddr} 0xa00000 0x800000;nand read ${fdt_addr} ${nand_addr} 0x40000;bootz ${loadaddr} - ${fdt_addr}; calibrate=y console=ttymxc0 env_addr=0x83200000 erase_env=nand erase 0x600000 0x100000; eth1addr=72:d9:26:cf:b7:42 ethaddr=ee:71:d9:26:cf:b7 ethprime=FEC fdt_addr=0x83000000 fdt_high=0xffffffff fl_menu1=1 initrd_addr=0x83800000 initrd_high=0xffffffff loadaddr=0x80800000 mfgtool_args=setenv bootargs console=${console},${baudrate} rdinit=/linuxrc g_mass_storage.stall=0 g_mass_storage.removable=1 g_mass_storage.file=/fat g_mass_storage.ro=1 g_mass_storage.idVendor=0x066F g_mass_storage.idProduct=0x37FF g_mass_storage.iSerialNumber="" clk_ignore_unused nand_addr=0x780000 nandargs=setenv bootargs console=ttymxc0,115200 cma=64M root=/dev/mtdblock5 rw rootfstype=yaffs2 panel=TFT70AB-1024x600 setenv_mfgtool=setenv_mfgtools ${env_addr} 2000 ; splashimage=0x83800000 splashpos=m,m update_from_sd=run update_nand; update_nand=mmc rescan;fatload mmc 0 ${loadaddr} /sdrun/zImage; fatload mmc 0 ${initrd_addr} /sdrun/ramdisk.img.u; fatload mmc 0 ${fdt_addr} /sdrun/imx6ull-14x14-evk.dtb; setenv bootargs console=${console},${baudrate} rdinit=/linuxrc; bootz ${loadaddr} ${initrd_addr} ${fdt_addr}; Write environment variable: root@fl-imx6ull:~# fw_setenv panel TFT70AB-800x480 root@fl-imx6ull:~# fw_printenv baudrate=115200 board_name=EVK board_rev=14X14 ...... panel=TFT70AB-800x480 Reboot and check the environment variables in uboot. => print baudrate=115200 board_name=EVK board_rev=14X14 ...... panel=TFT70AB-800x480 ...... Environment size: 1779/131068 bytes =>
  6. This article describes how to create a Debian filesystem for the OKMX6UL series development boards, primarily applicable to the Forlinx OKMX6UL series with the Linux 4.1.15 operating system. Other platforms can refer to this guide, but there will be differences between platforms, which need to be modified to suit the actual use. Note: Operate under the root user by default. 1. Qemu and Debootstrap Installation Since a Debian file system is built on Ubuntu apt- these two tools can be installed directly using the apt-get command. The commands are as follows: sudo apt-get install binfmt-support qemu qemu-user-static debootstrap 2. Extracting Debian File System Use the debootstrap command to extract the file system. Execute the following command to retrieve the file system from the Debian download source: mkdir /home/forlinx/debian sudo debootstrap --arch=armhf --foreign buster root https://mirrors.tuna.tsinghua.edu.cn/debian/ Explanation of command parameters: arch specifies the CPU architecture buster is the Debian version number. Currently, the latest version is 10 foreign: This parameter needs to be specified when the architecture is different from the host’s, used only for the initial unpacking root: The folder where the filesystem will be stored https://mirrors.tuna.tsinghua.edu.cn/debian/ is the download source. The extraction process takes a relatively long time, approximately 10 minutes. Please be patient. Once successful, the Linux directory structure can be seen. If the extraction fails, please try a few more times or change the network: 3. Improving the File System To improve the filesystem, the qemu is required. Since it is operating on an X86 virtual machine, the ARM filesystem can not be improved directly. Therefore, qemu is used to simulate an ARM environment. a.To copy qemu-arm-static into the newly built base system, use the following command: cd root sudo cp /usr/bin/qemu-arm-static usr/bin cd .. b.Initialize the file system. Execute the following command: sudo DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true LC_ALL=C LANGUAGE=C LANG=C chroot root debootstrap/debootstrap --second-stage c.Use the chroot root command to initialize file system chroot root d.Use the command to create the following echo "proc /proc proc defaults 0 0" >> etc/fstab mkdir -p usr/share/man/man1/ mknod dev/console c 5 1 e.Download Source Update Use the command vi /etc/apt/sources.list to open the source.list file and replace the contents with the following. deb http://mirrors.ustc.edu.cn/debian stable main contrib non-free #deb-src http://mirrors.ustc.edu.cn/debian stable main contrib non-free deb http://mirrors.ustc.edu.cn/debian stable-updates main contrib non-free #deb-src http://mirrors.ustc.edu.cn/debian stable-updates main contrib non-free #deb http://mirrors.ustc.edu.cn/debian stable-proposed-updates main contrib non-free #deb-src http://mirrors.ustc.edu.cn/debian stable-proposed-updates main contrib non-free Then save and exit, and use the command apt-get update to update the download source. When the update download source reports an error, the date command can be provided to modify the system time to solve the problem. apt-get update f.Use the command apt-get install vim to install some necessary software apt-get install vim apt-get install sudo apt-get install dpkg apt-get install bzip2 apt-get install net-tools apt-get install ntpdate apt-get install gcc g.Create a new user with the command adduser forlinx, then enter the password adduser forlinx h.Set the root password, use the command passwd root, and set the password to forlinx. passwd root i.To set up Ethernet, enter the following command: vi /etc/network/interfaces As follows: #/etc/network/interfaces -- configuration file for ifup(8), ifdown(8) #The loopback interface auto lo iface lo inet loopback #Wireless interfaces iface wlan0 inet dhcp wireless_mode managed wireless_essid any wpa-driver wext wpa-conf /etc/wpa_supplicant.conf iface atml0 inet dhcp #Wired or wireless interfaces auto eth0 #iface eth0 inet dhcp #iface eth1 inet dhcp iface eth0 inet static address 192.168.0.232 netmask 255.255.255.0 gateway 192.168.0.1 broadcast 192.168.0.255 auto eth1 iface eth1 inet static address 192.168.1.232 netmask 255.255.255.0 gateway 192.168.1.1 broadcast 192.168.1.255 #Ethernet/RNDIS gadget (g_ether) #... or on host side, usbnet and random hwaddr iface usb0 inet static address 192.168.7.2 netmask 255.255.255.0 network 192.168.7.0 gateway 192.168.7.1 #Bluetooth networking iface bnep0 inet dhcp j.Modify host name vi /etc/hostname Modify to: Debian k.Modify the system time zone cp /usr/share/zoneinfo/Hongkong /etc/localtime ntpdate ntp.aliyun.com Take East Zone 8 as an example, other time zone files are also included under this path. l.Configure the SSH service Install and enable SSH root@Debian:~# apt-get install ssh root@Debian:~# service ssh start Allow SSH login for root user root@Debian:~# vim /etc/ssh/sshd_config Find this line. If there is no comment, it needs to be commented out with: #PermitRootLogin prohibit-password Create a new line PermitRootLogin yes Re-enable SSH root@Debian:~# service ssh restart m.Configure the FTP service Install vsftpd root@Debian:~# apt-get install vsftpd After the installation is complete, run the following command in a terminal to check the version of the vsftpd package: root@Debian:~# systemctl status vsftpd Configure the FTP service root@Debian:~# cp /etc/vsftpd.conf /etc/vsftpd.conf.bak root@Debian:~# vi /etc/vsftpd.conf Use these values to add/modify the following options: write_enable=YES chroot_local_user=YES allow_writeable_chroot=YES local_root=/ Allow login for root user root@Debian:~# vi /etc/ftpusers Users in ftpusers can not log in via FTP, so please comment out root with #. #root Re-enable FTP root@Debian:~# systemctl restart vsftpd Safety Instructions The configuration of vsftpd is extensive, but this article only covers a small portion. The FTP configuration file is located at: /etc/vsftpd.conf. When connecting to the device using the Filezilla tool, please select the FTP protocol and choose the encryption method as "Only use plain FTP". When connecting using the WinSCP tool, please select the FTP protocol and choose the encryption method as "Not encrypted". n.Adapt WiFi module (1) Install the necessary commands root@Debian:~# apt-get install usbutils //lsusb root@Debian:~# apt-get install wpasupplicant //wpa_supplicant root@Debian:~# apt-get install udhcpc (2) lsusb to see if a WiFi device has been found root@Debian:~# lsusb Bus 001 Device 003: ID 0bda:d723 Realtek Semiconductor Corp. 802.11n WLAN Adapter Bus 001 Device 002: ID 0424:2514 Microchip Technology, Inc. (formerly SMSC) USB 2.0 Hub Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub 0bda:d723 is the ID of 8723du (3) Check if the driver is loaded root@Debian:~# lsmod Module Size Used by 8723du 1302499 0 mx6s_capture 14876 0 ov9650_camera 12446 0 evbug 1882 0 configfs 23785 1 (4) Set to use bash script by default Place the fltest_wifi.sh script in the /usr/bin path. Since the Debian filesystem uses dash instead of the traditional bash, running the shell script directly will result in a syntax error report, so please eliminate the dash. root@Debian:~# dpkg-reconfigure dash Select NO in the pop-up window, after which it can run the shell script normally. Note: If Don’t make the above changes, the bash + shell script also can be used, for example: root@Debian:~# bash fltest_wifi.sh (5) Modify udev rules cp /lib/udev/rules.d/80-net-setup-link.rules /etc/udev/rules.d/ vim /etc/udev/rules.d/80-net-setup-link.rules Amend line 11 to read: NAME=="", ENV{ID_NET_NAME}!="", NAME="$env{ID_NET_SLOT}" Note: If don’t make the above changes, wlan0 will be renamed, resulting in networking failure. (6) Connect WiFi Note: 1. The WiFi connection script needs to be copied from the file system provided by Forlinx; 2. To avoid routing table conflicts, down eth0 and eth1 before connecting to WiFi. ifconfig eth0 down ifconfig eth1 down fltest_cmd_wifi.sh -i 8723du -s forlinx-wlan -p fl03123102650 o.Install pyqt (1) python Installation sudo apt-get -y install python3-pip python3 (2) PyQt5 Installation sudo apt-get -y install python3-pyqt5 (3) Because the performance of 6ull is relatively weak, there is no desktop installed, just use exit to exit the qemu environment. exit (4) Package the file system Go to the Debian filesystem directory Directly use the command tar -cjf rootfs.tar.bz2 ./*. tar -cjvf rootfs.tar.bz2 ./* (5) Burn-in verification Place the packaged file system into the burner, while keeping the other images as they are and only replacing the file system. Then proceed with the burn-in test.
  7. In the field of embedded development, debugging is a critical step to ensure the stable operation of a program. For developers using the OKMX8MP-C development board, mastering GDB remote debugging techniques can significantly enhance development efficiency. GDB, short for The GNU Project Debugger, is a comprehensive debugging tool under Linux. GDB supports a variety of debugging methods, including setting breakpoints, single-step execution, printing variables, observing variables, examining registers, and viewing the call stack. In Linux environment software development, GDB is the primary debugging tool used to debug C and C++ programs. OKMX8MP-C's 5.4.70 version comes with default support for gdbserver, and our provided development environment also supports gdb by default. Next, will detail how to perform GDB remote debugging on the OKMX8MP-C. 1. Preparation Before Compilation Before performing GDB debugging, it is essential to ensure that the application has been correctly compiled and includes debugging information. This can be achieved by adding the -g option during compilation. For example: This command will compile the test_bug.c source file and generate an executable file test_bug with debugging information included. This way, GDB can accurately locate the corresponding positions in the source code during subsequent debugging processes. After compilation, the generated executable file needs to be copied to the development board. This is typically achieved via serial port, network, or other file transfer methods. In this example, we assume that the test_bug file has been copied to the / directory on the development board. 2. Development Board IP and Starting gdbserver Settings Next, you need to set the IP address on the development board and start the gdbserver service. The specific steps are as follows: Set the IP Address: Use the ifconfig command to set the IP address for the development board. For example: Here, the development board's IP address is set to 172.16.0.109 Start gdbserver on the development board, specifying the listening port number and the program to be debugged. For example: This command will start gdbserver and listen on port 2345 for connection requests from the GDB client. root@OK8MP:~# ifconfig eth0 172.16.0.109 root@OK8MP:~# gdbserver 172.16.0.109:2345 test_bug Process /home/root/test_bug created; pid = 1356 Listening on port 2345 On the virtual machine or host, set an IP address within the same network segment as the development board and use the ping command to test connectivity with the development board. Ensure successful pinging of the development board's IP address, which is a prerequisite for remote debugging. 3. Starting the GDB Client and Connecting to the Development Board Start the GDB client: On the virtual machine or host, use the aarch64-poky-linux-gdb command to start the GDB client and specify the program to be debugged. For example: forlinx@ubuntu:~/ aarch64-poky-linux-gdb test_bug GNU gdb (GDB) 8.3.1 Copyright (C) 2019 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "--host=x86_64-pokysdk-linux --target=aarch64-poky-linux". Type "show configuration" for configuration details. For bug reporting instructions, please see: http://www.gnu.org/software/gdb/bugs/ Find the GDB manual and other documentation resources online at: http://www.gnu.org/software/gdb/documentation/ For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from test_bug... (gdb) Connect to the board: In the GDB client, use the target remote command to connect to gdbserver on the board. For example: (gdb) target remote 172.16.0.109:2345 Remote debugging using 172.16.0.109:2345 Reading /lib/ld-linux-aarch64.so.1 from remote target... warning: File transfers from remote targets can be slow. Use "set sysroot" to access file s locally instead. Reading /lib/ld-linux-aarch64.so.1 from remote target... Reading symbols from target:/lib/ld-linux-aarch64.so.1... Reading /lib/ld-2.30.so from remote target... Reading /lib/.debug/ld-2.30.so from remote target... Reading /lib/.debug/ld-2.30.so from remote target... Reading symbols from target:/lib/.debug/ld-2.30.so... 0x0000fffff7fcf080 in _start () from target:/lib/ld-linux-aarch64.so.1 (gdb) At this point, the GDB client connects to gdbserver on the board and is ready to begin remote debugging. 4. Remote Debugging Upon successful connection, you can start using various GDB debugging commands for remote debugging. Below are some commonly used debugging commands: l (list): Lists source code. b (break): Sets a breakpoint. n (next): Steps through the code line by line. s (step): Steps into functions for line-by-line execution. c (continue): Continues program execution. p (print): Prints the value of a variable. For example, use the l command to view the source code at the current location: Then, you can use the B command to set a breakpoint on a line, such as line 16: bash copy code Use the c command to continue executing the program. The program will pause at the breakpoint, waiting for further debugging. 5. Debugging Techniques and Precautions Breakpoint Management: Setting breakpoints appropriately can significantly improve debugging efficiency. Use the d command to delete breakpoints. Use the info b command to view all current breakpoints. Variable Monitoring: Use the watch command to monitor variable changes. GDB will automatically pause execution when the variable's value changes. Multithreaded Debugging: If program is multithreaded, use thread command to switch threads for debugging. Security Considerations: Ensuring network environment security is crucial during remote debugging. Use SSH tunnels or other encryption methods to protect debugging data transmission. That's all OKMX8MP-C GDB remote debugging skills. This powerful tool enables efficient issue resolution and development enhancement.
  8. Cross-compilation Toolchain Location: OK113i-linux-sdk/out/t113_i/ ok113i/longan/buildroot/host/bin/arm-linux-gnueabihf-gcc‍ Before executing the method below, please delete the out directory and decompress the cross-compilation tool chain in the lower path of the source code./buildroot/buildroot-201902/dl/toolchain-external-linaro-arm/gcc-linaro-7.3.1-2018.05-x86_64_arm-linux-gnueabihf.tar.xz 1. Modify mkcmd.sh and mkcommon.sh according to the patch modification method in the figure. 2. Go back to the sdk path and execute the following command: forlinx@ubuntu:~/shuishui/OK113i-linux-sdk$ ./build.sh config It is modified to emmc or NAND version according to the actual board configuration. 3. Next, execute the following command to enter the configuration of buildroot. Enter toolchain Modify the relevant options as shown in the figure below: Enter target options Because hard-float is needed, the highlighted part in the diagram needs to be modified to EABIhf. Save and exit after setting. Enter the following path to compile. ./build.sh Full compilation may require an error with an environment variable, resulting in a failure to compile. If this problem occurs, execute the following instructions and compile the buildroot. export LD_LIBRARY_PATH="" In the middle of compiling buildroot, you may encounter an error as shown in the following figure. If these errors are encountered, you can find the corresponding source code and compile it through the tools in the decompressed cross-compilation chain. Subsequently, place the compiled executable file in the bin path and the library file in the lib path. Finally, continue executing ./build.sh until compilation is successful. After compiling successfully, return to the SDK path, perform full compilation build. sh, and then pack the image. Next, write a test program to verify whether the cross-compilation chain can be successfully replaced. Here, you need to compare the program compiled with the original compilation chain with the program cross-compiled with the current compilation chain. The part highlighted in the diagram is a program compiled using our original cross-compilation chain. It can be observed that it does not run normally. "Test" is a program compiled using the tools from the replaced cross-compilation chain, which runs normally. Additionally, the relevant information of the two programs can be determined using the ''strings'' tool.
  9. Routing is a core component of device networking, responsible for intelligent data packet forwarding, ensuring efficient communication and internet access. It also assigns IP addresses to devices connected via the network interface, ensuring stable and secure connections. Below is a guide on how to implement routing functionality on the Forlinx i.MX93 platform. 1. Bridge Building 1.1 Busybox Compilation and Brctl Tool Loading There is no brctl tool in the busybox of the 93 development board, so it needs to be recompiled. If the busybox of the board has the brctl tool, this step can be ignored. Down load busybox-1.35 source code, website: https://busybox.net/ Unzip it on the 93 development environment and execute make menuconfig to configure. forlinx@ubuntu:~/work/busybox$ tar -xvf busybox-1.35.0.tar.bz2 forlinx@ubuntu:~/work/busybox$ cd busybox-1.35.0/ forlinx@ubuntu:~/work/busybox/busybox-1.35.0$ . /opt/fsl-imx-xwayland/5.15-kirkstone/environment-setup-armv8a-poky-linux forlinx@ubuntu:~/work/busybox/busybox-1.35.0$ make menuconfig Select Setting-->[*] Don't use /usr Add cross-compilation path (it can be set according to your own requirements): Setting-->--- Build Options (arch64-poky-linux-) Cross compiler prefix (/opt/fsl-imx-xwayland/5.15-kirkstone/sysroots/armv8a-poky-linux) Path to sysroot (-O2 -pipe -g -feliminate-unused-debug-types) Additional CFLAGS (-Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed -Wl,-z,relro,-z,now) Additional LDFLAGS Select brctl tool Networking Utilities --->[*] brctl (4.7 kb) Modify and then compile forlinx@ubuntu:~/work/busybox/busybox-1.35.0$ make forlinx@ubuntu:~/work/busybox/busybox-1.35.0$ make install Copy the generated busybox command to the development board/home/root path 1.2 Kernel Source Code Modification forlinx@ubuntu:~/work/ok-mx93/OKMX93-linux-sdk/OKMX93-linux-kernel$ vi drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c (478 line) /* if (hw->promisc) { netdev_err(dev, “Adding VLAN in promisc mode not supported\n"); return -EPERM; }*/ (533 line) /* if (hw->promisc) { netdev_err(dev, "Deleting VLAN in promisc mode not supported\n"); return -EPERM; }*/ Save and recompile the kernel after modification, generate Image and update the kernel 1.3 Building a Bridge With Brctl root@ok-mx93:~# ./busybox brctl addbr br0 //Create bridge device br0 root@ok-mx93:~# ./busybox brctl stp br0 off //Turn off the STP root@ok-mx93:~# ./busybox brctl addif br0 eth0 //Add eth0 to the bridge root@ok-mx93:~# ./busybox brctl addif br0 eth1 //Add eth1 to the bridge root@ok-mx93:~# ifconfig br0 192.168.0.10 up configure br0 ip and start it 2. 4G for Network Forwarding 2.1 4G Dial-up If there is command service, you need to delete it and restart. root@ok-mx93:~# rm /usr/sbin/connmand root@ok-mx93:~# sync root@ok-mx93:~# reboot root@ok-mx93:~# fltest_quectel.sh root@ok-mx93:~# ifconfig eth0 up root@ok-mx93:~# ifconfig eth1 up Note: The network port will be closed in the 93 dial-up script. If it is not necessary, you can comment out the command to close the network port in the script. 2.2 Route Priority Adjustment Checking with ''route -n'' reveals that the priorities of eth0 and eth1 are higher than 4G. At this point, 4G cannot access the Internet, so it is necessary to adjust the priorities to avoid affecting the 4G network. root@ok-mx93:~# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0 0.0.0.0 192.168.2.1 0.0.0.0 UG 0 0 0 eth1 0.0.0.0 10.137.251.242 0.0.0.0 UG 10 0 0 usb0 10.137.251.240 0.0.0.0 255.255.255.252 U 0 0 0 usb0 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 192.168.2.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1 Modify the metric parameter to change the priority. root@ok-mx93:~# route del default gw 192.168.1.1 root@ok-mx93:~# route del default gw 192.168.2.1 root@ok-mx93:~# route add default gw 192.168.1.1 dev eth0 metric 11 root@ok-mx93:~# route add default gw 192.168.2.1 dev eth1 metric 11 root@ok-mx93:~# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 10.137.251.242 0.0.0.0 UG 10 0 0 usb0 0.0.0.0 192.168.2.1 0.0.0.0 UG 11 0 0 eth1 0.0.0.0 192.168.1.1 0.0.0.0 UG 11 0 0 eth0 10.137.251.240 0.0.0.0 255.255.255.252 U 0 0 0 usb0 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 192.168.2.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1 After modification, 4G can access the Internet normally. root@ok-mx93:~# ping www.baidu.com PING www.a.shifen.com (39.156.66.18) 56(84) bytes of data. 64 bytes from 39.156.66.18 (39.156.66.18): icmp_seq=1 ttl=51 time=32.7 ms 64 bytes from 39.156.66.18 (39.156.66.18): icmp_seq=2 ttl=51 time=31.4 ms 64 bytes from 39.156.66.18 (39.156.66.18): icmp_seq=3 ttl=51 time=29.3 ms 64 bytes from 39.156.66.18 (39.156.66.18): icmp_seq=4 ttl=51 time=29.1 ms ^C --- www.a.shifen.com ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3003ms rtt min/avg/max/mdev = 29.066/30.612/32.663/1.494 ms 2.3 4G Forwarding Turn on IP to forward. root@ok-mx93:~# echo 1 > /proc/sys/net/ipv4/ip_forward Set forwarding rules. root@ok-mx93:~# iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o usb0 -jMASQUERADE root@ok-mx93:~# iptables -A FORWARD -i br0 -j ACCEPT Configure the udhcpd service and modify the/etc/udhcpd. conf films. root@ok-mx93:~# vi /etc/udhcpd.conf ... # The start and end of the IP lease block start 192.168.0.100 end 192.168.0.254 # The interface that udhcpd will use interface br0 ... # Examples: opt dns 114.114.114.114 option subnet 255.255.255.0 opt router 192.168.0.10 Turn on the udhcpd service root@ok-mx93:~# udhcpd /etc/udhcpd.conf & 3. Computer and Device Side Set both the computer and the device to obtain IP automatically. After obtaining the IP, the two can access the external network and ping each other.
  10. The touchscreen driver usually employs the input subsystem driver framework, so the application layer interface must adhere to the interfaces of the input framework. By entering ls -l /dev/input in the command line, you can see the current input devices available. root@freescale ~$ ls -l /dev/input/ total 0 crw - r----- 1 root root 13, 64 Jan 1 00:17 event0 crw - r----- 1 root root 13, 65 Jan 1 00:17 event1 crw - r----- 1 root root 13, 66 Jan 1 00:17 event2 crw - r----- 1 root root 13, 63 Jan 1 00:17 mice Lrwxrwxrwx 1 root root 6 Jan 1 00:18 ts0 -> event2 Lrwxrwxrwx 1 root root 6 Jan 1 00:18 ts2 -> event1 root@freescale ~$ View Touch Original Data When there is an issue with the touch function, you can determine whether the problem lies in the driver layer or the application layer by checking the raw data. There are several methods to view the raw data: 1. cat /dev/event2 Directly using cat on the touch event will output garbled characters when you touch the screen. 2. hexdump $ hexdump -d /dev/input/event0 0000000 15989 00000 18969 00004 00004 00004 00001 00009 # Other events 0000010 15989 00000 18969 00004 00001 00272 00001 00000 # BTN_MOUSE,press 0000020 15989 00000 18969 00004 00003 00000 16333 00000 # ABS_X 0000030 15989 00000 18969 00004 00003 00001 09599 00000 # ABS_Y 0000040 15989 00000 18969 00004 00000 00000 00000 00000 # Synchronous events 0000050 15989 00000 49415 00005 00004 00004 00001 00009 # Other events 0000060 15989 00000 49415 00005 00001 00272 00000 00000 # BTN_MOUSE,release 0000070 15989 00000 49415 00005 00000 00000 00000 00000 # Synchronous events The fourth, third, and second-to-last lines correspond to type, code, and value, which are all defined in linux/input.h. The event types for input devices in Linux are: #define EV_SYN 0x00 // Synchronous events #define EV_KEY 0x01 // Key events #define EV_REL 0x02 // Relative coordinates #define EV_REL 0x03 // Absolute coordinates #define EV_MSC 0x04 // Other events Type is the event type, where 3 is the EV _ ABS = 0x03 and 0 is the EV _ SYN = 0x00 (as a separator of events). The value of code depends on the event type. If the type is EV _ ABS, the value of code 0 is ABS _ X and the value of code 1 is ABS _ Y. Then, the value represents the measurement under the premises of type and code. For example, if the type is EV_ABS and the code is 0 (which corresponds to ABS_X), then the value represents the absolute X-axis position of the touch point. For example, if the type is EV_KEY, the code 272 corresponds to BTN_MOUSE, and code 330 corresponds to BTN_TOUCH; a value of 1 indicates a press, while a value of 0 indicates a release. For instance, if the type is EV_ABS and the code is 24 (which corresponds to ABS_PRESSURE), a value of 1 indicates that the screen is being pressed, while a value of 0 indicates it is released. The tests show that the coordinate values generated by the touchscreen touch events have a range of X: 016384 and Y: 09600, and this touchscreen does not upload ABS_PRESSURE. 3. ts_print / ts_print_raw The difference between the two is that ts _ print prints the data after tslib processing, while ts _ print _ raw prints the data before tslib processing. 4. evtest Evtest can not only print original, but it also allows you to see the event types. Driving Layer Processing Idea 1. Find the corresponding driver in the kernel source code by checking the device information. You can look for the corresponding string in the kernel source code; 2. To locate the touch reporting position, you can search for the string ABS in the corresponding driver. The image above shows the touch driver for a resistive screen. 3. Add print statements for further processing. Application Layer Processing 1. Use tools like ts_test to check if tslib is receiving data. 2. Change the version of tslib. Capacitive Screen In theory, capacitive screens do not require touch calibration; however, if they are not calibrated, there may be instances where the touch effects are opposite to the actual response, requiring the touch input to be inverted. However, if the reported data on the screen does not match the actual resolution, lower versions of Qt may not be able to handle it, necessitating manual calibration.
  11. Configuring a Bridge for LAN Ports 1. Create/etc/systemd/network/br0.netdev 2. Create/etc/systemd/network/br0.network 3. Create the Port Configuration Files: Enter the following content, taking fm1-mac2.network as an example: Name=fm1-mac2 The attribute differs, must correspond to the filename. Enable 5G Dial-Up on Boot 1. Add 5G Autostart: At the end of the /root/.forlinx file, add the following content: Possible Reasons for Dial-Up Failure: SIM card inserted incorrectly, SIM card is out of credit. IoT card is locked, need to add APN (cmnet: Mobile; 3gnet: Unicom; ctnet: Telecom). The board has a 4/5G switching dial switch. Install and Configure udhcpd Service 1. Install udhcpd Service: Other Solutions for Source Update Failure: (1) https://blog.csdn.net/Chaowanq/article/details/121559709 apt command certificate error. (2) https://blog.csdn.net/zhushixia1989/article/details/104550890 GLib-CRITICAL **: g_strchomp: assertion ‘string != NULL’ failed (3) https://blog.csdn.net/downanddusk/article/details/126334776 kali-rolling InRelease‘ is not signed 2. Configure udhcpd Service: Open /etc/udhcpd.conf and modify the /etc/udhcpd.conf configuration file to customize the IP pool, gateway, DNS, interface, etc. Here, I allocate IP range 192.168.3.20 — 192.168.3.254, interface as br0. Modify /etc/default/udhcpd to enable it. DHCPD_ENABLED=“yes”. After configuration, start the service: systemctl start udhcpd.service. Restart the service: systemctl restart udhcpd.service. Enable the service at boot: systemctl enable udhcpd.service. Check the service status: systemctl status udhcpd.service. Set Network Node usb0 Forwarding Rules 1. Set Forwarding Rules: 2. Save Forwarding Rules: -t nat: Specifies the table to operate on as the nat table. The nat table is used for network address convert. -A POSTROUTING: -A indicates that a rule is being appended to the end of the chain, and in this case, the chain being appended is the POSTROUTING chain. Rules in the POSTROUTING chain are handled when a packet is about to leave a network interface. -o usb0: The -o option specifies which network interface the packets will be sent out from. In this example, usb0 is the designated network interface (usually a USB network adapter). -j MASQUERADE: The -j jump to target action, here is MASQUERADE, which means enabling IP masquerading, replacing the source address with the IP address of the interface sending the packets, useful especially for dynamically assigned IP addresses.
  12. Compile the driver to the kernel: Create the hello folder for the kernel driver source code, add the hello. c and Makefile file, modify the parent directory/kernel/drivers/Makefile file, and execute the full compilation operation. Modify as follows: /hello/Makefile is:obj-y += hello.o /kernel/drivers/Makefile; add the following code:obj-y += hello Compile the driver as a module: Method 1: Create the hello folder for the kernel driver source code, add the hello. c and Makefile file, modify the parent directory/kernel/drivers/Makefile file, and execute the full compilation operation. Modify as follows: /hello/Makefile is:obj-m += hello.o /kernel/drivers/Makefile; add the following code:obj-y += hello If wanting to compile the driver but not wanting to perform a full compile operation that takes too much time, the following method can be chosen. Method 2: Create a hello folder in the kernel driver source code, add the hello. c and Makefile file, modify the parent directory/kernel/drivers/Makefile file, modify the/kernel/Makefile file to add the architecture and cross-compiler, and execute the make modules command. Modify as follows: /hello/Makefile is:obj-m += hello.o /kernel/drivers/Makefile; add the following code:obj-y += hello /kernel/Makefile, add the following code: ARCH?= arm64 CROSS_COMPILE?= $(srctree)/../prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- Advantages: When executing the make modules command, only the modules will be compiled, and the compilation time will be shortened. Disadvantages: The driver source code needs to be added to the kernel, which is not easy to find and modify. In addition, the make modules command will determine that the source code is configured as a module and will be compiled. Issues encountered: Solution: The kernel top-level Makefile file specifies the architecture and cross-compiler. Method 3: Create a folder named "hello" at any path, and add the files ''hello.c'' and ''Makefile''. In the ''/hello/Makefile'', add the architecture and cross-compiler. Then, execute the ''make'' command in the directory where ''hello.c'' is located. /hello/Makefile to write the following code. Advantages: Execute the make command, and only hello. C driver files will be compiled separately. Issues encountered: Solution: The kernel top-level Makefile file specifies the architecture and cross-compiler. Appendix: hello.c #include #include MODULE_LICENSE("Dual BSD/GPL"); static int hello_init(void) { printk(KERN_ALERT "Hello World enter\n"); return 0; } static void hello_exit(void) { printk(KERN_ALERT "Hello World exit\n"); } module_init(hello_init); module_exit(hello_exit); MODULE_DESCRIPTION("A Sample Hello World Module"); MODULE_ALIAS("A Sample module");
  13. System sleep and wake technology is a crucial aspect of power management. Firstly, it allows the system to reduce power consumption to the lowest level when idle by putting external devices, internal IP of the chip, and clocks into a low-power state or completely shut off the power state, thereby greatly extending the product's runtime. Secondly, when users need the system to run, it can quickly recover power, clocks, internal IP of the chip, and the working state of external devices to ensure that the user's experience is not interrupted. Forlinx T113 supports two types of sleep modes: freeze and mem. These two methods can be operated through the/sys/power/state file node, and the user can trigger the corresponding sleep state by writing freeze or mem to the file node. Before hibernation, the system configures the wakeup source. Once the system enters the sleep state, it can be awakened by these wake-up sources, such as keys, RTC, etc., when needed. This design allows users to choose when and how to wake up the system quickly according to their needs, achieving a balance between power consumption minimization and fast recovery. This mechanism enables the system to greatly reduce power consumption in the sleep state, while retaining the convenience of the user to use the system quickly after waking up. Here's how to enter sleep mode and wake up the system using the RTC on the Forlinx Embedded OK113i-S development board. Two Sleep Modes: freeze: Freezes I/O devices, placing them into a low-power state, and puts the processor into an idle state. It offers the quickest wake-up time, but consumes more power than other methods. Measured current with only serial port connected and 5V power supply: Approximately 0.112A mem: Suspend-to-RAM, where the computer stores current runtime state data in memory and shuts down the hard drive, external devices, etc., entering a wait state. At this time, the memory still needs power to maintain its data, but the whole machine consumes very little power. When recovering, the computer reads data from memory, returns to the state before suspension, and recovers quickly. Measured current with only serial port connected and 5V power supply: approximately 0.076A 1. cat /sys/power/state shows the supported modes. 2. cat /sys/power/state shows the supported modes. 3. cat /sys/power/state shows the supported modes. RTC Alarm Wakeup Tips: Note that the internal RTC needs to be used here; external RTCs do not support wakeup functionality, and we will mention this later. Enter the kernel configuration: Follow the instructions in the diagram to select the wake-up function. After completing the configuration, save it, then modify the device tree file to enable the internal RTC. Compile after saving: After the compilation is successful, it is packaged into an image. After the programming is completed, we test it at the serial port terminal. Enter the serial port terminal for test: echo''+15''> /sys/class/rtc/rtc0/wakealarm This sets a 15-second timer, which can be adjusted as needed. After executing this command, it will take effect. If the system goes into sleep after 15 seconds, it will not trigger a wake-up. (Note: This requires using the internal RTC; external RTC does not support wake-up functionality.)echo mem > /sys/power/state (The two commands need to be entered closely together; a long interval between them will make them ineffective.) (It should be noted here that when the internal RTC is not opened, the default external RTC node is rtc0. After modification, the external RTC device node will be changed to rtc1.) 3. cat /sys/power/state shows the supported modes. RTC Alarm Wakeup Tips: Note that the internal RTC needs to be used here; external RTCs do not support wakeup functionality, and it will be mentioned later. Enter the kernel configuration: Follow the instructions in the diagram to select the wake-up function. After completing the configuration, save it, then modify the device tree file to enable the internal RTC. Compile after saving: After the compilation is successful, it is packaged into an image. After the programming is completed, we test it at the serial port terminal. Enter the serial port terminal for test: echo''+15''> /sys/class/rtc/rtc0/wakealarm This sets a 15-second timer, which can be adjusted as needed. After executing this command, it will take effect. If the system goes into sleep after 15 seconds, it will not trigger a wake-up. (Note: This requires using the internal RTC; external RTC does not support wake-up functionality.) echo mem > /sys/power/state (The two commands need to be entered closely together; a long interval between them will make them ineffective.) It should be noted here that when the internal RTC is not opened, the default external RTC node is rtc0. After modification, the external RTC device node will be changed to rtc1.
  14. This project is based on the Forlinx Embedded OKMX8MP-C development board, which has a virtual machine ported. It is necessary to install the required packages on the development board and ensure that the board is connected to the network. 01 Logging into the OKMX8MP-C Development Board Connect the Type-C cable to the Debug port and select eMMC as the boot mode (i.e., set mode selection switch 2 to “on” and all others to “off”). After booting, log in using the root account. 02 Modifying the pip Source To speed up the installation process, it is necessary to modify the pip source: Add the followings: 03 Installing the Python venv Environment First, install the python3-venv package: apt install python3-venv Once installed successfully, create a directory named yolo (or any name of choice) and enter this directory to set up the Python 3 environment: Create the yolo directory (the directory name can be taken by yourself), and enter the directory to install the python3 environment: Execute the following figure: Activate the Python 3 venv environment: If activation is successful, it will display the following: 04 Installing Ultralytics Ultralytics YOLOv8 is based on cutting-edge deep learning and computer vision technologies, offering unparalleled performance in speed and accuracy. Its streamlined design makes it suitable for various applications and easily adaptable to different hardware platforms, from edge devices to cloud API. To install it, use the following command: Be patient while the installation completes: Once the installation is successful: 05 Testing the Installation Use the following command to test the setup. The image link in source can be replaced with another link: During this process, the model and image will be downloaded, so patience is required. After successful execution, the results will be generated in the runs/detect/predict* directory. The results can be copied to a Windows computer using the scp command. In the cmd terminal, execute the following command: If the output can be recognized, it indicates that the YOLO environment is functioning correctly. It is the process of setting up the YOLO environment on the Forlinx Embedded OKMX8MP-C development board. Hope it is useful.
  15. MIPI-CSI is a common camera interface in embedded systems or mobile devices, enabling high-speed image data transfer. The latest OK3576-C development board from Forlinx Embedded offers a wealth of resource interfaces, including support for 5 x CSI-2 , meaning it can support up to five camera inputs simultaneously. This article introduces the Camera path of RK3576 processor and how to configure different output formats of MIPI-CSI camera through OK3576-C development board. 01. RK3576 Camera Channels If there is only one camera access, turn on only rkispx_vir0 . Please note: vicap and isp do not have a direct correspondence; The relationships between different vir0/vir1 channels are essentially the same hardware being multiplexed, with the same effect. When using multiple cameras, configure them using 0, 1, 2, etc., as much as possible. The hardware channel diagram is as follows: There is one dcphy interface and two dphy interfaces. The connection paths are as follows: Single Camera (connected to one dphy): Dual Cameras (connected to two dphys) Three Cameras (connected to dcphy and two dphys) Five Cameras (connected to dcphy and two split dphys) Camera Channel Connection Diagram: (Note: For RGB data input, it is also necessary to connect to rkisp_virx) 02. Sensor Link Scenarios for Different Platforms yuv422/rgb888 input There are three common scenarios for yuv422/rgb888 input: Cameras with Built-in isp or External isp. Enter yuv422 format; HDMI to MIPI CSI Input. Common chips like rk628d/f,lt6911xxx, etc., typically convert yuv422, but rgb888 format is also possible; Multiple ahd and serdes. A single mipi port can support up to four virtual channels. For these scenarios, an isp is not required, and the connection only needs to go to cif. Thus, the link is: The isp node can be disabled. The X varies depending on the platform and hardware connections. The node used for capturing images is the first video node corresponding to rkcif_mipi_lvdsX. This can be viewed using media-ctl to check the topology. For example, on the OK3576-C development board with an OV5645 camera, it is mounted on the media1 node. root@ok3576-buildroot:/# media-ctl -p -d /dev/media1 Media controller API version 6.1.57 driver rkcif model rkcif-mipi-lvds1 serial bus info platform:rkcif-mipi-lvds1 hw revision 0x0 driver version 6.1.57 Device topology - entity 1: stream_cif_mipi_id0 (1 pad, 11 links) type Node subtype V4L flags 0 device node name /dev/video11 pad0: Sink <- "rockchip-mipi-csi2":1 [ENABLED] <- "rockchip-mipi-csi2":2 [] <- "rockchip-mipi-csi2":3 [] <- "rockchip-mipi-csi2":4 [] <- "rockchip-mipi-csi2":5 [] <- "rockchip-mipi-csi2":6 [] <- "rockchip-mipi-csi2":7 [] <- "rockchip-mipi-csi2":8 [] <- "rockchip-mipi-csi2":9 [] <- "rockchip-mipi-csi2":10 [] <- "rockchip-mipi-csi2":11 [] - entity 5: stream_cif_mipi_id1 (1 pad, 11 links) type Node subtype V4L flags 0 device node name /dev/video12 pad0: Sink <- "rockchip-mipi-csi2":1 [] <- "rockchip-mipi-csi2":2 [ENABLED] <- "rockchip-mipi-csi2":3 [] <- "rockchip-mipi-csi2":4 [] <- "rockchip-mipi-csi2":5 [] <- "rockchip-mipi-csi2":6 [] <- "rockchip-mipi-csi2":7 [] <- "rockchip-mipi-csi2":8 [] <- "rockchip-mipi-csi2":9 [] <- "rockchip-mipi-csi2":10 [] <- "rockchip-mipi-csi2":11 [] - entity 9: stream_cif_mipi_id2 (1 pad, 11 links) type Node subtype V4L flags 0 device node name /dev/video13 pad0: Sink <- "rockchip-mipi-csi2":1 [] <- "rockchip-mipi-csi2":2 [] <- "rockchip-mipi-csi2":3 [ENABLED] <- "rockchip-mipi-csi2":4 [] <- "rockchip-mipi-csi2":5 [] <- "rockchip-mipi-csi2":6 [] <- "rockchip-mipi-csi2":7 [] <- "rockchip-mipi-csi2":8 [] <- "rockchip-mipi-csi2":9 [] <- "rockchip-mipi-csi2":10 [] <- "rockchip-mipi-csi2":11 [] - entity 13: stream_cif_mipi_id3 (1 pad, 11 links) type Node subtype V4L flags 0 device node name /dev/video14 pad0: Sink <- "rockchip-mipi-csi2":1 [] <- "rockchip-mipi-csi2":2 [] <- "rockchip-mipi-csi2":3 [] <- "rockchip-mipi-csi2":4 [ENABLED] <- "rockchip-mipi-csi2":5 [] <- "rockchip-mipi-csi2":6 [] <- "rockchip-mipi-csi2":7 [] <- "rockchip-mipi-csi2":8 [] <- "rockchip-mipi-csi2":9 [] <- "rockchip-mipi-csi2":10 [] <- "rockchip-mipi-csi2":11 [] - entity 17: rkcif_scale_ch0 (1 pad, 11 links) type Node subtype V4L flags 0 device node name /dev/video15 pad0: Sink <- "rockchip-mipi-csi2":1 [] <- "rockchip-mipi-csi2":2 [] <- "rockchip-mipi-csi2":3 [] <- "rockchip-mipi-csi2":4 [] <- "rockchip-mipi-csi2":5 [ENABLED] <- "rockchip-mipi-csi2":6 [] <- "rockchip-mipi-csi2":7 [] <- "rockchip-mipi-csi2":8 [] <- "rockchip-mipi-csi2":9 [] <- "rockchip-mipi-csi2":10 [] <- "rockchip-mipi-csi2":11 [] - entity 21: rkcif_scale_ch1 (1 pad, 11 links) type Node subtype V4L flags 0 device node name /dev/video16 pad0: Sink <- "rockchip-mipi-csi2":1 [] <- "rockchip-mipi-csi2":2 [] <- "rockchip-mipi-csi2":3 [] <- "rockchip-mipi-csi2":4 [] <- "rockchip-mipi-csi2":5 [] <- "rockchip-mipi-csi2":6 [ENABLED] <- "rockchip-mipi-csi2":7 [] <- "rockchip-mipi-csi2":8 [] <- "rockchip-mipi-csi2":9 [] <- "rockchip-mipi-csi2":10 [] <- "rockchip-mipi-csi2":11 [] - entity 25: rkcif_scale_ch2 (1 pad, 11 links) type Node subtype V4L flags 0 device node name /dev/video17 pad0: Sink <- "rockchip-mipi-csi2":1 [] <- "rockchip-mipi-csi2":2 [] <- "rockchip-mipi-csi2":3 [] <- "rockchip-mipi-csi2":4 [] <- "rockchip-mipi-csi2":5 [] <- "rockchip-mipi-csi2":6 [] <- "rockchip-mipi-csi2":7 [ENABLED] <- "rockchip-mipi-csi2":8 [] <- "rockchip-mipi-csi2":9 [] <- "rockchip-mipi-csi2":10 [] <- "rockchip-mipi-csi2":11 [] - entity 29: rkcif_scale_ch3 (1 pad, 11 links) type Node subtype V4L flags 0 device node name /dev/video18 pad0: Sink <- "rockchip-mipi-csi2":1 [] <- "rockchip-mipi-csi2":2 [] <- "rockchip-mipi-csi2":3 [] <- "rockchip-mipi-csi2":4 [] <- "rockchip-mipi-csi2":5 [] <- "rockchip-mipi-csi2":6 [] <- "rockchip-mipi-csi2":7 [] <- "rockchip-mipi-csi2":8 [ENABLED] <- "rockchip-mipi-csi2":9 [] <- "rockchip-mipi-csi2":10 [] <- "rockchip-mipi-csi2":11 [] - entity 33: rkcif_tools_id0 (1 pad, 11 links) type Node subtype V4L flags 0 device node name /dev/video19 pad0: Sink <- "rockchip-mipi-csi2":1 [] <- "rockchip-mipi-csi2":2 [] <- "rockchip-mipi-csi2":3 [] <- "rockchip-mipi-csi2":4 [] <- "rockchip-mipi-csi2":5 [] <- "rockchip-mipi-csi2":6 [] <- "rockchip-mipi-csi2":7 [] <- "rockchip-mipi-csi2":8 [] <- "rockchip-mipi-csi2":9 [ENABLED] <- "rockchip-mipi-csi2":10 [] <- "rockchip-mipi-csi2":11 [] - entity 37: rkcif_tools_id1 (1 pad, 11 links) type Node subtype V4L flags 0 device node name /dev/video20 pad0: Sink <- "rockchip-mipi-csi2":1 [] <- "rockchip-mipi-csi2":2 [] <- "rockchip-mipi-csi2":3 [] <- "rockchip-mipi-csi2":4 [] <- "rockchip-mipi-csi2":5 [] <- "rockchip-mipi-csi2":6 [] <- "rockchip-mipi-csi2":7 [] <- "rockchip-mipi-csi2":8 [] <- "rockchip-mipi-csi2":9 [] <- "rockchip-mipi-csi2":10 [ENABLED] <- "rockchip-mipi-csi2":11 [] - entity 41: rkcif_tools_id2 (1 pad, 11 links) type Node subtype V4L flags 0 device node name /dev/video21 pad0: Sink <- "rockchip-mipi-csi2":1 [] <- "rockchip-mipi-csi2":2 [] <- "rockchip-mipi-csi2":3 [] <- "rockchip-mipi-csi2":4 [] <- "rockchip-mipi-csi2":5 [] <- "rockchip-mipi-csi2":6 [] <- "rockchip-mipi-csi2":7 [] <- "rockchip-mipi-csi2":8 [] <- "rockchip-mipi-csi2":9 [] <- "rockchip-mipi-csi2":10 [] <- "rockchip-mipi-csi2":11 [ENABLED] - entity 45: rockchip-mipi-csi2 (12 pads, 122 links) type V4L2 subdev subtype Unknown flags 0 device node name /dev/v4l-subdev1 pad0: Sink [fmt:UYVY8_2X8/1920x1080 field:none colorspace:srgb crop.bounds:(0,0)/1920x1080 crop:(0,0)/1920x1080] <- "rockchip-csi2-dphy0":1 [ENABLED] pad1: Source -> "stream_cif_mipi_id0":0 [ENABLED] -> "stream_cif_mipi_id1":0 [] -> "stream_cif_mipi_id2":0 [] -> "stream_cif_mipi_id3":0 [] -> "rkcif_scale_ch0":0 [] -> "rkcif_scale_ch1":0 [] -> "rkcif_scale_ch2":0 [] -> "rkcif_scale_ch3":0 [] -> "rkcif_tools_id0":0 [] -> "rkcif_tools_id1":0 [] -> "rkcif_tools_id2":0 [] pad2: Source -> "stream_cif_mipi_id0":0 [] -> "stream_cif_mipi_id1":0 [ENABLED] -> "stream_cif_mipi_id2":0 [] -> "stream_cif_mipi_id3":0 [] -> "rkcif_scale_ch0":0 [] -> "rkcif_scale_ch1":0 [] -> "rkcif_scale_ch2":0 [] -> "rkcif_scale_ch3":0 [] -> "rkcif_tools_id0":0 [] -> "rkcif_tools_id1":0 [] -> "rkcif_tools_id2":0 [] pad3: Source -> "stream_cif_mipi_id0":0 [] -> "stream_cif_mipi_id1":0 [] -> "stream_cif_mipi_id2":0 [ENABLED] -> "stream_cif_mipi_id3":0 [] -> "rkcif_scale_ch0":0 [] -> "rkcif_scale_ch1":0 [] -> "rkcif_scale_ch2":0 [] -> "rkcif_scale_ch3":0 [] -> "rkcif_tools_id0":0 [] -> "rkcif_tools_id1":0 [] -> "rkcif_tools_id2":0 [] pad4: Source -> "stream_cif_mipi_id0":0 [] -> "stream_cif_mipi_id1":0 [] -> "stream_cif_mipi_id2":0 [] -> "stream_cif_mipi_id3":0 [ENABLED] -> "rkcif_scale_ch0":0 [] -> "rkcif_scale_ch1":0 [] -> "rkcif_scale_ch2":0 [] -> "rkcif_scale_ch3":0 [] -> "rkcif_tools_id0":0 [] -> "rkcif_tools_id1":0 [] -> "rkcif_tools_id2":0 [] pad5: Source -> "stream_cif_mipi_id0":0 [] -> "stream_cif_mipi_id1":0 [] -> "stream_cif_mipi_id2":0 [] -> "stream_cif_mipi_id3":0 [] -> "rkcif_scale_ch0":0 [ENABLED] -> "rkcif_scale_ch1":0 [] -> "rkcif_scale_ch2":0 [] -> "rkcif_scale_ch3":0 [] -> "rkcif_tools_id0":0 [] -> "rkcif_tools_id1":0 [] -> "rkcif_tools_id2":0 [] pad6: Source -> "stream_cif_mipi_id0":0 [] -> "stream_cif_mipi_id1":0 [] -> "stream_cif_mipi_id2":0 [] -> "stream_cif_mipi_id3":0 [] -> "rkcif_scale_ch0":0 [] -> "rkcif_scale_ch1":0 [ENABLED] -> "rkcif_scale_ch2":0 [] -> "rkcif_scale_ch3":0 [] -> "rkcif_tools_id0":0 [] -> "rkcif_tools_id1":0 [] -> "rkcif_tools_id2":0 [] pad7: Source -> "stream_cif_mipi_id0":0 [] -> "stream_cif_mipi_id1":0 [] -> "stream_cif_mipi_id2":0 [] -> "stream_cif_mipi_id3":0 [] -> "rkcif_scale_ch0":0 [] -> "rkcif_scale_ch1":0 [] -> "rkcif_scale_ch2":0 [ENABLED] -> "rkcif_scale_ch3":0 [] -> "rkcif_tools_id0":0 [] -> "rkcif_tools_id1":0 [] -> "rkcif_tools_id2":0 [] pad8: Source -> "stream_cif_mipi_id0":0 [] -> "stream_cif_mipi_id1":0 [] -> "stream_cif_mipi_id2":0 [] -> "stream_cif_mipi_id3":0 [] -> "rkcif_scale_ch0":0 [] -> "rkcif_scale_ch1":0 [] -> "rkcif_scale_ch2":0 [] -> "rkcif_scale_ch3":0 [ENABLED] -> "rkcif_tools_id0":0 [] -> "rkcif_tools_id1":0 [] -> "rkcif_tools_id2":0 [] pad9: Source -> "stream_cif_mipi_id0":0 [] -> "stream_cif_mipi_id1":0 [] -> "stream_cif_mipi_id2":0 [] -> "stream_cif_mipi_id3":0 [] -> "rkcif_scale_ch0":0 [] -> "rkcif_scale_ch1":0 [] -> "rkcif_scale_ch2":0 [] -> "rkcif_scale_ch3":0 [] -> "rkcif_tools_id0":0 [ENABLED] -> "rkcif_tools_id1":0 [] -> "rkcif_tools_id2":0 [] pad10: Source -> "stream_cif_mipi_id0":0 [] -> "stream_cif_mipi_id1":0 [] -> "stream_cif_mipi_id2":0 [] -> "stream_cif_mipi_id3":0 [] -> "rkcif_scale_ch0":0 [] -> "rkcif_scale_ch1":0 [] -> "rkcif_scale_ch2":0 [] -> "rkcif_scale_ch3":0 [] -> "rkcif_tools_id0":0 [] -> "rkcif_tools_id1":0 [ENABLED] -> "rkcif_tools_id2":0 [] pad11: Source -> "stream_cif_mipi_id0":0 [] -> "stream_cif_mipi_id1":0 [] -> "stream_cif_mipi_id2":0 [] -> "stream_cif_mipi_id3":0 [] -> "rkcif_scale_ch0":0 [] -> "rkcif_scale_ch1":0 [] -> "rkcif_scale_ch2":0 [] -> "rkcif_scale_ch3":0 [] -> "rkcif_tools_id0":0 [] -> "rkcif_tools_id1":0 [] -> "rkcif_tools_id2":0 [ENABLED] - entity 58: rockchip-csi2-dphy0 (2 pads, 2 links) type V4L2 subdev subtype Unknown flags 0 device node name /dev/v4l-subdev2 pad0: Sink [fmt:UYVY8_2X8/1920x1080@10000/300000 field:none colorspace:srgb crop:(0,0)/1920x1080] <- "m01_f_ov5645 3-003c":0 [ENABLED] pad1: Source -> "rockchip-mipi-csi2":0 [ENABLED] - entity 63: m01_f_ov5645 3-003c (1 pad, 1 link) type V4L2 subdev subtype Sensor flags 0 device node name /dev/v4l-subdev3 pad0: Source [fmt:UYVY8_2X8/1920x1080@10000/300000 field:none colorspace:srgb crop:(0,0)/1920x1080] -> "rockchip-csi2-dphy0":0 [ENABLED] If it is a multi-channel input, it corresponds to the first four, that is, video11-video14. RAW format input Starting from RK3588, that is, from isp3.0, the isp of Rockchip microprocessor no longer has the acquisition function, but only does image processing, so the whole path is: It needs to be explained here: Without running aiq (Automatic Image Quality), rkcif_mipi_lvdsX can directly capture RAW images; If only the isp node vir0, i.e., rkispx_vir0, is enabled and the subsequent nodes rkispx_vir1/vir2, etc., are not enabled, this is a direct pass-through configuration. Even without running aiq, nv12 images can still be obtained, but these images are unprocessed and generally appear in a light green color; Enabling other vir nodes indicates that the isp needs to be time-multiplexed, which requires aiq to be enabled in order to capture images (aiq will handle time-multiplexing of the isp). Therefore, if only one camera is used, it is advisable to disable other isp nodes. 03. Summary When configuring the camera, first determine the camera’s channel path and the format of the camera output. If it is RAW data, it must go through rkisp. If it is yuv422/rgb888, it only needs to be configured to rkcif_mipi_lvdsx. This article introduced the camera channels of the RK3576 processor and explained how to configure different output formats for MIPI-CSI cameras. Future articles will continue to cover camera parameter configuration and device tree setup for the RK3576 processor.
×
  • Create New...