Jump to content

    

fademike

Участник
  • Content Count

    19
  • Joined

  • Last visited

Community Reputation

0 Обычный

About fademike

  • Rank
    Участник
  1. Все заработало!)) Огромное Вам спасибо!!
  2. А кто-нибудь может подсказать, как вывести консоль на дисплей (/dev/tty1), используя клавиатуру матрицы кнопок с драйвером "Linux/drivers/input/keyboard/matrix_keypad.c"???
  3. Просто, для изучения ОС писал простой модуль опроса матрицы и наткнулся на ошибку в прерываниях, как избавиться от нее я не понял.. Ну, буду тогда использовать Linux/drivers/input/keyboard/matrix_keypad.c sasamy, спасибо за пример!
  4. Помогите, пожалуйста с проблемой очень начинающему "программисту"! К отладочной плате SK-AT91SAM9G45-XC6SLX_V1B с установленным на нее Linux kernel, подключена матрица кнопок с подтяжкой к питанию. Написал модуль линукса, чтобы он мне в устройстве "\dev\Keys" показывал какая кнопка нажата. Линии матрицы я подвязал к прерываниям, а столбцы к нулям. При нажатии на кнопку, модуль по отрицательному фронту запускает прерывание и начинает сканировать все кнопки, создавая еще прерывания и так, пока не выдаст ошибку или пока не отпустить кнопку. Как сделать так, чтобы прерывания не вызывались во время выполнения функции прерывания?? Флаги все перебрал, disable_irq вообще не вариант(( Ошибка в командной строке появляется после нажатия на кнопку более секунды! #irq 88: nobody cared (try booting with the "irqpoll" option) [<c002f584>] (unwind_backtrace+0x0/0xf4) from [<c0066dc8>] (__report_bad_irq+0x74/0xa4) [<c0066dc8>] (__report_bad_irq+0x74/0xa4) from [<c0066f7c>] (note_interrupt+0x184/0x1f4) [<c0066f7c>] (note_interrupt+0x184/0x1f4) from [<c00678a0>] (handle_simple_irq+0x7c/0x94) [<c00678a0>] (handle_simple_irq+0x7c/0x94) from [<c0033448>] (gpio_irq_handler+0xb8/0xdc) [<c0033448>] (gpio_irq_handler+0xb8/0xdc) from [<c0029044>] (asm_do_IRQ+0x44/0xa4) [<c0029044>] (asm_do_IRQ+0x44/0xa4) from [<c0029ad4>] (__irq_svc+0x34/0x60) Exception stack(0xc042df70 to 0xc042dfb8) df60: 00000000 0005317f 0005217f 60000013 df80: c042c000 c04526e8 c042fb88 c042fb80 70022f5c 41069265 70022f28 00000000 dfa0: 600000d3 c042dfb8 c002b52c c002b538 60000013 ffffffff [<c0029ad4>] (__irq_svc+0x34/0x60) from [<c002b538>] (default_idle+0x2c/0x34) [<c002b538>] (default_idle+0x2c/0x34) from [<c002b3c0>] (cpu_idle+0x6c/0xa4) [<c002b3c0>] (cpu_idle+0x6c/0xa4) from [<c03150e0>] (rest_init+0xc8/0x120) [<c03150e0>] (rest_init+0xc8/0x120) from [<c0008e60>] (start_kernel+0x414/0x5ac) [<c0008e60>] (start_kernel+0x414/0x5ac) from [<70008034>] (0x70008034) handlers: [<c01fef60>] (my_interrupt+0x0/0x22c) Disabling IRQ #88 После одной ошибки на линии прерывания он больше не выполняет прерывание по фронтам, а делает прерывание самостоятельно через какое-то время. А в столбце "CPU0" в таблице "#cat /dev/interrupts" ничего не меняется! Пробовал даже переназначать порты input на output (а output на input) в цикле опроса, чтобы прерываний не происходило, но и это не помогло(( #include <linux/fs.h> #include <linux/miscdevice.h> #include <asm/uaccess.h> #include <linux/module.h> #include <linux/init.h> #include <linux/interrupt.h> #include <mach/gpio.h> #include <asm-generic/gpio.h> #include <mach/at91_pio.h> #include <asm/gpio.h> static int my_dev_id; int bline[6]; unsigned long save_key = 0; const char button_name[30][15] = { {"Button Clear\n"},{"Left line 1\n"},{"Left line 2\n"},{"Left line 3\n"},{"Left line 4\n"},{"Return\n"},\ {"Escape\n"},{"Right line 1\n"},{"Right line 2\n"},{"Right line 3\n"},{"Right line 4\n"},{"Down\n"},\ {"Up\n"},{"Bk Sp\n"},{"Enter\n"},{"7\n"},{"4\n"},{"1\n"},{"0\n"},{"F1\n"},{"8\n"},\ {"5\n"},{"2\n"},{".\n"},{"F2\n"},{"9\n"},{"6\n"},{"3\n"},{"+/-\n"},{"F3\n"}}; char * str_word (void) { unsigned int count; for (count = 29; count>=1; count--) if (save_key&(0x1<<count)) break; return &button_name[count]; } static ssize_t hello_read(struct file * file, char * buf, size_t count, loff_t *ppos) { char *hello_str = str_word (); int len; len = strlen(hello_str); if (count < len) return -EINVAL; if (*ppos != 0) return 0; if (copy_to_user(buf, hello_str, len)) return -EINVAL; *ppos = len; return len; } static irqreturn_t my_interrupt (int irq, void *dev_id) { unsigned char line; unsigned long key = 0; at91_set_gpio_output(AT91_PIN_PB6, 1); at91_set_gpio_output(AT91_PIN_PB7, 1); at91_set_gpio_output(AT91_PIN_PB8, 1); at91_set_gpio_output(AT91_PIN_PB9, 1); at91_set_gpio_output(AT91_PIN_PB10, 1); key = 0; for (line =1; line<=5; line++) { if (line == 5) at91_set_gpio_output(AT91_PIN_PB6, 0); if (line == 4) at91_set_gpio_output(AT91_PIN_PB7, 0); if (line == 3) at91_set_gpio_output(AT91_PIN_PB8, 0); if (line == 2) at91_set_gpio_output(AT91_PIN_PB9, 0); if (line == 1) at91_set_gpio_output(AT91_PIN_PB10, 0); key <<= 6; if (!at91_get_gpio_value(AT91_PIN_PB26)) key |= (0x1<<6); if (!at91_get_gpio_value(AT91_PIN_PB25)) key |= (0x1<<5); if (!at91_get_gpio_value(AT91_PIN_PB24)) key |= (0x1<<4); if (!at91_get_gpio_value(AT91_PIN_PB23)) key |= (0x1<<3); if (!at91_get_gpio_value(AT91_PIN_PB22)) key |= (0x1<<2); if (!at91_get_gpio_value(AT91_PIN_PB28)) key |= (0x1<<1); if (line == 5) at91_set_gpio_output(AT91_PIN_PB6, 1); if (line == 4) at91_set_gpio_output(AT91_PIN_PB7, 1); if (line == 3) at91_set_gpio_output(AT91_PIN_PB8, 1); if (line == 2) at91_set_gpio_output(AT91_PIN_PB9, 1); if (line == 1) at91_set_gpio_output(AT91_PIN_PB10, 1); } if (key==0) save_key |= 0x1; else save_key = key; at91_set_gpio_output(AT91_PIN_PB6, 0); at91_set_gpio_output(AT91_PIN_PB7, 0); at91_set_gpio_output(AT91_PIN_PB8, 0); at91_set_gpio_output(AT91_PIN_PB9, 0); at91_set_gpio_output(AT91_PIN_PB10, 0); return IRQ_NONE; } static const struct file_operations hello_fops = { .owner = THIS_MODULE, .read = hello_read, }; static struct miscdevice hello_dev = { MISC_DYNAMIC_MINOR, "Key", &hello_fops }; static int __init my_init ( void){ unsigned long irqflags; printk(KERN_INFO "My_init\n"); at91_set_gpio_output(AT91_PIN_PB6, 0); at91_set_gpio_output(AT91_PIN_PB7, 0); at91_set_gpio_output(AT91_PIN_PB8, 0); at91_set_gpio_output(AT91_PIN_PB9, 0); at91_set_gpio_output(AT91_PIN_PB10, 0); at91_set_gpio_input(AT91_PIN_PB22, 1); at91_set_gpio_input(AT91_PIN_PB23, 1); at91_set_gpio_input(AT91_PIN_PB24, 1); at91_set_gpio_input(AT91_PIN_PB25, 1); at91_set_gpio_input(AT91_PIN_PB26, 1); at91_set_gpio_input(AT91_PIN_PB28, 1); bline[0] = gpio_to_irq(AT91_PIN_PB22); if (bline[0] < 0) {printk(KERN_INFO "\n\nError_button_22_irq!!\n\n");} bline[1] = gpio_to_irq(AT91_PIN_PB23); if (bline[1] < 0) {printk(KERN_INFO "\n\nError_button_23_irq!!\n\n");} bline[2] = gpio_to_irq(AT91_PIN_PB24); if (bline[2] < 0) {printk(KERN_INFO "\n\nError_button_24_irq!!\n\n");} bline[3] = gpio_to_irq(AT91_PIN_PB25); if (bline[3] < 0) {printk(KERN_INFO "\n\nError_button_25_irq!!\n\n");} bline[4] = gpio_to_irq(AT91_PIN_PB26); if (bline[4] < 0) {printk(KERN_INFO "\n\nError_button_26_irq!!\n\n");} bline[5] = gpio_to_irq(AT91_PIN_PB28); if (bline[5] < 0) {printk(KERN_INFO "\n\nError_button_28_irq!!\n\n");} irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_SHARED; if (request_irq( bline[0], my_interrupt, irqflags, "my_interrupt", &my_dev_id) ) return -1; if (request_irq( bline[1], my_interrupt, irqflags, "my_interrupt", &my_dev_id) ) return -1; if (request_irq( bline[2], my_interrupt, irqflags, "my_interrupt", &my_dev_id) ) return -1; if (request_irq( bline[3], my_interrupt, irqflags, "my_interrupt", &my_dev_id) ) return -1; if (request_irq( bline[4], my_interrupt, irqflags, "my_interrupt", &my_dev_id) ) return -1; if (request_irq( bline[5], my_interrupt, irqflags, "my_interrupt", &my_dev_id) ) return -1; if (misc_register(&hello_dev)) printk(KERN_ERR "Error\n"); printk( KERN_INFO "Siccessfully loading ISR handler on IRQ %d\n", irqq ); return 0; } static void __exit my_exit(void) { int x; for (x=0; x<=5; x++) synchronize_irq (bline[x]); for (x=0; x<=5; x++) free_irq(bline[x], &my_dev_id); printk(KERN_INFO "Successfully unloading, irq_counter = %d\n", irq_counter); } module_init(my_init); module_exit(my_exit); MODULE_AUTHOR("My_copy_internet"); MODULE_DESCRIPTION("LDD:1.0 s_08/lab1_interrupt.c"); MODULE_LICENSE( "GPL v2"); gpio_keys.txt
  5. Понял. Спасибо, за ответ!
  6. Это значит, мне перед бинарником нужно "ручкачи" вбивать ECC код до загрузки в nandflash? Или можно какой-нибудь утилиткой воспользоваться??
  7. Столкнулся с проблемой: отладочная плата SK-AT91SAM9G45-XC6SLX не грузится с NANDFLASH с моим BIN-файлом. Тот же файл без церемоний запускается с SD-карты, но с Nand-flash грузится отказывается(( А тестовые прошивки, что прилагались к комплекту CD-диска, грузятся с Nandflash без проблем! BIN-файл создавался в Keil. Может в программе нужно какие-нибудь настройки подправить? Или шапку BIN-файла изменить? Хотя, судя по http://microsin.net/programming/ARM/sk-mat...ng-started.html проблем не должно быть.. Подскажите, пожалуйста, в каком направлении копать!
  8. Огромное спасибо за помощь!
  9. aaarrr, прошу прощения, у меня в "Target" размер был 0x3000. Поэтому и выдавал ошибку.. Не могли бы мне объяснить что такое скаттер и как читать map-файл??
  10. DDR2 - 512 Мбит. И как я понял в файле SAM9G45.s уже инициализация прописана.. когда 0x1000: BOOT.axf: Error: L6406E: No space in execution regions with .ANY selector matching sam9g45.o(STACK). BOOT.axf: Error: L6407E: Sections of aggregate size 0x1088 bytes could not fit into .ANY selector(s). Как я понял "0x1088" - это объем всего стека, что равно 4'232 Байтам. И это максимальный объем хранимых переменных, чтоли??
  11. И, если не сложно, подскажите мне, пожалуйста, литературу! Увеличил уже до "USR_Stack_Size EQU 0x00000140" А программе ни по чем.. При дальнейшем увеличении - ошибка((
  12. Объем стека это там - ISR_Stack_Size??
  13. Значит, мне нужно подключать внешнее ОЗУ??
  14. Как я понимаю, я выделил: В keil-е size: 0x8000 - это 32 кБ - Должно хватать..
  15. Микроконтроллер: AT91SAM9G45. Кажись, должно хватать! Keil не жалуется!