Search the Community
Showing results for tags 'linux'.
-
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
-
- linux
- techupgrade
-
(and 2 more)
Tagged with:
-
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/
-
Software version: Linux 4.19 Design Idea: Detect screen touch events to determine whether the screen is being used or not in an auto-break application. If the screen detects input events, it will remain on. If no touch events are received for a period of time, the screen will transition from on to a dimmed state, reminding the user that it is about to enter the screen-off mode. If no touch events occur after dimming, the screen will enter the screen-off mode. When a touch event occurs again, the screen will transition from screen-off mode to the on state. Currently, the approach to implement automatic screen-off is to treat touch events as a fixed path that can be applied to familiar boards. To enhance convenience in application, two additional alternative approaches are provided below: ▊ The first implementation method You can apply the evtest command to get the path to/dev/input/event1 (event1 is the name of the touch event on my board). You can then pass the path to your program as a parameter. For example, you can modify your program to accept command-line arguments to specify the path of the device file to open int argc, char *argv[]; Opens a file with the passed in parameters as the device file path int fd = open(argv[1], O_RDONLY); You can compile and run the program, passing it/dev/input/event1 as a command-line argument, like this: ./your_program /dev/input/event1 ▊ The second implementation method is to fix the screen touch node in the device tree. Look for the screen touch node in the device tree and note its address. On the I2C bus, the address of the touch node is simply 2-0038 So we can use grep to filter out touch nodes based on their addresses. ls -l /sys/class/input | grep "0038" | awk -F ' ' '{print $9}' | grep "event" The following command is used in the application to find the touch event based on the touch address. char *command_output = exec("ls -l /sys/class/input | grep '0038' | awk -F ' ' '{print $9}' | grep 'event'"); Use the sprintf function to splice the path containing the event, and then read the event. Examples of using Sprintf: int main() { char str[100]; int num = 123; float f = 3.14; //Write the formatted data to the string sprintf(str, "%d%.2f", num, f); //print the generated string printf("The output is. %s\n", str); return 0; }
-
- rk3568 som
- automatic screen off configuration
- (and 3 more)
-
1. GPIO Wake-up The supported system sleep modes can be viewed with cat /sys/power/state. To achieve functionality similar to the 6ul, use the "wake-up" function in ''gpio-keys.c''. Add a GPIO node specifying the wake-up GPIO pin. During sleep, a message indicates only GPIO0 supports wake-up; testing confirmed only GPIO0 can wake up. cat /proc/interrupts indicates that the interrupt for key1 has been successfully registered. Testing has been conducted to verify that both freeze and mem modes can wake up. 2. Network Wake-up Firstly, NIC support for Wake-on-LAN is required. Use the ethtool tool to check NIC information. The default setting for wake-on is ''d'', which means network wake-up is disabled. The ''supports Wake-on'' option is ''ug'', where ''u'' allows any unicast data and ''g'' allows magic packets. The wake-on can be set to ''ug'' for eth0 using the following command: ''ethtool -s eth0 wol ug''. Test for u: echo freeze > /sys/power/state//Enter freeze sleep mode Waking up can be achieved by pinging the IP of this network port in any local area network. Test for g: ethtool -s eth0 wol g//Set wake-on to g At this point, the ping fails, but the mac can be specified through the wol to wake up. Testing revealed that Wake-On-LAN is only possible in freeze mode. Observations showed that after entering mem mode, the network LED does not light up; whereas, in freeze mode, the network LED continues to blink normally. This indicates that the PHY (physical layer) is not functioning in mem mode, and therefore, it cannot trigger an interrupt for wake-up. It is also possible that this interrupt pin is connected to gpio3 _ A2.
-
In this article, we will introduce the SoMs of the Allwinner series. Allwinner × Forlinx Embedded The cooperation between Forlinx Embedded and Allwinner Technology started in 2019. Up to now, Forlinx Embedded has launched 3 SoMs based on Allwinner processors--FETT507-C, FETA40i-C, and FETT3-C that won unanimous recognition of the market. 01 Allwinner T507 Series FETT507-C SoM is designed and developed based on Allwinner T507 quad-core industrial level processor Cortex-A53 with main frequency 1.5GHz, integrated with G31 GPU, 2GB DDR3L RAM, and 8GB eMMC storage. With Linux, Android, and Forlinx Desktop operating systems, it is suitable for in-vehicle electronics, power, medical care, industrial control, IoT, intelligent terminals, and other fields. 02 Allwinner A40i Series The FETA40i-C SoM is designed based on Allwinner industrial control level processor quad-core Cortex-A7 A40i with main frequency 1.2GHz, integrated with MAli400MP2 GPU, 1GB/2GB DDR3L RAM, 8GB eMMC storage. It supports most current popular video and image formats decoding and has the advantages of stable and reliable industrial-level product performance, cost-effective and low-power consumption, etc. Equipped with Linux and Android operating systems, it is suitable for industrial control products based on visual interaction. 03 Allwinner T3 Series FETT3-C SoM is designed and developed based on Allwinner quad-core car navigation processor Cortex-A7 with main frequency 1.2GHz, integrated with MAli400MP2 GPU, 1GB DDR3L RAM, 8GB eMMC storage. Entire board industrial level running temperature supports most current popular video and image formats decoding and has the advantages of stable and reliable industrial-level product performance, low-power consumption, rich interfaces etc. Equipped with Linux and Android operating systems, it is suitable for in-vehicle electronics, power, medical care, industrial control, IoT, intelligent terminals, and other fields. Above is the big list of Forlinx Embedded’s Allwinner series; the industrial-level quality makes the application more stable and reliable.
- 2 replies
-
- allwinner
- system on modules
-
(and 3 more)
Tagged with:
-
The Allwinner T507-H chip is widely used in various fields such as automotive electronics, power, healthcare, industrial control, IoT, and smart terminals. In complex embedded Linux application scenarios, it is important to break down the barriers between ARM boards and Windows devices in order to achieve cross-platform file sharing. Here’s how you can accomplish this: We can use Samba, which is free software for SMB on Linux systems, to share files and printers between different operating systems. Samba makes it easy to share files between different platforms such as Linux, Windows and Mac, which greatly improves the efficiency of file transfer. So, how to set up Samba service on the embedded OKT507-C development board? 01 Compile source code 1.Source code download address: http://ftp.samba.org/pub/samba/ Download the Samba source package and enter the source3 path: 2.Configure: ./configure CC=aarch64-linux-gnu-gcc LD=aarch64-linux-gnu-ld AR=aarch64-linux-gnu-ar --target=arm-none-linux --host=arm-none-linux-gnueabihf samba_cv_CC_NEGATIVE_ENUM_VALUES=yes --cache-file=arm-linux.cache 3. Compile the source code (with only single-threaded compilation, without using the -j parameter): make 4.make install Generate the installation file: Specify the installation path in the Makefile samba-3.4.17/source3$make install 02 Configuration Service 1.Extract the compressed package to the following path: 2.Create a new configuration file at the following path: 3.Edit the contents of the file: 4.Add a library file Copy the dynamic link library file in the following path to the/lib directory of the board: 5.Start the service 03 Application services 1.OKT507-C development board (Linux board) and Windows host to share files: (1) Start the Samba service and configure the IP of the same network segment as the host: (2) Add Samba support in the Windows host: Open the control panel to enter the following interface: Check the following three options: (3) Enter the server IP in the file manager, and press Enter to see the shared path: 2.The Linux board shares directories with the Ubuntu virtual machine: (1) Install cifs-utils: (2) Create a mount point: (3) Mount the shared directory: At this point, we have completed the implementation of Samba service on the embedded OKT507-C development board of Forlinx, and successfully made this Linux board share files with Windows host and Ubuntu virtual machine. Of course, the specific operation of different master control platform boards will be different, but the overall idea is the same. I hope that the method provided in this article can be helpful to the project development of engineers in front of the screen. Originally published at www.forlinx.net.
-
- allwinner t507h
- samba
-
(and 2 more)
Tagged with:
-
The pollutants produced by human activities are the main factors causing water pollution. To protect the water environment, we must strengthen the monitoring of sewage discharge, the analysis of surface water, groundwater, industrial wastewater, and other water quality, and ensure the safety of people's water use. Drinking water safety concerns everybody, but many people still do not know its quality. Does the residual chlorine exceed the standard? What is the pH? These important indicators related to drinking water health need to be accurately detected. A water quality detector is a professional instrument used to analyze the content of water quality components, which can measure BOD, COD, ammonia nitrogen, total phosphorus, total nitrogen, turbidity, pH, and dissolved oxygen in water. It plays an important role and has been widely used in water quality detection and water resources protection. FETMX6ULL-C arm core board launched by Forlinx Embedded can be effectively used in water quality detectors to help us better protect drinking water. FETMX6ULL-C core board is a processor-based NXP i.MX6ULL is designed with a low-power ARM Cortex-A7 architecture that runs at speeds up to 800MHz. A low main frequency can reduce the heat generated by the CPU and extend the service life of the CPU. Its stable performance has been verified in long-term use in many fields. FETMX6ULL-C SoM is highly integrated and supports 8x serial ports, 2x network ports, and 2x CAN. The rich interfaces can connect dissolved oxygen sensors (with temperature), pH sensors, conductivity sensors, turbidity sensors, ammonia nitrogen analyzers, total organic carbon analyzers TOC, etc., to facilitate on-site construction and assembly. Dual-lane Ethernet can achieve dual-network redundancy. The 10M/100M adaptive Ethernet interface provides double insurance for the network. The support of WiFi and 4G also makes operation and maintenance more convenient. The software system uses Linux 4.1.15 and has an experienced technical support team to solve problems in the user design, allowing customers to quickly enter the product testing phase. Originally published at www.forlinx.net.
-
- water quality detector
- imx6ull
-
(and 2 more)
Tagged with:
-
Hi, Guy I have joined this forum some time. Recently, i have just finished a project development. The project is building CMD line(cli) tools for multiple OS, windows10, linux and macos. I just want to share you guys my experience with the 3 platform. BTW, the RTL8722DM dev from following link is what my project is used for. https://www.amebaiot.com/en/amebad-arduino-getting-started/ Basically, windows is the most convenient platform. It has all kind of tools for compiling c, cpp and c# projects. One things need to be considered. 1, if you use visual studio for c# in windows. the tool you have build is not easy to transfer in to the other platforms. To support a visual studio c# project there a lot of works to do in linux and macos. Additionally, you have to set up the toolchain/compiler properly for windows. Linux has no issue to compile my project. But lack of development tools and "sudo" sometimes gives you big problem. For, c and cpp development, i suggest that linux is the best and all project is able to transfer to the other platform. Macos has the most limitations. i am a windows person so using macos to development is a bit trouble for me. And the disc name of macos always has a "space" which is very bad for process command. However, i would say the project made by macos is the most stable and small size one. To summarize, if you trying to make a multiple platform/OS support project. I would recommend to use c/cpp project and start on linux. Please try not to start with windows, windows is the easiest way, but will gives you troubles when trying to support all 3 platform/OS.