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

设备树及gpio子系统及ioctl控制及字符设备驱动及内核模块编程事项仨LED灯说点就点说灭就灭

 设备树文件stm32mp157a-fsmp1a.dts

(主要是添加 leds 节点)

// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
 * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
 * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
 */

/dts-v1/;

#include "stm32mp157.dtsi"
#include "stm32mp15xa.dtsi"
#include "stm32mp15-pinctrl.dtsi"
#include "stm32mp15xxac-pinctrl.dtsi"
#include "stm32mp15xx-fsmp1x.dtsi"

/ {
	model = "HQYJ STM32MP157A-FSMP1A Discovery Board";
	compatible = "st,stm32mp157a-fsmp1a", "st,stm32mp157";

	aliases {
		serial0 = &uart4;
	};

	chosen {
		stdout-path = "serial0:115200n8";
	};
	 reserved-memory {
        gpu_reserved: gpu@da000000 {
            reg = <0xda000000 0x4000000>;
            no-map;
        };

        optee_memory: optee@0xde000000 {
		    reg = <0xde000000 0x02000000>;
            no-map;
        };
    };
	mynode@0x12345678{
			compatible = "hqyj,mynode";
			astring = "hello 24081";
			uint = <0xaabbccdd 0x11223344>;
			binarry=[00 0c 29 7b f9 be];
			mixed = "helle", [11 22], <0x12345678>;
		};
	leds {
			led1-gpio = <&gpioe 10 0>;
			led2-gpio = <&gpiof 10 0>;
			led3-gpio = <&gpioe 8 0>;
};
};

&optee {
    status = "okay";
};


 驱动文件dt_test.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>
#include "det_led.h"

unsigned int major;

char kbuf[128] = {};

struct device_node *np;
int gpiono;

int myled_open(struct inode* inode , struct file * file)
{
    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    return 0;    
}
ssize_t myled_read(struct file*file , char __user* ubuf , size_t size , loff_t * lft)
{
    unsigned long ret;
    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    if(size > sizeof(kbuf))
    {
        size = sizeof(kbuf);
    } 
    ret = copy_to_user(ubuf ,kbuf, size);
    if(ret)
    {
        printk("cpoy_to_user failed\n");
        return ret;
    }
    return 0;
}
ssize_t myled_write(struct file*file , const char __user * ubuf , size_t size , loff_t *lft)
{
    unsigned long ret;
    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    if(size > sizeof(kbuf))
    {
        size = sizeof(kbuf);
    }
    ret = copy_from_user(kbuf ,ubuf, size);
    if(ret)
    {
        printk("cpoy_from_user failed\n");
        return ret;
    }
    return 0;

}

long myled_ioctl(struct file* file ,unsigned int cmd , unsigned long arg)
{
    int ch;
    unsigned long ret =copy_from_user(&ch ,  (int *)arg ,4);
    if(ret){
        printk("ch get error");
        return ret;
    }
    switch (cmd)
    {
    case LED_ON:
        switch (ch)
        {
        case 1:
            gpiono = of_get_named_gpio(np, "led1-gpio", 0);
            gpio_set_value(gpiono, 1);
            break;
        case 2:
            gpiono = of_get_named_gpio(np, "led2-gpio", 0);
            gpio_set_value(gpiono, 1);
            break;        
        case 3:
            gpiono = of_get_named_gpio(np, "led3-gpio", 0);
            gpio_set_value(gpiono, 1);
            break;
        default:
            break;
        }
        break;
    case LED_OFF:
        switch (ch)
        {
        case 1:
            gpiono = of_get_named_gpio(np, "led1-gpio", 0);
            gpio_set_value(gpiono, 0);
            break;
        case 2:
            gpiono = of_get_named_gpio(np, "led2-gpio", 0);
            gpio_set_value(gpiono, 0);
            break;        
        case 3:
            gpiono = of_get_named_gpio(np, "led3-gpio", 0);
            gpio_set_value(gpiono, 0);
            break;
        default:
            break;
        }
        break;
    
    default:
        break;
    }
    return 0;
}
int myled_close(struct inode*indoe , struct file* file)
{
    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    return 0;
}

struct file_operations fops={
    .open=myled_open,
    .read=myled_read,
    .write=myled_write,
    .unlocked_ioctl=myled_ioctl,
    .release=myled_close,
};

