驱动开发 作业1

这篇具有很好参考价值的文章主要介绍了驱动开发 作业1。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  1. 下面代码中的 gpio.hrcc.h 是 led 项目中的 common/include 目录下的 stm32mp1xx_gpio.hstm32mp1xx_rcc.h 所以不贴代码了,完整的目录查看这个仓库
  2. 这里直接把 GPIOE/GPIOFRCC 结构体的地址映射到虚拟地址中
  3. 用户空间应用程序的代码没有修改,也不贴上来了,输入 1,2,3 分别对应开关 LED1,2,3
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include "gpio.h"
#include "rcc.h"

int major; // 用于保存主设备号
char kbuf[128] = { 0 };
unsigned int *vir_gpioe;
unsigned int *vir_gpiof;
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)
{
	int ret;
	if (sizeof(kbuf) < size)
		size = sizeof(kbuf);
	ret = copy_to_user(ubuf, kbuf, size);
	if (ret) {
		printk("copy_tO_user filed\n");
		return -EIO;
	}
	printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
	return 0;
}

ssize_t mycdev_write(struct file *file, const char *ubuf, size_t size,
		     loff_t *lof)
{
	int ret;
	//判断用户空间的需求是否能被驱动满足,满足不了就给能给的最好的
	if (sizeof(kbuf) < size)
		size = sizeof(kbuf);
	ret = copy_from_user(kbuf, ubuf, size);
	if (ret) {
		printk("copy_from_user filed\n");
		return -EIO;
	}
	if (kbuf[0] == '1') { // 开关 LED1 PE10
		((gpio_t *)vir_gpioe)->ODR ^= (0x1 << 10);
	} else if (kbuf[0] == '2') { // 开关 LED2 PF10
		((gpio_t *)vir_gpiof)->ODR ^= (0x1 << 10);
	} else if (kbuf[0] == '3') { // 开关 LED3 PE8
		((gpio_t *)vir_gpioe)->ODR ^= (0x1 << 8);
	}
	printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
	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, "mychrdev", &fops);
	if (major < 0) {
		printk("字符设备驱动注册失败\n");
		return major;
	}
	printk("字符设备驱动注册成功major=%d\n", major);
	//映射物理寄存器
	vir_gpioe = ioremap((volatile unsigned int)GPIOE, sizeof(gpio_t));
	if (vir_gpioe == NULL) {
		printk("GPIOE结构体映射表失败\n");
		return -EFAULT;
	}
	vir_gpiof = ioremap((volatile unsigned int)GPIOF, sizeof(gpio_t));
	if (vir_gpioe == NULL) {
		printk("GPIOF结构体映射表失败\n");
		return -EFAULT;
	}
	vir_rcc = ioremap((volatile unsigned int)RCC, sizeof(rcc_t));
	if (vir_rcc == NULL) {
		printk("RCC结构体映射表失败\n");
		return -EFAULT;
	}
	printk("寄存器地址映射成功\n");
	//寄存器初始化
	((rcc_t *)vir_rcc)->MP_AHB4ENSETR |= (1 << 4) | (1 << 5);
	// LED1 初始化
	((gpio_t *)vir_gpioe)->MODER &= (~(0x3 << 20));
	((gpio_t *)vir_gpioe)->MODER |= (0x1 << 20);
	((gpio_t *)vir_gpioe)->ODR &= (~(0x1 << 10));
	// LED2 初始化
	((gpio_t *)vir_gpiof)->MODER &= (~(0x3 << 20));
	((gpio_t *)vir_gpiof)->MODER |= (0x1 << 20);
	((gpio_t *)vir_gpiof)->ODR &= (~(0x1 << 10));
	// LED3 初始化
	((gpio_t *)vir_gpioe)->MODER &= (~(0x3 << 16));
	((gpio_t *)vir_gpioe)->MODER |= (0x1 << 16);
	((gpio_t *)vir_gpioe)->ODR &= (~(0x1 << 8));

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

static void __exit mycdev_exit(void)
{
	//取消寄存器地址映射
	iounmap(vir_gpioe);
	iounmap(vir_gpiof);
	iounmap(vir_rcc);
	//字符设备驱动的注销
	unregister_chrdev(major, "mychrdev");
}

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

文章来源地址https://www.toymoban.com/news/detail-541041.html

到了这里,关于驱动开发 作业1的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【驱动开发day4作业】

    头文件代码  应用层代码  驱动代码

    2024年02月15日
    浏览(28)
  • 【驱动开发day2作业】

    head.h mychrdev.c led.c

    2024年02月15日
    浏览(29)
  • 【驱动开发day3作业】

    head.h  应用层代码 灯驱动代码 蜂鸣器驱动代码 风扇驱动代码 马达驱动代码  测试结果:    

    2024年02月15日
    浏览(32)
  • 【驱动开发day8作业】

     作业1: 应用层代码 驱动代码 作业2 驱动代码

    2024年02月14日
    浏览(28)
  • 驱动开发作业3——GPIO子系统

    作业1:在内核模块中启用定时器,定时1s,让LED1以1s为周期实现流水灯  myled.c(驱动文件)    作业2:基于GPIO子系统完成LED灯驱动的注册,并利用应用程序测试  chrdevled.c(驱动文件) test.c(测试文件)

    2024年02月16日
    浏览(25)
  • 华清远见嵌入式学习——驱动开发——作业1

    通过字符设备驱动分步注册过程实现LED驱动的编写,编写应用程序测试,发布到CSDN

    2024年02月20日
    浏览(44)
  • 2023年7月4日 星期二 linux驱动作业

    2024年02月12日
    浏览(25)
  • 2023年7月13日 星期四 Linux驱动作业

    a.应用程序通过阻塞的io模型来读取number变量的值 b.number是内核驱动中的一个变量 c.number的值随着按键按下而改变(按键中断) 例如number=0 按下按键number=1再次按下按键number=0d.在按下按键的时候需要同时将1ed1的状态取反 t e.驱动中需要编写字符设备驱动f.驱动中需要自动创建设备

    2024年02月16日
    浏览(29)
  • 【李老师云计算】作业二,大数据开发开发面试书籍

    public class MaxValueReducer extends ReducerIntWritable, IntWritable, IntWritable, IntWritable { private IntWritable result = new IntWritable(); @Override public void reduce(IntWritable key, Iterable values, Context context) throws IOException, InterruptedException { int max = Integer.MIN_VALUE; for (IntWritable value : values) { max = Math.max(max, value.ge

    2024年04月14日
    浏览(27)
  • Java Web应用开发 ——作业七

    一.单项选择题(共7题,28.7分) 1 Servlet程序的入口点是( )。 A、 init() B、 main() C、 service() D、 doGet() 正确答案: A 2 JSP和Servlet的关系是() A、 没有关系,因为前者是页面,后者是java类 B、 继承关系 C、 Servlet就是JSP D、 JSP会被翻译成Servlet 正确答案: D 3 编写Servl

    2024年02月01日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包