mmap操作荔枝派gpio v3s Linux

摘要:
Fr=阿拉丁你可以清楚地看到百度百科。因此,起始地址应该是0x1000的整数倍。显然,0x01C20800需要减去0x800才能成为整数倍!如果{printf;close;return;}printf;//这里,0x1c20000的地址已映射到内存,但我们需要的地址是0x01C20800,因此我们需要添加地址偏移量~PIO=;输出函数关闭;//映射后可以关闭文件吗?“);}return0;}gpio.h#ifndef_gpio_h__#define_gpio_h__#include<studio.h>#include<unistd.h>#include<sys/mamman.h>#include˂sys/types.h>#incinclude<sys/stat.h偏移值。-1的否定值为01,-2的否定值是01…gpio_SetPin;//usleep;sleep;}gpio_Free() ;} MakefileTARGET=myGPIO#可执行文件名########################编译参数######################

1.预备知识

https://baike.baidu.com/item/mmap/1322217?fr=aladdin 大家直接看百度百科,比较清楚了。

2.代码

gpio.c

#include "gpio.h"

unsigned int fd;
PIO_Map *PIO = NULL;
unsigned int *gpio_map;
unsigned int addr_start, addr_offset;
unsigned int PageSize, PageMask;
void GPIO_Init(void)
{

    if ((fd = open("/dev/mem", O_RDWR)) == -1)
    {
        printf("open error
");
        return;
    }

    PageSize = sysconf(_SC_PAGESIZE); //使用sysconf查询系统页面大小
    PageMask = (~(PageSize - 1));     //页掩码
    printf("PageSize:%d,PageMask:0x%.8X
", PageSize, PageMask);

    addr_start = PIO_BASE_ADDRESS & PageMask;   //0x01C20800 & 0xfffff000 =  0x1C20000
    addr_offset = PIO_BASE_ADDRESS & ~PageMask; //0x01C20800 & 0x00000100 = 0x800
    printf("addr_start:%.8X,addr_offset:0x%.8X
", addr_start, addr_offset);
    //mmap(系统自动分配内存地址,映射区长度“内存页的整数倍”,选择可读可写,MAP_SHARED=与其他所有映射到这个对象的进程共享空间,文件句柄,被映射内容的起点)
    //offest 映射物理内存的话,必须页对其!!!   所以这个起始地址应该是0x1000的整数倍,那么明显0x01C20800需要减去0x800才是整数倍!
    if ((gpio_map = mmap(NULL, PageSize * 2, PROT_READ | PROT_WRITE, MAP_SHARED, fd, addr_start)) == NULL)
    {
        printf("mmap error
");
        close(fd);
        return;
    }
    printf("gpio_map:%.8X
", gpio_map);
    //这里已经将0x1c20000的地址映射到了内存中,但是我们需要的地址是0x01C20800,所以要再加上地址偏移量~
    PIO = (PIO_Map *)((unsigned int)gpio_map + addr_offset);
    printf("PIO:0x%.8X
", PIO);

    close(fd); //映射好之后就可以关闭文件?
}

void GPIO_ConfigPin(PORT port, unsigned int pin, PIN_MODE mode)
{
    if (gpio_map == NULL)
        return;
    PIO->Pn[port].CFG[pin / 8] &= ~((unsigned int)0x07 << pin % 8 * 4);
    PIO->Pn[port].CFG[pin / 8] |= ((unsigned int)mode << pin % 8 * 4);
    printf("struct PIO_Struct size : %d",sizeof(PIO->Pn[port]));
}

void GPIO_SetPin(PORT port, unsigned int pin, unsigned int level)
{
    if (gpio_map == NULL)
        return;
    if (level)
        PIO->Pn[port].DAT |= (1 << pin);
    else
        PIO->Pn[port].DAT &= ~(1 << pin);
}

int GPIO_Free(void)
{
    if ((munmap(gpio_map, PageSize * 2)) == 0)//取消映射
    {
        printf("unmap success!
");
    }
    else
    {
        printf("unmap failed!
");
    }
    return 0;
}

gpio.h

#ifndef __GPIO_H__
#define __GPIO_H__
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define PIO_BASE_ADDRESS 0x01C20800


//unsigned int 4字节 一个PIO_Struct占36字节,对应十六进制就是0x24,正好是一个offset值。
typedef struct
{
    unsigned int CFG[4];
    unsigned int DAT;
    unsigned int DRV0;
    unsigned int DRV1;
    unsigned int PUL0;
    unsigned int PUL1;
} PIO_Struct;

typedef struct
{
    PIO_Struct Pn[7];
} PIO_Map;

typedef enum {
    PA = 0,
    PB = 1,
    PC = 2,
    PD = 3,
    PE = 4,
    PF = 5,
    PG = 6,
} PORT;

typedef enum {
    IN = 0x00,
    OUT = 0x01,
    AUX = 0x02,
    INT = 0x06,
    DISABLE = 0x07,
} PIN_MODE;

extern PIO_Map *PIO;

void GPIO_Init(void);
void GPIO_ConfigPin(PORT port, unsigned int pin, PIN_MODE mode);
void GPIO_SetPin(PORT port, unsigned int pin, unsigned int level);
unsigned int GPIO_GetPin(PORT port, unsigned int pin);
int GPIO_Free(void);
#endif

main.c

#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "gpio.h"
#include <stdbool.h>
int main()
{
    int a=0,b=-1,i;
    GPIO_Init();
    GPIO_ConfigPin(PB,4,OUT);
    GPIO_ConfigPin(PB,5,OUT);
    for(i=0;i<20;i++)
    {
        GPIO_SetPin(PB,4,a=~a);//!!-1的取反是0 1的取反是-2....
        GPIO_SetPin(PB,5,b=~b);
        //usleep(100000);
        sleep(1);
    }
    GPIO_Free();
}

makefile

TARGET        = myGPIO    #可执行文件名称

########################编译参数############################
CC            = arm-linux-gnueabihf-gcc 
CXX           = arm-linux-gnueabihf-g++ 
DEFINES       = 
CFLAGS        = -pipe -g -Wall -W -fPIE $(DEFINES)
CXXFLAGS      = -pipe -g -Wall -W -fPIE $(DEFINES)
INCPATH       = -I. 


########################编译文件############################
SOURCES       = ./main.c ./gpio.c
OBJECTS       = main.o gpio.o

$(TARGET) : $(OBJECTS)
        $(CC) -o $(TARGET) $(OBJECTS)
main.o : main.c gpio.h
        $(CC) $(include) $(CFLAGS) -c main.c 
gpio.o : gpio.c gpio.h 
        $(CC) $(include) $(CFLAGS) -c gpio.c 
clean :
        rm  $(OBJECTS) $(TARGET)

3.运行

将程序编译出来放到v3s上运行,那么pb4 pb5 会交替高低电平。

免责声明:文章转载自《mmap操作荔枝派gpio v3s Linux》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇bootstrap基础(六)警告:Nvidia 官方二进制驱动严重问题下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

c语言进阶6-指针

指针是c语言的一个重要组成部分 是c语言的核心、精髓所在,用好指针可以在c语言编程中起到事半功倍的效果。一方面,可以提高程序的编译效率和执行速度以及实现动态的存储分配;另一方面,使用指针可使程序更灵活,全球表示各种数据结构,编写高质量的程序。 指针是c语言显著的优点之一,其使用起来十分灵活而且能提高某些程序的效率,但是如果使用不当则很容易造成系统错误。许多...

qmake的使用(可设置c编译器flag参数)

本文由乌合之众 lym瞎编,欢迎转载 my.oschina.net/oloroso***还是先说一下当前的系统环境:Ubuntu 14.04 + Qt5.4如果没有安装过QT,可以安装下面几个qt软件 sudo apt-get install qt5-default qt5-doc-html qt5-qmake qt5-doc qt5-image-form...

Linux系统扩容根目录磁盘空间的操作方法

一、使用背景 Linux根目录磁盘空间不够用了,当修改了虚拟机模版增加磁盘大小或者插入了一块新硬盘,但是发现系统里的大小还是没改变。 产生的原因是没有给磁盘格式化,没有增加分区。 二、操作方法 1. 查看磁盘空间大小,使用df -h 命令,发现挂载根目录节点的/dev/mapper/ubuntu14--vg-root 只有28G容量。 1 2 3 4...

linux下deb包的管理及制作 | 一次成功

1.deb包介绍 在debian/ubuntu环境下,很多情况下,我们安装已经开发的程序运用,可以通过deb包的命令进行程序的部署,对应的项目目录文件也会同步到某些目录下,有些情况下将程序做成service启动,这样会更方便运用的管理,如通过service xxx start|stop|status|restart。 deb 是 Unix 系统(其实主要是...

linux 根目录扩容方法

准备知识 linux volume 1.(PV)physical volume disk ; 物理硬盘 物理硬盘需要转换成lvm(logic volume manage)可识别的状态,将磁盘的system id 转换成8e(lvm的识别码),再通过 pvcreate转换成PV,这样才能对磁盘加以利用 2.(VG) volume group 磁盘组, 由p...

Linux文件目录及权限

一、Linux下的文件目录 简介:linux的文件系统是采用级层式的树状目录结构,在此 结构中的最上层是根目录“/”,然后在此目录下再创建 其他的目录。深刻理解linux文件目录是非常重要的,如下图所示: 将来你用哪个用户登录,你就会在那个用户的目录下面。为了大家再进一步加深对Linux的文件目录的理解,下面再附上一张对应目录作用的解释: 简单演示:...