head.h

#ifndef __HEAD_H__

#define __HEAD_H__

#define PHY_RCC 0X50000A28

#define PHY_GPIOE 0X50006000

#define PHY_GPIOE_ODR 0X50006014

#define PHY_GPIOF 0X50007000

#define PHY_GPIOF_ODR 0X50007014

#endif // MACRO

fun.c

#include

#include

#include

#include

#include

#include

#include

int main(int argc, char const *argv[])

{

/* code */

char buf[128] = {0};

printf("调用open\n");

int fd = open ("/dev/mycdev",O_RDWR);

if(fd < 0)

{

printf("打开设备文件失败\n");

exit(-1);

}

while(1)

{

printf("请输入要点亮的灯号(1-3)及操作(0[灭]、1[亮])[exit退出程序]:");

fgets(buf,sizeof(buf),stdin);

buf[strlen(buf)-1] = '\0';

write(fd,buf,sizeof(buf));

if(!strcmp(buf,"exit")) break;

}

printf("调用close\n");

close (fd);

return 0;

}

mycdev.c

#include

#include

#include

#include

#include "head.h"

unsigned int major;

char kbuf[128] = {0};

unsigned int *vir_moder;

unsigned int *vir_odr;

unsigned int *vir_rcc;

int mycdev_open(struct inode *inode,struct file *file)

{

printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);

return 0;

}

ssize_t mycdev_read(struct file *file,char *ubuf,size_t size,loff_t *lof)

{

printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);

if(copy_to_user(ubuf,kbuf,size))

{

printk("copy_to_user filed\n");

return -EIO;

}

return 0;

}

ssize_t mycdev_write(struct file *file,const char *ubuf,size_t size,loff_t *lof)

{

unsigned int pin;

printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);

if(copy_from_user(kbuf,ubuf,size))

{

printk("copy_to_user filed\n");

return -EIO;

}

switch(kbuf[0])

{

case '1':

pin = 10;

vir_odr=ioremap(PHY_GPIOE_ODR,4);

if(vir_odr==NULL)

{

printk("映射物理内存失败%d\n",__LINE__);

return -EFAULT;

}

break;

case '2':

pin = 10;

vir_odr=ioremap(PHY_GPIOF_ODR,4);

if(vir_odr==NULL)

{

printk("映射物理内存失败%d\n",__LINE__);

return -EFAULT;

}

break;

case '3':

pin = 8;

vir_odr=ioremap(PHY_GPIOE_ODR,4);

if(vir_odr==NULL)

{

printk("映射物理内存失败%d\n",__LINE__);

return -EFAULT;

}

break;

default:

printk("语法错误,请重新输入>>>");

return -1;

}

if(kbuf[1] == '0')

{

//关灯逻辑

(*vir_odr) &= (~(0X1<

}

else if(kbuf[1]=='1')

{

//开灯逻辑

(*vir_odr) |=(0X1<

}

else

{

printk("语法错误,请重新输入>>>");

return -1;

}

return 0;

}

int mycdev_close(struct inode *inode,struct file *file)

{

printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);

return 0;

}

struct file_operations fops={

.open = mycdev_open,

.release = mycdev_close,

.read = mycdev_read,

.write = mycdev_write,

};

void GPIO_INIT(unsigned int gpio,unsigned int pin)

{

//进行寄存器地址的映射

vir_moder=ioremap(gpio,4);

if(vir_moder==NULL)

{

printk("映射物理内存失败%d\n",__LINE__);

return;

}

vir_rcc=ioremap(PHY_RCC,4);

if(vir_rcc==NULL)

{

printk("映射物理内存失败%d\n",__LINE__);

return;

}

if(gpio == PHY_GPIOE)

{

vir_odr=ioremap(PHY_GPIOE_ODR,4);

if(vir_odr==NULL)

{

printk("映射物理内存失败%d\n",__LINE__);

return;

}

(*vir_rcc)|=(0X1<<4);//rcc使能GPIOE组

}

else if(gpio == PHY_GPIOF)

{

vir_odr=ioremap(PHY_GPIOF_ODR,4);

if(vir_odr==NULL)

{

printk("映射物理内存失败%d\n",__LINE__);

return;

}

(*vir_rcc)|=(0X1<<5);//rcc使能GPIOF组

}

printk("映射物理内存成功\n");

//硬件寄存器的初始化

(*vir_moder) &= (~(0X3 << pin*2));//设置为输出

(*vir_moder) |= (0X1 << pin*2);

(*vir_odr) &= (~(0X1 << pin));//输出低电平

printk("硬件寄存器初始化成功\n");

}

static int __init mycdev_init(void)

{

major = register_chrdev(0,"mycdev",&fops);

if(major < 0)

{

printk("注册失败\n");

}

printk("注册成功major = %d\n",major);

GPIO_INIT(PHY_GPIOE,10);

GPIO_INIT(PHY_GPIOF,10);

GPIO_INIT(PHY_GPIOE,8);

return 0;

}

static void __exit mycdev_exit(void)

{

unregister_chrdev(major,"mycdev");

printk("出口函数\n");

}

module_init(mycdev_init);

module_exit(mycdev_exit);

MODULE_LICENSE("GPL");

Makefile

modname ?= mycdev

arch ?= arm

ifeq ($(arch),arm)

KERNELDIR:= /home/ubuntu/13_UBOOT/linux-stm32mp-5.10.61-stm32mp-r2-r0/linux-5.10.61

else

KERNELDIR:=/lib/modules/$(shell uname -r)/build/

endif

PWD:=$(shell pwd)

all:

make -C $(KERNELDIR) M=$(PWD) modules

clean:

make -C $(KERNELDIR) M=$(PWD) clean

obj-m:=$(modname).o

好文阅读

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。