21 static struct class *drv_class = NULL;
22 static struct class_device *drv_class_dev = NULL;
twenty three
24 //Register base address;
25 static unsigned long base_iomux; //iomux base address 0X 43FA C000 - 0X 43FA FFFF
26 static unsigned long base_gpio3; //gpio3 0X 53FA 4000 - 0X 53FA 7FFF
27 //MUX_CTL mode selection configuration register
28 #define MUX_CTL (*(volatile unsigned long *)(base_iomux + 0x0060))
29 //PAD_CTL GPIO common function settings
30 #define PAD_CTL (*(volatile unsigned long *)(base_iomux + 0x0270))
31 //GPIO DR data register DR
32 #define DR_GPIO3 (*(volatile unsigned long *)(base_gpio3 + 0x0000))
33 // GPIO GDIR direction control register GDIR
34 #define GDIR_GPIO3 (*(volatile unsigned long *)(base_gpio3 + 0x0004))
35
36
37 extern int myprintk(const char *fmt, ...);
38
39 static int key_open(struct inode *inode, struct file *file)
40 {
41 myprintk("<0>function open!nn");
42 return 0;
43 }
44
45 static int key_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)
46 {
47 return 0;
48 }
49
50 static ssize_t key_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
51 {
52 myprintk("<0>function write!nn");
53 return 1;
54 }
55
56 static int key_release(struct inode *inode, struct file *filp)
57 {
58 myprintk("<0>function write!nn");
59 return 0;
60 }
61
62 static int key_ioctl(struct inode *inode,struct file *flip,unsigned int command,unsigned long arg)
63 {
64 myprintk("<0>function ioctl!nn");
65 return 0;
66 }
67 static struct file_operations key_fops = {
68 .owner = THIS_MODULE, /* This is a macro that pushes to the __this_module variable that is automatically created when compiling the module*/
69 .open = key_open,
70 .read = key_read,
71 .write = key_write,
72.release= key_release,
73 .ioctl = key_ioctl,
74 };
75
76 void gpio_addr(void){
77 myprintk("<0>addr base_iomux : %x n",base_iomux);
78 myprintk("<0>addr base_gpio3 : %x n",base_gpio3);
79 myprintk("<0>addr MUX_CTL : %x n",&MUX_CTL);
80 myprintk("<0>addr PAD_CTL : %x n",&PAD_CTL);
81 myprintk("<0>addr GDIR_GPIO3 : %x n",&GDIR_GPIO3);
82 myprintk("<0>addr DR_GPIO3 : %x n",&DR_GPIO3);
83 }
84
85 void led_on_off(void){
86 ssleep(1);
87 DR_GPIO3 |= (0x01 << 23); //Set GPIO2_23 to 1
88 ssleep(1);
89 DR_GPIO3 &= ~(0x01 << 23); // Clear GPIO2_23
90 ssleep(1);
91 DR_GPIO3 |= (0x01 << 23); //Set GPIO2_23 to 1
92 ssleep(1);
93 DR_GPIO3 &= ~(0x01 << 23); // Clear GPIO2_23
94 ssleep(1);
95 DR_GPIO3 |= (0x01 << 23); //Set GPIO2_23 to 1
96 ssleep(1);
97 DR_GPIO3 &= ~(0x01 << 23); // Clear GPIO2_23
98 ssleep(1);
99 DR_GPIO3 |= (0x01 << 23); //Set GPIO2_23 to 1
100 ssleep(1);
101 DR_GPIO3 &= ~(0x01 << 23); //Clear GPIO2_23
102 ssleep(1);
103 DR_GPIO3 |= (0x01 << 23); //Set GPIO2_23 to 1
104 }
105
106 static int __init key_irq_init(void)
107 {
108 myprintk("<0>nHello,this is %s module!nn",Driver_NAME);
109 //register and mknod
110 major = register_chrdev(0,Driver_NAME,&key_fops);
111 drv_class = class_create(THIS_MODULE,Driver_NAME);
112 drv_class_dev = device_create(drv_class,NULL,MKDEV(major,0),NULL,DEVICE_NAME); /*/dev/key_query*/
113
114 //IO port application ioremap can directly access these addresses through pointers
115 base_iomux = ioremap(0x43FAC000,0xFFF);
116 base_gpio3 = ioremap(0x53FA4000,0xFFF);
117
118 //MUX_CTL
119 MUX_CTL &= ~(0x07 << 0);
120 MUX_CTL |= (0X05 << 0); //Set to ALT5 GPIO3_23 ERR_LED
121 //PAD_CTL
122 PAD_CTL &= ~(0x01<<13 | 0x01<<3 | 0x03<<1 | 0x01<<0); //1.8v does not require pull-up or pull-down CMOS output slew rate
123 //GDIR_GPIO3 is configured as output mode
124 GDIR_GPIO3 &= ~(0x01 << 23);
125 GDIR_GPIO3 |= (0x01 << 23); //Configure to output mode
126
127 //DR_GPIO3 is configured as output 0 to light up ERR_LED
128 DR_GPIO3 &= ~(0x01 << 23); // Clear GPIO2_23
129 DR_GPIO3 &= ~(0x01 << 23); // Clear GPIO2_23
130 gpio_addr();
131 led_on_off();
132 return 0;
133 }
134
135 static void __exit key_irq_exit(void)
136 {
137 gpio_addr();
138 myprintk("<0>nGoodbye,%s!nn",Driver_NAME);
139 led_on_off();
140
141 unregister_chrdev(major,Driver_NAME);
142 device_unregister(drv_class_dev);
143 class_destroy(drv_class);
144
145 //Release IO port
146 iounmap(base_iomux);
147 iounmap(base_gpio3);
148 }
149
150
151 /* These two lines specify the driver's initialization function and uninstallation function*/
152 module_init(key_irq_init);
153 module_exit(key_irq_exit);
154
155 /* Describes some information about the driver, not required*/
156 MODULE_AUTHOR("Lover Cher");
157 MODULE_VERSION("0.1.0");
158 MODULE_DESCRIPTION("IMX257 key Driver");
159 MODULE_LICENSE("GPL");
OK, it's done.
The advantage of doing this is that we can concentrate the printing information of a certain driver in a certain file, so that the printing information will not be affected by other drivers, which is convenient for subsequent debugging.
Previous article:Debug analysis: PC pointer analysis error based on kernel error information
Next article:iMX257 pin configuration function/memory read and write function
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- CGD and Qorvo to jointly revolutionize motor control solutions
- CGD and Qorvo to jointly revolutionize motor control solutions
- Keysight Technologies FieldFox handheld analyzer with VDI spread spectrum module to achieve millimeter wave analysis function
- Infineon's PASCO2V15 XENSIV PAS CO2 5V Sensor Now Available at Mouser for Accurate CO2 Level Measurement
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- A new chapter in Great Wall Motors R&D: solid-state battery technology leads the future
- Naxin Micro provides full-scenario GaN driver IC solutions
- Interpreting Huawei’s new solid-state battery patent, will it challenge CATL in 2030?
- Are pure electric/plug-in hybrid vehicles going crazy? A Chinese company has launched the world's first -40℃ dischargeable hybrid battery that is not afraid of cold
- Industrial Communication Issues with the AMIC110 SoC
- Analysis Example: A Zener Diode Regulator Circuit
- Comparison of CC2540 and nRF51822 application development
- [Evaluation of Anxinke Bluetooth Development Board PB-02-Kit] Light up the LED
- 6. Voltage-divided bias common emitter amplifier circuit
- MSP430F6638 MCU FLL——Frequency Locked Loop
- Bluetooth packaging problem
- 【Qinheng Trial】Five final chapters--IoT system based on CH549
- What should you pay attention to when purchasing encryption chips?
- What exactly is op amp noise?