First, we will introduce the locations of some required header files
linux-2.6.32. Important kernel file directory:
linux-2.6.32.2/arch/arm/mach-s3c2410/include/mach/regs-gpio.h
linux-2.6.32.2/arch/arm/plat-s3c24xx/gpio.c
linux-2.6.32.2/linux/asm-generic/io.h
linux-2.6.32.2/include/linux/wait.h
asm -- linux-2.6.32.2/linux/asm-generic
mach -- linux-2.6.32.2/arch/arm/mach-s3c2410/include/mach
plat -- linux-2.6.32.2/arch/arm/plat-s3c24xx/include/plat
-- linux-2.6.32.2/arch/arm/plat/include/plat
1. 2440 buzzer core driver
Display kernel driver
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
static int beep_major = 0;
module_param(beep_major, int, 0); // parameter transfer function, and generate parameter directory and parameter file in the module directory
/*
MODULE_AUTHOR (declares who wrote the module),
MODULE_DESCRIPION (a human-readable description of what the module does),
MODULE_VERSION (a code revision number; see the comments in
MODULE_ALIAS (another name by which the module is known), and MODULE_DEVICE_TABLE (to tell userspace which devices the module supports).
MODULE_LICENSE(“GPL”);
The specific licenses recognized by the kernel are "GPL" (any version of the GNU General Public License applies), "GPL v2" (only version 2 of the GPL applies), "GPL and additional rights", "Dual BSD/GPL", "Dual MPL/GPL", and "Proprietary". Unless your module is explicitly marked as being under a free license recognized by the kernel, it is assumed to be proprietary.
*/
MODULE_AUTHOR("All");
MODULE_LICENSE("Dual BSD/GPL");
#define BEEP_MAGIC 'b'
#define BEEP_START_CMD _IO (BEEP_MAGIC, 1) //Use the _IO function provided by the kernel function library, and refer to the reference for details
#define BEEP_STOP_CMD _IO (BEEP_MAGIC, 2)
/*
* Open the device; in fact, there's nothing to do here.
*/
int beep_open (struct inode *inode, struct file *filp)
{
return 0;
}
ssize_t beep_read(struct file *file, char __user *buff, size_t count, loff_t *offp)
{
return 0;
}
ssize_t beep_write(struct file *file, const char __user *buff, size_t count, loff_t *offp)
{
return 0;
}
//Generally, functions like read and write do not write anything, but open sometimes puts an initialization function
/*
Use the s3c2410_gpio_cfgpin function to initialize the port and set it as output. Use s3c2410_gpio_setpin to set the port output high and low voltages. Set the output voltage you need according to the development manual. s3c2410_gpio_pullup controls the pull-up resistor.
*/
void beep_stop( void )
{
//set GPB0 as output
s3c2410_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPIO_OUTPUT);
s3c2410_gpio_setpin(S3C2410_GPB(0),0);
}
void beep_start( void )
{
//set GPB0 as output
s3c2410_gpio_pullup(S3C2410_GPB(0),1);
s3c2410_gpio_cfgpin(S3C2410_GPB(0), S3C2410_GPIO_OUTPUT);
s3c2410_gpio_setpin(S3C2410_GPB(0),1);
}
/*Function call, using ioctl to select the kernel function to call through different cmd numbers*/
static int beep_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
//add your src HERE!!!
switch ( cmd ) {
case BEEP_START_CMD: {
beep_start(); break;
}
case BEEP_STOP_CMD: {
beep_stop(); break;
}
default: {
break;
}
}
return 0;
}
static int beep_release(struct inode *node, struct file *file)
{
return 0;
}
/*
* Set up the cdev structure for a device.
*/
static void beep_setup_cdev(struct cdev *dev, int minor,
struct file_operations *fops)
{
int err, devno = MKDEV(beep_major, minor);
cdev_init(dev, fops);
//Register the device, or should I say initialize it
dev->owner = THIS_MODULE;
dev->ops = fops;
err = cdev_add(dev, devno, 1);
//Failed to add device to kernel, after linux-2.6, two functions are used to register and add
if (err)
printk (KERN_NOTICE "Error %d adding beep%d", err, minor);
}
/*
file_operations structure
Linux uses the file_operations structure to access the driver's functions. The name of each member of this structure corresponds to a function call.
When the user process performs operations such as read/write on the device file, the system call finds the corresponding device driver through the major device number of the device file, then reads the corresponding function pointer of this data structure, and then transfers control to the function. This is the basic principle of how Linux device drivers work.
struct module *owner
The first file_operations member is not an operation at all, it is a pointer to the module that owns the structure. This member is used to prevent the module from being unloaded while its operations are still being used. Almost all of the time, it is simply initialized to THIS_MODULE, a macro defined in
https://blog.csdn.net/zqixiao_09/article/details/50850475
*/
static struct file_operations beep_remap_ops = {
.owner = THIS_MODULE,
.open = beep_open,
.release = beep_release,
.read = beep_read,
.write = beep_write,
.ioctl = beep_ioctl,
};
/*
* There's no need for us to maintain any
* special housekeeping info, so we just deal with raw cdevs.
*/
static struct cdev BeepDevs;
/*
* Module housekeeping.
*/
/*beep_init function is mainly used to obtain the device number for kernel identification*/
static int beep_init(void)
{
int result;
dev_t dev = MKDEV(beep_major, 0);
//Format conversion, beep_major is the major device number, which is passed when calling the driver, and the default is 0
char dev_name[]="beep";
/* Figure out our device number. */
if (beep_major)
result = register_chrdev_region(dev, 1, dev_name);
//Manually assign the registered device number. If the device number has not been assigned before, beep_major is 0, so the dynamic allocation device number is called for registration. However, after the kernel assigns beep_major to 0, this function will be called. In other words, the function is used only when the major device number is known.
else {
result = alloc_chrdev_region(&dev, 0, 1, dev_name);
beep_major = MAJOR(dev);
//Dynamically assign registered device numbers and update primary device numbers. For details, see https://blog.csdn.net/welbell_uplooking/article/details/83654312
}
if (result < 0) {
printk(KERN_WARNING "beep: unable to get major %dn", beep_major);
return result;
}
if (beep_major == 0)
beep_major = result;
/* Now set up cdev. */
beep_setup_cdev(&BeepDevs, 0, &beep_remap_ops);
printk("beep device installed, with major %dn", beep_major);
printk("The device name is: %sn", dev_name);
return 0;
}
static void beep_cleanup(void)
{
cdev_del(&BeepDevs);
//Unregister the device and delete a cdev
unregister_chrdev_region(MKDEV(beep_major, 0), 1);
//Release the device number occupied by the logout
printk("beep device uninstalledn");
}
module_init(beep_init);
module_exit(beep_cleanup);
//Driver loading system parameter transfer
EXPORT_SYMBOL(beep_major);
Loading the driver module
insmod beep_dev.ko
Create the beep device file under dev and bind it to our beep_dev driver
mknod /dev/beep c 251 0
Original command format: mknod /dev/node_name c major minor
Only when the beep file is created can the user access it through operations such as open or call the kernel driver function.
2. 2440 buzzer user function
The second is the application layer function outside the buzzer core
#include
#include
#include
#include
#include
#define BEEP_MAGIC 'b'
#define BEEP_START_CMD _IO (BEEP_MAGIC, 1)
#define BEEP_STOP_CMD _IO (BEEP_MAGIC, 2)
int main()
{
int i = 0;
int dev_fd;
dev_fd = open("/dev/beep",O_RDWR | O_NONBLOCK);
if ( dev_fd == -1 ) {
printf("Cann't open file /dev/beepn");
exit(1);
}
printf("Start beepn");
ioctl (dev_fd, BEEP_START_CMD,0);
getchar();
ioctl (dev_fd, BEEP_STOP_CMD,0);
printf("Stop beep and Close devicen");
close(dev_fd);
return 0;
}
The relationship is roughly as follows:
Previous article:TQ2440--nandflash (K9F2G08U0A) driver writing
Next article:S3C2440 SPI driver framework
- Popular Resources
- Popular amplifiers
- 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
- Pickering Launches New Future-Proof PXIe Single-Slot Controller for High-Performance Test and Measurement Applications
- Apple faces class action lawsuit from 40 million UK iCloud users, faces $27.6 billion in claims
- Apple faces class action lawsuit from 40 million UK iCloud users, faces $27.6 billion in claims
- The US asked TSMC to restrict the export of high-end chips, and the Ministry of Commerce responded
- The US asked TSMC to restrict the export of high-end chips, and the Ministry of Commerce responded
- ASML predicts that its revenue in 2030 will exceed 457 billion yuan! Gross profit margin 56-60%
- Detailed explanation of intelligent car body perception system
- How to solve the problem that the servo drive is not enabled
- Why does the servo drive not power on?
- What point should I connect to when the servo is turned on?
- Sound Level Meter MASTECH MS6700 Disassembly Pictures and Information
- Design of Multi-channel Data Acquisition System Based on CPLD
- It's so tiring to work under a fool!
- Could you please tell me what glue is used to stick piezoelectric ceramic sheets to ultrasonic sensors?
- Let's talk about what technologies we can use to help in the face of this pneumonia virus? ? ?
- EEWORLD University Hall----C2000 series new products bring convenience to servo and motor drive systems
- [GD32E231 DIY Contest] 01. GD32E231-start and creative content introduction
- Wireless positioning principle: TOA&AOA
- Old Iron
- What are the losses in transformers? Explain eddy current, hysteresis, leakage flux, etc.