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

设备树及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;
}

 

 

 

相关文章:

  • 计算机原理第三章——存储器(未完善
  • 计算机网络面试知识点总结
  • 一文说清楚编码、摘要、加密、公钥、私钥、解密、签名、验签
  • 具有整合各亚专科医学领域知识能力的AI智能体开发纲要(2025版)
  • docker基操
  • Unity游戏制作中的C#基础(4)数组声明和使用
  • Python 高级特性-迭代
  • 写大论文的word版本格式整理,实现自动生成目录、参考文献序号、公式序号、图表序号
  • Orange 单体架构 - 快速启动
  • VMware Workstation安装Windows10
  • Linux下基本指令(4)
  • android系统SystemServer进程启动流程分析
  • 002 SpringCloudAlibaba整合 - Feign远程调用、Loadbalancer负载均衡
  • 大数据学习之任务流调度系统Azkaban、Superset可视化系统
  • Cursor和Trae使用的感受
  • Spring 到 Spring Boot:配置文件管理的灵活封装与扩展
  • 爬虫第七篇数据爬取及解析
  • SpringBoot 配置文件
  • AGI觉醒假说的科学反驳:从数学根基到现实约束的深度解析
  • JavaScript变量的作用域介绍
  • 习近平在河南洛阳市考察调研
  • 上海文化馆服务宣传周启动,为市民提供近2000项活动
  • 【社论】进一步拧紧过紧日子的制度螺栓
  • 83岁山水花鸟画家、书法家吴静山离世,系岭南画派代表人物
  • 江苏疾控:下设部门无“病毒研究所”,常荣山非本单位工作人员
  • 国际博物馆日|航海博物馆:穿梭于海洋神话与造船工艺间