Virtual Machine and Operating System Setup
Establishing a stable development environment is the prerequisite for embedded Linux work. Ubuntu 20.04 LTS is recommended for compatibility with Loongson toolchains.
VMware Configuration
- Install VMware Workstation on the host machine.
- Create a new virtual machine using the Ubuntu 20.04 ISO image.
- Allocate resources: 2-4 CPU cores, 4GB RAM, and sufficient disk space (preferably on an SSD).
- Set the network adapter to NAT mode to ensure internet access within the guest OS.
- Complete the Ubuntu installation, setting up a user account and configuring the region to China for optimal package mirror selection.
Environment Optimization
VMware Tools Install VMware Tools to enable shared folders and clipboard integration. Mount the ISO via VM settings, extract the tarball in Ubuntu, and execute the installation script with root privileges.
Package Sources Replace default repositories with domestic mirrors (e.g., Tsinghua) to accelerate package management.
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
sudo vim /etc/apt/sources.list
# Replace content with mirror URLs corresponding to Ubuntu 20.04 (focal)
sudo apt update
Shared Folders
Enable shared folders in VM settings to facilitate file transfer between Windows and Ubuntu. Mount the shared directory permanently by editing /etc/fstab:
.host:/ /mnt/hgfs fuse.vmhgfs-fuse allow_other,uid=0,gid=0,umask=022 0 0
Create a symbolic link on the desktop for easy access.
Cross-Compilation Toolchain
Native compilation on the embedded board is inefficient due to limited resources. Cross-compilation allows building executables on x86 hosts for the LoongArch architectuer.
Toolchain Installation
- Download the Loongson GNU toolchain (loongarch64-linux-gnu).
- Extract the archive to
/opt/. - Configure environment variables by appending the bin path to
~/.bashrc:
export PATH=/opt/loongson-gnu-toolchain/bin:$PATH
source ~/.bashrc
- Verify installation by running
loongarch64-linux-gnu-gcc --version.
Compilation Workflow
Create a test C program in the shared folder:
#include <stdio.h>
int main(void) {
printf("System Initialized\n");
return 0;
}
Compile using the cross-compiler:
loongarch64-linux-gnu-gcc main.c -o app_loong
Verify the architecture using file app_loong. It should indicate LoongArch. Transferring this binary to the 2K0300 board allows execution, whereas an x86 binary would fail.
Board Connectivity and Kernel
SSH Access
Use MobaXterm or similar clients to connect via SSH. Ensure the board and host are on the same network. Retrieve the board's IP address via router admin pages or ARP commands.
Kernel Compilation
Customizing the kernel requires specific dependencies:
sudo apt install bison libncurses5-dev libssl-dev flex
Load the default configuration for 2K0300:
cp arch/loongarch/configs/loongson_2k300_defconfig .config
make menuconfig ARCH=loongarch
Compile the kernel image:
make vmlinuz ARCH=loongarch CROSS_COMPILE=loongarch64-linux-gnu- -j$(nproc)
GPIO Control via Sysfs
Linux exposes GPIO interfaces through the sysfs filesystem, allowing control via file operations.
Pin Configuration
Refer to the board schematic to identify GPIO numbers. For example, GPIO 83 might control an onboard LED.
Bash Script Implementation
A shell script can toggle the pin state:
#!/bin/bash
GPIO_ID=83
echo $GPIO_ID > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio$GPIO_ID/direction
while true; do
echo 0 > /sys/class/gpio/gpio$GPIO_ID/value
sleep 0.5
echo 1 > /sys/class/gpio/gpio$GPIO_ID/value
sleep 0.5
done
C Implementation
For better performance, use file I/O instead of system calls.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#define GPIO_PATH "/sys/class/gpio/gpio"
#define GPIO_ID 64
void write_gpio(int id, const char* value) {
char path[64];
snprintf(path, sizeof(path), "%s%d/value", GPIO_PATH, id);
int fd = open(path, O_WRONLY);
if (fd >= 0) {
write(fd, value, 1);
close(fd);
}
}
void setup_gpio(int id) {
int export_fd = open("/sys/class/gpio/export", O_WRONLY);
if (export_fd >= 0) {
char buf[16];
snprintf(buf, sizeof(buf), "%d", id);
write(export_fd, buf, strlen(buf));
close(export_fd);
}
char dir_path[64];
snprintf(dir_path, sizeof(dir_path), "%s%d/direction", GPIO_PATH, id);
int dir_fd = open(dir_path, O_WRONLY);
if (dir_fd >= 0) {
write(dir_fd, "out", 3);
close(dir_fd);
}
}
int main(void) {
setup_gpio(GPIO_ID);
while (1) {
write_gpio(GPIO_ID, "0");
usleep(500000);
write_gpio(GPIO_ID, "1");
usleep(500000);
}
return 0;
}
Compile with the cross-compiler and deploy to the board.
Computer Vision with OpenCV
OpenCV provides robust tools for image processing. Using Python with Anaconda simplifies dependancy management.
Environment Setup
- Install Anaconda and initialize the shell.
- Create a dedicated environment:
conda create -n vision_env python=3.8
conda activate vision_env
- Install OpenCV:
pip install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple
Color Detection Logic
The following script captures video, converts frames to LAB color space, and isolates specific colors using trackbars for threshold adjustment.
import cv2
import numpy as np
class ColorDetector:
def __init__(self):
self.lower_bound = np.array([0, 0, 0])
self.upper_bound = np.array([255, 255, 255])
def create_trackbars(self, window_name):
cv2.namedWindow(window_name)
cv2.createTrackbar('L_min', window_name, 0, 255, self.update_bounds)
cv2.createTrackbar('A_min', window_name, 0, 255, self.update_bounds)
cv2.createTrackbar('B_min', window_name, 0, 255, self.update_bounds)
cv2.createTrackbar('L_max', window_name, 255, 255, self.update_bounds)
cv2.createTrackbar('A_max', window_name, 255, 255, self.update_bounds)
cv2.createTrackbar('B_max', window_name, 255, 255, self.update_bounds)
def update_bounds(self, pos):
self.lower_bound = np.array([
cv2.getTrackbarPos('L_min', 'Controls'),
cv2.getTrackbarPos('A_min', 'Controls'),
cv2.getTrackbarPos('B_min', 'Controls')
])
self.upper_bound = np.array([
cv2.getTrackbarPos('L_max', 'Controls'),
cv2.getTrackbarPos('A_max', 'Controls'),
cv2.getTrackbarPos('B_max', 'Controls')
])
def process_frame(self, frame):
blurred = cv2.blur(frame, (3, 3))
lab = cv2.cvtColor(blurred, cv2.COLOR_BGR2LAB)
mask = cv2.inRange(lab, self.lower_bound, self.upper_bound)
contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
output = frame.copy()
for cnt in contours:
if cv2.contourArea(cnt) > 500:
cv2.drawContours(output, [cnt], -1, (0, 255, 0), 2)
return output, mask
if __name__ == "__main__":
detector = ColorDetector()
detector.create_trackbars('Controls')
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
if not ret:
break
result, mask = detector.process_frame(frame)
cv2.imshow('Original', result)
cv2.imshow('Mask', mask)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Adjust the trackbars until the mask window displays the target object in white against a black background. Save thresholds for persistent detection.