linux存在名为mmap的函数,能把物理地址映射为虚拟地址,并且这个函数能直接在应用程序中直接调用而不是仅仅属于内核调用的函数,这样在应用层直接操作S3C6410的物理外设成为可能。考虑到在特定的嵌入式系统中,特定外设的使用可以由程序控制,这样可以简化共享设备的互斥保护,进一步减少代码量,提高了访问效率。

mmap函数调用实例

mmap函数作用是将物理地址映射至用户空间。下面是函数的参数简单说明

void* mmap(void * addr, size_t len, int prot, int flags, int fd, off_t offset);

addr: 指定文件应被映射到进程空间的起始地址

len: 映射到用户空间的字节数

prot: 指定被映射空间的访问权限,

flags: 由以下几个常值指定:

fd: 映射到用户空间的文件的描述符

offset: 被映射内存区在文件中的偏移值该函数映射文件描述符

通过这个函数,我们可以在应用层访问对应物理地址正确映射后的虚拟地址,这个函数使我们在应用层也具有对任意物理地址的操作权限,下面代码配置S3C6410的SPI0,因为使用mmap映射,所以不论内核是否带有SPI驱动都不影响我们使用SPI0,但是因为本程序需要对比研究标准驱动方式与直接存储器访问方式的执行差异,所以在内核中编译了标准SPI的驱动程序。由于S3C6410多数脚都有复用功能,为了使SPI0正确工作,还需要配置相关对应的GPIO为SPI功能(实际上因为我们编译的内核带有SPI0的驱动,内核程序已经完成了SPI的初始化,有的内核没有编译SPI,所以下面还是完整配置了SPI,供参考),同时为了观察研究SPI的执行效率,我们程序还对其他GPIO做了配置以便输出脉冲,通过示波器来评估观察。另外我们还使用若干时间标志来记录操作过程时间,对于在没有示波器的情况下也能评估执行时间。

下面是测试程序代码以及测试过程的示波器记录抓图。

#include “test.h”

void Init_FPGA_SPI(){ //配置SPI端口

int fbb;

fbb=open(“/dev/mem”,O_RDWR | O_SYNC);

map_base=(char *)mmap(0,4096,PROT_READ|PROT_WRITE,MAP_SHARED,fbb,0x7f00b000);

*(volatile unsigned int *)(map_base+0x04)=0x00000101; //CLK=16.625MHz

*(volatile unsigned int *)(map_base+0x08)=0x00000000;

*(volatile unsigned int *)(map_base+0x0c)=0x00000002;

*(volatile unsigned int *)(map_base)=0x00000003;

FPGA_RUN=map_base+0x18;

map_base=(char *)mmap(0,4096,PROT_READ|PROT_WRITE,MAP_SHARED,fbb,0x7f008000);

GPC=map_base+0x40; //配置端口复用功能为SPI

map_GPC=*(volatile unsigned int *)(GPC+4);

*(volatile unsigned int *)(GPC)=0x12201222;

  • UC3846控制芯片工作原理控制图 逆变焊机原理与用途
  • 数字万用表电阻档测试二极管正反向没有阻值(使用万用表测量二极管的正向电阻,为什么各档)
  • 学单片机需要学数电模电吗(学单片机要先学数电模电吗)
  • 电工怎么选择适合自己用的万用表(电工初学者买什么样的万用表好)
  • 单片机需要同时运行多个任务怎么办(单片机怎么同时执行多个任务)
  • 电机保护的方案取决于负载的机械特性
  • 绝缘电阻表正负搭接不复零位是怎么回事
  • 短路怎么用万用表查