SOC FPGA写测试时的一些相关函数(Linux 下的内存映射)
Posted w²大大
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SOC FPGA写测试时的一些相关函数(Linux 下的内存映射)相关的知识,希望对你有一定的参考价值。
Linux 下的内存映射
一、open()函数
open函数的定义形式:
int open(const char *pathname, int flags);
int open(const char * pathname, int flags, mode_t mode);
返回值:
1、返回值是一个整数。
2、打开文件成功,返回文件描述符。
3、打开文件失败,返回-1。
函数说明:
参数 pathname 指向欲打开的文件路径字符串.
下列是参数flags 所能使用的旗标:
O_RDONLY 以只读方式打开文件
O_WRONLY 以只写方式打开文件
O_RDWR 以可读写方式打开文件. 上述三种旗标是互斥的, 也就是不可同时使用, 但可与下列的旗标利用OR(|)运算符组合.
O_CREAT 若欲打开的文件不存在则自动建立该文件.
O_EXCL 如果O_CREAT 也被设置, 此指令会去检查文件是否存在. 文件若不存在则建立该文件, 否则将导致打开文件错误. 此外, 若O_CREAT 与O_EXCL 同时设置, 并且欲打开的文件为符号连接, 则会打开文件失败.
O_NOCTTY 如果欲打开的文件为终端机设备时, 则不会将该终端机当成进程控制终端机.
O_TRUNC 若文件存在并且以可写的方式打开时, 此旗标会令文件长度清为0, 而原来存于该文件的资料也会消失.
O_APPEND 当读写文件时会从文件尾开始移动, 也就是所写入的数据会以附加的方式加入到文件后面.
O_NONBLOCK 以不可阻断的方式打开文件, 也就是无论有无数据读取或等待, 都会立即返回进程之中.
O_NDELAY 同O_NONBLOCK.
O_SYNC 以同步的方式打开文件.
O_NOFOLLOW 如果参数pathname 所指的文件为一符号连接, 则会令打开文件失败.
O_DIRECTORY 如果参数pathname 所指的文件并非为一目录, 则会令打开文件失败。注:此为Linux2. 2 以后特有的旗标, 以避免一些系统安全问题.
参数mode 则有下列数种组合, 只有在建立新文件时才会生效, 此外真正建文件时的权限会受到umask 值所影响, 因此该文件权限应该为 (mode-umaks).
S_IRWXU00700 权限, 代表该文件所有者具有可读、可写及可执行的权限.
S_IRUSR 或S_IREAD, 00400 权限, 代表该文件所有者具有可读取的权限.
S_IWUSR 或S_IWRITE, 00200 权限, 代表该文件所有者具有可写入的权限.
S_IXUSR 或S_IEXEC, 00100 权限, 代表该文件所有者具有可执行的权限.
S_IRWXG 00070 权限, 代表该文件用户组具有可读、可写及可执行的权限.
S_IRGRP 00040 权限, 代表该文件用户组具有可读的权限.
S_IWGRP 00020 权限, 代表该文件用户组具有可写入的权限.
S_IXGRP 00010 权限, 代表该文件用户组具有可执行的权限.
S_IRWXO 00007 权限, 代表其他用户具有可读、可写及可执行的权限.
S_IROTH 00004 权限, 代表其他用户具有可读的权限
S_IWOTH 00002 权限, 代表其他用户具有可写入的权限.
S_IXOTH 00001 权限, 代表其他用户具有可执行的权限.
返回值:若所有欲核查的权限都通过了检查则返回0 值, 表示成功, 只要有一个权限被禁止则返回-1.
错误代码:
EEXIST 参数pathname 所指的文件已存在, 却使用了O_CREAT 和O_EXCL 旗标.
EACCESS 参数pathname 所指的文件不符合所要求测试的权限.
EROFS 欲测试写入权限的文件存在于只读文件系统内.
EFAULT 参数pathname 指针超出可存取内存空间.
EINVAL 参数mode 不正确.
ENAMETOOLONG 参数 pathname 太长.
ENOTDIR 参数pathname 不是目录.
ENOMEM 核心内存不足.
ELOOP 参数pathname 有过多符号连接问题.
EIO I/O 存取错误.
代码示例:
int fd;
//打开MMU
fd = open("/dev/mem",(O_RDWR | O_SYNC));
if(fd == (-1))
{
printf("ERROR:could not open\\"/dev/mem\\"...\\n");
}
二、mmap()
mmap映射函数
功能:将一个文件或者其它对象映射进内存。文件被映射到多个页上,如果文件的大小不是所有页的大小之和,最后一个页不被使用的空间将会清零
void *mmap(void *start, size_t length, Int prot, int flags, int fd, off_t offsize);
参数:
start:映射区的开始地址
length:映射区的长度
prot:映射区域的保护方式。
flags:指定映射对象的类型,映射选项和映射页是否可以共享
fd:有效的文件描述词。
offset:被映射对象内容的起点
返回:成功,返回被映射区的指针 失败,返回MAP_FAILED(其为(void*)-1)
Prot:
PROT_EXEC //页内容可以被执行
PROT_READ //页内容可以被读取
PROT_WRITE //页可以被写入
PROT_NONE //页不可访问
flags:
MAP_FIXED //使用指定的映射起始地址,如果由 start和len 参数指定的内存区重叠于现存的映射空间,重叠部分将会被丢 弃。如果指定的起始地址不可用,操作将会失败。并且起始地址必须落在页的边界上
MAP_SHARED //与其它所有映射这个对象的进程共享映射空间。对共享区的写入,相当于输出到文件。直到 msync()或者munmap() 被调用,文件实际上不会被更新
MAP_PRIVATE //建立一个写入时拷贝的私有映射。内存区域的写入不会影响到原文件。这个标志和以上标志是互斥的,只能使用其中一个
MAP_DENYWRITE、MAP_EXECUTABLE //标志被忽略
MAP_NORESERVE //不要为这个映射保留交换空间。当交换空间被保留,对映射区修改的可能会得到保证。当交换空间不被保留,同时内存不足,对映射区的修改会引起段违例信号
void *virtual_base;
virtual_base = mmap(NULL,HW_REGS_SPAN, ( PROT_READ | PROT_WRITE ),MAP_SHARED,fd,HW_REGS_BASE);
if(virtual_base==MAP_SHARED)
{
printf("ERROR:mmap()failed...\\n");
close(fd);
return 1;
}
三、munmap()
munmap取消映射函数
功能:删除特定地址区域的对象映射
int munmap(void *start, size_t length);
参数:
start:映射区的开始地址
length:映射区的长度
返回:成功 0 失败 -1
if(munmap(virtual_base,HW_REGS_SPAN)!=0)
{
printf("ERROR:munmap()failed...\\n");
close(fd);
return 1;
}
四、close
int close(int fd)
说明:该函数用来关闭已打开的文件.指定的参数fd为open()或creat()打开的文件描述符.
返回值:关闭成功返回0,失败则返回-1.
详解:close()函数用来关闭一个已打开的文件,并且将文件修改过的内容写回磁盘
任何有关该文件描述符上的记录锁,和使用该文件的进程都会被关闭和移除
//关闭MMU
close(fd);
以上是关于SOC FPGA写测试时的一些相关函数(Linux 下的内存映射)的主要内容,如果未能解决你的问题,请参考以下文章