1.Principles of Linux Kernel Timers
1.1Kernel Time Management
1.The Cortex-M kernel uses systick as the system timer.
2.Hardware timers and software timers rely on the system timer for operation.
3.The frequency of the Linux kernel can be configured through a graphical interface. By opening the .config file in the root directory of the Linux kernel source code, you can see the configuration of CONFIG_HZ.
4.The Linux kernel uses CONFIG_HZ to set its system clock. You can view this in the file include/asm-generic/param.h.
5.Importantly, HZ represents the system tick rate.
1.2. Defects of High and Low Tick Rates
A high tick rate increases the precision of system time. For example, with a tick rate of 100Hz, the time precision is 10ms, while at 1000Hz, the precision is 1ms, improving precision by a factor of 10. However, frequent interrupts can lead to increased CPU processing, though this is generally manageable with modern CPUs.
1.3Jiffies
1.The Linux kernel uses a global variable jiffies to record the number of system ticks since boot. At system startup, jiffies is initialized to 0, and jiffies is defined in the file include/linux/jiffies.h. HZ indicates the number of ticks per second, so jiffies/HZ represents the system uptime in seconds.
2.There is a risk of overflow for jiffies, which will reset to 0 after overflowing, a phenomenon also referred to as wrapping. This needs to be handled, and there are specific API functions available for this purpose.
3.The Linux kernel provides several conversion functions between jiffies and ms, us, and ns.
1.4Kernel Timers
1.Using kernel timers does not require extensive register initialization. Unlike hardware timers, software timers do not directly set a period value but rather specify a time point after the period expires.
3.Kernel timers do not run periodically; they automatically shut off after timing out. To implement periodic timing, the timer must be restarted in the timeout handler.
The Linux kernel uses the timer_list structure to represent kernel timers, which is defined in the file include/linux/timer.h.
2. The timeout handler is defined by adding a callback function after defining the timer_list structure. This allows the callback function to be executed when the timer expires.
1.5 Linux Kernel Short Delay Functions
void ndelay(unsigned long nsecs)
void udelay(unsigned long usecs)
void mdelay(unsigned long msecs)
2. Writing Experimental Drivers
1. Define a timer using the structure timer_list
2. Use the ioctl function -> unlocked_ioctl and compat_ioctl.
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long)
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
The ioctl commands are user-defined but must comply with Linux standards. Command construction:
#define _IO(type,nr)// Command with no parameters
#define _IOR(type,nr,size)// Command for reading data from the driver
#define _IOW(type,nr,size)// Command for writing data to the driver
#define _IOWR(type,nr,size)// Command for bidirectional data transfer
Type is a magic number, nr is the sequence number, and size is the size.
1. Steps for using the timer:
init_timer(&timerled.timer);/* Initialize the timer */
timerled.timer.function=timer_function;/* Timer callback function */
timerled.timer.expires=jiffies+msecs_to_jiffies(1000);/* Timer expiration time */
timerled.timer.data=(unsigned long)&timerled;/* Data to pass to the function */
add_timer(&timerled.timer);/* Start the timer */
2.int del_timer(struct timer_list * timer);/* Delete a timer */
The function parameters and return values are as follows:
Timer: The timer to be deleted.
Return value: 0 if the timer has not been activated; 1 if the timer has been activated.
3.int mod_timer(struct timer_list *timer, unsigned long expires);/* This function modifies the timer value. If the timer has not been activated, mod_timer will activate it. */
The function parameters and return values are as follows:
Timer: The timer whose expiration time (timer value) is to be modified.
Expires: The modified expiration time.
Return value: 0 if the timer was not activated before calling mod_timer; 1 if the timer was activated before calling mod_timer.
4. The ioctl function is used to control the timer (open, close, set timing period); the callback function is executed when the timer expires. In Linux, unlocked_ioctl corresponds to ioctl