点灯实验:
//led.h
#ifndef __LED_H__
#define __LED_H__
//pe10,pf10,pe8
#define RCC 0x50000a28
#define GPIOE_MODER 0x50006000
#define GPIOE_ODR 0x50006014
#define GPIOF_MODER 0x50007000
#define GPIOF_ODR 0x50007014
#endif//应用层代码
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
int main(int argc,const char * argv[])
{
int fd=open("/dev/mycdev",O_RDWR);
if(fd<0)
{
perror("open");
return -1;
}
char buf[128]="";
while(1)
{
printf("请输入命令>>");
fgets(buf,sizeof(buf),stdin);
buf[strlen(buf)-1]='\0';
write(fd,buf,sizeof(buf));
}
close(fd);
return 0;
}//内核层的代码
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include<linux/uaccess.h>
#include<linux/io.h>
#include "led.h"
int major; //接收主设备号
int res;
//接收映射后的虚拟内存地址
unsigned int *vir_rcc;
unsigned int *vir_emoder;
unsigned int *vir_eodr;
unsigned int *vir_fmoder;
unsigned int *vir_fodr;
char kbuf[128]="";
//定义自己的open,read,write,release函数
int my_open(struct inode *indoe,struct file *file)
{
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
return 0;
}
ssize_t my_read(struct file *file,char *user,size_t size,loff_t *loff)
{
if(size>sizeof(kbuf)) //判断kbuf的大小
{
size=sizeof(kbuf);
}
//内核空间的数据拷贝到用户空间
res=copy_to_user(user,kbuf,size);
if(res)
{
printk("copy failed\n");
return -1;
}
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
return 0;
}
ssize_t my_write(struct file *file,const char *user,size_t size,loff_t *loff)
{
if(size>sizeof(kbuf))
{
size=sizeof(kbuf);
}
//用户空间中的数据拷贝到内核空间
res=copy_from_user(kbuf,user,size);
if(res)
{
printk("copy failed\n");
return -1;
}
//判断用户在终端输入的数据
switch(kbuf[0])
{
case '1':
if(kbuf[1]=='1')
{
//led1亮
*vir_eodr |= (1<<10);
}
else if (kbuf[1]=='0')
{
//led1灭
*vir_eodr &= (~(1<<10));
}
break;
case '2':
if(kbuf[1]=='1')
{
*vir_fodr |= (1<<10);
}
else if (kbuf[1]=='0')
{
*vir_fodr &= (~(1<<10));
}
break;
case '3':
if(kbuf[1]=='1')
{
*vir_eodr |= (1<<8);
}
else if (kbuf[1]=='0')
{
*vir_eodr &= (~(1<<8));
}
break;
default:break;
}
//printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
return 0;
}
int my_close(struct inode *inode,struct file *file)
{
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
return 0;
}
//定义操作方法结构体并初始化
struct file_operations fops=
{
.open=my_open,
.read=my_read,
.write=my_write,
.release=my_close,
};
//入口函数
static int __init mycdev_init(void)
{
//注册字符驱动设备
major=register_chrdev(0,"mycdev",&fops);
if(major<0)
{
printk("字符设备驱动注册失败\n");
return major;
}
printk("字符设备驱动注册成功,主设备号:%d",major);
/****映射物理内存地址到虚拟内存中****/
vir_rcc=ioremap(RCC,4);
if(vir_rcc==NULL)
{
printk("rcc寄存器映射失败\n");
return -1;
}
vir_emoder=ioremap(GPIOE_MODER,4);
if(vir_emoder==NULL)
{
printk("emoder寄存器映射失败\n");
return -1;
}
vir_eodr=ioremap(GPIOE_ODR,4);
if(vir_eodr==NULL)
{
printk("eodr寄存器映射失败\n");
return -1;
}
vir_fmoder=ioremap(GPIOF_MODER,4);
if(vir_fmoder==NULL)
{
printk("fmoder寄存器映射失败\n");
return -1;
}
vir_fodr=ioremap(GPIOF_ODR,4);
if(vir_fodr==NULL)
{
printk("fodr寄存器映射失败\n");
return -1;
}
(*vir_rcc) |= (3<<4);
//初始化led1,led2,led3
(*vir_emoder) &= (~(3<<20));
(*vir_emoder) |= (1<<20);
(*vir_fmoder) &= (~(3<<20));
(*vir_fmoder) |= (1<<20);
(*vir_emoder) &= (~(3<<16));
(*vir_emoder) |= (1<<16);
return 0;
}
//出口函数
static void __exit mycdev_exit(void)
{
//注销字符设备驱动
unregister_chrdev(major,"mycdev");
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
1540

被折叠的 条评论
为什么被折叠?



