当前位置: 首页 > article >正文

ARM驱动学习之5 LEDS驱动

                              ARM驱动学习之5 LEDS驱动

知识点:
• linuxGPIO申请函数和赋值函数
– gpio_request
– gpio_set_value
• 三星平台配置GPIO函数
– s3c_gpio_cfgpin
• GPIO配置输出模式的宏变量
– S3C_GPIO_OUTPUT

注意点:
DRIVER_NAME 和 DEVICE_NAME 匹配。

实现步骤:
1.加入需要的头文件:
//Linux平台的gpio头文件
#include <linux/gpio.h>
//三星平台的GPIO配置函数头文件
//包括三星所有处理器的配置函数
– arch/arm/plat-samsung/include/plat/gpio-cfg.h
#include <plat/gpio-cfg.h>
//三星平台EXYNOS系列平台,GPIO配置参数宏定义头文件
// GPIO管脚拉高拉低配置参数等等
//配置参数的宏定义应该在arch/arm/plat-samsung/include/plat/gpio-cfg.h文件中
– arch/arm/mach-exynos/include/mach/gpio.h
#include <mach/gpio.h>
//三星平台4412平台,GPIO宏定义头文件。已经包含在头文件gpio.h中
//包括4412处理器所有的GPIO的宏定义
– arch/arm/mach-exynos/include/mach/gpio-exynos4.h
#include <mach/gpio-exynos4.h>

2.驱动注册的时候就需要加载GPIO资源
在hello_probe函数添加如下: 
int ret = gpio_request(EXYNOS4_GPL2(0),"LEDS");
//GPIO映射管教,字符串位增加程序可读性任意即可。
if(ret < 0){
    printk(KERN_EMERG "Failed\n");
}

s3c_gpio_cfgpin(EXYNOS4_GPL2(0),S3C_GPIO_OUTPUT);//GPIO 模式配置

gpio_set_value(EXYNOS4_GPL2(0),0);//对应GPIO口拉低

在 hello_ioctl函数添加如下:
if(cmd > 1){
    printk(KERN_EMERG "cmd is 0 or 1\n");
}
if(arg > 1){
    printk(KERN_EMERG "arg is only 1\n");
}

gpio_set_value(EXYNOS4_GPL2(0),cmd);//根据cmd命令来设置对应值;

3.在应用部分:
将invoke_hello.c改写为invoke_leds.c
char *hello_node = "/dev/hello_ctl";

ioctl(fd,1,1);//根据驱动的参数传值控制LED。
sleep(3);
ioctl(fd,0,1);//根据驱动的参数传值控制LED。
sleep(3);

4.Makefile部分:
#引用文件部分改成leds.
obg-m += leds.o

5. 
编译invoke_leds.c
arm-none-linux-gnueabi-gcc -o invoke_leds invoke_leds.c
将invoke_leds,devicenode_device_led.ko拷贝到开发板
insmod devicenode_device_led.ko
看是否有hello_ctl设备节点
chmod 777 invoke_leds
./invoke_leds


源码:应用

/*************************************************************************
> File Name: Invoke.c
> Author: 
> Mail: 
> Created Time: Fri 27 Sep 2019 10:51:55 PM CST
************************************************************************/

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

int main(void)
{
    char *fp = "/dev/hello_ctl";
    int fd; 
    //注意这里的括号不要加错了。
    if((fd = open(fp,O_RDWR|O_NDELAY)) < 0){
		printf("\t File open %s  failed \n",fp);
    }
		ioctl(fd,1,1);
		sleep(3);
		ioctl(fd,0,1);
		sleep(3);
		ioctl(fd,1,1);
        sleep(3);
        ioctl(fd,0,1);
        sleep(3);
	close(fd);
    return 0;
}

驱动:

#include <linux/init.h>
#include <linux/module.h>

/*驱动注册的头文件,包含驱动的结构体和注册和卸载的函数*/
#include <linux/platform_device.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>


#include <linux/gpio.h>
#include <plat/gpio-cfg.h>
#include <mach/gpio.h>
#include <mach/gpio-exynos4.h>

#define DRIVER_NAME "hello_ctl"
#define DEVICE_NAME "hello_ctl"

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("TOPEET");

static long hello_ioctl(struct file *file,unsigned int cmd,unsigned long arg){
	printk("cmd is %d,arg is %ld\n",cmd,arg);
	if(cmd > 1){
		printk(KERN_EMERG "cmd is 0 or 1\n");
	}
	if(arg > 1){
		printk(KERN_EMERG "arg is only 1\n");
	}
	gpio_set_value(EXYNOS4_GPL2(0),cmd);//根据cmd命令来设置对应值;
	return 0;
}

static int hello_open(struct inode *inode, struct file *file){
	printk(KERN_EMERG "hello_open");
	
	return 0;
}

static int hello_release(struct inode *inode, struct file *file){
	printk(KERN_EMERG "hello_release");
	return 0;
}

