day4 驱动开发 c语言学习

不利用系统提供的register_chrdev,自己实现字符设备的注册

底层代码

led.c

cpp 复制代码
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include "head.h"

struct cdev *mycdev;
struct class *my_cls;
struct device *my_dev;
dev_t devno;
unsigned int major = 0; //定义一个变量保存主设备号
char kbuf[128] = { 0 }; //定义一个内核中的buffer
unsigned int *vir_gpioe_moder = NULL;
unsigned int *vir_gpioe_odr = NULL;
unsigned int *vir_gpiof_moder = NULL;
unsigned int *vir_gpiof_odr = NULL;
unsigned int *vir_rcc = NULL;
//封装注册设备方法
int mycdev_regist(void)
{
	int res = 0;
    int i = 0;
	//为驱动对象申请空间 cdev_alloc()
	mycdev = cdev_alloc();
	if (mycdev == NULL) {
		return -EFAULT;
	}
	//对象的初始化 cdev_init()
	cdev_init(mycdev, &fops);
	//申请设备号 register_chrdev_region()/alloc_chrdev_region()
	res = alloc_chrdev_region(&devno, 0, 3, "my_cdev");
	if (res != 0) {
		goto out;
	}
	//注册驱动对象 cdev_add()
	res = cdev_add(mycdev, devno, 3);
	if (res != 0) {
		goto out2;
	}
    major = MAJOR(devno);
	//向上提交目录 class_create()
	my_cls = class_create(THIS_MODULE, "my_cdev");
	if (my_cls == NULL) {
		goto out3;
	}
	//向上提交设备节点信息 device_create()
    for(i = 0; i < 3; i++)
    {
        my_dev = device_create(my_cls, NULL, MKDEV(major, i), NULL, "LED%d", i);
		if (IS_ERR(my_dev)) {
			goto out4;
		}
    }
	return 0;

out4:
    for(i--; i >= 0; i-- )
    {
        device_destroy(my_dev,MKDEV(major,i));
    }
	class_destroy(my_cls);
out3:
	cdev_del(mycdev);
out2:
	unregister_chrdev_region(devno, 3);
out:
	kfree(mycdev);
	return -PTR_ERR(res);
}
//封装操作方法
int mycdev_open(struct inode *inode, struct file *file)
{
	devno = inode->i_rdev;
	file->private_data = (void *)MINOR(devno);
	printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
	return 0;
}

long mycdev_ioctl(struct file *file, unsigned int request, unsigned long args)
{
	unsigned int minor = (unsigned int)file->private_data;
	if (minor = 0) 
    {
		//开led1
		if (request == LED1_ON) {
			*vir_gpioe_odr |= 0x1 << 10;
		}
		//关led1
		else if (request == LED1_OFF) {
			*vir_gpioe_odr &= ~(0x1 << 10);
		}
	} 
    else if (minor == 1) 
    {
		//开led2
		if (request == LED2_ON) {
			*vir_gpiof_odr |= 0x1 << 10;
		}
		//关led2
		else if (request == LED2_OFF) {
			*vir_gpiof_odr &= ~(0x1 << 10);
		}
	} 
    else if (minor == 2) 
    {
		//开led3
		if (request == LED3_ON)
		{
			*vir_gpioe_odr |= 0x1 << 8;
		}
		//关led3
		else if (request == LED3_OFF)
		{
			*vir_gpioe_odr &= ~(0x1 << 8);
		}
	}

	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,
	.unlocked_ioctl = mycdev_ioctl,
	.release = mycdev_close,
};

