【驱动开发】控制stm32mp157a开发板三盏灯的亮灭

news2024/11/6 21:25:10

编写应用程序控制三盏灯的亮灭

head.h:

#ifndef __HEAD_H__
#define __HEAD_H__

typedef struct
{
    unsigned int MODER;
    unsigned int OTYPER;
    unsigned int OSPEEDR;
    unsigned int PUPDR;
    unsigned int IDR;
    unsigned int ODR;   
}gpio_t;

//LED灯的寄存器地址
#define LED1_ADDR 0X50006000
#define LED2_ADDR 0X50007000
#define LED3_ADDR 0X50006000
#define RCC_ADDR 0X50000A28

#endif

demo.c:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include "head.h"
#include <linux/device.h>

char kbuf[128] = {};
unsigned int major;
gpio_t *vir_led1;
gpio_t *vir_led2;
gpio_t *vir_led3;
// 定义指针指向映射后的虚拟内存
unsigned int *vir_rcc;

// 封装操作方法
int mycdev_open(struct inode *inode, struct file *file)
{
    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    return 0;
}
ssize_t mycdev_read(struct file *file, char *ubuf, size_t size, loff_t *lof)
{
    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    int ret;
    ret = copy_to_user(ubuf, kbuf, size);
    if (ret)
    {
        printk("copy_to_user filed\n");
        return -EIO;
    }
    return 0;
}
ssize_t mycdev_write(struct file *file, const char *ubuf, size_t size, loff_t *lof)
{
    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    int ret;
    ret = copy_from_user(kbuf, ubuf, size);
    if (ret)
    {
        printk("copy_from_user filed\n");
        return -EIO;
    }
    switch (kbuf[0])
    {
    case '1':
        if (kbuf[1] == '1')      // 开灯
            vir_led1->ODR |= (0x1 << 10);
        else if (kbuf[1] == '0') // 关灯
            vir_led1->ODR &= (~(0x1 << 10));
        break;
    case '2':
        if (kbuf[1] == '1')      // 开灯
            vir_led2->ODR |= (0x1 << 10);
        else if (kbuf[1] == '0') // 关灯
            vir_led2->ODR &= (~(0x1 << 10));
        break;
    case '3':
        if (kbuf[1] == '1')      // 开灯
            vir_led3->ODR |= (0x1 << 8);
        else if (kbuf[1] == '0') // 关灯
            vir_led3->ODR &= (~(0x1 << 8));
        break;
    default:
        printk("输入错误\n");
    }
    return 0;
}
int mycdev_close(struct inode *inode, struct file *file)
{
    printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
    return 0;
}
// 定义操作方法结构体对象
struct file_operations fops = {
    .open = mycdev_open,
    .read = mycdev_read,
    .write = mycdev_write,
    .release = mycdev_close,
};
static int __init mycdev_init(void)
{
    // 注册字符设备驱动
    major = register_chrdev(0, "mychrdev", &fops);
    if (major < 0)
    {
        printk("字符设备驱动注册失败\n");
        return major;
    }
    printk("注册字符设备驱动成功major=%d\n", major);
    // 进行寄存器的地址映射
    vir_led1 = ioremap(LED1_ADDR, sizeof(gpio_t));
    if (vir_led1 == NULL)
    {
        printk("物理内存地址映射失败%d\n", __LINE__);
        return -EFAULT;
    }
    vir_led2 = ioremap(LED2_ADDR, sizeof(gpio_t));
    if (vir_led2 == NULL)
    {
        printk("物理内存地址映射失败%d\n", __LINE__);
        return -EFAULT;
    }
    vir_led3 = ioremap(LED3_ADDR, sizeof(gpio_t));
    if (vir_led3 == NULL)
    {
        printk("物理内存地址映射失败%d\n", __LINE__);
        return -EFAULT;
    }
    vir_rcc=ioremap(RCC_ADDR,4);
    if(vir_rcc == NULL)
    {
        printk("物理内存映射失败%d\n",__LINE__);
        return -EFAULT;
    } 
    printk("寄存器内存映射成功\n");

    // 寄存器初始化
    (*vir_rcc) |= (0x3 << 4); // GPIOE控制器时钟使能
    // LED1
    vir_led1->MODER &= (~(0x3 << 20));
    vir_led1->MODER |= (0x1 << 20);
    vir_led1->ODR &= (~(0x1 << 10));

    // LED2
    vir_led2->MODER &= (~(0x3 << 20));
    vir_led2->MODER |= (0x1 << 20);
    vir_led2->ODR &= (~(0x1 << 10));

    // LED3
    vir_led3->MODER &= (~(0x3 << 16));
    vir_led3->MODER |= (0x1 << 16);
    vir_led3->ODR &= (~(0x1 << 8));

    printk("寄存器初始化成功\n");
    return 0;
}
static void __exit mycdev_exit(void)
{
    // 取消内存映射
    iounmap(vir_led1);
    iounmap(vir_led2);
    iounmap(vir_rcc);
    // 注销字符设备驱动
    unregister_chrdev(major, "mychrdev");
    return 0;
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

test.c:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
    char buf[128] = {0};
    int fd = open("/dev/mychrdev", O_RDWR);
    if (fd < 0)
    {
        printf("打开设备文件失败\n");
        return -1;
    }
    printf("打开设备文件成功\n");
    while (1)
    {
        printf("请输入要控制的灯:1(LED1) 2(LED2) 3(LED3)  >>>\n");
        printf("请输入您要进行的操作:1(开灯) 0(关灯)       >>>\n");
        printf("请输入控制灯的两个字符  >>> ");
        fgets(buf, sizeof(buf), stdin);    //在终端读一个字符串
        buf[strlen(buf) - 1] = '\0';
        write(fd, buf, sizeof(buf));       //将数据传递给内核
    }
    close(fd);
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1115130.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

unity脚本_力 c#

创建一个脚本 将代码挂载到物体上 取消物体的重力 运行即向z轴运动 加力之后 是否停止是由阻力影响 如果阻力为零 则会一直运动 如果希望就算有阻力也让物体一直动就将加力代码放在Update函数里 using UnityEngine; public class Power : MonoBehaviour{ Rigidbody rigidBo…

SpringBoot 打包与运行

一、SpringBoot 程序打包 1、在Springboot工程 pom文件中&#xff0c;引入 spring-boot-maven-plugin 插件。 <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifact…

基于鹈鹕优化的BP神经网络(分类应用) - 附代码

基于鹈鹕优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于鹈鹕优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.鹈鹕优化BP神经网络3.1 BP神经网络参数设置3.2 鹈鹕算法应用 4.测试结果&#xff1a;5.M…

基于蛇优化优化的BP神经网络(分类应用) - 附代码

基于蛇优化优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于蛇优化优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.蛇优化优化BP神经网络3.1 BP神经网络参数设置3.2 蛇优化算法应用 4.测试结果&#x…

二零二三充能必读 | 1024程序员狂欢节 —— 掌握前沿技术,探索未知领域

文章目录 I T 技术 ( I T T e c h n o l o g y ) IT技术(IT Technology) IT技术(ITTechnology)▊《 速学Linux&#xff1a;系统应用从入门到精通》▊《Python网络爬虫入门到实战》 人工智能 ( A r t i f i c i a l I n t e l l i g e n c e ) 人工智能(Artificial Intelligence…

【STM32】两个版本MDK搭建和三种调试器的使用

一、Keil MDK4的安装和介绍 1.Keil MDK和Keil C51的关系 1&#xff09;Keil原来是专门做51&#xff0c;后面被ARM收购&#xff0c; 2&#xff09;Keil MDK是Keil C51的另外一个版本。 2.MDK4下载 Keil Embedded Development Tools for Arm, Cortex-M, Cortex-R4, 8051, C166,…

js鼠标点击添加图标并获取图标的坐标值

给这个图片添加摄像头图标&#xff0c;并获取图标的坐标值&#xff0c;也就是图标的css样式是positon:absolute,获取left和top的值。 图片1 思路是这样的&#xff0c;获取这里的长度&#xff0c; 图片2 1.鼠标点击时距浏览器的左边距离和上边距离&#xff0c;相当于(0,0)坐标 …

1024程序员狂欢节 | IT前沿技术、人工智能、数据挖掘、网络空间安全技术

一年一度的1024程序员狂欢节又到啦&#xff01;成为更卓越的自己&#xff0c;坚持阅读和学习&#xff0c;别给自己留遗憾&#xff0c;行动起来吧&#xff01; 那么&#xff0c;都有哪些好书值得入手呢&#xff1f;小编为大家整理了前沿技术、人工智能、集成电路科学与芯片技术、…

关于AIGC研修班学习笔记

AI工具排行&#xff1a; ChatGptMidjourney——绘画AINotion AI——笔记AITome——做PPT的AIpeioriss Palette.fm——调色AIRemove.bg——抠图AIFliki——视频AIAutoDraw——设计AICopilot——编程AI 国内大模型&#xff1a; 阿里通义千问文心一言讯飞星火商汤日日新腾讯混元…

一文拿下HTTP

HTTP HTTP协议 是应用层使用最广泛的协议之一&#xff0c;从浏览器获取到网页&#xff0c;就是基于http 浏览器和服务器之间的交互桥梁 基于传输层的TCP协议来实现的&#xff0c;是一种无状态的应用层协议 为啥是无状态的呢 简化服务器端的处理逻辑&#xff1a;HTTP是无状态…

【调度算法】NSGA III

写在前面&#xff1a;NSGA III算法在数学上比NSGA II算法要复杂得多&#xff0c;尤其是在参考点那里&#xff0c;我也不是看得很明白&#xff0c;所以这篇文章只是尝试梳理下NSGA III的整体改进思路和优势&#xff0c;不对函数、公式、代码之类的细节做过多分析。如有错误&…

【CANoe】文件处理_hex文件读取解析

hex文件里面只有00&#xff0c;01&#xff0c;04三种码。那么我们在解析的时候只需要对这三种不同状态的进行不同的解析即可。 hex文件格式的解析&#xff0c;可阅读&#xff1a;HEX文件格式详解 首先创建一个Block的结构体&#xff0c;根据经验我们知道&#xff0c;一个数据…

gRPC之gRPC转换HTTP

1、gRPC转换HTTP 我们通常把RPC用作内部通信&#xff0c;而使用Restful Api进行外部通信。为了避免写两套应用&#xff0c;我们使用grpc- gateway 把gRPC转成HTTP。服务接收到HTTP请求后&#xff0c;grpc-gateway把它转成gRPC进行处理&#xff0c;然后以JSON 形式返回数据。…

FOC程序算法编写

1、FOC多路PWM驱动 在BLDC电机控制上&#xff0c;6路PWM 控制模式比3路PWM更自由&#xff0c;因为6个半桥式晶体管的每一个都可以单独控制。 &#xff08;1&#xff09;3PWM &#xff08;2&#xff09;6PWM 2、死区时间 开关元器件的和严格意义并不是相同的。IGBT&#xff0c;…

驱动编写LED灯

demo.c #include <linux/init.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/uaccess.h> #include<linux/io.h> #include "head.h" unsigned int major; char kbuf[128] {}; // 定义三个指针指向映射后的虚拟…

vue3.0 + element plus upload文件上传

提供了&#xff0c;文件超过指定个数&#xff0c;页面做了隐藏的效果 记录一下

HTTPS、SSL/TLS,HTTPS运行过程,RSA加密算法,AES加密算法

1、为什么网站要使用安全证书 我们所处的网络环境是复杂多样的&#xff0c;大致分为两类&#xff0c;一类是可信的网络服务商&#xff0c;比如直接连的电信运营商的网络&#xff0c;网线&#xff0c;4G&#xff0c;5G&#xff1b;另一类是不可信的网络&#xff0c;比如WIFI&am…

libpcap之零拷贝mmap

一、用户空间 在通过socket(AF_PACKET,…)创建fd后&#xff0c;进行接收队列的建立 //pcap-linux.c static int pcap_activate_linux(pcap_t *handle) { ...ret setup_mmapped(handle, &status); ... }1.1 设置默认ring bufer size static int setup_mmapped(pcap_t *h…

点云处理【六】(点云分割)

点云分割 第一章 点云数据采集 1. 点云分割 点云数据中包含目标物体&#xff0c;点云分割算法即将物体分割出来。 2 分割算法 2.1 RANSAC(随机采样一致性)方法 基于随机采样一致性的分割的步骤如下&#xff1a; 1.从一个样本集S中&#xff0c;随机抽取n个样本&#xff0c;…

下拉选择框监听el-option的方式

<el-select v-model"form.expenseType" placeholder"请选择费用类型" clearable filterable size"small"><el-option v-for"item in expenseNameList" :key"item.value" :label"item.label" :value"…