9.8 作业

实现三盏灯的控制

mycdev.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/io.h>
#include "head.h"

int major;
char *devname = "mycdev";
char buf[128]={0};
unsigned int *rcc;//存放rcc的地址
unsigned int *pe_moder;//pe_moder的地址
unsigned int *pe_odr;
unsigned int *pf_moder;//pf的地址
unsigned int *pf_odr;

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__);
    long ref = copy_to_user(ubuf,buf,size);
    if(ref)
    {
        printk("copy_to_user err\n");
        return -EIO;
    }
    return 0;
}
ssize_t mycdev_write(struct file *file,const char *ubuf,size_t size,loff_t *lof)
{
    printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
    copy_from_user(buf,ubuf,size);
    if(buf[0]==1)
    {
        *pe_odr ^= 1 << 10;//led1
    }
    else if(buf[0]==2)
    {
        *pf_odr ^= 1 << 10;//led2
    }
    else if(buf[0]==3)
    {
        *pe_odr ^= 1 << 8;//led3
    }
    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,
    .read=mycdev_read,
    .write=mycdev_write,
    .release=mycdev_close,
};

static int __init mycdev_init(void)
{
    //注册
    major = register_chrdev(0,devname,&fops);
    if(major < 0)
    {
        printk("error\n");
        return major;
    }
    printk("success major=%d\n",major);

    //物理内存映射
    rcc = ioremap(RCC,4);
    if(!rcc)
    {
        printk("物理内存映射失败%d\n",__LINE__);
        return -EFAULT;
    }
    pe_odr = ioremap(PE_ODR,4);
    if(!pe_odr)
    {
        printk("物理内存映射失败%d\n",__LINE__);
        return -EFAULT;
    }
    pe_moder = ioremap(PE_MODER,4);
    if(!pe_moder)
    {
        printk("物理内存映射失败%d\n",__LINE__);
        return -EFAULT;
    }
    pf_odr = ioremap(PF_ODR,4);
    if(!pf_odr)
    {
        printk("物理内存映射失败%d\n",__LINE__);
        return -EFAULT;
    }
    pf_moder = ioremap(PF_MODER,4);
    if(!pf_moder)
    {
        printk("物理内存映射失败%d\n",__LINE__);
        return -EFAULT;
    }

    //使能
    *rcc |= 3 << 4;
    *pe_moder &= ~(3 << 20);
    *pe_moder |= 1 << 20;
    *pe_moder &= ~(3 << 16);
    *pe_moder |= 1 << 16;
    *pf_moder &= ~(3 << 20);
    *pf_moder |= 1 << 20;
    return 0;
}

static void __exit mycdev_exit(void)
{
    //取消物理内存映射
    iounmap(rcc);
    iounmap(pe_moder);
    iounmap(pe_odr);
    iounmap(pf_moder);
    iounmap(pf_odr);
    //取消注册
    unregister_chrdev(0,devname);
}

module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

head.h

#ifndef __HEAD_H__
#define __HEAD_H__

#define RCC 0x50000a28
#define PE_MODER 0x50006000
#define PE_ODR 0x50006014
#define PF_MODER 0x50007000
#define PF_ODR 0x50007014

#endif

test.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>

int main()
{
    char buf[128] = {0};
    int fd = open("/dev/mycdev",O_RDWR);
    if(fd<0)
    {
        printf("文件打开失败\n");
        return -1;
    }
    while(1)
    {
        buf[0]=1;
        write(fd,buf,sizeof(buf));
        sleep(1);
        buf[0]=1;
        write(fd,buf,sizeof(buf));
        sleep(1);
        buf[0]=2;
        write(fd,buf,sizeof(buf));
        sleep(1);
        buf[0]=2;
        write(fd,buf,sizeof(buf));
        sleep(1);
        buf[0]=3;
        write(fd,buf,sizeof(buf));
        sleep(1);
        buf[0]=3;
        write(fd,buf,sizeof(buf));
        sleep(1);
    }
    close(fd);

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值