static int __init mycdev_init(void)
{   
    mycdev_regist();
	//定义一个long类型(匹配ioremap函数第一个参数),用来保存每个寄存器的地址信息
	volatile unsigned long tmp = 0;
	//初始化几个寄存器,将物理地址映射到虚拟地址,以方便用户空间进行读写操作

	//将地址信息强转为long类型方便tmp保存
	tmp = (long)&GPIOE->MODER;
	//将寄存器的物理地址映射到虚拟地址并保存
	vir_gpioe_moder = ioremap(tmp, 4);
	if (vir_gpioe_moder == NULL) {
		printk("映射物理内存失败");
		return -EFAULT;
	}
	//将地址信息强转为long类型方便tmp保存
	tmp = (long)&GPIOF->MODER;
	//将寄存器的物理地址映射到虚拟地址并保存
	vir_gpiof_moder = ioremap(tmp, 4);
	if (vir_gpioe_moder == NULL) {
		printk("映射物理内存失败");
		return -EFAULT;
	}
	//将地址信息强转为long类型方便tmp保存
	tmp = (long)&GPIOE->ODR;
	//将寄存器的物理地址映射到虚拟地址并保存
	vir_gpioe_odr = ioremap(tmp, 4);
	if (vir_gpioe_odr == NULL) {
		printk("映射物理内存失败");
		return -EFAULT;
	}
	//将地址信息强转为long类型方便tmp保存
	tmp = (long)&GPIOF->ODR;
	//将寄存器的物理地址映射到虚拟地址并保存
	vir_gpiof_odr = ioremap(tmp, 4);
	if (vir_gpiof_odr == NULL) {
		printk("映射物理内存失败");
		return -EFAULT;
	}
	//将地址信息强转为long类型方便tmp保存
	tmp = (long)&RCC->MP_AHB4ENSETR;
	//将寄存器的物理地址映射到虚拟地址并保存
	vir_rcc = ioremap(tmp, 4);
	if (vir_rcc == NULL) {
		printk("映射物理内存失败");
		return -EFAULT;
	}
	//初始化几个寄存器的值
	//设置RCC_MP_AHB4ENSETR寄存器第4第5两个引脚为1,使能GPIOE,GPIOF
	*vir_rcc |= (0b11 << 4);
	//设置GPIOE_MODER第20-21位为01
	*vir_gpioe_moder &= ~(0b11 << 20);
	*vir_gpioe_moder |= (0b01 << 20);
	//设置GPIOF_MODER第20-21位为01
	*vir_gpiof_moder &= ~(0b11 << 20);
	*vir_gpiof_moder |= (0b01 << 20);
	//设置GPIOE_MODER第16-17位为01
	*vir_gpioe_moder &= ~(0b11 << 16);
	*vir_gpioe_moder |= (0b01 << 16);
	//设置GPIOE_ODR第10位为0
	*vir_gpioe_odr &= ~(0b1 << 10);
	//设置GPIOF_ODR第10位为0
	*vir_gpiof_odr &= ~(0b1 << 10);
	//设置GPIOE_ODR第8位为0
	*vir_gpiof_odr &= ~(0b1 << 8);
	return 0;
}

static void __exit mycdev_exit(void)
{
	//取消物理内存映射
	iounmap(vir_gpioe_moder);
	iounmap(vir_gpiof_moder);
	iounmap(vir_gpioe_odr);
	iounmap(vir_gpiof_odr);
	iounmap(vir_rcc);
	printk("设备卸载\n");
	unregister_chrdev(MAJOR(devno), "mychrdev");
}

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

应用层代码

app.c

cpp 复制代码
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include "head.h"

int main()
{
    int dev = 0;
    char buf[128] = {0};
    fprintf(stdout,"调用open\n");
    int fd_led0 = open("/dev/LED0",O_RDWR);
    if( fd_led0 < 0)
    {
        perror("");
        exit(-1);
    }
    int fd_led1 = open("/dev/LED1",O_RDWR);
    if( fd_led1 < 0)
    {
        perror("");
        exit(-1);
    }
    int fd_led2 = open("/dev/LED2",O_RDWR);
    if( fd_led2 < 0)
    {
        perror("");
        exit(-1);
    }
    
    while(1)
    {
        fprintf(stdout,"请输入开关选项:\n");
        fprintf(stdout,"11开1号灯,10关1号灯以此类推\n");
        fprintf(stdout,"输入q来结束\n");
        fgets(buf,sizeof(buf),stdin);
        buf[strlen(buf) - 1] = '\0';
        //如果输入的是q或Q,结束循环
        if(buf[0] == 'q' || buf[0] == 'Q')
        {
            break;
        }
        else if(buf[0] == '0')
        {
            
            if(buf[1] == '1' && buf[2] == '0')
            {
                ioctl(fd_led0, LED1_OFF, dev);
            }
            else if(buf[1] == '1' && buf[2] == '1')
            {
                ioctl(fd_led0, LED1_ON, dev);
            }
            else if(buf[1] == '2' && buf[2] == '0')
            {
                ioctl(fd_led1, LED2_OFF, dev);
            }
            else if(buf[1] == '2' && buf[2] == '1')
            {
                ioctl(fd_led1, LED2_ON, dev);
            }
            else if(buf[1] == '3' && buf[2] == '0')
            {
                ioctl(fd_led2, LED3_OFF, dev);
            }
            else if(buf[1] == '3' && buf[2] == '1')
            {
                ioctl(fd_led2, LED3_ON, dev);
            }
        }
    }
    close(fd_led0);
    close(fd_led1);
    close(fd_led2);
    return 0;
}

