Instance 2-learning interruption from the RTC device (System Real-time clock)

Source: Internet
Author: User
Document directory
  • RTC interrupt service program

Reprint address (this article is also reproduced): http://blog.chinaunix.net/uid-15443744-id-2772596.html

 

 

Each pc has a Real-Time Clock device. When you turn off the computer power, it maintains the system's date and time information.

In addition, it can also be used to generate periodic signals with a frequency change ranging from 2Hz to 8192Hz -- of course, the frequency must be a multiple of 2. In this way, the device can be used as a timer. For example, if we set the frequency to 4Hz, after the device is started, the system's real clock sends four scheduled signals per second to the CPU, which are submitted to the system through the interruption of the 8 th (the IRQ 8 of the standard PC is set in this way ). Since the real-time clock of the system is programmable, you can also set it as an alarm to trigger an alarm at a specific time-send an IRQ 8 interrupt signal to the system. From this point of view, IRQ 8 is similar to the alarm in life: the interrupt signal represents the occurrence of an alarm or timer.

In the Linux operating system, the above interrupt signal can be obtained through the/dev/rtc (master device number 10, from device number 135, read-only character device) device. After the read operation is performed on the device, the returned value of the unsigned long type is obtained. The lowest byte indicates the type of interruption (update-done after update), which is scheduled to reach alarm-rang, cycle signal periodic); the remaining bytes contain the number of times the last read operation was interrupted. If the system supports the/proc file system, the same status information can also be reflected in/proc/driver/rtc.

This device can only be exclusive to each process. That is to say, after a process opens the device, other processes are not allowed to open it before it is released. In this way, your program can monitor the interruption by executing read () or select () system calls to/dev/RTC-the user process will be blocked, until the system receives the next interruption signal. For some high-speed data collection programs, this function is very useful, and the program does not have to stick to repeated queries, consuming all CPU resources; as long as you set it up, you can query it at a certain frequency.

# Include <stdio. h>

# Include <Linux/RTC. h>

# Include <sys/IOCTL. h>

# Include <sys/time. h>

# Include <sys/types. h>

# Include <fcntl. h>

# Include <unistd. h>

# Include <errno. h>

Int main (void)

{

Int I, FD, retval, irqcount = 0;

Unsigned long TMP, data;

Struct rtc_time rtc_tm;

// Enable the RTC Device

FD = open ("/dev/RTC", o_rdonly );

If (FD =-1 ){

Perror ("/dev/RTC ");

Exit (errno );

}

Fprintf (stderr, "\ n \ t \ tEnjoy TV while boiling water. \ n ");

// The first example is an alarm. Set the alarm to "ring the bell" 10 minutes later"

// Obtain the current date and time information saved in RTC

/* Read the RTC time/date */

Retval = ioctl (fd, RTC_RD_TIME, & rtc_tm );

If (retval =-1 ){

Perror ("ioctl ");

Exit (errno );

}

Fprintf (stderr, "\ n \ nCurrent RTC date/time is % d-% d, % 02d:

% 02d: % 02d. \ n ",

Rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900,

Rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec );

// Avoid overflow when setting the time

Rtc_tm.tm_min + = 10;

If (rtc_tm.tm_sec> = 60 ){

Rtc_tm.tm_sec % = 60;

Rtc_tm.tm_min ++;

}

If (rtc_tm.tm_min = 60 ){

Rtc_tm.tm_min = 0;

Rtc_tm.tm_hour ++;

}

If (rtc_tm.tm_hour = 24)

Rtc_tm.tm_hour = 0;

// Actual settings

Retval = ioctl (fd, RTC_ALM_SET, & rtc_tm );

If (retval =-1 ){

Perror ("ioctl ");

Exit (errno );

}

// Check to see if the setting is successful.

/* Read the current alarm settings */

Retval = ioctl (fd, RTC_ALM_READ, & rtc_tm );

If (retval =-1 ){

Perror ("ioctl ");

Exit (errno );

}

Fprintf (stderr, "Alarm time now set to % 02d: % 02d: % 02d. \ n ",

Rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec );

// If the light setting is not complete, you must enable the alarm type interrupt.

/* Enable alarm interrupts */

Retval = ioctl (fd, RTC_AIE_ON, 0 );

If (retval =-1 ){

Perror ("ioctl ");

Exit (errno );

}

// Now the program can sleep patiently. It will be awakened when it is interrupted in 10 minutes.

/* This blocks until the alarm ring causes an interrupt */

Retval = read (fd, & data, sizeof (unsigned long ));

If (retval =-1 ){

Perror ("read ");

Exit (errno );

}

Irqcount ++;

Fprintf (stderr, "okay. Alarm rang. \ n ");

}

This example is a little complicated and uses open, ioctl, read, and many other system calls. It looks dazzling at the beginning. In fact, if it is simplified, the process is still "Boiling Water": set the timer, wait for the timer to time out, and execute the corresponding operations ("off the gas stove ").

What readers may not understand is: This example shows the benefits of interruptions. During the 10-minute timeout process, the program can only sleep?

Readers need to pay attention to their own perspectives. We say that interruptions can improve the concurrent processing capability and improve the CPU's concurrent processing capability. Here, the above program can be regarded as boiling water. before boiling water, the alarm has been well performed, and the CPU will be interrupted (with an alarm) after 10 minutes, come and execute the subsequent gas close work. That is to say, the CPU is the only subject with processing capabilities. We take the initiative to use the interrupt mechanism in the program to save CPU consumption and improve the concurrent processing capability of the CPU. What are the benefits? Imagine if we still need CPU to bake, the CPU will be able to complete the corresponding work, and other work will be the same. This is actually the moral foundation for program survival in a multi-task operating system environment-"I am for everyone, everyone is for me ".

Well, this program is actually an introduction to the Linux interrupt mechanism. Now we are in the Linux interrupt world.

For more details and other precautions, see Documentations/rtc.txt in the kernel source code package.



 

RTC interrupt service program

The RTC interrupt service program contains driver/char/rtc under the root directory of the kernel source code. in the c file, this file is the driver of the RTC device-we once mentioned that the interrupt service program is generally provided by the device driver to implement the unique operation of the device interrupt.

The steps for registering an interrupt in SagaLinux are equally rare in Linux. In fact, the principles of the two are slightly different, linux uses more complex implementation methods to solve a large number of practical problems (such as SMP support and interrupted sharing.

When the RTC driver is loaded, the rtc_init () function is called to initialize the driver. An important role of this function is to register the interrupt handler:

if (request_irq(RTC_IRQ,rtc_interrupt,SA_INTERRUPT,”rtc”,NULL)){
   printk(KERN_ERR “rtc:cannot register IRQ %d\n”,rtc_irq);
return –EIO;
}

This request_irq function is obviously much more complex than the function with the same name in SagaLinux. Just look at the number of parameters. However, there is no difference between the first two parameters. It can be inferred that their main functions are to bind the interrupt number to the interrupt service program.

Many books provide detailed descriptions of interrupt-related functions provided by Linux to system programmers, such as "Linux Kernel Development ". I will not repeat the work here, and now I am focusing on interrupting the service program itself.

Static
Irqreturn_t
Rtc_interrupt (int
Irq, void * dev_id,

Struct
Pt_regs * regs)

{

/*

* Can be an alarm interrupt, update complete interrupt,

* Or a periodic interrupt. We store the status in

* Low byte and the number of interrupts encoded ed since

* The last read in the remainder of rtc_irq_data.

*/

Spin_lock (& rtc_lock );

Rtc_irq_data + = 0x100;

Rtc_irq_data & = ~ 0xff;

Rtc_irq_data | = (CMOS_READ (RTC_INTR_FLAGS)
& 0xF0 );

If (rtc_status & RTC_TIMER_ON)

Mod_timer (& rtc_irq_timer,

Jiffies + HZ/rtc_fre

Q

+ 2 * HZ/100 );

Spin_unlock (& rtc_lock );

/* Now do the rest of the actions */

Spin_lock (& rtc_task_lock );

If (rtc_callback)

Rtc_callback-> func (rtc_callback-> private_data );

Spin_unlock (& rtc_task_lock );

Wake_up_interruptible (& rtc_wait );

Kill_fasync (& rtc_async_queue, sigio, poll_in );

Return irq_handled;

}

Here, we should first remind readers that the interrupted service program is of the static type. That is to say, this function is a local function and can only be called in the RTC. c file. How is this possible? Based on our experience gained from sagalinux, when the interruption arrives, the core code of the OS interrupt will certainly call this function. Otherwise, what is the significance of this function? In fact, the request_irq function registers the pointer pointing to this function to the corresponding query table (remember irq_handler [] In sagalinux ?). Static can only ensure that code other than the RTC. c file cannot explicitly call a function through the function name, but it cannot be hard to draw a pointer.

The program uses the spin_lock function, which is a spin lock function provided by Linux. For details about the spin lock, we will introduce it in future articles. Remember that the spin lock is used to prevent other CPUs in the SMP structure from accessing data concurrently. The protected data here is rtc_irq_data. Rtc_irq_data stores information about RTC, which is updated each time it is interrupted to reflect the interrupted status.

Next, if the RTC periodic timer is set, update it through the mod_timer () function. Timer is a very important concept in the Linux operating system. We will explain it in detail in future articles.

The last part of the Code should be protected by setting the spin lock, which will execute a callback function that may be preset. The RTC driver allows you to register a callback function and execute it when every RTC is interrupted.

Wake_up_interruptible is a very important call. After it is executed, the system will wake up the sleeping processes and the RTC interruption they are waiting for will arrive. This part involves waiting for the queue. We will also explain it in a later article.

Experience RTC-the simplest change

We can further feel the interruption, which is very simple. We need to add a printk statement to the RTC interrupt service program and print what? "I'm
Coming, interrupt !".

Next, we will add it:

......

Spin_unlock (& rtc_task_lock );

Printk ("I'm coming, interrupt! \ N ");

Wake_up_interruptible (& rtc_wait );

......

That's right. Just do this first. Please find the drivers \ char \ rtc. c file of the code tree and add this printk statement to the irqreturn_t rtc_interrupt function. Then re-compile the kernel module (of course, you need to include RTC When configuring the kernel compilation option, and in the form of a module). Now, when we insert the compiled rtc. o module, execute the user space program described in the previous real-time clock section, and you will see the "I'm" printed on the screen
Coming, interrupt !" Information.

This is a real process of service interruption. If we change the running mode of the RTC device through ioctl and set the periodic interruption, let's assume that the frequency is located at 8 HZ, you will find that the information is printed eight times per second on the screen.

Modifying RTC is actually the most intuitive way to understand the interrupt. I suggest you not only interrupt the service program, but also take a look at the implementation of ioctl In the RTC driver, in this way, you will be more familiar with the actual interaction between external devices and drivers and interrupt service programs.

In addition, by modifying the RTC driver, I have done a lot of strange work, for example, in the high-speed data collection process, I used high-frequency RTC interruptions to check the hardware buffer usage of the high-speed AD sampling board, and cooperated with DMA to complete data collection. Of course, this is not necessarily applicable when there are very strict time limits. However, when two 12-bit, 20-gigabit sampling rate adcards work alternately, and one kHz radar video data is continuously sampled per second, my RTC runs quite well.

Of course, this may not be a beautiful and standard practice. However, I am only a programmer, not an artist. I just learned a little bit about interruptions and I finished my work, I think maybe you want to get the benefits from the secrets at the bottom of the system. Let's see you later.

[1] Isn't PowerOff counted as an interruption? Literally speaking, it must be in line with the definition of interruptions in Chinese. However, from the aspect of Signal Format and processing method, it is very difficult to meet our understanding. What Does Intel say? The interrupt does not adopt a general interrupt processing mechanism. So what is the interruption from time to time? I cannot say that :(

[2] compilation rather than C is used to implement these functions because the C compiler pushes additional stack information into the function implementation. However, when the CPU is interrupted, temporary storage and recovery are performed in strict format, and the change of one byte is not allowed.

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.