基于tiny6410开发板的LED驱动 编写与使用(第一个linux驱动)

2024-06-10 22:38

本文主要是介绍基于tiny6410开发板的LED驱动 编写与使用(第一个linux驱动),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

定义本次驱动为misc device(杂项设备驱动),包含头文件miscdevice.h,其实所谓的杂项驱动程序就是主设备号为10的字符设备驱动,其实就是用主设备号10调用了函数register_chrdev()。且misc device会自动在/dev目录下建立设备节点,而不需用mkmod手动建立。

编写tiny6410 LED驱动的内核模块

tiny6410_leds.c

#include <linux/miscdevice.h>  

#include <linux/fs.h>  
#include <linux/pci.h>  
#include <mach/map.h>  
#include <mach/regs-gpio.h>  
#include <mach/gpio-bank-k.h>  
#define DEVICE_NAME "tiny6410_leds"  
MODULE_LICENSE("GPL");  
MODULE_AUTHOR("ziye334");  
static long tiny6410_leds_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)  
{  switch(cmd) {  unsigned tmp;  case 1:  case 2:  case 3:  case 4:  tmp = readl(S3C64XX_GPKDAT);  tmp = (tmp & ~(1<<(cmd - 1 + 4)))|(arg<<(cmd -1 + 4));  writel(tmp, S3C64XX_GPKDAT);  return 0;      default:  return -EINVAL;  }  
}  
static struct file_operations dev_fops = {  .owner          = THIS_MODULE,  .unlocked_ioctl = tiny6410_leds_ioctl,  
};  
//misc device:杂项设备,即主设备号为10的特殊字符设备  
static struct miscdevice misc = {  //次设备号,注意不要与/proc/misc中已有杂项设备次设备号冲突  //MISC_DYNAMIC_MINOR来动态获取次设备号  .minor = MISC_DYNAMIC_MINOR,  //设备名称  .name = DEVICE_NAME,  .fops = &dev_fops,  
};  
static int __init dev_init(void)  
{  int ret;  {  unsigned tmp;  tmp = readl(S3C64XX_GPKCON);  //GPKCON配置GPK4到GPK7配置为0001输出  tmp = (tmp & ~(0xffffU<<16))|(0x1111U<<16);  writel(tmp, S3C64XX_GPKCON);  //GPKDAT[7:4] = 1  //灯灭  tmp = readl(S3C64XX_GPKDAT);  tmp |= (0xF << 4);  writel(tmp, S3C64XX_GPKDAT);  //禁止上拉下拉  tmp = readl(S3C64XX_GPKPUD);  tmp &= (0x00 << 8);  writel(tmp, S3C64XX_GPKPUD);  }  //该函数会自动创建设备节点,即设备文件  ret = misc_register(&misc);  printk (DEVICE_NAME"/tinitialized/n");  return ret;  
}  
static void __exit dev_exit(void)  
{  misc_deregister(&misc);  
}  
module_init(dev_init);  

module_exit(dev_exit);  

编写Makefile文件

 Makefile

ifneq ($(KERNELRELEASE))

 obj-m := tiny6410_leds.o  

else

KERNELDIR := /home/ziye334/tiny6410/linux-2.6.38 

#KERNELDIR的路径根据自己的情况编写

PWD:=$(shell pwd) all: make -C $(KERNELDIR) M=$(PWD) modules clean: rm -rf *.ko *.o *.mod.c *.mod.o *.symvers

endif

编写led的应用程序

tiny6410_leds_test.c

#include <stdio.h>  
#include <stdlib.h>  
#include <sys/ioctl.h>  
int main(int argc, char **argv)  
{  int num = 0;  int led_state = 1;  int fd = 0;  //参数赋值  if(argc != 3 || sscanf(argv[1],"%d", &num) != 1 || sscanf(argv[2], "%d", &led_state) != 1 || num > 4 || led_state > 1)  {  fprintf(stderr, "error/n");  exit(1);  }  printf("num = %d, led_state = %d/n", num, led_state);  fd = open("/dev/tiny6410_leds", 0);  if (fd < 0) {  perror("open device leds");  exit(1);  }  ioctl(fd, num, led_state);  printf("led%d/n", num);  close(fd);  return 0;  
}  

我在/home/ziye334/目录下创建module目录,将tiny6410_leds.c ,Makefile 和tiny6410_leds_test.c放到module目录下,首先要编译下岗编写好的led驱动的内核代码:

    输入命令行:#make 就会在当前目录下生成一个tiny6410_leds.ko文件,

接下来我们来编译写LED的应用代码,因为是要在开发板上运行的,用arm-linux-gcc编译,

    #arm-linux-gcc tiny6410_leds_test.c -o tiny6410_leds_test  生成tiny6410_led_test文件

将tiny6410_leds.ko和tiny6410_leds_test 两个文件拷贝到NFS共享目录下,当让NFS要事先搭建好,我的NFS服务器的共享目录在/home/share/下,所以我将上面两个文件拷贝到/home/share/下:

    #cp tiny6410_leds.ko /home/share/  

    #cp tiny6410_leds_test /home/share/

在开发板的终端中,访问/mnt/(这是我NFS共享目录挂载的目录),#ls /mnt/ 就可以看到tiny6410_leds.ko和timy6410_leds_test两个文件,接下去当然是安装内核模块tiny6410_leds.ko:

    #insmod tiny6410_leds.ko 

    如果安装成功,#cd /dev/ 目录下会发现多了一个tiny6410_leds文件

接着运行之前编译好的应用程序tiny6410_leds_test:

    #cd /mnt/

    #./tiny6410_leds_test 1 0     点亮第一盏led灯

    #./tiny6410_leds_test 2 0     点亮第二盏led灯

    #./tiny6410_leds_test 3 0     点亮第三盏led灯

    #./tiny6410_leds_test 4 0     点亮第四盏led灯

    #./tiny6410_leds_test 1 1     熄灭第一盏led灯

    #./tiny6410_leds_test 2 1     熄灭第一盏led灯    

    #./tiny6410_leds_test 3 1     熄灭第一盏led灯

    #./tiny6410_leds_test 4 1     熄灭第一盏led灯


观察开发板tiny6410核心板上的四盏LED灯会按指令亮灭

  
  
  

这篇关于基于tiny6410开发板的LED驱动 编写与使用(第一个linux驱动)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1049466

相关文章

VScode连接远程Linux服务器环境配置图文教程

《VScode连接远程Linux服务器环境配置图文教程》:本文主要介绍如何安装和配置VSCode,包括安装步骤、环境配置(如汉化包、远程SSH连接)、语言包安装(如C/C++插件)等,文中给出了详... 目录一、安装vscode二、环境配置1.中文汉化包2.安装remote-ssh,用于远程连接2.1安装2

Java中使用Java Mail实现邮件服务功能示例

《Java中使用JavaMail实现邮件服务功能示例》:本文主要介绍Java中使用JavaMail实现邮件服务功能的相关资料,文章还提供了一个发送邮件的示例代码,包括创建参数类、邮件类和执行结... 目录前言一、历史背景二编程、pom依赖三、API说明(一)Session (会话)(二)Message编程客

C++中使用vector存储并遍历数据的基本步骤

《C++中使用vector存储并遍历数据的基本步骤》C++标准模板库(STL)提供了多种容器类型,包括顺序容器、关联容器、无序关联容器和容器适配器,每种容器都有其特定的用途和特性,:本文主要介绍C... 目录(1)容器及简要描述‌php顺序容器‌‌关联容器‌‌无序关联容器‌(基于哈希表):‌容器适配器‌:(

使用Python实现高效的端口扫描器

《使用Python实现高效的端口扫描器》在网络安全领域,端口扫描是一项基本而重要的技能,通过端口扫描,可以发现目标主机上开放的服务和端口,这对于安全评估、渗透测试等有着不可忽视的作用,本文将介绍如何使... 目录1. 端口扫描的基本原理2. 使用python实现端口扫描2.1 安装必要的库2.2 编写端口扫

使用Python实现操作mongodb详解

《使用Python实现操作mongodb详解》这篇文章主要为大家详细介绍了使用Python实现操作mongodb的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、示例二、常用指令三、遇到的问题一、示例from pymongo import MongoClientf

SQL Server使用SELECT INTO实现表备份的代码示例

《SQLServer使用SELECTINTO实现表备份的代码示例》在数据库管理过程中,有时我们需要对表进行备份,以防数据丢失或修改错误,在SQLServer中,可以使用SELECTINT... 在数据库管理过程中,有时我们需要对表进行备份,以防数据丢失或修改错误。在 SQL Server 中,可以使用 SE

使用Python合并 Excel单元格指定行列或单元格范围

《使用Python合并Excel单元格指定行列或单元格范围》合并Excel单元格是Excel数据处理和表格设计中的一项常用操作,本文将介绍如何通过Python合并Excel中的指定行列或单... 目录python Excel库安装Python合并Excel 中的指定行Python合并Excel 中的指定列P

浅析Rust多线程中如何安全的使用变量

《浅析Rust多线程中如何安全的使用变量》这篇文章主要为大家详细介绍了Rust如何在线程的闭包中安全的使用变量,包括共享变量和修改变量,文中的示例代码讲解详细,有需要的小伙伴可以参考下... 目录1. 向线程传递变量2. 多线程共享变量引用3. 多线程中修改变量4. 总结在Rust语言中,一个既引人入胜又可

golang1.23版本之前 Timer Reset方法无法正确使用

《golang1.23版本之前TimerReset方法无法正确使用》在Go1.23之前,使用`time.Reset`函数时需要先调用`Stop`并明确从timer的channel中抽取出东西,以避... 目录golang1.23 之前 Reset ​到底有什么问题golang1.23 之前到底应该如何正确的

详解Vue如何使用xlsx库导出Excel文件

《详解Vue如何使用xlsx库导出Excel文件》第三方库xlsx提供了强大的功能来处理Excel文件,它可以简化导出Excel文件这个过程,本文将为大家详细介绍一下它的具体使用,需要的小伙伴可以了解... 目录1. 安装依赖2. 创建vue组件3. 解释代码在Vue.js项目中导出Excel文件,使用第三