头文件

head.h

cpp 复制代码
#ifndef __LED_H__
#define __LED_H__

typedef struct {
	volatile unsigned int TZCR;     	// 0x000
	volatile unsigned int res1[2]; 		// 0x004-0x008
	volatile unsigned int OCENSETR;     // 0x00C
	volatile unsigned int OCENCLRR;  	// 0x010
	volatile unsigned int res2[1]; 		// 0x014
	volatile unsigned int HSICFGR; 		// 0x018
	volatile unsigned int CSICFGR; 		// 0x01C
	volatile unsigned int MPCKSELR; 	// 0x020
	volatile unsigned int ASSCKSELR; 	// 0x024
	volatile unsigned int PCK12SELR; 	// 0x028
	volatile unsigned int MPCKDIVR; 	// 0x02C
	volatile unsigned int AXIDIVR; 		// 0x030
	volatile unsigned int res3[2];      
	volatile unsigned int APB4DIVR; 	// 0x03C
	volatile unsigned int APB5DIVR; 	// 0x040
	volatile unsigned int RTCDIVR; 		// 0x044
	volatile unsigned int MSSCKSELR;    // 0x048
	volatile unsigned int res4[13];
	volatile unsigned int PLL1CR; 		// 0x080
	volatile unsigned int PLL1CFGR1; 	// 0x084
	volatile unsigned int PLL1CFGR2; 	// 0x088
	volatile unsigned int PLL1FRACR; 	// 0x08C
	volatile unsigned int PLL1CSGR;     // 0x090
	volatile unsigned int PLL2CR; 		// 0x094
	volatile unsigned int PLL2CFGR1; 	// 0x098
	volatile unsigned int PLL2CFGR2; 	// 0x09C
	volatile unsigned int PLL2FRACR;    // 0x0A0
	volatile unsigned int PLL2CSGR;     // 0x0A4
	volatile unsigned int res5[6];
	volatile unsigned int I2C46CKSELR;  // 0x0C0
	volatile unsigned int SPI6CKSELR;   // 0x0C4
	volatile unsigned int UART1CKSELR;  // 0x0C8
	volatile unsigned int RNG1CKSELR;   // 0x0CC
	volatile unsigned int CPERCKSELR;   // 0x0D0
	volatile unsigned int STGENCKSELR;  // 0x0D4
	volatile unsigned int DDRITFCR; 	// 0x0D8
	volatile unsigned int res6[9];
	volatile unsigned int MP_BOOTCR;  	// 0x100
	volatile unsigned int MP_SREQSETR;  // 0x104
	volatile unsigned int MP_SREQCLRR;  // 0x108
	volatile unsigned int MP_GCR;  		// 0x10C
	volatile unsigned int MP_APRSTCR; 	// 0x110 
	volatile unsigned int MP_APRSTSR;   // 0x114
	volatile unsigned int res7[10];
	volatile unsigned int BDCR; 		// 0x140
	volatile unsigned int RDLSICR;  	// 0x144
	volatile unsigned int res8[14];
	volatile unsigned int APB4RSTSETR; 	// 0x180
	volatile unsigned int APB4RSTCLRR; 	// 0x184
	volatile unsigned int APB5RSTSETR;  // 0x188
	volatile unsigned int APB5RSTCLRR;  // 0x18C
	volatile unsigned int AHB5RSTSETR;  // 0x190
	volatile unsigned int AHB5RSTCLRR;  // 0x194
	volatile unsigned int AHB6RSTSETR;  // 0x198
	volatile unsigned int AHB6RSTCLRR;  // 0x19C
	volatile unsigned int TZAHB6RSTSELR;// 0x1A0
	volatile unsigned int TZAHB6RSTCLRR;// 0x1A4
	volatile unsigned int res9[22];
	volatile unsigned int MP_APB4ENSETR;// 0x200
	volatile unsigned int MP_APB4ENCLRR;// 0x204
	volatile unsigned int MP_APB5ENSETR;// 0x208
	volatile unsigned int MP_APB5ENCLRR;// 0x20C
	volatile unsigned int MP_AHB5ENSETR;// 0x210
	volatile unsigned int MP_AHB5ENCLRR;// 0x214
	volatile unsigned int MP_AHB6ENSETR;// 0x218
	volatile unsigned int MP_AHB6ENCLRR;// 0x21C
	volatile unsigned int MP_TZAHB6ENSELR;// 0x220
	volatile unsigned int MP_TZAHB6ENCLRR;// 0x224
	volatile unsigned int res10[22];
	volatile unsigned int MC_APB4ENSETR; // 0x280
	volatile unsigned int MC_APB4ENCLRR; // 0x284
	volatile unsigned int MC_APB5ENSETR; // 0x288
	volatile unsigned int MC_APB5ENCLRR; // 0x28C
	volatile unsigned int MC_AHB5ENSETR; // 0x290
	volatile unsigned int MC_AHB5ENCLRR; // 0x294
	volatile unsigned int MC_AHB6ENSETR; // 0x298
	volatile unsigned int MC_AHB6ENCLRR; // 0x29C
	volatile unsigned int res11[24];
	volatile unsigned int MP_APB4LPENSETR; // 0x300
	volatile unsigned int MP_APB4LPENCLRR; // 0x304
	volatile unsigned int MP_APB5LPENSETR; // 0x308
	volatile unsigned int MP_APB5LPENCLRR; // 0x30C
	volatile unsigned int MP_AHB5LPENSETR; // 0x310
	volatile unsigned int MP_AHB5LPENCLRR; // 0x314
	volatile unsigned int MP_AHB6LPENSETR; // 0x318
	volatile unsigned int MP_AHB6LPENCLRR; // 0x31C
	volatile unsigned int MP_TZAHB6LPENSETR; // 0x320
	volatile unsigned int MP_TZAHB6LPENCLRR; // 0x324
	volatile unsigned int res12[22];
	volatile unsigned int MC_APB4LPENSETR; // 0x380
	volatile unsigned int MC_APB4LPENCLRR; // 0x384
	volatile unsigned int MC_APB5LPENSETR; // 0x388
	volatile unsigned int MC_APB5LPENCLRR; // 0x38C
	volatile unsigned int MC_AHB5LPENSETR; // 0x390
	volatile unsigned int MC_AHB5LPENCLRR; // 0x394
	volatile unsigned int MC_AHB6LPENSETR; // 0x398
	volatile unsigned int MC_AHB6LPENCLRR; // 0x39C
	volatile unsigned int res13[24];
	volatile unsigned int BR_RSTSCLRR; 		// 0x400
	volatile unsigned int MP_GRSTCSETR; 	// 0x404
	volatile unsigned int MP_RSTSR; 		// 0x408 
	volatile unsigned int MP_IWDGFZSETR; 	// 0x40C
	volatile unsigned int MP_IWDGFZCLRR;  	// 0x410
	volatile unsigned int MP_CIER; 			// 0x414
	volatile unsigned int MP_CIFR; 			// 0x418
	volatile unsigned int PWRLPDLYCR; 		// 0x41C
	volatile unsigned int MP_RSTSS; 		// 0x420
	volatile unsigned int res14[247];
	volatile unsigned int MCO1CFGR; 		// 0x800
	volatile unsigned int MCO2CFGR; 		// 0x804 
	volatile unsigned int OCRDYR; 			// 0x808
	volatile unsigned int DBGCFGR; 			// 0x80C
	volatile unsigned int res15[4];
	volatile unsigned int RCK3SELR; 		// 0x820
	volatile unsigned int RCK4SELR; 		// 0x824
	volatile unsigned int TIMG1PRER;  		// 0x828
	volatile unsigned int TIMG2PRER; 		// 0x82C
	volatile unsigned int MCUDIVR; 			// 0x830
	volatile unsigned int APB1DIVR; 		// 0x834
	volatile unsigned int APB2DIVR; 		// 0x838
	volatile unsigned int APB3DIVR; 		// 0x83C
	volatile unsigned int res16[16];
	volatile unsigned int PLL3CR;   		// 0x880
	volatile unsigned int PLL3CFGR1; 		// 0x884
	volatile unsigned int PLL3CFGR2; 		// 0x888
	volatile unsigned int PLL3FRACR; 		// 0x88C
	volatile unsigned int PLL3CSGR; 		// 0x890
	volatile unsigned int PLL4CR; 			// 0x894
	volatile unsigned int PLL4CFGR1; 		// 0x898
	volatile unsigned int PLL4CFGR2; 		// 0x89C
	volatile unsigned int PLL4FRACR; 		// 0x8A0
	volatile unsigned int PLL4CSGR; 		// 0x8A4
	volatile unsigned int res17[6];
	volatile unsigned int I2C12CKSELR; 		// 0x8C0
	volatile unsigned int I2C35CKSELR;  	// 0x8C4
	volatile unsigned int SAI1CKSELR; 		// 0x8C8
	volatile unsigned int SAI2CKSELR; 		// 0x8CC
	volatile unsigned int SAI3CKSELR; 		// 0x8D0
	volatile unsigned int SAI4CKSELR; 		// 0x8D4
	volatile unsigned int SPI2S1CKSELR; 	// 0x8D8
	volatile unsigned int SPI2S23CKSELR; 	// 0x8DC
	volatile unsigned int SPI45CKSELR; 		// 0x8E0
	volatile unsigned int UART6CKSELR; 		// 0x8E4
	volatile unsigned int UART24CKSELR; 	// 0x8E8
	volatile unsigned int UART35CKSELR; 	// 0x8EC
	volatile unsigned int UART78CKSELR; 	// 0x8F0
	volatile unsigned int SDMMC12CKSELR; 	// 0x8F4
	volatile unsigned int SDMMC3CKSELR; 	// 0x8F8
	volatile unsigned int ETHCKSELR; 		// 0x8FC
	volatile unsigned int QSPICKSELR; 		// 0x900
	volatile unsigned int FMCCKSELR; 		// 0x904
	volatile unsigned int res18[1];
	volatile unsigned int FDCANCKSELR; 		// 0x90C
	volatile unsigned int res19[1];
	volatile unsigned int SPDIFCKSELR; 		// 0x914
	volatile unsigned int CECCKSELR; 		// 0x918
	volatile unsigned int USBCKSELR; 		// 0x91C
	volatile unsigned int RNG2CKSELR;  		// 0x920
	volatile unsigned int DSICKSELR; 		// 0x924
	volatile unsigned int ADCCKSELR; 		// 0x928
	volatile unsigned int LPTIM45CKSELR; 	// 0x92C
	volatile unsigned int LPTIM23CKSELR;    // 0x930
	volatile unsigned int LPTIM1CKSELR; 	// 0x934
	volatile unsigned int res20[18];
	volatile unsigned int APB1RSTSETR; 		// 0x980
	volatile unsigned int APB1RSTCLRR; 		// 0x984
	volatile unsigned int APB2RSTSETR; 		// 0x988
	volatile unsigned int APB2RSTCLRR; 		// 0x98C
	volatile unsigned int APB3RSTSETR; 		// 0x990
	volatile unsigned int APB3RSTCLRR; 		// 0x994
	volatile unsigned int AHB2RSTSETR; 		// 0x998
	volatile unsigned int AHB2RSTCLRR;  	// 0x99C
	volatile unsigned int AHB3RSTSETR; 		// 0x9A0
	volatile unsigned int AHB3RSTCLRR; 		// 0x9A4
	volatile unsigned int AHB4RSTSETR; 		// 0x9A8
	volatile unsigned int AHB4RSTCLRR; 		// 0x9AC
	volatile unsigned int res21[20];
	volatile unsigned int MP_APB1ENSETR; 	// 0xA00
	volatile unsigned int MP_APB1ENCLRR; 	// 0xA04
	volatile unsigned int MP_APB2ENSETR; 	// 0xA08
	volatile unsigned int MP_APB2ENCLRR;  	// 0xA0C
	volatile unsigned int MP_APB3ENSETR; 	// 0xA10
	volatile unsigned int MP_APB3ENCLRR; 	// 0xA14
	volatile unsigned int MP_AHB2ENSETR; 	// 0xA18
	volatile unsigned int MP_AHB2ENCLRR; 	// 0xA1C
	volatile unsigned int MP_AHB3ENSETR; 	// 0xA20
	volatile unsigned int MP_AHB3ENCLRR; 	// 0xA24
	volatile unsigned int MP_AHB4ENSETR; 	// 0xA28
	volatile unsigned int MP_AHB4ENCLRR; 	// 0xA2C
	volatile unsigned int res22[2];
	volatile unsigned int MP_MLAHBENSETR; 	// 0xA38
	volatile unsigned int MP_MLAHBENCLRR; 	// 0xA3C
	volatile unsigned int res23[16];
	volatile unsigned int MC_APB1ENSETR; 	// 0xA80
	volatile unsigned int MC_APB1ENCLRR; 	// 0xA84
	volatile unsigned int MC_APB2ENSETR; 	// 0xA88
	volatile unsigned int MC_APB2ENCLRR; 	// 0xA8C
	volatile unsigned int MC_APB3ENSETR; 	// 0xA90
	volatile unsigned int MC_APB3ENCLRR; 	// 0xA94
	volatile unsigned int MC_AHB2ENSETR; 	// 0xA98
	volatile unsigned int MC_AHB2ENCLRR; 	// 0xA9C
	volatile unsigned int MC_AHB3ENSETR; 	// 0xAA0
	volatile unsigned int MC_AHB3ENCLRR; 	// 0xAA4
	volatile unsigned int MC_AHB4ENSETR; 	// 0xAA8
	volatile unsigned int MC_AHB4ENCLRR; 	// 0xAAC
	volatile unsigned int MC_AXIMENSETR; 	// 0xAB0
	volatile unsigned int MC_AXIMENCLRR; 	// 0xAB4
	volatile unsigned int MC_MLAHBENSETR; 	// 0xAB8
	volatile unsigned int MC_MLAHBENCLRR; 	// 0xABC
	volatile unsigned int res24[16];
	volatile unsigned int MP_APB1LPENSETR; 	// 0xB00
	volatile unsigned int MP_APB1LPENCLRR; 	// 0xB04
	volatile unsigned int MP_APB2LPENSETR;  // 0xB08
	volatile unsigned int MP_APB2LPENCLRR; 	// 0xB0C
	volatile unsigned int MP_APB3LPENSETR; 	// 0xB10
	volatile unsigned int MP_APB3LPENCLRR;  // 0xB14
	volatile unsigned int MP_AHB2LPENSETR;  // 0xB18
	volatile unsigned int MP_AHB2LPENCLRR;  // 0xB1C
	volatile unsigned int MP_AHB3LPENSETR;  // 0xB20
	volatile unsigned int MP_AHB3LPENCLRR;  // 0xB24
	volatile unsigned int MP_AHB4LPENSETR;  // 0xB28
	volatile unsigned int MP_AHB4LPENCLRR;  // 0xB2C
	volatile unsigned int MP_AXIMLPENSETR;  // 0xB30
	volatile unsigned int MP_AXIMLPENCLRR;  // 0xB34
	volatile unsigned int MP_MLAHBLPENSETR; // 0xB38
	volatile unsigned int MP_MLAHBLPENCLRR; // 0xB3C
	volatile unsigned int res25[16];
	volatile unsigned int MC_APB1LPENSETR;  // 0xB80
	volatile unsigned int MC_APB1LPENCLRR; 	// 0xB84
	volatile unsigned int MC_APB2LPENSETR;  // 0xB88
	volatile unsigned int MC_APB2LPENCLRR;  // 0xB8C
	volatile unsigned int MC_APB3LPENSETR;  // 0xB90 
	volatile unsigned int MC_APB3LPENCLRR;  // 0xB94
	volatile unsigned int MC_AHB2LPENSETR;  // 0xB98
	volatile unsigned int MC_AHB2LPENCLRR;  // 0xB9C
	volatile unsigned int MC_AHB3LPENSETR;  // 0xBA0 
	volatile unsigned int MC_AHB3LPENCLRR;  // 0xBA4
	volatile unsigned int MC_AHB4LPENSETR;  // 0xBA8
	volatile unsigned int MC_AHB4LPENCLRR;  // 0xBAC
	volatile unsigned int MC_AXIMLPENSETR;  // 0xBB0
	volatile unsigned int MC_AXIMLPENCLRR;  // 0xBB4
	volatile unsigned int MC_MLAHBLPENSETR; // 0xBB8
	volatile unsigned int MC_MLAHBLPENCLRR; // 0xBBC
	volatile unsigned int res26[16];
	volatile unsigned int MC_RSTSCLRR;  	// 0xC00
	volatile unsigned int res27[4];
	volatile unsigned int MC_CIER;  		// 0xC14
	volatile unsigned int MC_CIFR; 			// 0xC18
	volatile unsigned int res28[246];
	volatile unsigned int VERR; 			// 0xFF4
	volatile unsigned int IDR; 				// 0xFF8
	volatile unsigned int SIDR; 			// 0xFFC
}rcc_t;