static int __init mycdev_init(void)
{

    int i = 0;//for循环参数变量
    major = register_chrdev(0 ,"myled", &fops);
    printk("%s:%s:%d\n", __FILE__, __func__, major);
    if(major<0)
    {
        printk("register_chrdev error\n");
    }
    np = of_find_node_by_path("/leds");
    if(np == NULL)
    {   
        printk("find node failed\n");
        return -1;
    }
  
    for(i=0 ; i<3 ;  i++){
        if(i==0){
            gpiono = of_get_named_gpio(np, "led1-gpio", 0);
        }
        if(i==1){
            gpiono = of_get_named_gpio(np, "led2-gpio", 0);
        }
        if(i==2){
            gpiono = of_get_named_gpio(np, "led3-gpio", 0);
        }
        if(gpiono < 0)
        {
            printk("get gpiono failed \n");
            return -1;
        }
        printk("get gpiono success \n");


        if(gpio_request(gpiono , NULL))
        {
            printk("gpio requset failed\n");
        }
            printk("gpio requset success\n");

        if (gpio_direction_output(gpiono , 0))
        {
            printk(" direction failed\n");
        }
            printk("gpio direction success\n");
    }

    return 0;



}
static void __exit mycdev_exit(void)
{
    int i;
    for(i=0;i<3;i++)
    {
        if(i==0){
            gpiono = of_get_named_gpio(np, "led1-gpio", 0);
        }
        if(i==1){
            gpiono = of_get_named_gpio(np, "led2-gpio", 0);
        }
        if(i==2){
            gpiono = of_get_named_gpio(np, "led3-gpio", 0);
        }
        gpio_free (gpiono );
    }
    unregister_chrdev(major, "myled");
    printk("gpio free success");

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

应用文件头文件 

led.h

#ifndef __LED_H__
#define __LED_H__


#define LED_ON _IOW('l', 1, int)
#define LED_OFF _IOW('l', 0, int)

#endif

 应用文件 dpp.c(或许该叫他led.c)

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

int main(int argc,const char * argv[])
{
    int fd = open("/dev/led" , O_RDWR);
    if(fd<0)
    {
        printf("file open failed\n");
        return fd;
    }
    printf("file open success\n");    
    int a , b;
    while(1){
        printf("选择要控制的灯 1-(LED1) 2-(LED2) 3-(LED3)\n");
        scanf("%d", &a);
        if(a!=1 &&  a!=2 && a!=3)
        {
            printf("选择有误请重新输入\n");
            continue;
        }
loop:
        printf("控制灯的状态   1-(ON)  0-(OFF)\n");
        scanf("%d", &b);
        if(b!=1 &&  b!=0)
        {
            printf("选择有误请重新输入\n");
            goto loop;
        }
        switch (b)
        {
        case 0:
            ioctl(fd ,LED_OFF ,&a);
            break;
        case 1:
            ioctl(fd ,LED_ON ,&a);
            break;
        default:
             break;
         }
    }
    close(fd);
    return 0;
}

 

 

 


http://www.kler.cn/a/556305.html

相关文章:

  • VMWare安装Debian操作系统
  • CSS 解决 Flex 布局中 justify-content: space-between; 导致最后一排项目分散对齐的问题
  • 数据结构——二叉树经典习题讲解
  • MATLAB学习之旅:从入门到基础实践
  • 【.NET全栈】.NET包含的所有技术
  • Github开源AI LLM大语言模型WebUI框架推荐
  • 【Gin】| 框架源码解析 :路由详解
  • QT SQL框架及QSqlDatabase类
  • MATLAB | 设置滑动窗口计算栅格数据的CV变异系数
  • 装win10系统提示“windows无法安装到这个磁盘,选中的磁盘采用GPT分区形式”解决方法
  • 计算机视觉算法实战——图像风格迁移(主页有源码)
  • solidity之Foundry安装配置(一)
  • 利用Postman和Apipost进行WebSocket调试和文档设计
  • 国产开源PDF解析工具MinerU
  • 网络运维学习笔记 013网工初级(HCIA-Datacom与CCNA-EI)DHCP动态主机配置协议(此处只讲华为)
  • 【C语言】结构体内存对齐问题
  • 前端ES面试题及参考答案
  • Node.js 的 http 模块
  • Vue 3 和 Vite 从零开始搭建项目的详细步骤
  • 在 Flutter 中实现文件读写