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 好文阅读
发表评论