include linux kernel include linux module include linux version includ

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <asm/io.h>
#include "rtai.h"
#include "rtai_sched.h"
// Две задачи реального времени
static RT_TASK sound_task;
static RT_TASK delay_task;
static RTIME sound_period_ns = 1e5; // 100 000 нс = 10 kHz
static RTIME delay_period_ns = 1e9; // 1000 000 000 нс = 1 Hz
#define SOUND_PORT 0x61 // адрес порта динамика
#define SOUND_MASK 0x02 // бит порта динамика
// Разделяемая переменная обеими задачами
static int delay_count = 2;
// =============================================================
void sound_function(int arg)
{
int delay_left = delay_count; // Каждый раз уменьшается
unsigned char sound_byte;
unsigned char toggle = 0;
while (1)
{
if (delay_left > 0) // Время задержки еще осталось
{
delay_left--;
}
else // если время переключения динамика
{
sound_byte = inb(SOUND_PORT);
if (toggle)
{
sound_byte = sound_byte | SOUND_MASK;
}
else
{
sound_byte = sound_byte & ~SOUND_MASK;
}
outb(sound_byte, SOUND_PORT);
toggle = ! toggle;
delay_left = delay_count; // Перезагружать время задержки
}
rt_task_wait_period();
}
return;
}
//=========================================
void delay_function(int arg)
{
while (1)
{
delay_count++; //Каждый раз частота увеличивается
rt_task_wait_period();
}
return;
}
//==========================================
int init_module(void)
{
RTIME sound_period_count; //1е5
RTIME delay_period_count; //1е9
RTIME timer_period_count;
//Установка таймера в чисто периодическом режиме
rt_set_periodic_mode();
// Установка периода таймера
sound_period_count = nano2count(sound_period_ns);
delay_period_count = nano2count(delay_period_ns);
//Запускаем таймер
start_rt_timer(sound_period_count);
rt_task_init(&sound_task, sound_function, 0, 1024, 0, 0, 0);
rt_task_init(&delay_task, delay_function, 0, 1024, 1, 0, 0);
rt_task_make_periodic(&sound_task,
rt_get_time() + sound_period_count,
sound_period_count);
rt_task_make_periodic(&delay_task,
rt_get_time()+ delay_period_count,
delay_period_count);
return 0;
}
// ============================================================
void cleanup_module(void)
{
rt_task_delete(&sound_task);
rt_task_delete(&delay_task);
outb(inb(SOUND_PORT) & ~SOUND_MASK, SOUND_PORT);
return;
}