Embedded systems generally consist of four parts: embedded microprocessors, peripheral hardware devices, embedded operating systems, and user applications. Their development is primarily reflected in advancements in chip technology, and in the progress of algorithms and software within the limitations of chip technology. With the development of chip manufacturing technology, the structure of embedded systems has undergone significant changes, from microprocessor-based embedded systems to microcontroller-based embedded systems, then the introduction of programmable logic device (PLD) technology into embedded system design, further evolving into system-on-chip (SoC), and finally combining PLDs with embedded processors to form system-on-a-chip (SOPC), making SOPC a development trend in embedded system design. This paper uses the SOPC with an embedded 32-bit soft-core processor, NiOS, to implement a converter for a UART serial port and an Ethernet interface (hereinafter referred to as the converter), and develops an application based on μClinux, a Microtronix product ported for the NiOS processor. Its system architecture is shown in Figure 1. 1. Construction of an Embedded Hardware Platform Based on SOPC Unlike embedded systems based on processors, controllers, and SoCs, SOPC-based embedded systems are configurable and do not include any dedicated peripherals. Instead, peripheral interfaces can be flexibly constructed on a single FPGA as needed. An SOPC-based embedded system mainly consists of a core SOPC chip, external devices, and some related interface devices. The converter implemented in this paper uses Altera's Cyclone chip and peripheral circuitry, including two 512 kb SRAMs, one 8 MB flash memory, a UART electronic converter, and one LAN91C111 Ethernet controller. The system circuit block diagram is shown in Figure 2. The SOPC chip embeds a soft-core processor, NiOS. Besides the CPU, the SOPC chip can be equipped with on-chip ROM, internal timers, a UART serial port, SRAM, flash interfaces, and other system components. These components are all implemented as programmable logic units, and the internal component structure diagram of the chip is shown in Figure 3. The CPU and all components are connected together via an Avalon bus. The system modules and Avalon bus modules within the SOPC chip are automatically generated by the SOPCBuilder tool. The logic design and pin definitions within the chip can be implemented using the Qualitus II integrated development environment. After compilation, a hardware image file with the .sof extension is generated and downloaded to the Cyclone chip on the target board via a ByteBlaster II cable, or the .sof file is converted to a .flash file and downloaded to the flash memory of the target board. This completes the hardware design of the converter. 2. SOPC Application Development Based on μCLinux Application development can be performed directly on the hardware platform, but this requires understanding the details of all hardware components and writing corresponding driver subroutines. The software design is difficult and labor-intensive, and portability is poor. Applications based on embedded operating systems shield all hardware details from the user. The low-level drivers that directly control the hardware are encapsulated within the operating system and implemented through device driver interfaces. Users only need to program at a higher level using system calls provided by the operating system. μCLinux is an embedded Linux operating system for the control field, suitable for microprocessors/microcontrollers without a memory management unit (MMU), such as Nios processors. Developing based on an operating system requires loading the operating system onto the hardware platform. μclinux can be integrated into the SOPC system as a component. 2.1 Steps for Loading the μclinux System Loading μclinux onto the SOPC target board requires a cross-compilation environment. Hardware requirements include a PC workstation with a serial port, a Nios processor-based SOPC target board, and ByteBlasterV cables, etc. Software requirements include Windows NT v4.0, Windows 2000 or Windows XP, the Nios GNUPro tools provided in the Altera Nios development kit NDK 3.0, the Cygwin installation provided in the Ahera Nios development kit, and Quartus II programmable logic development tools v2.2, etc. 2.1.1 Creating and Loading the Kernel Image Creating and loading the μclinux image file is performed in the Linux Developer Bash environment. First, the kernel needs to be configured and built according to the following steps. [linux developer]…μclinux/: cd linux [linux developer]…linux/: make xconfig [linux developer]…linux/: make clean [linux developer]…linux/: make dep [linux developer]…linux/: make [linux developer]…μclinux/: make linux.flash The generated linux.flash file is the μclinux kernel image. When the SOPC target board is powered on, after the Germs monitoring program in the on-chip ROM runs, type nios-runlinux.flash at [linux developer]…μclinux/: to download the linux.flash file to the target board, completing the loading of the kernel image. 2.1.2 Creating and Mounting the Root File System In addition to loading the kernel, the root file system also needs to be mounted. μClinux uses the romfs file system, which requires less space than the general ext2 file system. On the host, the target directory of linux represents the root directory under μclinux. The current scripts and tools can convert the target directory into an image file (romdisk.flash). Create it as follows: `[linux developer]…μclinux/:make clean_target` `[linux developer]…μclinux/:make romfs` Then type the following command: `[linux developer]…μclinux/:nios-run romdisk.flash` This will download the romdisk.flash file to the target board, completing the loading of the μclinux root filesystem. 2.1.3 Loading the Application User applications can be loaded into the root filesystem through the target directory. The romdisk image can be rebuilt as needed. The application is located in the userland directory. After compiling and generating the executable file, it is copied to the target directory tree, and the romdisk.flash file is created based on the contents of the target directory. To create a new application, first open a Linux Developer Bash window, create a directory named app in the userland directory, store the application source files in this directory, and then create a makefile in userland/app/. The makefile content is shown below, where appfile is the application name. stackslze="8192" include../../rules.mak all: appfile.relocbflt sources="appfile".c install: $(romfsinst)appfile.relocebfh $(romfsdir)/bin/appfile $(execsuffix) clean: rm -f *.[iods]core appfile appfile.*elf appfile.*bflt Run make to compile the application and modify the userland/.config and /userland/makefile files. In the userland/.config file, add the line config_my_app=y. In the userland/makefile file, add dir_$(config_my_app)+=app. Enter the userland subdirectory and run make to install the application into userland/bin. The application binary will be copied to the target directory according to the corresponding variables in the userland/.config file. Finally, type the following command to rebuild the romdisk image file (romdisk.flash) and download it to the target board. [linux developer]...uclinux/: make clean_target [linux developer]...uclinux/: make romfs [linux developer]...uclinux/: nios-run romdisk.flash 2.1.4 Running μclinux After loading the μclinux kernel and file system, μclinux can be run. Type g800000 (800000 is the boot code address, set in SOPC Builder), μclinux will automatically complete the initialization process. The user enters the login username nios and the password μclinux. The μclinux prompt # appears, indicating that you have entered the μclinux runtime environment. 2.2 Implementation of the Converter Application The converter application system mainly completes the data transmission between the network interface and the serial interface. The transmitted data flow is shown in Figure 4. The μclinux operating system provides network drivers and serial port drivers, and provides multi-threading support. In the converter application system, serial port data transmission and reception and network port data transmission and reception are asynchronous and can be treated as separate tasks. These tasks are concurrent, so multithreading can be used to achieve concurrent execution. The main program flowchart is shown in Figure 5. This application system has four tasks, each creating a separate thread: a network receiving thread, a network sending thread, a serial port receiving thread, and a serial port sending thread. These four threads can execute concurrently. Due to the difference between network and serial port speeds, appropriate buffers are needed to buffer the transmitted and received data. Two circular buffers are set up in this application system, as shown in Figure 4. `nctrv_uartsd_buf` is used to receive network data, storing the data received from the network port, and then the serial port retrieves data from this buffer for transmission. The other buffer, `uartrv_netsd_buf`, is used to receive serial port data, and then the network port retrieves data from this buffer for transmission. Threads need to communicate and synchronize with each other. The shared buffers must be executed both mutually exclusively and synchronously, following a producer-consumer model. Mutual exclusion between threads is implemented using a mutex (mutual exclusion lock). Synchronization between threads is achieved by setting two pointers: a read pointer and a write pointer. The write pointer points to the head of the queue and is initialized to 0, while the read pointer points to the tail of the queue and is initialized to bufsize - 1. When writing data, the read and write pointers are compared. If they are equal, the write thread blocks; otherwise, the data is written, and the write pointer is incremented by 1. When reading data, the read pointer is incremented, and then the read and write pointers are compared. If they are equal, the read thread blocks; otherwise, the data is read. The network sending thread (flowchart shown in Figure 6) and the serial port receiving thread share a circular buffer uartrv_netsd_buf. The serial port sending thread and the network receiving thread share a circular buffer netrv_uartsd_buf. The relationship and processing between the two threads are similar to those between the network sending thread and the serial port receiving thread. 3 System Testing After completing the hardware and software design of the converter, the system is connected as shown in Figure 7 to test the data transmission of the converter. A serial port transceiver program was run on PC A, while an Ethernet transceiver program was run on PC B. After testing, the data transmission was found to be error-free.