面试题答案
一键面试#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#define DEVICE_MEM_SIZE 4096 // 假设设备内存大小为4096字节
#define CONTROL_REG_OFFSET 0 // 控制寄存器偏移
#define DATA_BUFFER_OFFSET 1024 // 数据缓冲区偏移
#define DATA_BUFFER_SIZE 1024 // 数据缓冲区大小
// 模拟设备内存结构
typedef struct {
volatile unsigned int control_reg;
char data_buffer[DATA_BUFFER_SIZE];
} DeviceMemory;
// 初始化设备
void init_device(DeviceMemory *device) {
device->control_reg = 0x00; // 设置控制寄存器初始值
}
// 从数据缓冲区读取数据
void read_data(DeviceMemory *device, char *buffer, size_t length) {
if (length > DATA_BUFFER_SIZE) {
printf("Read length exceeds buffer size\n");
return;
}
memcpy(buffer, device->data_buffer, length);
}
// 向数据缓冲区写入数据
void write_data(DeviceMemory *device, const char *buffer, size_t length) {
if (length > DATA_BUFFER_SIZE) {
printf("Write length exceeds buffer size\n");
return;
}
memcpy(device->data_buffer, buffer, length);
}
int main() {
int fd;
DeviceMemory *device_memory;
// 打开 /dev/mem 设备文件,该文件提供对物理内存的直接访问
fd = open("/dev/mem", O_RDWR);
if (fd == -1) {
perror("open /dev/mem");
return 1;
}
// 将设备内存映射到用户空间
device_memory = (DeviceMemory *)mmap(
NULL,
DEVICE_MEM_SIZE,
PROT_READ | PROT_WRITE,
MAP_SHARED,
fd,
0x10000000 // 假设设备物理地址为0x10000000,需根据实际情况调整
);
if (device_memory == MAP_FAILED) {
perror("mmap");
close(fd);
return 1;
}
// 初始化设备
init_device(device_memory);
// 测试写入数据
char write_buf[] = "Hello, Device!";
write_data(device_memory, write_buf, strlen(write_buf));
// 测试读取数据
char read_buf[DATA_BUFFER_SIZE];
read_data(device_memory, read_buf, strlen(write_buf));
printf("Read data: %s\n", read_buf);
// 解除内存映射
if (munmap(device_memory, DEVICE_MEM_SIZE) == -1) {
perror("munmap");
}
close(fd);
return 0;
}
说明
- 设备内存结构定义:定义了一个结构体
DeviceMemory
来模拟设备内存,包含控制寄存器和数据缓冲区。 - 初始化设备函数:
init_device
函数设置控制寄存器的初始值。 - 数据读写函数:
read_data
和write_data
函数分别实现从数据缓冲区读取数据和向数据缓冲区写入数据,并处理了可能的长度越界问题。 - 内存映射与使用:在
main
函数中,通过open
打开/dev/mem
设备文件,使用mmap
将设备内存映射到用户空间,然后调用初始化和数据读写函数进行操作,最后通过munmap
解除内存映射并关闭文件。
实际应用中,设备的物理地址和内存大小等需要根据具体硬件情况进行调整。同时,访问 /dev/mem
可能需要超级用户权限。对于不同操作系统,内存映射的细节和设备文件可能有所不同。