#define RCC   ((rcc_t *)0x50000000)

typedef struct {
	volatile unsigned int MODER;   // 0x00
	volatile unsigned int OTYPER;  // 0x04
	volatile unsigned int OSPEEDR; // 0x08
	volatile unsigned int PUPDR;   // 0x0C
	volatile unsigned int IDR;     // 0x10
	volatile unsigned int ODR;     // 0x14
	volatile unsigned int BSRR;    // 0x18
	volatile unsigned int LCKR;    // 0x1C 
	volatile unsigned int AFRL;    // 0x20 
	volatile unsigned int AFRH;    // 0x24
	volatile unsigned int BRR;     // 0x28
	volatile unsigned int res;
	volatile unsigned int SECCFGR; // 0x30

}gpio_t;

#define  GPIOA   ((gpio_t *)0x50002000)
#define  GPIOB   ((gpio_t *)0x50003000)
#define  GPIOC   ((gpio_t *)0x50004000)
#define  GPIOD   ((gpio_t *)0x50005000)
#define  GPIOE   ((gpio_t *)0x50006000)
#define  GPIOF   ((gpio_t *)0x50007000)
#define  GPIOG   ((gpio_t *)0x50008000)
#define  GPIOH   ((gpio_t *)0x50009000)
#define  GPIOI   ((gpio_t *)0x5000A000)
#define  GPIOJ   ((gpio_t *)0x5000B000)
#define  GPIOK   ((gpio_t *)0x5000C000)
#define  GPIOZ   ((gpio_t *)0x54004000)

