Input/Output Operation Techniques
I/O Port Operations
x86 Port I/O Instructions:
; Basic port input/output
in al, 0x60 ; Read keyboard scan code from port 0x60
out 0x64, al ; Send command byte to port 0x64
; Extended port access (32-bit)
mov dx, 0x3F8 ; COM1 port base address
in eax, dx ; 32-bit input (limited to certain CPUs)
Port Operation Precautions:
- Port address space limit (0-65535)
- Requires I/O privilege level (CPL ≤ IOPL)
- Modern devices mostly use MMIO instead
Memory-Mapped I/O (MMIO)
MMIO Operation Example:
// Access MMIO region via pointer
volatile uint32_t *reg = (uint32_t *)0xFE000000;
*reg = 0x12345678; // Write to register
uint32_t status = *reg; // Read status
Hardware Register Design Principles:
- Address alignment (32-bit registers aligned on 4-byte boundaries)
- Memory barrier usage:
// Ensure write operation completion
__asm__ volatile("" ::: "memory");
- Bit field operations:
#define REG_ENABLE (1 << 0)
reg[CTRL_REG] |= REG_ENABLE; // Set enable bit
Device Controller Programming
Keyboard Controller (8042) Example:
; Read keyboard scan code
mov al, 0x01 ; Read command
out 0x64, al
in al, 0x60 ; Get scan code
; LCD controller initialization (typical embedded process)
mov dx, LCD_CTRL_REG
mov al, 0x30 ; 8-bit mode
out dx, al
call delay_15ms ; Wait for reset completion
Disk Controller Interaction:
// ATA command send example
void ata_write_cmd(uint8_t cmd) {
outb(ATA_CMD_REG, cmd);
while (!(inb(ATA_STATUS_REG) & ATA_SR_DRQ)) {
// Wait for data ready
}
}
Interrupt-Driven I/O and DMA
Interrupt Handling Process Optimization:
; x86 interrupt service routine framework
isr_keyboard:
pushad ; Save registers
call handle_key ; Handle keyboard input
mov al, 0x20 ; EOI command
out 0x20, al ; Send EOI to PIC
popad
iret ; Return
; DMA setup example (IDE disk)
mov dx, DMA_ADDR_REG
mov ax, buffer_phys_addr
out dx, ax ; Set source address
mov ax, transfer_size
out dx, ax ; Set transfer length
mov al, 0x01 ; Start DMA
out 0x03, al ; DMA control port
Interrupt vs. Polling Comparison:
| Feature | Interrupt-Driven I/O | Polling I/O |
|---|---|---|
| CPU Utilization | High | Low |
| Response Latency | Variable | Fixed |
| Implementation Complexity | High | Low |
| Applicable Scenarios | High-speed devices | Low-speed devices |
Hardware Programming Interfaces
PCI Device Configuration Space Access:
// Read device ID via PCI configuration space
uint16_t pci_read_config(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg) {
outl(0xCF8, 0x80000000 | (bus<<16) | (dev<<11) | (func<<8) | (reg&0xFC));
return inw(0xCFC + (reg&0x3));
}
USB Device Communication Process:
- Enumeration phase (get device descriptor)
- Configuration phase (set interface)
- Data transfer (control/bulk/interrupt/isochronous)
- Disconnect
Embedded System Development
Embedded Assembly Programming
ARM Assembly Basic Example:
; ARMv7 GPIO control
ldr r0, =GPIO_BASE
mov r1, #0x01 ; Set pin 1 as output
str r1, [r0, #GPIO_DIR]
mov r1, #0x01 ; High level
str r1, [r0, #GPIO_OUT]
MIPS Assembly Key Instructions:
; MIPS GPIO operation
li $t0, 0xBFD00000 # GPIO base address
li $t1, 0x01 # Pin mask
sw $t1, 0($t0) # Set direction
sw $t1, 4($t0) # Set output value
Microcontroller Programming
STM32 Timer Configuration:
// Initialize TIM2 timer
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // Enable clock
TIM2->PSC = 8400-1; // Prescaler (84MHz/8400=10kHz)
TIM2->ARR = 10000-1; // Auto-reload (10kHz/10000=1Hz)
TIM2->DIER |= TIM_DIER_UIE; // Enable update interrupt
TIM2->CR1 |= TIM_CR1_CEN; // Start timer
Interrupt Service Routine Example:
void TIM2_IRQHandler(void) {
if(TIM2->SR & TIM_SR_UIF) {
TIM2->SR &= ~TIM_SR_UIF; // Clear interrupt flag
GPIO_ToggleBits(GPIOA, GPIO_Pin_5); // Toggle LED
}
}
Embedded Operating Systems
FreeRTOS Task Creation:
// Create LED control task
void vLEDTask(void *pvParameters) {
while(1) {
GPIO_ToggleBits(GPIOA, GPIO_Pin_5);
vTaskDelay(pdMS_TO_TICKS(500)); // Delay 500ms
}
}
xTaskCreate(vLEDTask, "LED_Task", 128, NULL, 1, NULL);
RT-Thread Device Driver Framework:
// Custom character device driver
static struct rt_device gpio_dev;
static rt_size_t gpio_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) {
*(int*)buffer = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0);
return sizeof(int);
}
rt_err_t gpio_init(void) {
gpio_dev.type = RT_Device_Class_Char;
gpio_dev.init = gpio_init;
gpio_dev.read = gpio_read;
rt_device_register(&gpio_dev, "gpio0", RT_DEVICE_FLAG_RDWR);
}
Low-Power Design Techniques
STM32 Low-Power Mode Comparison:
| Mode | Current Consumption | Wake-Up Sources | Recovery Time |
|---|---|---|---|
| Run Mode | 1-2mA | – | – |
| Sleep Mode | 20μA | Interrupts/Events | 1 clock cycle |
| Stop Mode | 0.5μA | RTC/External Interrupts | 10-100μs |
| Standby Mode | 2μA | WKUP Pin/RTC | 1ms |
Clock Gating Example:
// Disable unused peripheral clocks
RCC->APB1ENR &= ~(RCC_APB1ENR_USART2EN | RCC_APB1ENR_I2C1EN);
Hardware Debugging Techniques
JTAG Debugging Process:
- Boundary scan chain initialization
- Instruction register load (IDCODE)
- Data register access
- Breakpoint setting and hit
Oscilloscope Measurement Key Points:
- Trigger mode setting (edge/pulse width)
- Sampling rate selection (≥5× signal frequency)
- Probe compensation calibration
- Timing measurement techniques
Hardware Acceleration and Optimization
SIMD Instruction Optimization
Image Convolution Example (SSE)
; 3x3 convolution kernel processing
movdqa xmm0, [src] ; Load 3 pixels
movdqa xmm1, [kernel] ; Load convolution kernel
pmaddwd xmm0, xmm1 ; Multiply-add operation
movhlps xmm2, xmm0 ; High part separation
paddd xmm0, xmm2 ; Horizontal sum
psrldq xmm0, 4 ; Adjust data position
paddd xmm0, [sum] ; Accumulate result
Optimization Effect Comparison:
| Implementation | Processing Time (1080p) | Speedup Ratio |
|---|---|---|
| C Language | 120ms | 1x |
| SSE | 35ms | 3.4x |
| AVX2 | 18ms | 6.7x |
GPU Programming Basics
CUDA Kernel Example:
__global__ void vector_add(float *A, float *B, float *C) {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
C[idx] = A[idx] + B[idx];
}
// Launch configuration
vector_add<<<256, 256>>>(d_A, d_B, d_C);
Performance Optimization Keys:
- Thread block size (16×16 or 32×32)
- Shared memory utilization
- Coalesced memory access
- Register pressure control
Dedicated Instruction Set Acceleration
AES-NI Instruction Sequence:
; AES-128 encrypt single block
movdqu xmm0, [plaintext]
movdqu xmm1, [key]
aesenc xmm0, xmm1 ; Round function 1
aesenc xmm0, xmm2 ; Round function 2
...
aesenclast xmm0, xmm10 ; Final round
movdqu [ciphertext], xmm0
SHA-NI Optimization Example:
#include <wmmintrin.h>
void sha256_hash(const uint8_t *data, size_t len, uint8_t *digest) {
__m128i state[8];
// Initialize state...
for(; len >= 64; len -= 64, data += 64) {
__m128i block = _mm_loadu_si128((__m128i*)data);
// SHA-256 compression...
}
}
Hardware Performance Analysis
Intel PMC Counter Configuration:
# Use perf to monitor cache misses
perf stat -e L1-dcache-misses,L1-icache-misses,dTLB-load-misses ./program
# Custom event monitoring
perf stat -e cpu/event=0x0E,umask=0x01/ ./program
Key Performance Indicators:
- Instructions retired rate (IPS)
- Cache hit rate
- Branch prediction accuracy
- Memory bandwidth utilization
Assembly and Hardware Co-Design
Custom Instruction Development Process:
- Hardware design (add new instruction to ISA)
- Microarchitecture implementation (modify execution unit)
- Compiler support (extend GCC/LLVM)
- Application optimization (rewrite critical paths)
Typical Application Scenarios:
- Cryptographic algorithm acceleration (e.g., national secret SM4)
- Multimedia processing (HEVC encoding)
- Machine learning inference (matrix operations)
- Network protocol processing (TCP checksum)
By comprehensively applying these techniques, developers can achieve:
- Critical algorithm performance improvement of 10-100x
- Energy efficiency optimization of 5-20x
- Real-time system latency reduction to microsecond level
- Hardware utilization improvement of 30-70%
- Development cycle shortening of 40%



