рд╕рднреА рдХреЛ рдирдорд╕реНрдХрд╛рд░ред рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рдПрдХ рд╕рд░рд▓ рд▓рд┐рдирдХреНрд╕ рдХрд░реНрдиреЗрд▓ рдореЙрдбреНрдпреВрд▓ рдмрдирд╛рдиреЗ рдХрд╛ рдЕрдиреБрднрд╡ рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рдпрд╣ рд▓реЗрдЦ рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ рдЬреЛ рдпрд╣ рд╕рдордЭрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рдХрд░реНрдиреЗрд▓ рдореЙрдбреНрдпреВрд▓ рдХреИрд╕реЗ рд▓рд┐рдЦреЗрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ рдХрд╣рд╛рдВ рд╕реЗ рд╢реБрд░реВ рдХрд░реЗрдВред
рдореИрдВ рд▓рдВрдмреЗ рд╕рдордп рд╕реЗ рдЗрд╕ рд╡рд┐рд╖рдп рдХреЛ рд╕рдордЭрдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛, рд▓реЗрдХрд┐рди рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдЬрдм рддрдХ рдореИрдВ рдпрд╣ рдирд╣реАрдВ рдЬрд╛рдирддрд╛ рдерд╛ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдХрд░рдирд╛ рд╣реИред рдореИрдВ рдЪрд╛рд╣рддрд╛ рдерд╛ рдХрд┐ рдореЙрдбреНрдпреВрд▓ рдкрд░реНрдпрд╛рдкреНрдд рд╕рд░рд▓ рд╣реЛ, рд▓реЗрдХрд┐рди "рд╣реИрд▓реЛ рджреБрдирд┐рдпрд╛!" рд╕рдВрджреЗрд╢ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИред рдПрдХ рд▓реЙрдЧ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдЖрдЙрдЯрдкреБрдЯред рдЕрдВрдд рдореЗрдВ, рдореИрдВрдиреЗ рдПрдХ рдПрд▓рдИрдбреА рдЪрдордХрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рд▓рдХреНрд╖реНрдп sysfs рдореЗрдВ рдкрд▓рдХ рдЖрд╡реГрддреНрддрд┐ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рдХрдо рдХрд░рдирд╛ рдерд╛ред
рдкреНрд░рдпреЛрдЧ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдЙрдмрдВрдЯреВ рд▓рд┐рдирдХреНрд╕ рдХреЗ рд╕рд╛рде рдСрд░реЗрдВрдЬ рдкрд╛рдИ рд╡рди рдмреЛрд░реНрдб (рдХрд░реНрдиреЗрд▓ рд╕рдВрд╕реНрдХрд░рдг 3.4.113) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ред рдХрд░реНрдиреЗрд▓ рдореЙрдбреНрдпреВрд▓ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ gcc рдХрдВрдкрд╛рдЗрд▓рд░, рдореЗрдХ рдпреВрдЯрд┐рд▓рд┐рдЯреА, рдФрд░ рдХрд░реНрдиреЗрд▓ рд╣реЗрдбрд░ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рд╢реАрд░реНрд╖ рд▓реЗрдЦ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдирд┐рдореНрди рдХрдорд╛рдВрдб рдЪрд▓рд╛рдПрдБ:
sudo apt-get install linux-headers-$(uname -r)
рдЗрд╕рдХреЗ рдмрд╛рдж, рдореИрдВ рдЕрдкрдиреА рд░рд╛рдп рдореЗрдВ рдореЙрдбреНрдпреВрд▓ рдХреЗ рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рд╣рд┐рд╕реНрд╕реЛрдВ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реВрдВрдЧрд╛ред рдЕрдВрддрд░рд┐рдХреНрд╖ рдХреЛ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВ рдпрд╣рд╛рдВ рд╕рднреА рдХреЛрдб рдирд╣реАрдВ рджреВрдВрдЧрд╛, рдпрд╣ рдореЗрдХ рдлрд╛рдЗрд▓ рдХреЗ рд╕рд╛рде
рдЬреАрдердм рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реИред
рдореЙрдбреНрдпреВрд▓ рдореЗрдВ, рдореИрдВрдиреЗ рд╣реЗрдбрд░ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИ:
#include <linux/kernel.h> #include <linux/module.h> #include <linux/gpio.h> #include <linux/hrtimer.h> #include <linux/moduleparam.h>
рдХрд░реНрдиреЗрд▓ рдореЙрдбреНрдпреВрд▓ рдХреЛ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░реНрдиреЗрд▓ рдореЙрдбреНрдпреВрд▓, gpio.h рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИ, gpio.h рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред
рд╕рд┐рд╕реНрдЯрдо рдХреЗ рдХрд░реНрдиреЗрд▓ рдореЗрдВ рдЙрдирдХреЗ рдЪрд░ рдФрд░ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдЪрдордХрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ, рдЙрди рд╕рднреА рдХреЛ рд╕реНрдерд┐рд░ рдХреЗ рд░реВрдк рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдмрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдореИрдВ рдзреНрдпрд╛рди рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рдХрд░реНрдиреЗрд▓ рд╕реА рдФрд░ рд╕реНрдЯреЗрдЯрд┐рдХ рдореЗрдВ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ, рд╕реА ++ рдХреЗ рд╡рд┐рдкрд░реАрдд, рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗрд╡рд▓ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдлрд╝рд╛рдЗрд▓ рдХреЗ рдЕрдВрджрд░ рдЙрдкрд▓рдмреНрдз рд╣реИред
рдкреНрд░рд╡реЗрд╢ рдмрд┐рдВрджреБ рд╣реИ:
static int blink_module_init(void)
рдпрд╣рд╛рдВ рдореИрдВ рдЙрди рдЪрд░реЛрдВ рдХреЛ рдЖрд░рдВрднреАрдХреГрдд рдХрд░рддрд╛ рд╣реВрдВ, рдЬрд┐рдирдХрд╛ рдореИрдВ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВрдЧрд╛, рдЬрд┐рдирдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ:
gpio_timer_interval = ktime_set(gpio_blink_interval_s, 0);
ktime_set рдбреЗрдЯрд╛ рдХреЗ рд╡рд╛рдВрдЫрд┐рдд рд╕рдВрдЦреНрдпрд╛ (gpio_blink_interval_s) рдФрд░ рдиреИрдиреЛрд╕реЗрдХрдВрдбреНрд╕ (0) рджреЗрдХрд░ ktime_t рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рдХреЛ рдЖрд░рдВрдн рдХрд░рддрд╛ рд╣реИред рднрд╡рд┐рд╖реНрдп рдореЗрдВ, рдЗрд╕ рдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдЯрд╛рдЗрдорд░ рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд GPIO рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдиреБрд░реЛрдз рд╣реИ:
err = gpio_request(BLINK_PIN_NR, "blink_led");
рдпрд╣ рдлрд╝рдВрдХреНрд╢рди 0 рдкрд░ рд╡рд╛рдкрд╕ рдЖрддрд╛ рд╣реИ рдпрджрд┐ рд╕рдлрд▓ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдореИрдВ рдЬрд╛рдВрдЪрддрд╛ рд╣реВрдВ рдХрд┐ рдпрд╣ рд╡рд╛рдкрд╕ рдЖ рдЧрдпрд╛ред рдЕрдЧрд▓рд╛, рдЪрдпрдирд┐рдд рдкрд┐рди рд╕рд┐рдЧреНрдирд▓ рдЖрдЙрдЯрдкреБрдЯ рдкрд░ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рди рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред
err = gpio_direction_output(BLINK_PIN_NR, GPIOF_INIT_LOW);
рдпрджрд┐ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рдирд╣реАрдВ рдереА, рддреЛ рдкреНрд░рд╛рд░рдВрдн рдХрд░реЗрдВ рдФрд░ рдЯрд╛рдЗрдорд░ рд╢реБрд░реВ рдХрд░реЗрдВ
hrtimer_init(&gpio_blink_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); gpio_blink_timer.function = &gpio_blink_timer_callback; hrtimer_start(&gpio_blink_timer, gpio_timer_interval, HRTIMER_MODE_REL);
рдЯрд╛рдЗрдорд░ рдХреЙрд▓рдмреИрдХ рдлрд╝рдВрдХреНрд╢рди gpio_blink_timer_callback рд╣реЛрдЧрд╛ред рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ, рдореИрдВ рдкрд┐рди рдореВрд▓реНрдп рдХреЛ рд╡рд┐рдкрд░реАрдд рдореЗрдВ рдмрджрд▓рддрд╛ рд╣реВрдВ
gpio_value ^= 0x01; gpio_set_value(BLINK_PIN_NR, gpio_value);
рдореИрдВ рдкреВрдЫрддрд╛ рд╣реВрдВ рдХрд┐ рдЕрдЧрд▓реА рдмрд╛рд░ рдХрдм рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП
hrtimer_forward_now(&gpio_blink_timer, gpio_timer_interval);
рдФрд░ HRTIMER_RESTART рдкрд░ рд╡рд╛рдкрд╕ рд▓реМрдЯреЗрдВред
рдЕрдм, рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХреЗ рдЪрд░ рдХреЛ sysfs рдореЗрдВ рдХреИрд╕реЗ рджрд┐рдЦрд╛рдпрд╛ рдЬрд╛рдПред рдЗрд╕рдХреЗ рд▓рд┐рдП рдореИрдВ рдПрдХ рдореИрдХреНрд░реЛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ
module_param_cb(gpio_blink_interval_s, &kp_ops, &gpio_blink_interval_s, 0660);
рдЗрд╕ рдореИрдХреНрд░реЛ рдХрд╛ рдкрд╣рд▓рд╛ рдкреИрд░рд╛рдореАрдЯрд░ sysfs рдореЗрдВ рдлрд╝рд╛рдЗрд▓ рдирд╛рдо рд╣реИред рджреВрд╕рд░реА рдХреЙрд▓рдмреИрдХ рдлрд╝рдВрдХреНрд╢рди рд╡рд╛рд▓реА рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛ рд╣реИред рддреАрд╕рд░рд╛ рдкреИрд░рд╛рдореАрдЯрд░ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЪрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реВрдЪрдХ рд╣реИ рдФрд░ рдЪреМрдереЗ рдлрд╛рдЗрд▓ рдХреА рдЕрдиреБрдорддрд┐ sysfs рдореЗрдВ рд╣реИред
Kp_ops рдХреЗ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХреЛ рддрдм рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдм рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ sysfs рдлрд╝рд╛рдЗрд▓ рдХреЗ рдореВрд▓реНрдпреЛрдВ рдХреЛ рдмрджрд▓рддрд╛ рд╣реИ рдпрд╛ рдЗрд╕рдХреЗ рдореВрд▓реНрдп рдХреЛ рдкрдврд╝рддрд╛ рд╣реИред рдпрд╣рд╛рдВ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдореИрдВрдиреЗ рдЙрдиреНрд╣реЗрдВ рдХреИрд╕реЗ рдЖрд░рдВрдн рдХрд┐рдпрд╛:
static const struct kernel_param_ops kp_ops = { .set = &set_blink_interval, .get = &get_blink_interval };
рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╕реЗрдЯ рдмреНрдпрд╛рдЬ рдХрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдПрдХ рдирдпрд╛ рдорд╛рди рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИ, gpio_timer_intervalред
gpio_timer_interval = ktime_set(gpio_blink_interval_s, 0);
рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдиреЗ рдХреЗ рдмрд┐рдВрджреБ рдкрд░, рдореИрдВрдиреЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рд╕рднреА рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЛ рд╕рд╛рдлрд╝ рдХрд░ рджрд┐рдпрд╛
static void blink_module_exit(void) { hrtimer_cancel(&gpio_blink_timer); gpio_set_value(BLINK_PIN_NR, 0); gpio_free(BLINK_PIN_NR); printk(KERN_ALERT "Blink module unloaded\n"); }
рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдФрд░ рдирд┐рдХрд╛рд╕ рдмрд┐рдВрджреБрдУрдВ рдХреЛ рд╕рдВрдмрдВрдзрд┐рдд рдореИрдХреНрд░реЛрдЬрд╝ рдореЗрдВ рдЗрдВрдЧрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП
module_init(blink_module_init); module_exit(blink_module_exit);
рдпрд╣ рд╕рднреА рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд┐рдВрджреБрдУрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИред рдЕрдЧрд░ рдкрд╛рдардХреЛрдВ рдХреЗ рдкрд╛рд╕ рдХреЛрдИ рдкреНрд░рд╢реНрди рд╣реИ, рддреЛ рдореБрдЭреЗ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рдЙрдирдХрд╛ рдЬрд╡рд╛рдм рджреЗрдиреЗ рдореЗрдВ рдЦреБрд╢реА рд╣реЛрдЧреАред