struct file_operations hello_ops = {
	.owner = THIS_MODULE,
	.open = hello_open,
	.release = hello_release,
	.unlocked_ioctl = hello_ioctl,
	
	
};



static struct miscdevice hello_dev = {
	.minor = MISC_DYNAMIC_MINOR,
	.name = DEVICE_NAME,
	.fops = &hello_ops,
};


static int hello_probe(struct platform_device *pdv){	
	printk(KERN_EMERG "\t Go into hello_probe \n");
	int ret = gpio_request(EXYNOS4_GPL2(0),"LEDS");//GPIO映射管教,字符串位增加程序可读性任意即可。
	if(ret < 0){
		printk(KERN_EMERG "Failed \n");
	}
	s3c_gpio_cfgpin(EXYNOS4_GPL2(0),S3C_GPIO_OUTPUT);//GPIO 模式配置
	gpio_set_value(EXYNOS4_GPL2(0),0);//对应GPIO口拉低	
	misc_register(&hello_dev);
	
	return 0;
}

static int hello_remove(struct platform_device *pdv){
	printk(KERN_EMERG "\t remove \n");

	misc_deregister(&hello_dev);
	return 0;
}

static void hello_shutdown(struct platform_device *pdv){
	
	
}

static int hello_suspend(struct platform_device *pdv,pm_message_t pmt){
	
	return 0;
}

static int hello_resume(struct platform_device *pdv){
	
	return 0;
}


struct platform_driver hello_driver = {
	.probe = hello_probe,
	.remove = hello_remove,
	.shutdown = hello_shutdown,
	.suspend = hello_suspend,
	.resume = hello_resume,
	.driver = {
		.name = DRIVER_NAME,
		.owner = THIS_MODULE,
	}
};

static int hello_init(void)
{
	int DriverState;
	
	printk(KERN_EMERG "HELLO j enter!\n");
	DriverState = platform_driver_register(&hello_driver);
	
	printk(KERN_EMERG "\tDriverState is %d\n",DriverState);
	return 0;
}

static void hello_exit(void)
{
	printk(KERN_EMERG "HELLO WORLD exit!\n");
	
	platform_driver_unregister(&hello_driver);	
}

module_init(hello_init);
module_exit(hello_exit);

Makefile:

#!/bin/bash
#通知编译器我们要编译模块的哪些源码
#这里是编译itop4412_hello.c这个文件编译成中间文件itop4412_hello.o
#obj-m += mini_linux_module.o 
obj-m += devicenode_device_led.o 
#源码目录变量,这里用户需要根据实际情况选择路径
#作者是将Linux的源码拷贝到目录/home/topeet/android4.0下并解压的
KDIR := /home/topeet/Android4.0/iTop4412_Kernel_3.0
#当前目录变量
PWD ?= $(shell pwd)

#make命名默认寻找第一个目标
#make -C就是指调用执行的路径
#$(KDIR)Linux源码目录,作者这里指的是/home/topeet/android4.0/iTop4412_Kernel_3.0
#$(PWD)当前目录变量
#modules要执行的操作
all:
	make -C $(KDIR) M=$(PWD) modules
		
#make clean执行的操作是删除后缀为o的文件
clean:
	rm -rf *.o


http://www.kler.cn/news/306384.html

相关文章:

  • Blender/3ds Max/C4D哪个软件好?
  • C/C++语言基础--从C到C++的不同(上)
  • MyBatis - 一对多对象关联查询
  • OpenCV和Tesseract OCR识别复杂验证码喽~~
  • 使用 element UI 实现自定义日历
  • 日元走强引领外汇市场新动向,全球经济指标波动加剧
  • Radware 报告 Web DDoS 攻击活动
  • 7.1溪降技术:徒步
  • LEAN 赋型唯一性(Unique Typing)之 在 n-provability 下 的 赋型唯一性
  • 什么是API网关(API Gateway)?
  • docker 数据管理
  • 运维面试题-2
  • 单组件的编写
  • Vue:使用v-model绑定的textarea在光标处插入指定文本
  • 爬虫代理API的全面解析:让数据抓取更高效
  • vue part 10
  • ctfshow-web入门-sql注入-web248-UDF 注入
  • Luban策划开源工具
  • 【Vue】- Vue应用
  • RZ7888电机驱动芯片
  • 【2023年】云计算金砖牛刀小试5
  • GitLab权限及设置
  • 【Git】Clone
  • 人工智能(AI)正在以前所未有的速度融入我们生活的方方面面
  • 基于AgentUniverse在金融场景中的多智能体应用探索
  • 学习记录:js算法(三十四):合并 K 个升序链表
  • 计算机网络 ---- 电路交换、报文交换、分组交换
  • 开发后台管理系统-开发环境搭建
  • 【STM32】esp8266通过MQTT连接服务器|订阅发布
  • 10分钟在网站上增加一个AI助手