注意参考内核例程。
字符设备驱动程序框架。
1.确定主设备号;
2.定义自己的file_operations结构体;
3.实现对应的open、read、write等函数,填入file_operations结构体;
4.把file_operations告诉(注册)内核;register_chrdev;
5.入口函数,用来注册驱动程序,安装驱动程序时,会调用这个函数;
6.有入口函数就有出口函数;卸载驱动时,出口函数调用unregister_chrdev;
7.其他完善,提供设备信息,自动创建设备节点:class_create,device_create;

一、驱动

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/mutex.h>
#include <linux/wait.h>
#include <linux/uaccess.h>
#include <asm/io.h>
#include <linux/device.h>static int major;
static struct class *led_class;/* 寄存器 */
//RCC PLL4 Control Register (RCC_PLL4CR) 0x50000000+0x894  //使能PLL4时钟
static volatile unsigned int *RCC_PLL4CR;   //RCC_MP_AHB4ENSETR地址:0x50000000 + 0xA28                    //使能GPIO
static volatile unsigned int *RCC_MP_AHB4ENSETR;//GPIOA_MODER地址:0x50002000 + 0x00,设置bit[21:20]=0b01,        //PA10输出
static volatile unsigned int *GPIOA_MODER;//GPIOA_ODR地址: 0x50002000 + 0x14                          //读寄存、修改值、写回去(低效)
static volatile unsigned int *GPIOA_ODR;//GPIOA_BSRR地址: 0x50002000 + 0x18                           // 直接写寄存器,一次操作即可,高效
static volatile unsigned int *GPIOA_BSRR;static ssize_t led_write(struct file *filp, const char __user *buf,size_t count, loff_t *ppos)
{printk("%s %s %d\n",__FILE__, __FUNCTION__,__LINE__);char val;/* copy_from_user: 从应用程序中获取数据*/copy_from_user(&val, buf, 1);/* 设置数据,设置gpio输出,0/1 */if(val){  //灯亮*GPIOA_BSRR = (1<<26);   //输出低电平 GPIOA10}else{//灯灭*GPIOA_BSRR = (1<<10); //输出高电平}return 1;
}static int led_open(struct inode *inode, struct file *filp)
{/* 配置gpio,使能、配置为gpio,配置输入输出 *///配置时钟*RCC_PLL4CR |= (1<<0);while((*RCC_PLL4CR & (1<<1)) == 0);//使能GPIOA*RCC_MP_AHB4ENSETR |= (1<<0);//设置PA10用作输出,先清零,在设置为输出*GPIOA_MODER &= ~(3<<20);*GPIOA_MODER |= (0x01<<20);return 0;
}static const struct file_operations led_fops = {.owner        = THIS_MODULE,//.read      = led_read,.write      = led_write,.open      = led_open,//.release  = led_close,//.poll        = led_poll,//.llseek       = no_llseek,
};/* 入口函数 */
static int __init led_init(void)
{major = register_chrdev(0, "tanzhenwen_led", &led_fops);    //在/proc/devices会显示if (major < 0) {printk("could not get major number\n");class_destroy(led_class);return major;}led_class = class_create(THIS_MODULE, "led_calss");//if (IS_ERR(led_class))//  return PTR_ERR(led_class);device_create(led_class, NULL, MKDEV(major, 0), NULL, "led_drv");   // /dev/led_drv/* ioremap :使用虚拟地址,后期可以用虚拟地址来访问寄存器 *///ioremap(mem_addr, mem_len);//RCC PLL4 Control Register (RCC_PLL4CR) 0x50000000+0x894  //使能PLL4时钟RCC_PLL4CR = ioremap(0x50000000+0x894, 4);  //RCC_MP_AHB4ENSETR地址:0x50000000 + 0xA28                    //使能GPIORCC_MP_AHB4ENSETR = ioremap(0x50000000 + 0xA28, 4);//GPIOA_MODER地址:0x50002000 + 0x00,设置bit[21:20]=0b01,       //PA10输出GPIOA_MODER = ioremap(0x50002000 + 0x00, 4);//GPIOA_ODR地址: 0x50002000 + 0x14                          //读寄存、修改值、写回去(低效)GPIOA_ODR = ioremap(0x50002000 + 0x14, 4);;//GPIOA_BSRR地址: 0x50002000 + 0x18                         // 直接写寄存器,一次操作即可,高效GPIOA_BSRR = ioremap(0x50002000 + 0x18, 4);return 0;
}static void __exit led_exit(void)
{iounmap(RCC_PLL4CR);iounmap(RCC_MP_AHB4ENSETR);iounmap(GPIOA_MODER);iounmap(GPIOA_ODR);iounmap(GPIOA_BSRR);unregister_chrdev(major, "tanzhenwen_led");device_destroy(led_class,  MKDEV(major, 0));class_destroy(led_class);
}module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");

二、测试程序

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>//ledtest /dev/led_drv on
//ledtest /dev/led_drv off
int main(int argc, char *argv[])
{int fd;char status = 0;if(argc != 3 ){printf("Usage: %s <dev> <on|off>\n",argv[0]);printf("   eg: %s /dev/led_drv on\n");printf("   eg: %s /dev/led_drv off\n");}//openfd = open(argv[1],O_RDWR);if(fd < 0){printf("can not open %s\n",argv[1]);return -1;}//writeif(strcmp(argv[2],"on") == 0){status = 1;}else{status = 0;}write(fd,&status,1);return 0;
}

三、测试

让心跳灯不闪烁

echo none > /sys/class/leds/heartbeat/trigger

cat /proc/devices可以看见tanzhenwen_led字符设备节点

执行ls /dev/led_drv -al,可以看见具有led_drv的设备。

执行./led_test /dev/led_drv off以及./led_test /dev/led_drv on可以观察到LED灯的亮灭。

基于STM32MP1的简单LED驱动程序相关推荐

  1. jz2440_基于平台设备的LED驱动程序

    平台设备驱动程序是基于总线系统实现的,由三个部分组成: 总线,这里的总线使用的是内核自带的 platform_bus_type 总线,无需我们进行实现: 设备,这个驱动主要是对 LED 灯的操作,因此 ...

  2. 基于HDF的LED驱动程序开发(2)

    引言 本文以小熊派BearPi-HM_Micro_small开发板上的一个LED灯为例,介绍如何基于HDF框架开发一个外设的驱动程序. 在阅读本文之前,建议大家先阅读:<OpenHarmony驱 ...

  3. 基于HDF的LED驱动程序开发(1)

    引言 本文以小熊派BearPi-HM_Micro_small开发板上的一个LED灯为例,介绍如何基于HDF框架开发一个外设的驱动程序. 在阅读本文之前,建议大家先阅读:<OpenHarmony驱 ...

  4. Microwindows及基于Nano-X的简单程序开发

    http://www.rdxx.com 05年09月13日 22:26 Blog.ChinaUnix.net Nano-X是一种图形编程接口,和Win32一样,在上面我们可以编写自己的应用程序,下面转 ...

  5. 【Linux笔记】LED驱动程序

    前言 上一篇我们分享了字符设备驱动框架:[Linux笔记]驱动基础篇,当时分享的是hello驱动程序. 学STM32我们从点灯开始,学Linux驱动我们自然也要点个灯来玩玩,尽量在从这些基础例程中榨取 ...

  6. 基于74LS148的简单四路抢答器 Multisim

    基于74LS148的简单四路有优先报警器 Multisim 上数电课的作业:假如有四个病房,四个病人的病情情况不同,分别对应优先级:最高.高.中.低.优先级低的会被优先级高得中断,此处用LED灯的亮灭 ...

  7. Yocto创建自己的分区(基于STM32MP1)

    Yocto创建自己的分区(基于STM32MP1) 前几章节我们分析了machine class里面几篇关键的class,还有machine conf里面的inc文件,大致的创建分区的流程都比较清晰了, ...

  8. ARM开发(9)基于STM32的简单四则运算计算器

    基于STM32的简单四则运算计算器 一 计算器原理: 1.1 本实验实现基于STM32的简单四则运算计算器 1.2 实验思路:理解计算器原理(按键扫描,字符实时显示,运算表达式计算,浮点数转字符串,字 ...

  9. 基于sys文件系统的LED驱动的移植【原创】

    基于RK3188平台LED驱动程序的移植的移植.如有不正确之处,欢迎大家指点. 本文的LED驱动程序不是通过打开设备节点来访问和控制LED的,是通过sys文件系统来控制LED. 板子上有四盏灯以及对应 ...

最新文章

  1. 嵌入式程序员应知道的基本问题-C语言(zz)
  2. Java控制台如何输入一行、多行?
  3. Scala集合:List修改及删除数据
  4. java jni helloword_JNI学习一:编写HelloWorld程序
  5. Asp: 解决脚本输出网页出现乱码情况
  6. c# asp.net 2.0 tableadapter 动态 dynamic sql语句
  7. js三大系列之二scroll
  8. input美化上传按钮美化
  9. VS遍历windows文件夹的代码
  10. jq 如何获取和当然元素相同类名的标签_JS/JQ基于localStorage的本地数据储存指南...
  11. 虚幻airsim1:下载安装
  12. 基于RFM模型的Kmeans聚类算法实现
  13. rabbitmq版本升级
  14. 实例理解月末结账任务中,重估未结外币余额的原理
  15. Android程序的目录结构分析——manifests目录、Java目录、res目录
  16. 局域网-无法访问网上邻居解决方法
  17. 《考博英语词汇重难点20天冲刺》
  18. ant-design在 vue 抽屉(drawer)里面嵌套弹出框(modal)出现蒙层遮挡弹框问题
  19. SSL1232雷达覆盖(normal)
  20. rtx android,RTX 腾讯通 | im.qq.com

热门文章

  1. 四个高逼格技术简历制作技巧啦~
  2. 猎杀对决计算机丢失进不去,猎杀对决错误代码解决方法汇总 进不去游戏解决方法...
  3. 广告-信息流跨域ctr预估
  4. 东莞农商行再度申请港股上市:财务数据打架,多项业务违规曾被罚
  5. 【java】生成【PDF】后端接口-- java生成PDF的第二步
  6. Python中的递归【建议收藏】
  7. 50天50个前端小项目(纯html+css+js)第八天(形成波浪动画结合登录表单)
  8. 黑鲨游戏手机Helio在各大平台开启促销
  9. 手机c语言编辑emoji,Emojicode | 基于表情编程?
  10. 税控盘查看服务器设置的网站,税控盘系统参数设置服务器设置