General-purpose embedded motherboard design with PCI bus interface
2026-04-06 07:21:07··#1
Abstract: The widespread application of embedded systems and PCI devices necessitates that more and more products run on a platform shared by these two advanced technologies. This article takes the design of an embedded video transmission system as an example, introducing the design concept of an embedded system motherboard with two PCI slots and an ARM9 processor S3C2510A as the main chip. It describes the system's hardware configuration, bootloader porting, and device driver writing methods. The application of this motherboard can avoid redundant development of embedded systems and allows various PCI device cards to easily run using embedded system management modes. Keywords: PCI bus; S3C2510A; embedded system; Boot loader; μClinux, Abstract: With the wide application of embedded system and PCI devices, many products need to run on both platforms of embedded system and systems with PCI interface. The design of the embedded video transmission system, for example, is presented in the paper. The hardware design of the embedded motherboard of 2 PCI slots with processor S3C2510A of ARM9; transplantation of Boot loader and methods of constructing device driver is also described. The application of the newly developed motherboard will eliminate the necessity of repeated development of embedded system and kinds of ready-made PCI device can be applied to the embedded system conveniently. Key words: PCI Bus; S3C2510A; embedded system; Boot loader; μClinux 1. Introduction The use of ARM microprocessors to build embedded systems has been widely applied in various fields such as industrial control, video and audio acquisition, security monitoring, consumer handheld mobile products, and home gateway devices[1]. Most current embedded systems are developed for specific applications and are typically divided into two parts: a main control unit and a data processing unit. The main control units of different embedded systems are generally similar in function, with the differences mostly concentrated in the data processing unit. For example, the difference between a video acquisition and processing system and a device operation status monitoring system is that the former acquires and processes video data, while the latter acquires and processes monitored device operating parameters (such as pressure, temperature, and flow rate). Therefore, the main control units of the two systems can be completely identical. Based on this situation, we developed and designed a general-purpose embedded motherboard to complete the main control unit functions of the embedded system. This allows us to focus our main efforts on developing the data processing card during system development, reducing redundant development of the main control unit. Furthermore, the widespread use of the PCI bus, with its 32-bit data bus, clock frequency of up to 66MHz, and maximum transmission rate of 264MB/s, meets the needs of high-speed data transmission. In addition, most data processing and communication modules have PCI interfaces; therefore, the interface design of the embedded motherboard's main control and data processing units adopts the PCI bus (the designed motherboard provides two PCI slots). By utilizing a general-purpose embedded motherboard with a PCI interface, along with data processing boards developed or selected according to functional requirements, the embedded system can operate in "standalone mode," enabling tasks that previously required designing the entire embedded system to be completed. Now, only PCI device drivers need to be written to directly apply existing PCI devices to the general-purpose embedded motherboard. 2. Hardware Circuit Design Figure 1 illustrates the application of a general-purpose embedded motherboard using a video transmission system as an example. The system processor uses Samsung's S3C2510A chip, with an ARM 940T core and a maximum operating frequency of 200MHz. The motherboard design directly utilizes the chip's built-in SDRAM controller, PCI controller, USB controller, and 10M/100M Ethernet controller, among other interface controllers. The motherboard's external clock source is 10MHz. Through the four built-in multipliers of the S3C2510A, pins CLKMOD0, CLKMOD1, CPU_FREQ1, and BUS_FREQ0 are set high; pins CPU_FREQ0, CPU_FREQ2, BUS_FREQ1, and BUS_FREQ2 are set low, resulting in a system core operating frequency of 133MHz, PCI device operating frequency of 66MHz, and USB device operating frequency of 48MHz. The motherboard adopts a layered design concept of a minimum system core board and peripheral interface expansion boards, connected by high-speed interconnects, making the motherboard's application more convenient and flexible. The minimum core board consists of three parts: the main control chip, the storage system, and the debug interface. The main control chip uses the S3C2510A with a built-in PCI controller. To meet the large memory space required for video transmission and the storage of the embedded Linux operating system, the storage module consists of two 32MByte, 16Bit K4S561632E SDRAM chips and two 8MByte, 16Bit AM29LV640MT FLASH chips. The debugging interface includes one RS232 serial port and one JTAG hardware debugging interface. The peripheral interface expansion card has two 10M/100M Ethernet interfaces, one RS232 serial port, one RS485 serial port, two USB HOST interfaces for connecting external hard drives and other storage devices, and one USB DEVICE interface to set the motherboard as a target device for a PC. This section will focus on the hardware design of the PCI bus interface. Figure 2 is a block diagram of the connection principle between the S3C2510A and the PCI slot. [align=center]Figure 2. Block diagram of S3C2510A PCI implementation principle[/align] After the system powers on, the video and audio processing card in the PCI slot awaits input of analog video and analog audio signals. Once the processing card receives the analog data, it compresses and encodes it. The processed data is then transmitted to the Ethernet port via the S3C2510A's internal AHB bus. The video service program in the embedded Linux system on the motherboard transmits the compressed data to the client PC via Ethernet. The client only needs a decoding player to view the video. Simultaneously, the data can also be transmitted to the USB port to save the video file to a hard drive. System debugging on the development board can be completed via the RS232 serial port. Furthermore, an external GPRS wireless modem can be connected via RS232, allowing wireless internet access and the transmission of important data when data transmission via Ethernet is not possible. The RS485 serial port can implement the transmission of certain special protocols, such as PTZ control protocols. 2.1 S3C2510A with built-in PCI bus controller [align=center]Table 1. Operation Mode According to Mode Pin Setting[/align] Samsung's S3C2510A ARM processor integrates a PCI (MINI-PCI) & PC Card controller. According to the application requirements, the S3C2510A's PCI (MINI-PCI) & PC Card controller can be set to PCI Host mode. This is achieved by setting the levels of the two configuration pins, PCI_PCCDM and PCI_HOSTM[2]. See Table 1 on the previous page. The PCI bus controller embedded in the S3C2510A conforms to the PCI bus specification version 2.2, has a 32-bit address/data multiplexed bus, supports non-linear transmission and burst transmission, and the maximum data transmission speed can reach 264MB/s@66MHz (132MB/s@33MHz). Moreover, it has an address translation mechanism that can map the internal PCI bus address to memory or peripheral devices. The pin definitions of the S3C2510A are named according to the PCI bus, so designers only need to connect the PCI control pins of the S3C2510A. In this design, the PCI bus clock frequency is set to 66MHz, thus the maximum transfer speed of the PCI bus on the motherboard can reach 264MB/s, which is sufficient for fast data transfer. Clock feedback is needed here to compensate for the PCI clock latency. [align=center] Fig3. PCI Clock Schemes[/align] As shown in the figure above, when the PCI controller is working in PCI HOST mode, its clock source is provided by the system. The S3C2510A has three PCI clock output signals PCICLK1, PCICLK2 and PCICLK3. Set the DC3 bit of the PCI device diagnostic register PCIDIAG0 to 1, that is, set PCICLK3 to be invalid output. At this time, PCICLK1 is connected to PCICLK3, and the clock signal is fed back to the processor core through PCICLK3. This can keep the external PCI device in line with the PCI clock, thereby making up for the clock delay [3]. 2.2 Startup sequence of the system and PCI controller After the system is powered on, the startup sequence of the system and PCI controller is shown in Figure 4: When configuring the special function register of the PCI controller, the interrupt needs to be disabled first, that is, set PCIINTEN=0. Then set the PCI control and status registers PCICON[ARB, ATS, SPL, IOP, MMP]. In some cases, the PCI diagnostic register also needs to be set. This register is for testing functions and does not need to be set in PCMCIA Host working mode. Then the registers PCIBAM0~1 and PCIBATPA0~2 related to the base address need to be designed. After setting, the registers related to PCI restart and clock need to be configured. The key step is to set the PCI restart and clock register PCIRCC[MSK]=0, which is to prevent the restart signal and clock signal from conflicting[3]. [align=center] Fig4. PCI Controller's Booting Sequence[/align] When the PCI controller detects peripheral devices and initializes the registers of peripheral devices, the following work needs to be done: 1) Read all configuration register values, including PCIHID, PCIHSC, PCIHSSID, etc. 2) Check the range of BAR (Backup Address Register) and allocate space one by one. 3) Enable external devices and activate the bus. The above configurations are all completed within the PCI video processing card driver. Since the driver has been loaded into the uClinux kernel, the operating system will automatically configure the PCI external devices after system startup. 3. System Software Design The system software mainly consists of two parts: the Boot Loader and the embedded uClinux. The Boot Loader is equivalent to the BIOS of a PC; it's a program that runs before the operating system kernel. Its main function is to initialize hardware devices, establish system memory space mapping, and then call the operating system kernel. The embedded uClinux is the OS of this system, mainly including device drivers and upper-layer applications. This section mainly introduces the method of porting the Boot Loader and the implementation of device drivers in uClinux. 3.1 Porting the Boot Loader The Boot Loader is tightly connected to the hardware. The system uses the Boot Loader to call the operating system kernel and ultimately run the operating system. This system uses U-Boot (Universal Boot Loader) as the Boot Loader. The following section describes how to build the motherboard's Boot Loader based on the porting of U-Boot. U-Boot is essentially a small Linux system. Its operation involves hardware system initialization, memory allocation, and more. Therefore, porting it requires careful reading of the relevant chip's hardware manual. The following tasks were primarily completed during the design process, and the related programming can be done based on the examples provided by U-Boot: 1) Modify the Makefile configuration file to add compilation command lines specific to the target board. 2) Create an arm940t directory under the CPU directory, mainly including the system entry function start.S, interrupt setting function code interrupts.c, CPU-related code file cpu.c, and serial port initialization code file serial.c, etc. 3) Create an S3C2510 directory under the Board directory, mainly including FLASH initialization code flash.c, memory allocation code memsetup.S, linker file u-boot.lds, etc. 4) Write the configuration file, i.e., include/configs/s3c2510.h, completing system configuration such as register definitions. Most of this work was done by referring to the S3C2510 datasheet. 5) Write the flash.c file. Based on the AMD NOR Flash being used, write the Flash driver, mainly including the flash chip model, capacity, print information, and flash erase function. 6) Modify the SDRAM size. Simply modify `#define PHYS_SDRAM_SIZE 0X200000` in the previously created configuration file `include/configs/s3c2510.h`. Its size is determined based on the actual SDRAM size used in the application. 7) Modify the serial port parameter file `serial.c`. This includes setting the serial port baud rate, which is calculated using the following formula: `RUBRDIV0 = (int)(MCLK/16./(gd->baudrate) + 0.5) - 1)`. 8) Modify the start.S file. An executable image must have one entry point and only one unique global entry point, usually located at address 0x0 of the ROM (flash). For example, `.globl_start_start:` in start.S. After completing the above work, U-Boot can be compiled and downloaded to the target board for debugging via the Jtag port. 3.2 uClinux device driver writing The Linux kernel is composed of device management, process management, memory management and file system. Linux device drivers can be divided into character devices, block devices, network interface devices and other non-standard drivers. Among them, PCI devices are regarded as character devices[5]. Each PCI peripheral is identified by a bus number, a device number and a function number. There are three access spaces, namely memory space, I/O port and configuration register. The PCI configuration space consists of 256 bytes, and each device function has a configuration space, which is used to determine the working mode of the PCI device and the address mapped to the system. The basic functions are as follows: int pci_present(void) // Check if the system supports PCI struct pci_dev // Software object of PCI device int pci_find_device(...) // Find the specified PCI device int pci_find_class(...) // Find the specified PCI class int pci_read_config_byte(...) // Read the configuration space int pci_write_config_byte(...) // Write the configuration space The following describes the implementation steps of uClinux device driver by adding the system's PCI device driver: 1) Create a PCI device with the following command: mknod pci_dev c 245 0 where c represents a character device, 245 represents the major device number, and 0 represents the minor device number. 2) Initialize external devices. Add the function pci_dev_init() to the chr_dev_init() function in the uClinux/linux/drivers/char/mem.c file. chr_dev_init() will be called during system startup and will complete the device driver initialization: /* Modify the file_operations data structure */ Struct file_operations pci_dev_fops = { read: pci_dev_read; write: pci_dev_write; open: pci_dev_open; release: pci_dev_release; }; /* Initialize PCI external devices */ Int pci_dev_init(void) { int result; printk(“pci_dev_init()\n”); /* Device registration */ result = register_chrdev(245,”pci_dev”,&pci_dev_fops); } 3) Write the device driver file pci_dev.c. The device registration interface function, interrupt handling function, etc., constitute the main code of the PCI device driver, specifically the functions in `file_operations`. The device driver is closely related to the kernel; careful attention must be paid to the use of library functions and I/O space allocation during the writing process. The standard library provided by LibC cannot be used in embedded system programming. I/O space checking is crucial. Data must be read and written according to the base address given by the S3C2510A's PCI configuration register. Because the PCI-defined I/O space is a 32-bit address space, memory and I/O can use the same configuration interface. 4) Loading the PCI device. Because uClinux does not support dynamic loading of device drivers, the driver needs to be compiled into the uClinux kernel. First, modify the Makefile file and add the following line: `obj_$(CONFIG_PCI_DEV) += pci_dev.o`. Then modify `config.in` and add: `bool 'pci_dev install' CONFIG_PCI_DEV`. Adding this line allows selection of this device when configuring the target board's Linux kernel. Finally, add the device node `pci_dev,c,245,0` to the target system's Makefile. This allows you to select `pci_dev install` during Linux kernel configuration and then compile, thus loading the PCI device driver into the uClinux system. 4. Summary The video transmission system using this motherboard and PCI interface video processing card provides smooth and clear video transmission within a local area network. The development of a general-purpose embedded motherboard with a PCI interface can reduce repetitive development of embedded systems and shorten the development cycle. The design of the core board and expansion interface board makes the motherboard's application more convenient and flexible. Different data processing cards can be combined with the motherboard according to specific applications to form different functional systems applicable to various specific needs. References [1] Li Shanping, Liu Wenfeng, Wang Huanlong. Linux and Embedded Systems [M]. Beijing: Tsinghua University Press, 2003.1-4 [2] Li Guishan, Wei Dehu. PCI Local Bus Developer Guide [M]. Xi'an: Xi'an University of Electronic Science and Technology Press, 1997 [3] SNSung Electronics. S3C2510A 32bit RISC Microprocessor user's manual [M], 2003.3, 43-47 [4] Li Juguang, Nie Xueyuan, Jiang Zeming, Wang Zhaowei. ARM Application System Development Explained [M]. Beijing: Tsinghua University Press, 2003.202-205 [5] Alessandro Rubini, Jonathan Corbet, Wei Yongming, Luo Gang, Jiang Jun, translated. Linux Device Drivers (2nd Edition) [M], China Electric Power Press, 2002.11 502-526