一共进行了LED灯点亮和蜂鸣器以及马达的启动实验
头文件
#ifndef __HEAD__H__
#define __HEAD__H__
typedef struct
{
volatile unsigned int MODER;
volatile unsigned int OTYPER;
volatile unsigned int OSPEEDR;
volatile unsigned int PUPDR;
volatile unsigned int IDR;
volatile unsigned int ODR;
volatile unsigned int BSRR;
}gpio_t;
#define PHY_RCC_ADDR 0x50000A28
#define PHY_LED1_ADDR 0x50006000
#define PHY_LED2_ADDR 0x50007000
#define PHY_LED3_ADDR 0x50006000
#define PHY_H_RCC_ADDR 0x50000290
#define PHY_H_LED1_ADDR 0x54004000
#define PHY_H_LED2_ADDR 0x54004000
#define PHY_H_LED3_ADDR 0x54004000
#define PHY_BUZ_ADDR 0x50003000
#define PHY_MOT_ADDR 0x50007000
#define LED_ON _IOW('l',1,int)
#define LED_OFF _IOW('l',0,int)
#define LED_H_ON _IOW('l',3,int)
#define LED_H_OFF _IOW('l',2,int)
#define BUZ_ON _IO('l',1)
#define BUZ_OFF _IO('l',0)
#define MOT_ON _IO('l',3)
#define MOT_OFF _IO('l',2)
#endif
应用层代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include "head.h"
int main(int argc, char const *argv[])
{
int func,num,op;
char buf[128]={0};
int fd = open("/dev/mycdev",O_RDWR);
if(fd < 0 )
{
perror("文件打开失败\n");
return -1;
}
while (1)
{
func = 100;
printf("请输入: 0(控制拓展板的LED灯亮灭) 1(控制主板的LED灯亮灭) 2(控制蜂鸣器) 3(控制马达) ->");
scanf("%d",&func);
while(getchar()!='\n');
switch (func)
{
case 0:
printf("请输入选择哪盏灯: 1(LED1) 2(LED2) 3(LED3)");
scanf("%d",&num);
while(getchar()!='\n');
printf("请输入: 0 (关闭) 1 (开启)");
scanf("%d",&op);
while(getchar()!='\n');
if(1 == op)
ioctl(fd,LED_ON,&num);
else if(0 == op)
ioctl(fd,LED_OFF,&num);
break;
case 1:
printf("请输入选择哪盏灯: 1(LED1) 2(LED2) 3(LED3)");
scanf("%d",&num);
while(getchar()!='\n');
printf("请输入: 0 (关闭) 1 (开启)");
scanf("%d",&op);
while(getchar()!='\n');
if(1 == op)
ioctl(fd,LED_H_ON,&num);
else if(0 == op)
ioctl(fd,LED_H_OFF,&num);
break;
case 2:
printf("请输入: 0 (关闭) 1 (开启)");
scanf("%d",&op);
while(getchar()!='\n');
if(1 == op)
ioctl(fd,BUZ_ON);
else if(0 == op)
ioctl(fd,BUZ_OFF);
break;
case 3:
printf("请输入: 0 (关闭) 1 (开启)");
scanf("%d",&op);
while(getchar()!='\n');
if(1 == op)
ioctl(fd,MOT_ON);
else if(0 == op)
ioctl(fd,MOT_OFF);
break;
default:
printf("输入有误!");
while(getchar()!='\n');
break;
}
}
close(fd);
return 0;
}
内核代码
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include "head.h"
#include <linux/io.h>
#include <linux/device.h>
int major;
struct class * cls;
struct device * dev;
unsigned int *vir_rcc;
unsigned int *vir_h_rcc;
gpio_t *vir_led1;
gpio_t *vir_led2;
gpio_t *vir_led3;
gpio_t *vir_h_led1;
gpio_t *vir_h_led2;
gpio_t *vir_h_led3;
gpio_t *vir_buz;
gpio_t *vir_mot;
int kbuf[128]={0};
int mydev_open(struct inode *inode, struct file *file)
{
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
return 0;
}
ssize_t mydev_read(struct file *file, char *ubuf, size_t size, loff_t *off)
{
int ret;
if(size > sizeof(kbuf))
{
size=sizeof(kbuf);
}
ret = copy_to_user(ubuf,kbuf,size);
if(ret)
{
printk("copy_to_user failed\n");
}
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
return 0;
}
long mydev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
int op,ret;
switch (cmd)
{
case LED_ON:
ret = copy_from_user(&op,(void*)arg, sizeof(int));
if(ret)
{
printk("copy_from_user failed\n");
return -ENOMEM;
}
switch (op)
{
case 1:
vir_led1->ODR |= (1 << 10);
break;
case 2:
vir_led2->ODR |= (1 << 10);
break;
case 3:
vir_led3->ODR |= (1 << 8);
break;
default:
break;
}
break;
case LED_OFF:
ret = copy_from_user(&op,(void*)arg, sizeof(int));
if(ret)
{
printk("copy_from_user failed\n");
return -ENOMEM;
}
switch (op)
{
case 1:
vir_led1->ODR &= (~(1 << 10));
break;
case 2:
vir_led1->ODR &= (~(1 << 10));
break;
case 3:
vir_led1->ODR &= (~(1 << 8));
break;
default:
break;
}
break;
case LED_H_ON:
ret = copy_from_user(&op,(void*)arg, sizeof(int));
if(ret)
{
printk("copy_from_user failed\n");
return -ENOMEM;
}
switch (op)
{
case 1:
vir_h_led1->ODR |= (1 << 5);
break;
case 2:
vir_h_led2->ODR |= (1 << 6);
break;
case 3:
vir_h_led3->ODR |= (1 << 7);
break;
default:
break;
}
break;
case LED_H_OFF:
ret = copy_from_user(&op,(void*)arg, sizeof(int));
if(ret)
{
printk("copy_from_user failed\n");
return -ENOMEM;
}
switch (op)
{
case 1:
vir_h_led1->ODR &= (~(1 << 5));
break;
case 2:
vir_h_led2->ODR &= (~(1 << 6));
break;
case 3:
vir_h_led3->ODR &= (~(1 << 7));
break;
default:
break;
}
break;
case BUZ_ON:
vir_buz->ODR |= (1 << 6);
break;
case BUZ_OFF:
vir_buz->ODR &= (~(1 << 6));
break;
case MOT_ON:
vir_mot->ODR |= (1 << 6);
break;
case MOT_OFF:
vir_mot->ODR &= (~(1 << 6));
break;
}
return 0;
}
ssize_t mydev_write(struct file *file, const char *ubuf, size_t size, loff_t *off)
{
int ret;
if(size > sizeof(kbuf))
{
size=sizeof(kbuf);
}
ret = copy_from_user(kbuf,ubuf,size);
if(ret)
{
printk("copy_to_user failed\n");
return -EIO;
}
return 0;
}
int mydev_close (struct inode *inode, struct file *file)
{
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
return 0;
}
struct file_operations fops=
{
.open=mydev_open,
.read=mydev_read,
.write=mydev_write,
.release=mydev_close,
.unlocked_ioctl=mydev_ioctl,
};
int all_init(void)
{
vir_rcc = ioremap(PHY_RCC_ADDR, 4);
if(NULL ==vir_rcc)
{
printk("rcc寄存器映射失败\n");
return -ENOMEM;
}
printk("rcc寄存器映射成功\n");
vir_h_rcc = ioremap(PHY_H_RCC_ADDR, 4);
if(NULL ==vir_h_rcc)
{
printk("h_rcc寄存器映射失败\n");
return -ENOMEM;
}
printk("h_rcc寄存器映射成功\n");
vir_led1 = ioremap(PHY_LED1_ADDR, sizeof(gpio_t));
if(NULL ==vir_led1)
{
printk("led1寄存器映射失败\n");
return -ENOMEM;
}
printk("led1寄存器映射成功\n");
vir_led2 = ioremap(PHY_LED2_ADDR, sizeof(gpio_t));
if(NULL ==vir_led2)
{
printk("led2寄存器映射失败\n");
return -ENOMEM;
}
printk("led2寄存器映射成功\n");
vir_led3 = ioremap(PHY_LED3_ADDR, sizeof(gpio_t));
if(NULL ==vir_led3)
{
printk("led3寄存器映射失败\n");
return -ENOMEM;
}
printk("led3寄存器映射成功\n");
vir_h_led1 = ioremap(PHY_H_LED1_ADDR, sizeof(gpio_t));
if(NULL ==vir_led1)
{
printk("h_led1寄存器映射失败\n");
return -ENOMEM;
}
printk("h_led1寄存器映射成功\n");
vir_h_led2 = ioremap(PHY_H_LED2_ADDR, sizeof(gpio_t));
if(NULL ==vir_h_led2)
{
printk("h_led2寄存器映射失败\n");
return -ENOMEM;
}
printk("h_led2寄存器映射成功\n");
vir_h_led3 = ioremap(PHY_H_LED3_ADDR, sizeof(gpio_t));
if(NULL ==vir_h_led3)
{
printk("h_led3寄存器映射失败\n");
return -ENOMEM;
}
printk("h_led3寄存器映射成功\n");
vir_buz = ioremap(PHY_BUZ_ADDR, sizeof(gpio_t));
if(NULL ==vir_buz)
{
printk("buz寄存器映射失败\n");
return -ENOMEM;
}
printk("buz寄存器映射成功\n");
vir_mot = ioremap(PHY_MOT_ADDR, sizeof(gpio_t));
if(NULL ==vir_mot)
{
printk("mot寄存器映射失败\n");
return -ENOMEM;
}
printk("mot寄存器映射成功\n");
(*vir_rcc) |= (3 << 4);
(*vir_rcc) |= (1 << 1);
(*vir_h_rcc) |= (1 << 0);
(vir_led1->MODER) &= (~(3 << 20));
(vir_led1->MODER) |= (1 << 20);
(vir_led1->ODR) &= (~(1<<10));
(vir_led2->MODER) &= (~(3 << 20));
(vir_led2->MODER) |= (1 << 20);
(vir_led2->ODR) &= (~(1<<10));
(vir_led3->MODER) &= (~(3 << 16));
(vir_led3->MODER) |= (1 << 16);
(vir_led3->ODR) &= (~(1<<8));
(vir_h_led1->MODER) &= (~(3 << 10));
(vir_h_led1->MODER) |= (1 << 10);
(vir_h_led1->ODR) &= (~(1<<5));
(vir_h_led2->MODER) &= (~(3 << 12));
(vir_h_led2->MODER) |= (1 << 12);
(vir_h_led2->ODR) &= (~(1<<6));
(vir_h_led3->MODER) &= (~(3 << 14));
(vir_h_led3->MODER) |= (1 << 14);
(vir_h_led3->ODR) &= (~(1<<7));
(vir_buz->MODER) &= (~(3 << 12));
(vir_buz->MODER) |= (1 << 12);
(vir_buz->ODR) &= (~(1<<6));
(vir_mot->MODER) &= (~(3 << 12));
(vir_mot->MODER) |= (1 << 12);
(vir_mot->ODR) &= (~(1<<6));
printk("寄存器初始化成功\n");
return 0;
}
static int __init mycdev_init(void)
{
major=register_chrdev(0,"mychrdev",&fops);
printk("字符设备注册成功major=%d\n",major);
cls = class_create(THIS_MODULE,"mycdev");
if(IS_ERR(cls))
{
printk("提交目录信息失败\n");
return PTR_ERR(cls);
}
printk("提交目录信息成功\n");
dev = device_create(cls,NULL,MKDEV(major,0),NULL,"mycdev");
if(IS_ERR(dev))
{
printk("提交设备节点信息失败\n");
return PTR_ERR(cls);
}
printk("提交设备节点信息成功\n");
all_init();
return 0;
}
static void __exit mycdev_exit(void)
{
iounmap(vir_rcc);
iounmap(vir_led1);
iounmap(vir_led2);
iounmap(vir_led3);
iounmap(vir_h_led1);
iounmap(vir_h_led2);
iounmap(vir_h_led3);
iounmap(vir_buz);
iounmap(vir_mot);
device_destroy(cls,MKDEV(major,0));
class_destroy(cls);
unregister_chrdev(major,"mychrdev");
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");