liunx驱动----点亮LED

自动挂接根文件系统(直接从NFS启动)

  1. 修改uboot命令行

把 bootargs=noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0,115200

改为:

set bootarges noinitrd root=/dev/nfs nfsroot=192.168.0.104:/home/book/work/nfs_root/first_fs ip=192.168.0.10:192.168.0.104:192.168.0.1:255.255.255.0::eth0:off init=/linuxrc console=ttySAC0,115200

在uboot中设置如下:

setenv bootargs noinitrd root=/dev/nfs console=ttySAC0 nfsroot=192.168.0.104:/home/book/work/nfs_root/first_fs ip=192.168.0.3:192.168.0.104:192.168.0.1:255.255.255.0::eth0:off init=/linuxrc

设置NFS启动参数 :

  1. 设置服务器IP,目录
  2. 设置自己的IP

运行第一个驱动程序

insmod first_drv.ko 挂载first_drv.ko

cat /proc/devices 查看当前挂载了的驱动

??

增加一个测试程序

include <sys/types.h>
include <sys/stat.h>
include <fcntl.h>
include <stdio.h>

int main(int argc, char **argv)
{
int fd;
int val = 1;
fd = open("/dev/xxx", O_RDWR);//打开
if (fd < 0)
{
printf("can‘t open!\n");
}
write(fd,&val,4);//写
return 0;
}

编译测试程序

arm-linux-gcc -o first_dev_test first_dev_test.c

??

提示不能打开当前测试文件是因为不存在/dev/xxx这个文件

所以需要创建这个设备节点

创建设备节点使用mknod 命令

mknod /dev/xxx c 111 0

命令 设备节点 设备类型(字符型) 主设备号(111) 次设备号

??

挂载设备 命令:insmod xxx(设备名称)

卸载设备命令:rmmod xxx(设备名称)

查看设备命令:lsmod

cat /proc/devices 查看当前挂载了的驱动

自动分配主设备号

???

在注册 register_chrdev函数中设备号位置填写0 系统将在自动分配设备号

1驱动程序里面可以自动分配主设备号 也可以手动指定设备号

  1. 应用程序去打开一个open("/dev/xxx", O_RDWR); 使用 mknod /dev/xxx c 主设备号 次设备号 手动创建
  2. 使用自动创建 使用udev机制 就是busybox 中的mdev机制自动创建 (根据系统信息创设备节点)

定义一个类和一个设备

static struct class *firstdrv_class;

static struct class_device *firstdrv_class_dev;

在初始化设备时添加

  1. 使用class_create创建一个firstdrv_class类

firstdrv_class = class_create(THIS_MODULE,"firstdrv");//创建一个 first_class 这样的一个类

  1. 使用class_device_create创建一个设备 设备节点是 xyz

firstdrv_class_dev = class_device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xyz"); //mdev 自动创建一个 /dev/xyz */

int frist_drv_init(void)

{

major= register_chrdev(0,"frist_drv",&first_drv_fops);//注册函数(注册驱动程序) (major 主设备号 )告诉内核

//主设备号 驱动名称 file_operations结构

/*生成系统信息*/

firstdrv_class = class_create(THIS_MODULE,"firstdrv");//创建一个 first_class 这样的一个类

firstdrv_class_dev = class_device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xyz"); //mdev 自动创建一个 /dev/xyz */

return 0;

}

在出口函数中添加如下

  1. 使用class_device_unregister 函数来卸载 class_device_create创建的设备

class_device_unregister(firstdrv_class_dev);

  1. 使用class_destroy 释放 掉firstdrv_class这个类

class_destroy(firstdrv_class);

void frist_drv_exit(void)
{
unregister_chrdev(major,"frist_drv");//卸载函数 卸载驱动
class_device_unregister(firstdrv_class_dev);
class_destroy(firstdrv_class);
}

实现点亮LED灯功能

硬件操作