#define LED1_ON _IOW('l',11,int)
#define LED1_OFF _IOW('l',10,int)
#define LED2_ON _IOW('l',21,int)
#define LED2_OFF _IOW('l',20,int)
#define LED3_ON _IOW('l',31,int)
#define LED3_OFF _IOW('l',30,int)
#define FAN_ON _IOW('f',1,int)
#define FAN_OFF _IOW('f',0,int)
#define BUZ_ON _IOW('b',1,int)
#define BUZ_OFF _IOW('b',0,int)
#define MOT_ON _IOW('m',1,int)
#define MOT_OFF _IOW('m',0,int)
#endif
相关推荐
数据的世界012 小时前
.NET开发人员学习书籍推荐
学习·.net
四口鲸鱼爱吃盐2 小时前
CVPR2024 | 通过集成渐近正态分布学习实现强可迁移对抗攻击
学习
Uu_05kkq2 小时前
【C语言1】C语言常见概念(总结复习篇)——库函数、ASCII码、转义字符
c语言·数据结构·算法
OopspoO4 小时前
qcow2镜像大小压缩
学习·性能优化
嵌入式科普4 小时前
十一、从0开始卷出一个新项目之瑞萨RA6M5串口DTC接收不定长
c语言·stm32·cubeide·e2studio·ra6m5·dma接收不定长
A懿轩A5 小时前
C/C++ 数据结构与算法【栈和队列】 栈+队列详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·栈和队列
居居飒5 小时前
Android学习(四)-Kotlin编程语言-for循环
android·学习·kotlin
kkflash35 小时前
提升专业素养的实用指南
学习·职场和发展
1 9 J6 小时前
数据结构 C/C++(实验五:图)
c语言·数据结构·c++·学习·算法
仍然探索未知中7 小时前
C语言经典100例
c语言