arm-linux spin lock

Precautions for using spin locks:
①. The critical area protected by the spin lock should be as short as possible , so apply for the spin lock in the open function, and then in the release function
The method of releasing the spin lock in the number is not advisable. We can use a variable to represent the usage of the device, if the device is
If it is used, the variable will be incremented by one, and the variable will be decremented by one after the device is released . We only need to use the spin lock to protect this variable that is
Can.
②. Consider the compatibility of the driver and choose the API function reasonably .
To sum up, in this section of the routine, we define a variable dev_stats to indicate the usage of the device, dev_stats
When it is 0 , it means that the device is not used, and when dev_stats is greater than 0 , it means that the device is used. In the driver open function first
Determine whether dev_stats is 0 , that is, determine whether the device is available, if it is 0 , use the device, and set dev_stats
Add 1 to indicate that the device is in use. After use, decrement dev_stats by 1 in the release function , indicating that the device is not used
up. Therefore, it is the variable dev_stats that actually realizes mutual exclusive access to the device , but we need to use a spin lock to protect dev_stats
protect.
Device structure:
/* gpioled device structure */
34 struct gpioled_dev {
35 dev_t devid ; /* device number */
36 struct cdev cdev ; /* cdev */
37 struct class * class ; /* */
38 struct device * device ; /* device */
39 int major ; /* Major device number */
40 int minor ; /* minor device number */
41 struct device_node * nd ; /* device node */
42 int led_gpio ; /* GPIO number used by led */
43 int dev_stats ; /* Device status, 0 , the device is not used ; >0, the device has been used */
44 spinlock_t lock ; /* spin lock */
45 };
open function:
spin_lock_irqsave (& gpioled . lock , flags ); /* 上锁 *
/* Call the spin_lock_irqsave function to obtain
To take the lock, in order to consider the driver compatibility, the spin_lock function is not used to acquire the lock. */
if ( gpioled . dev_stats ) { /* if the device is used
spin_unlock_irqrestore (& gpioled . lock , flags ); /* 解锁 */
return - EBUSY ;
}
gpioled . dev_stats ++; /* If the device is not open, then mark it is open */ spin_unlock_irqrestore (& gpioled . lock , flags ); /* unlock */ *
Determine whether dev_stats is greater than 0 , if yes, it means that the device has been used, then call the spin_unlock_irqrestore function to release the lock, and return -EBUSY . If the device is not in use, add 1 to dev_stats on line 66 , indicating that the device is about to be used, and then call the spin_unlock_irqrestore function to release the lock. The job of the spin lock is to protect the dev_stats variable, and it is dev_stats that actually realizes mutual exclusive access to the device .

release function:
/* Decrease dev_stats by 1 when closing the driver file */
spin_lock_irqsave (& dev -> lock , flags ); /* lock */
if ( dev -> dev_stats )
{ dev -> dev_stats --; }
spin_unlock_irqrestore (& dev -> lock , flags ); /* unlock */
Decrease dev_stats by 1 , indicating that the device is released and can be used by other applications. When decrementing dev_stats by 1 , a spin lock is required to protect it.
init function:
/* Initialize the spinlock */ spin_lock_init (& gpioled . lock );

Guess you like

Origin blog.csdn.net/L1153413073/article/details/125548087