映射虚拟地址 :使用 ioremap(off,sz) 函数 映射

/*将设备的物理地址映射为虚拟地址*/

gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16); //0x56000050 (物理 地址) 16(长度)

gpfdat = gpfcon+1; //0x56000050+4 = 0x56000054 (物理地址) 16(长度)

取消虚拟地址映射:iounmap(_addr);

iounmap(gpfcon);

iounmap(gpfcon+1);

内核和用户之间参数传递 :

copy_from_user的功能是从用户空间传递数据到内核空间

对应的 copy_to_user 从内核空间传递数据到 用户空间

copy_from_user(&val,buf,count);

  1. 配置 GPFCON open
static int first_drv_open(struct inode *inode, struct file *file)

{

//printk("first_drv_open\n");

/*配置GPFCON 4 5 6为输出*/

*gpfcon &=~((0x3<<(4*2))|(0x3<<(5*2))|(0x3<<(6*2)));//清除GPFCON 4 5 6对应位

*gpfcon |= ((0x1<<(4*2))|(0x1<<(5*2))|(0x1<<(6*2)));//设置 GPFCON 4 5 6 为输出

return 0;

}
  1. 设置 GPFDAT write
static ssize_t first_drv_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
{
int val;
//printk("first_drv_write\n");
copy_from_user(&val,buf,count);//将buf中的数据拷贝到 val中 val的值等于 *buf的前0-count的数据 copy_from_user的功能是从用户空间传递数据到内核空间
// 对应的 copy_to_user 从内核空间传递数据到 用户空间
if(val == 0)
{
*gpfdat |= ((1<<4)|(1<<5)|(1<<6));// 熄灭灯
}
else
{
*gpfdat &= ~((1<<4)|(1<<5)|(1<<6));//打开led
}
return 0;
}

使用次设备号:

主设备号 是建立与内核的链接,次设备号 是用来给驱动使用的

原文地址:https://www.cnblogs.com/hjxzjp/p/10428662.html

时间: 2024-08-27 20:45:41

liunx驱动----点亮LED的相关文章

驱动编程思想之初体验 --------------- 嵌入式linux驱动开发之点亮LED

这节我们就开始开始进行实战啦!这里顺便说一下啊,出来做开发的基础很重要啊,基础不好,迟早是要恶补的.个人深刻觉得像这种嵌入式的开发对C语言和微机接口与原理是非常依赖的,必须要有深厚的基础才能hold的住,不然真像一些人说的,学了一年嵌入式感觉还没找到门. 不能再扯了,涉及到linux的驱动开发知识面灰常广,再扯文章就会变得灰常长.首先还是回到led驱动的本身上,自从linux被移植到arm上后,做驱动开发的硬件知识要求有所降低,很多都回归到了软件上,这是系统编程的一大特点,当然 ,也不排除有很多

嵌入式linux驱动开发之点亮led未遂(驱动编程思想之初体验)

有了上两篇文章的基础,我们就可以开始开始进行实战啦!这里顺便说一下啊,出来做开发的基础很重要啊,基础不好,迟早是要恶补的.个人深刻觉得像这种嵌入式的开发对C语言和微机接口与原理是非常依赖的,必须要有深厚的基础才能hold的住,不然真像一些人说的,学了一年嵌入式感觉还没找到门. 另外实践很重要,一年多以前就知道了arm,那时整天用单片机的思维去yy着arm,直到前段时间弄来一块arm板,烧上linux系统后才知道,坑呀!根本不是那回事,所以实践是学习计算机类最重要的基本素质,如果整天看书,那基本上

【Linux驱动】TQ2440 LED驱动程序

★总体介绍 LED驱动程序主要实现了TQ2440开发板上的4个LED灯的硬件驱动,实现了对引脚GPIOB5.GPIOB6.GPIOB7.GPIOB8的高低电平设置(common-smdk.c中已经实现了对引脚的配置),利用测试程序调用该驱动程序,通过命令控制LED灯的亮灭. ★详细介绍 1.驱动程序代码:My_led.c #include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #

ARM学习篇一 点亮LED

要点亮LED,先决条件是什么,当然得有相应的硬件设施.板子的整个电路图比较大,我就直接取相关部分. 给发光二级管加上3.3v电压后,通过1k电阻,直接与S3C2440连接.至于为什么要加电阻,大家应该都知道,发光二极管的正向电阻很小,管子很容易因电流过大而烧坏.至于具体多少,可以看你买的管子的说明. 具体的烧写驱动安装,ARM集成开发环境安装我就不说了.一般都有手册,手册里面说得很清楚. 下面是代码实现: AREA LED,CODE,READONLY ENTRY CODE32GPFCON EQU

mini2440驱动奇谭——LED驱动与测试(动态加载)

我的博客:http://blog.csdn.net/muyang_ren 实现功能:开发板动态加载led驱动模块并能通过测试程序 系统:Ubuntu 14.04 驱动交叉编译内核:linux-2.6.32.2               //建立交叉编译 开发板:mini2440 (128M nandflash)     //关于怎么烧写linux到开发板请点击,Linux RootFs 选择rootfs_rtm_2440.img  (光盘目录:image/linux/rtm ) 开发所需工具:

STM32-新建工程,点亮led

讲之前忽然想起来,keil arm和51一起安装需要做点工作,可以参考这里点击打开链接,我也简单讲一下,如下图 如果装了arm或51的keil就会有arm文件夹或者c51文件夹,在此基础上要再装一个,就直接把相应的那个文件夹复制到这里来,文件夹可以上网找,或者装了再复制出来,这样就有了arm和51两个文件夹,接下只要改一下TOOLS文件就行了,就是把相应加进来的文件夹的配置填到TOOLS里去,注意path要根据个人情况填安装的路径,具体的内容看 链接. 首先新建工程 我用的是正点原子的mini板

TQ2440按键点亮LED驱动程序

一,硬件分析: 1.打开TQ2440的底板原理图找到按键测试的模块,如下图所示: 从图我们知道,控制按键k1 k2 k3 k4 的管脚为EINT1 EINT4 EINT2 EINT0 ,当按键按下时,管脚输出低电平,当按键没有被按下时,管脚输出高电平. 2.打开TQ2440核心板原理图找到EINT1  EINT4 EINT2 EINT0所对应的cpu控制引脚,如下图所示: 从图我们可以知道,EINT1  EINT4 EINT2 EINT0 对应的cpu控制引脚为GPF1 GPF4 GPF2 GP

嵌入式学习笔记002-点亮led

正如编写第一个程序所打印"hello world"那样,对TQ2440开发板的初次使用也是从最简单的部分入手,点亮led灯无疑是最简单的,起码只要设置几个寄存器就好,比起打印容易得多了,后续会讲到串口部分再来实现我们这句金典的对白~~~~ 板子共有4个led灯,如果能够成功点亮其中一个,那么其他几个将不是问题,故而我们的目标是先点亮第一个先,在此我们必须理清几个问题: a. led的引脚连接的相关寄存器 b. 编写的语言 c. 用什么来编译链接成可执行文件 d. 怎么download到

STM32F407第一步之点亮LED

STM32F407第一步之点亮LED. 要点亮LED,首先了解一下F4的GPIO模块.首先看一下STM32F4数据手册,GPIO模块的内部结构图 看上去有点复杂,不要怕,慢慢理解就可以了.对外引脚那里二极管就是保护的作用.通过上.下拉对应的开关配置,控制引脚默认状态的电压,开启上拉的时候引脚电压为高电平,开启下拉的时候引脚电压为低电平,这样可以消除引脚不定状态的影响.但是这个不应该用来作为外部的上拉或下拉用,如按键的拉电阻不能用这个内部来作用,如果用可能会引起按键不稳定. GPIO 具有了“推挽