简介
MMIO,内存映射输入输出;在嵌入式开发中,常常通过MMIO实现外围设备的访问。
嵌入式系统,通常通过特定内存地址范围提供外围设备的访问功能,当程序访问该区域的某一个地址时,并不会读取或写入某个值,相反数据会被发送至设备中,或者是从相关联设备读取数据
其他说明
测试设备的系统时钟分配的物理内存地址偏移:0x3F003000
constexpr uint32_t kTimerBase = 0x3F003000;
linux通过/dev/mem访问物理内存地址
int memfd = open("/dev/mem", O_RDWR | O_SYNC);
内存映射
SystemTimer *timer = (SystemTimer*)mmap(NULL, sizeof(SystemTimer),
PROT_READ|PROT_WRITE, MAP_SHARED,
memfd, kTimerBase);
接下来就是使用系统时钟指针对象可以直接访问系统时间
完整代码
#include <iostream>
#include <chrono>
#include <system_error>
#include <thread>
#include <fcntl.h>
#include <sys/mman.h>
constexpr uint32_t kTimerBase = 0x3F003000;
struct SystemTimer {
uint32_t CS;
uint32_t counter_lo;
uint32_t counter_hi;
};
int main() {
int memfd = open("/dev/mem", O_RDWR | O_SYNC);
if (memfd < 0) {
throw std::system_error(errno, std::generic_category(),
"Failed to open /dev/mem. Make sure you run as root.");
}
SystemTimer *timer = (SystemTimer*)mmap(NULL, sizeof(SystemTimer),
PROT_READ|PROT_WRITE, MAP_SHARED,
memfd, kTimerBase);
if (timer == MAP_FAILED) {
throw std::system_error(errno, std::generic_category(),
"Memory mapping failed");
}
uint64_t prev = 0;
for (int i = 0; i < 10; i++) {
uint64_t time = ((uint64_t)timer->counter_hi << 32) + timer->counter_lo;
std::cout << "System timer: " << time;
if (i > 0) {
std::cout << ", diff " << time - prev;
}
prev = time;
std::cout << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
return 0;
}
我公司承接各类技术服务,主要聚焦于:stm32、单片机、嵌入式、QT应用开发、Web+Python+Django应用开发。欢迎合作。