LINUX.ORG.RU

Программинирование таймера

 , in, , ,


0

1

Нужно запрограммировать таймер и канал 2, чтобы системный спикер издал звук. Так вот, собрал программу. Запустил из под рут. Молчит. (ArchLinux x86_64). Собрал на AltLinux i486 - работает. В чем может быть проблема?


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/io.h>

#include <stack>


#define F_MAX 1193180
#define F_MIN 18.2

//get port permisions
int get_perm(int, int);
//convert integer to binary asci
char* itoba(int in);

int main( int argc, char** argv )
{
 
  //geting port acess
  if(  iopl(3) )
  {
    fprintf(stderr, "iopl() fail\n\n");
    return -1;
  }
  
  //writing to 0x43 port
  //канал 2|  операция 4|  режим 3 |  формат 0
  //10     |  11        |  01      |  10

  outb( 0b10110110, 0x43);
  
  //writing to 0x42 port
  /*
  требуемое значение счетчика посылается в порт канала (адреса 40h...42h), причем вначале выводится младший, а затем старший байты значения счетчика.
  Max: 1193180 Hz
  Min: 18.2 Hz
  */
  outb(0x01, 0x42);
  outb(0x01, 0x42);

  //switching on speaker and chanel 2 on timer
  int p61 = inb(0x61);
  printf("Reading from port 0x61: %s\n", itoba( p61 ) );
  p61 = p61 | 0b00000011;
  printf("Converting to 0x61: %s\n", itoba( p61 ) );
  outb(p61, 0x61);


  getchar();
  
  p61 = p61 & 0b11111100;
  outb(p61, 0x61);
  
  return 0;

}


char* itoba(int in)
{
  static char buf[10];
  int i=0;
  int base = 2;

  std::stack<int> dig;

  while ( in / base >= base)
  {
      dig.push( in % base);
      in /= base;
  }

  dig.push( in % base );
  dig.push( in / base );

  buf[i++] = '0';
  buf[i++] = 'b';

  while( ! dig.empty() )
  {
      buf[i] = dig.top() +'0';
      dig.pop();
      i++;
  }

  buf[i]=0;

  return buf;
}

Может поэтому?

SYNOPSIS #include <sys/io.h>

int iopl(int level);

This call is mostly for the i386 architecture. On many other architectures it does not exist or will always return an error.

Но дело в том, что функция iopl возвращает нуль и запись в 61h порт проходит нормально, т.е. считывая назад - все работает.

Следующее задание - запрограммировать индикаторы клавы. Сейчас не знаю как мне быть, индикаторов Caps Lock и т.п. нету на клавиатуре ноутбука. Может есть какие-либо эмуляторы с поддержкой клавиатуры?

Под убунтой 64-бита пищит, этот канал таймера под свои задачи в ОС случайно не используется ? Как вариант через /dev/port тоже самое сделать.

ilovewindows ★★★★★
()

УМВР. Может быть Beep в alsamixer отключен (ну, по крайней мере, если ноутбук, там какими-то костылями оно отключается, на десктопах вроде нет)?

Q3164
()
Ответ на: комментарий от denisnet

Попробовал под i386 Debian Squazy под VirtualBox. Тоже не эмулируется. У кого получилось, напишите, какая у вас система стоит.

denisnet
() автор топика

А теперь расскажи, как это выключить

Больше никогда не буду запускать программы с ЛОРа.

Atragor
()
Ответ на: комментарий от denisnet

Склоняюсь к тому, что какой-то из модулей использует этот канал под свои нужды. Кто может минимальное ядро или дистр.

denisnet
() автор топика
Ответ на: комментарий от denisnet

А, теперь вижу :) Я привычным Ctrl-C её убил, но это, естественно, таймер не остановило.

Linux archhost 3.5.4-1-ARCH #1 SMP PREEMPT Sat Sep 15 08:12:04 CEST 2012 x86_64 GNU/Linux

Пользуюсь Pulseaudio.

Atragor
()
Ответ на: комментарий от denisnet

Попробовал загрузиться с загрузочного диска арча. Не работает тоже.

denisnet
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.