shamrel 0 2 июля, 2013 Опубликовано 2 июля, 2013 · Жалоба Доброго Здоровья! Стоит задача создать приложение, работающее с устройством, подключенным к процессору AM3354 через интерфейс SPI. Так как опыт работы с Linux сравнительно небольшой, было принято решение строить взаимодействие с железом через драйвер "spidev". По этому поводу на хабре наше две статьи: Обзор шины SPI и разработка драйвера ведомого SPI устройства для embedded Linux (Часть первая, обзорная) Обзор шины SPI и разработка драйвера ведомого SPI устройства для embedded Linux (Часть вторая, практическая) На первом шаге следует добиться появления в системе устройства /dev/spidevX.Y, для этого в настройках ядра добавляю: Device Drivers ---> SPI Device Drivers ---> SPI ---> Atmel SPI Controller Device Drivers ---> SPI ---> User mode SPI device driver support Затем в файле arch/arm/mach-omap2/board-am335xevm.c добавляю структуру: static struct spi_board_info am335x_spi1_master_info[] = { { .modalias = "spidev", .chip_select = 2, .max_speed_hz = 6 * 1000 * 1000, .mode = SPI_MODE_0, .bus_num = 1, }, }; и "регистрирую эту структуру: static void spi1_init(int evm_id, int profile) { setup_pin_mux(spi1_pin_mux); spi_register_board_info(am335x_spi1_master_info, ARRAY_SIZE(am335x_spi1_master_info)); return; } Пересобираем ядро, заливаем, загружаемся. В системе нет /dev/spidevX.Y. :( некоторый оптимизм внушает наличие: /sys/class/spi_master/ и /sys/class/spidev/, причем последняя директория пуста. root@var-som-am33:~# ls /sys/class/spi_master/ spi1 spi2 root@var-som-am33:~# ls /sys/class/spi_master/spi2 device power subsystem uevent Что может быть? Как получить устройство /dev/spidevX.Y? Складывается впечатление, что бутерброд не правильно ем, или лыжи не едут. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alx2 0 2 июля, 2013 Опубликовано 2 июля, 2013 · Жалоба и "регистрирую эту структуру: spi_register_board_info(am335x_spi1_master_info, ARRAY_SIZE(am335x_spi1_master_info)); } Этого недостаточно. Надо еще создать структуру platform_device и зарегистрировать с помощью platform_device_register(). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
shamrel 0 4 июля, 2013 Опубликовано 4 июля, 2013 · Жалоба Этого недостаточно. Надо еще создать структуру platform_device и зарегистрировать с помощью platform_device_register(). Спасибо за ответ, но не помогло. Получился такой код: /* Module pin mux for SPI */ static struct pinmux_config spi1_pin_mux[] = { {"mcasp0_aclkx.spi1_sclk", OMAP_MUX_MODE3 | AM33XX_PULL_ENBL | AM33XX_INPUT_EN}, {"mcasp0_fsx.spi1_d0", OMAP_MUX_MODE3 | AM33XX_PULL_ENBL | AM33XX_PULL_UP | AM33XX_INPUT_EN}, {"mcasp0_axr0.spi1_d1", OMAP_MUX_MODE3 | AM33XX_PULL_ENBL | AM33XX_INPUT_EN}, {"mcasp0_ahclkr.spi1_cs0", OMAP_MUX_MODE3 | AM33XX_PULL_ENBL | AM33XX_PULL_UP | AM33XX_INPUT_EN}, {NULL, 0}, }; static struct spi_board_info am335x_spi1_master_info[] = { { .modalias = "spidev", .chip_select = 2, .max_speed_hz = 6 * 1000 * 1000, .mode = SPI_MODE_0, .bus_num = 1, }, }; static struct platform_device am335x_spi1t = { .name = "spi1_custom", .id = -1, }; /* setup spi1 */ static void spi1_init(void) { int ret; printk("SPI1: init"); setup_pin_mux(spi1_pin_mux); spi_register_board_info(am335x_spi1_master_info, ARRAY_SIZE(am335x_spi1_master_info)); ret = platform_device_register(&am335x_spi1t); if (ret) pr_err(" failed to register SPI1\n"); return; } При загрузке пишет "SPI1: init", "failed to register SPI1" не пишет. Что делать, куда смотреть? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ZASADA 0 4 июля, 2013 Опубликовано 4 июля, 2013 · Жалоба было что-то похожее. Проц с несколькими аппаратными SPI контролерами. В ядре линукс все оказались закомментированы кроме нулевого (или просто был описан только нулевой, подробностей не помню). решилось простой правкой ядра. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alx2 0 4 июля, 2013 Опубликовано 4 июля, 2013 · Жалоба Что делать, куда смотреть? Хм... А spi_register_board_info() возвращает 0? А метод probe() Вашего драйвера вызывается? Если да, то что возвращает? Хотя, насколько я понимаю, если бы он возвращал ошибку, была бы хоть какая-то ругань в логах... Покажите вывод команды ls -l /sys/class/spi_master Ну и до кучи ls -l /sys/devices/platform И, кстати, почему у Вас в структуре platform_device .id равен -1? Мне казалось, что там должен быть номер шины, то есть в вашем случае 1... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
shamrel 0 5 июля, 2013 Опубликовано 5 июля, 2013 · Жалоба Спасибо. Изменил platform_device .id на 1. initspi_register_board_info возвращает 0. В /sys/devices/platform есть устройство spi1_custom.1: root@var-som-am33:~# ls -l /sys/class/spi_master lrwxrwxrwx 1 root root 0 Jul 5 09:52 spi1 -> ../../devices/platform/omap/omap2_mcspi.1/spi_master/spi1 lrwxrwxrwx 1 root root 0 Jul 5 09:52 spi2 -> ../../devices/platform/omap/omap2_mcspi.2/spi_master/spi2 root@var-som-am33:~# ls -l /sys/devices/platform drwxr-xr-x 3 root root 0 Jul 5 09:52 alarmtimer drwxr-xr-x 3 root root 0 Jul 5 09:52 cpuidle-am33xx.0 drwxr-xr-x 4 root root 0 Jul 5 09:52 leds-gpio drwxr-xr-x 3 root root 0 Jul 5 09:52 nop_usb_xceiv.0 drwxr-xr-x 3 root root 0 Jul 5 09:52 nop_usb_xceiv.1 drwxr-xr-x 39 root root 0 Jul 5 09:52 omap drwxr-xr-x 3 root root 0 Jul 5 09:52 omap2-nand.0 drwxr-xr-x 2 root root 0 Jul 5 09:56 power drwxr-xr-x 3 root root 0 Jul 5 09:52 pruss_uio drwxr-xr-x 4 root root 0 Jul 5 09:52 pwm-backlight drwxr-xr-x 3 root root 0 Jul 5 09:52 reg-dummy drwxr-xr-x 3 root root 0 Jul 5 09:52 regulatory.0 drwxr-xr-x 3 root root 0 Jul 5 09:52 sgx drwxr-xr-x 3 root root 0 Jul 5 09:52 spi1_custom.1 -rw-r--r-- 1 root root 4096 Jul 5 09:52 uevent Однако в /dev ничего SPI'йного не появилось. Директория /sys/class/spidev/ пуста (а там должно что-то быть?) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alx2 0 5 июля, 2013 Опубликовано 5 июля, 2013 · Жалоба lrwxrwxrwx 1 root root 0 Jul 5 09:52 spi1 -> ../../devices/platform/omap/omap2_mcspi.1/spi_master/spi1 lrwxrwxrwx 1 root root 0 Jul 5 09:52 spi2 -> ../../devices/platform/omap/omap2_mcspi.2/spi_master/spi2 Стоп. Я, видимо, Вас изначально неправильно понял. Я думал, Вы делаете и хотите использовать свой собственный драйвер (spi1_custom). Но, насколько я вижу, оба имеющиеся у Вас мастера используют omap2_mcspi. Правильно ли я понял, что Вы хотите использовать уже имеющийся omap2_mcspi? Если да, то register_platform_device Вам делать не надо, это уже сделано. Надо только зарегистрировать spi-устройства на шине. Вы так и делаете, но результата нет (в /sys/class/spidev/ должно появиться spidev1.2)... В такой ситуации могу только посоветовать смотреть в spidev_probe() (которая находится в drivers/spi/spidev.c) - именно там регистрируются устройства spidevX.Y. Либо она у Вас вообще по каким-то причинам не выполняется, либо не может создать устройство. Попробуйте понавтыкать туда printk()... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
shamrel 0 8 июля, 2013 Опубликовано 8 июля, 2013 · Жалоба Ура! Появился /dev/spidev1.0 ! Итого: /* Module pin mux for SPI */ static struct pinmux_config spi1_pin_mux[] = { {"mcasp0_aclkx.spi1_sclk", OMAP_MUX_MODE3 | AM33XX_PULL_ENBL | AM33XX_INPUT_EN}, {"mcasp0_fsx.spi1_d0", OMAP_MUX_MODE3 | AM33XX_PULL_ENBL | AM33XX_PULL_UP | AM33XX_INPUT_EN}, {"mcasp0_axr0.spi1_d1", OMAP_MUX_MODE3 | AM33XX_PULL_ENBL | AM33XX_INPUT_EN}, {"mcasp0_ahclkr.spi1_cs0", OMAP_MUX_MODE3 | AM33XX_PULL_ENBL | AM33XX_PULL_UP | AM33XX_INPUT_EN}, {NULL, 0}, }; static struct spi_board_info am335x_spi1_master_info[] = { { .modalias = "spidev", .chip_select = 1, .max_speed_hz = 6 * 1000 * 1000, .mode = SPI_MODE_0, .bus_num = 0, }, { .modalias = "spidev", /* piggyback A2 */ .chip_select = 0, .max_speed_hz = 6 * 1000 * 1000, .mode = SPI_MODE_0, .bus_num = 1, }, }; static struct platform_device am335x_spi1t = { .name = "spi1_custom", .id = 1, }; /* setup spi1 */ static void spi1_init(void) { int ret; printk("SPI1: init"); setup_pin_mux(spi1_pin_mux); ret = spi_register_board_info(am335x_spi1_master_info, ARRAY_SIZE(am335x_spi1_master_info)); printk("spi_register_board_info: %d \n", ret); // ret = platform_device_register(&am335x_spi1t); // if (ret) // pr_err(" failed to register SPI1\n"); return; } alx2, Спасибо огромное и низкий поклон! Перехожу на следующий уровень бесконечной игры под названием Embedded Linux. :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alx2 0 9 июля, 2013 Опубликовано 9 июля, 2013 · Жалоба Ура! Появился /dev/spidev1.0 ! Правильно ли я понял, что проблема была в chip_select'е (было 2, а теперь Вы сделали 0)? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться