Timer timer instance in Linux

Source: Internet
Author: User
The recent work involves processing specific actions after a certain period of time. For example, when pressing a button, you need to restart the system after pressing at least 4s, and then use a timer to ensure accurate timing. The following implementation can be universal. Struct timer_list OS _timer_t; // defines the timer # define OS _timer_func (_ FN) \ void _ FN (unsigned long timer_arg) # define OS _get_timer_arg (_ Arg, _ type) \ (_ Arg) = (_ type) (timer_arg) # define OS _init_timer (_ osdev, _ timer, _ FN, _ Arg) \ do {\ init_timer (_ timer); \ (_ timer) -> function = (_ FN); \ (_ timer)-> DATA = (unsigned long) (_ Arg); \} while (0) # define OS _set_timer (_ timer, _ MS) \ mod_timer (_ timer, jiffies + (_ MS) * Hz)/1000) # define OS _cancel_timer (_ timer) del_timer (_ timer) 1: initialization timer // initialization. The processing function is: timer (null, & OS _timer_t, wps_led_blink, & OS _timer_t); 2: start the Timer/set the timer OS _set_timer (& OS _timer_t, 1000); // set the timer to start after Ms. 3. Cancel the Timer: OS _cancel_timer (& OS _timer_t); 4: The timer processing function is defined as follows: static OS _timer_func (wps_led_blink) {static int wpsled = wps_led_on, SEC = 0; cancel, wpsled); wpsled =! Wpsled; OS _set_timer (& OS _timer_t, 1000);/* sec ++; If (SEC <130) {OS _set_timer (& OS _timer_t, 1000);} else {SEC = 0; handler = 0; OS _cancel_timer (& OS _timer_t); handler (wps_led_gpio, wps_led_off);} */} the preceding processing function shows that the wps_led_gpio output level is 1 s every 1000ms. Periodic flashes. The complete test code is as follows: # include <Linux/kernel. h> # include <Linux/module. h> # include <Linux/signal. h> # include <Linux/interrupt. h> # include <Linux/IRQ. h> # include <Linux/init. h> # include <Linux/resource. h> # include <Linux/proc_fs.h> # include <Linux/miscdevice. h> # include <ASM/types. h> # include <ASM/IRQ. h> # include <ASM/delay. h> # include <ASM/system. h> // ar7240.h (E: \ sdk_wlan_db12x \ SDK \ WLAN-AP \ Linux \ kernels \ mips-linux-2.6.31 \ Arch \ MIPS \ include \ ASM \ mach-ar7240) 407732011-12-1 # include <ASM/mach-ar7240/ar7240.h> # include <ASM/Mach-atheros/724x. h> # define defaults 0 # define then 1 # define then 0 # define simple_config_off 1 # define simple_config_on 2 # define simple_config_blink 3 typedef Enum {led_state_off = 1, led_state_on = 2, led_state_blinking = 3,} led_state_e; # define OS _timer_func (_ FN) \ void _ FN (unsigned L Ong timer_arg) # define OS _get_timer_arg (_ Arg, _ type) \ (_ Arg) = (_ type) (timer_arg) # define OS _init_timer (_ osdev, _ timer, _ FN, _ Arg) \ do {\ init_timer (_ timer); \ (_ timer)-> function = (_ FN); \ (_ timer)-> DATA = (unsigned long) (_ Arg) ;\} while (0) # define OS _set_timer (_ timer, _ MS) mod_timer (_ timer, jiffies + (_ MS) * Hz)/1000) # define OS _cancel_timer (_ timer) del_timer (_ timer) Static struct proc_dir_entry * s Imple_config_entry = NULL; static struct proc_dir_entry * simple_config_led_entry = NULL; static int primary = 0; struct timer_list OS _timer_t; static led_state_e primary = primary; void primary (INT gpio) {# ifdef config_wasp_support ar7240_reg_rmw_clear (ar7240_gpio_oe, (1 <gpio); # else events (ar7240_gpio_oe, (1 <gpio); # endif} void ar72 42_gpio_config_input (INT gpio) {# ifdef config_wasp_support partition (ar7240_gpio_oe, (1 <gpio); # else partition (ar7240_gpio_oe, (1 <gpio )); # endif} void ar7242_gpio_out_val (INT gpio, int Val) {If (Val & 0x1) {ar7240_reg_rmw_set (ar7240_gpio_out, (1 <gpio ));} else {ar7240_reg_rmw_clear (ar7240_gpio_out, (1 <gpio) ;}} int ar7242_gpio_in_val (INT gpio) {return (1 <gpio )&( Ar7240_reg_rd (rows);} static OS _timer_func (wps_led_blink) {static int wpsled = wps_led_on, SEC = 0; round (wps_led_gpio, wpsled); wpsled =! Wpsled; OS _set_timer (& OS _timer_t, 1000);/* sec ++; If (SEC <130) {OS _set_timer (& OS _timer_t, 1000);} else {SEC = 0; cursor = 0; OS _cancel_timer (& OS _timer_t); trim (wps_led_gpio, wps_led_off);} */} static int trim (char * Page, char ** start, off_t off, int count, int * EOF, void * Data) {return sprintf (page, "% d \ n", simple_config_led_state);} static int GPI O_simple_config_led_write (struct file * file, const char * Buf, unsigned Long Count, void * Data) {u_int32_t val = 0; If (sscanf (BUF, "% d ", & Val )! = 1) {return-einval;} If (val = simple_config_blink )&&! Rows)/* wps led blinking */{rows = 1; simple_config_led_state = simple_config_blink; rows (rows, wps_led_on); // values (null, & OS _timer_t, rows, & OS _timer_t ); OS _set_timer (& OS _timer_t, 1000);} else if (val = simple_config_on)/* WPS success */{struct = 0; struct = simple_config_on; struct (& OS _timer_t); Round (round, wps_led_on);} else if (val = simple_config_off)/* WPS failed */{round = 0; simple_config_led_state = simple_config_off; round (& OS _timer_t ); ar7242_gpio_out_val (wps_led_gpio, wps_led_off);} return count;} static int create_simple_config_led_proc_entry (void) {If (simple_config_entry! = NULL) {printk ("already have a proc entry for/proc/simple_config! \ N "); Return-enoent;} simple_config_entry = proc_mkdir (" simple_config ", null); If (! Simple_config_entry) Return-enoent; simple_config_led_entry = create_proc_entry ("simple_config_led", 0644, simple_config_entry); If (! Simple_config_led_entry) Return-enoent; simple_config_led_entry-> write_proc = Program; simple_config_led_entry-> read_proc = Program;/* configure gpio as outputs */queues (wps_led_gpio ); /* switch off the LED */trim (outputs, wps_led_off); OS _init_timer (null, & OS _timer_t, wps_led_blink, & OS _timer_t); OS _set_timer (& OS _t) Imer_t, 1000); // start the timer here. Return 0;} // ar7240_reg_rd (region) = 480fa // ar7240_reg_rd (region) = 4800a static int _ init init_ar7242_gpio_module (void) {unsigned int rddata; rddata = ar7240_reg_rd (ar7240_gpio_in_eth_switch_led); printk ("First: Reg 0x18040028 = % x \ n", rddata); rddata = rddata &(~ (0xf0); ar7240_reg_wr (ar7240_gpio_in_eth_switch_led, rddata); rddata = ar7240_reg_rd (bytes); printk ("Second: Reg 0x18040028 = % x \ n", rddata ); create_simple_config_led_proc_entry (); printk ("*** init_ar7242_gpio_module success *** \ n"); Return 0;} static void _ exit cleanup_ar7242_gpio_module (void) {printk ("% s (% s) line: % d \ n", _ file __, _ FUNC __,__ line _);} module_init (init_ar7242_g Pio_module); module_exit (modules); module_license ("GPL"); module_author ("Suiyuan from test"); module_description ("LED driver for atheros 7242 platform "); -------------------------- test code 2 ------------------------------------------ # include <Linux/kernel. h> # include <Linux/module. h> # include <Linux/signal. h> # include <Linux/interrupt. h> # include <Linux/IRQ. h> # include <Linux/init. h> # include <li Nux/resource. h> # include <Linux/proc_fs.h> # include <Linux/miscdevice. h >\# include <Linux/delay. h> # include <Linux/types. h> # include <ASM/types. h> # include <ASM/IRQ. h> # include <ASM/delay. h> # include <ASM/system. h> # include <ASM/Mach-atheros/724x. h> # include <ASM/mach-ar7240/ar7240.h> # define ath_factory_reset0x89abcdef # define button_gpio 11 # define udelay_count 8000000 # define button_minor 189 // # define ath_wd T_test_code # ifdef ath_wdt_test_code # define btdbg printk # else # define btdbg (junk ,...) # endif/* Listen 8 */typedef Enum {int_type_edge, int_type_level,} percent; typedef Enum {percent, int_pol_active_high,} percent; typedef struct {percent buttons_waitqueue;/* Wait queue, when no key is pressed, if a process calls the s3c24xx_buttons_read function, it will sleep */volatile int ev_press;/* interrupted Indicates the number of times the four buttons are pressed (accurately, is the number of interruptions) */struct timer_list button_timers;/* buttons delay timer */INT hour; int button_short_time; int hour;} buttons_dev_t;/* extern void hour (INT gpio, ar7240_gpio_int_type_t type, ar7240_gpio_int_pol_t polarity); extern void ar7240_gpio_config_output (in T gpio); extern void ar7240_gpio_config_input (INT gpio); extern void trim (INT gpio, int Val); extern int trim (INT gpio); */void ar7240_gpio_config_int (INT gpio, struct type, inclupolarity) {u32 val;/** allow edge sensitive/rising edge too */If (type = int_type_level) {/* level sensitive */struct (ar7240_gpio_int_type, (1 <Gpio);} else {/* edge triggered */val = ar7240_reg_rd (ar7240_gpio_int_type); Val & = ~ (1 <gpio); ar7240_reg_wr (ar7240_gpio_int_type, Val);} If (polarity = int_pol_active_high) {ar7240_reg_rmw_set (callback, (1 <gpio ));} else {val = ar7240_reg_rd (ar7240_gpio_int_polarity); Val & = ~ (1 <gpio); ar7240_reg_wr (values, Val);} ar7240_reg_rmw_set (ar7240_gpio_int_enable, (1 <gpio);} round (INT gpio) {# ifdef config_wasp_support partition (ar7240_gpio_oe, (1 <gpio); # else partition (ar7240_gpio_oe, (1 <gpio); # endif} partition (INT gpio) {# ifdef config_wasp_support ar7240_reg_rmw_set (ar7240_gpio_oe, (1 <<Gpio); # else ar7240_reg_rmw_clear (ar7240_gpio_oe, (1 <gpio); # endif} encode (INT gpio, int Val) {If (Val & 0x1) {round (ar7240_gpio_out, (1 <gpio);} else {ar7240_reg_rmw_clear (ar7240_gpio_out, (1 <gpio) ;}} round (INT gpio) {return (1 <gpio) & (ar7240_reg_rd (ar7240_gpio_in);} static buttons_dev_t buttons_dev = {. ev_press = 0 ,. press_cnt = 0 ,. B Utton_short_time = 0 ,. struct = 1 ,}; struct timer_list OS _timer_t; # define OS _timer_func (_ FN) \ void _ FN (unsigned long timer_arg) # define OS _get_timer_arg (_ Arg, _ type) \ (_ Arg) = (_ type) (timer_arg) # define OS _init_timer (_ osdev, _ timer, _ FN, _ Arg) \ do {\ init_timer (_ timer ); \ (_ timer)-> function = (_ FN); \ (_ timer)-> DATA = (unsigned long) (_ Arg); \} while (0) # define OS _set_timer (_ timer, _ MS) \ mod_timer (_ Timer, jiffies + (_ MS) * Hz)/1000) # define OS _cancel_timer (_ timer) del_timer (_ timer) Static OS _timer_func (wps_led_blink) {static int sec = 0; SEC ++; If (SEC <40) {// printk ("sec: % d \ n", Sec); {If (ar7240_gpio_in_val (button_gpio) = 0) {OS _set_timer (& OS _timer_t, 100); // printk ("Callback (button_gpio): % d \ n", ar7240_gpio_in_val (button_gpio);} else {timeout = 0; OS _cancel_timer (& OS _time R_t); buttons_dev.is_interrupt_finished = 1; printk ("the key time is less than 4 seconds. You have pressed the key: % d seconds \ n", (SEC/10); sec = 0; enable_irq (callback (button_gpio); // printk ("Callback (button_gpio): % d \ n", callback (button_gpio) ;}} else {OS _set_timer (& OS _timer_t, 100); If (ar7240_gpio_in_val (button_gpio) {printk ("the key time is greater than 4 seconds. If you press: % d seconds, the system will reset. \ N ", (SEC/10); OS _cancel_timer (& OS _timer_t); sec = 0; priority = 1; priority = 1; enable_irq (ar7240_gpio_irqn (button_gpio ));}} if (Bytes = 1) {buttons_dev.press_cnt = 1;/* Add 1 x/buttons_dev.ev_press = 1; buttons_dev.button_short_time = 0; sec = 0; printk ("buttons_dev.press_cnt: % d \ n ", buttons_dev.press_cnt); // wake_up_interruptible (& (buttons_de V. buttons_waitqueue);/* wake up the sleep process */} // interrupt response function, which indicates that an interruption has occurred and enters the interrupt processing function. Static irqreturn_t ar7242buttons_interrupt (int irq, void * dev_id) {disable_irq (ar7240_gpio_irqn (button_gpio); // If the interrupt is disabled, the system will not respond again. OS _set_timer (& OS _timer_t, 0); // printk ("The key is interrupted once. The system responds to the key, please wait ................. \ n "); Return irq_handled;} static int ar7242button_open (struct inode * inode, struct file * file) {int ret = 0; If (minor (inode-> I _rdev )! = Button_minor) {return-enodev;} If (response) {return-ebusy;} response = 1; ret = request_irq (ar7240_gpio_irqn (button_gpio), ar7242buttons_interrupt, 0, "ar7242 button", null); If (Ret! = 0) {printk ("request_irq for button (error % d) \ n", RET);} return ret;} static int ar7242button_close (struct inode * inode, struct file * file) {If (minor (inode-> I _rdev )! = Button_minor) {return-enodev;} bytes = 0; free_irq (callback (button_gpio), null); Return 0;} static ssize_t ar7242button_read (struct file * file, char * buff, size_t count, loff_t * PPOs) {unsigned long err; int retval = 0;/* If ev_press is equal to 0, sleep * // The application needs to read the key state, otherwise, the application will be blocked. // Return (-efault) when data cannot be read // wait_event_interruptible (buttons_dev.buttons_waitqueue, (buttons_dev.ev_press! = 0);/* when it is executed here, ev_press is equal to 1 and it is cleared 0 */buttons_dev.ev_press = 0;/* copy the key status to the user, clear 0 */err = copy_to_user (buff, (const void *) & buttons_dev.press_cnt, sizeof (buttons_dev.press_cnt); If (ERR <0 )) {// printk ("\ ncopy_to_user error RET: % d \ n", err); retval =-efault;} else {retval = sizeof (buttons_dev.press_cnt );} // buttons_dev.press_cnt = 0; // when the number of times the application reads the key is greater than 1, it indicates that the key has been pressed. You can determine the next step based on this value. // Printk ("\ nretval: % d buttons_dev.press_cnt: % d: buttons_dev.ev_press: % d \ n", retval, buttons_dev.press_cnt, buttons_dev.ev_press); Return retval ;} static ssize_t ar7242button_write (struct file * file, const char * Buf, size_t count, loff_t * PPOs) {unsigned int CNT = 0; int ret; int _ User * PTR = (INT _ User *) BUF; ret = get_user (CNT, PTR); If (RET) {ret =-efault ;} else {ret = count;} buttons_dev.press_cnt = 0; // printk ("\ rret: % d buttons_dev.press_cnt: % d count; % d \ n", RET, buttons_dev.press_cnt, CNT, count); return ret;} static int ar7242button_ioctl (struct inode * inode, struct file * file, unsigned int cmd, unsigned long Arg) {int ret = 0; return ret;} static struct file_operations failed = {read: failed, write: failed, IOCTL: Disabled, open: enabled, release: ar7242button_close}; static struct miscdevice athfr_miscdev = {button_minor, "ar7242_button", & ar7242button_fops}; static int _ init ar7242_button_init (void) {int ret; ret = misc_register (& athfr_miscdev); If (Ret <0) {printk ("*** insmod failed % d *** \ n", RET); Return-1;} OS _init_timer (null, & OS _timer_t, wps_led_blink, & OS _timer_t ); init_waitqueue_head (& (response); Round (button_gpio, int_type_level, int_pol_active_low); printk ("*** insmod restart success *** \ n "); return ret;} static void _ exit register (void) {misc_deregister (& athfr_miscdev); // convert (ath_gpio_irqn (button_gpio); printk ("% s (% s) line: % d \ n ", _ file __, _ FUNC __,__ line _);} module_init (ar7242_button_init); module_exit (ar7242_buttons_exit ); module_author ("CCTV from test"); // module_description ("button driver for atheros 7242 platform"); // module_license ("GPL "); // The following agreement

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.