Ник:
Пароль:

Контакты

E-mail: info@starterkit.ru
тел.: +7 922 680-21-73
тел.: +7 922 680-21-74
Телеграм: t.me/starterkit_ru

Способы оплаты

User Info


Добро пожаловать,
Guest

Регистрация или входРегистрация или вход
Потеряли пароль?Потеряли пароль?

Ник:
Пароль:

ПользователейПользователей:5
Поисковых ботовПоисковых ботов:3
ГостейГостей:1

ОбновитьПодробнееВсегоВсего:9
Форум » starterkit.ru » Отладочные платы » SK-MAT91SAM9XXXXX
контроллер CAN
link29
Добавлено 21.03.2010 22:59
0
Сообщение: 1
link29
0

Пункты: 380
Регистрация: 21.01.2010
Доброго времени суток.

Есть контроллер CAN - mcp2515, в ядре есть драйвер под него,
в комментариях к нему :

* static struct mcp251x_platform_data mcp251x_info = {
* .oscillator_frequency = 8000000,
* .board_specific_setup = &mcp251x_setup,
* .model = CAN_MCP251X_MCP2510,
* .power_enable = mcp251x_power_enable,
* .transceiver_enable = NULL,
* };
*
* static struct spi_board_info spi_board_info[] = {
* {
* .modalias = "mcp251x",
* .platform_data = &mcp251x_info,
* .irq = IRQ_EINT13,
* .max_speed_hz = 20000,
* .chip_select = 2,
* },
* };

1. я так понимаю mcp251x_platform_data надо засунуть куда-нибудь в arch/arm/mach-at91/at91sam9260_devices.c ,
а spi_board_info править в linux/arch/arm/mach-at91/board-sam9260ek.c ?
2. При этом в комментариях spi_board_info нет поля bus_num,
означает ли это что контроллер найдётся на любом SPI с заданным CS, или bus_num надо указывать явно в любом случае?
3. Если необходимо подключить два контроллера для сетей can0 и can1, то если их повесить на разный SPI(CS), то ядро найдёт 2 устройства? естественно соответственно править spi_board_info для двух чипов.
4. IRQ_EINT13 это програмное прерывание или аппаратное? У mcp2515 есть выход прерывания,но его использовать не обязательно(имеется внутренний буфер сообщений). то есть достаточно ли мне просто подключить SPI от mcp2515 к плате?

Заранее благодарен.
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 22.03.2010 12:27 Редактировалось 22.03.2010 12:42 Сообщение: 2
sasamy
4.71

Пункты: 83552
Регистрация: 14.08.2009
1 Это нужно прописать все в arch/arm/mach-at91/board-sam9260ek.c - там есть специальный раздел для spi slave устройств.
2 bus_num необходимо прописать - как иначе будет обращение идти - на деревню бабушке ? bus_num совместно с cs однозначно определяют подключение устройства.
3 да
4 попробуйте не указывать никакое прерывание.

PS с прерыванием не уверен, посмотрел драйвер - оно используется там явно, возможно нужно будет gpio задействовать в качестве источника внешнего прерывания предварительно проинициализировав. я раньше никогда не использовал его, поэтому затрудняюсь сказать, нужно смотреть исходники подсистемы spi.
Спуститься к концу Подняться к началу
Персональная информация
Sol
Добавлено 15.07.2010 17:15 Сообщение: 3
Sol
0

Пункты: 578
Регистрация: 01.07.2010
Цитата
...возможно нужно будет gpio задействовать в качестве источника внешнего прерывания предварительно проинициализировав...

А можно чуть больше информации про то как именно это сделать? Перерыл форум, из близких тем нашел только эту.

Т.е. задача - научиться из юзерспейса реагировать прерыванием на спад на оперделенной ноге. Сейчас эта нога сконфигурирована через mmap как gpio и идет ее опрос по таймеру. Работает, но все же это тупой поллинг. А вот как посадить на ногу прерывание и тем более как в программе не из пространства ядра на него среагировать - не представляю (если что - плата iMX233)
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 15.07.2010 17:56 Редактировалось 15.07.2010 17:57 Сообщение: 4
sasamy
4.71

Пункты: 83552
Регистрация: 14.08.2009
Цитата

А вот как посадить на ногу прерывание и тем более как в программе не из пространства ядра на него среагировать - не представляю (если что - плата iMX233)


Честно говоря я не слышал чтобы обработчик прерываний работал в юзерспейс :) а прерываание на ногу gpio в ядре вешается достаточно просто:
Код

#define TS_PENIRQ_GPIO PINID_PWM2

static int ads7846_dev_init(void)
{

if (gpio_request(TS_PENIRQ_GPIO, "ADS7846 pendown") < 0)
printk(KERN_ERR "can't get ads7846 pen down GPIO\n");

gpio_direction_input(TS_PENIRQ_GPIO);
set_irq_type(gpio_to_irq(TS_PENIRQ_GPIO), IRQ_TYPE_EDGE_FALLING);

return gpio_to_irq(TS_PENIRQ_GPIO);
}
Спуститься к концу Подняться к началу
Персональная информация
Sol
Добавлено 15.07.2010 18:19 Редактировалось 15.07.2010 18:22 Сообщение: 5
Sol
0

Пункты: 578
Регистрация: 01.07.2010
Цитата
Честно говоря я не слышал чтобы обработчик прерываний работал в юзерспейс :) а прерываание на ногу gpio в ядре вешается достаточно просто:


Т.е. получается что более-менее грамотный путь это сделать - писать свой специальный драйвер, который например на вход из юзерспейса берет адрес callback-функции и вызывает ее при появлении нужного прерывания? Просто предполагал что в ядре столько всего есть, и подобный драйвер-прослойка тем более - все же без прерываний как-то тоскливо код писать, пусть и в юзерспейсе - не всегда ведь требуется целый дравер городить
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 15.07.2010 18:54 Сообщение: 6
sasamy
4.71

Пункты: 83552
Регистрация: 14.08.2009
Цитата

Просто предполагал что в ядре столько всего есть, и подобный драйвер-прослойка тем более


С наскоку не могу вспомнить чтобы такое вообще было и не знаю как можно дергать из ядра юзерспейсный код - просто не встречался с такой задачей. А что конкретно делаете с gpio в юзерспейс что даже прерывания потребовались ? может драйвер проще написать ?
Спуститься к концу Подняться к началу
Персональная информация
Sol
Добавлено 15.07.2010 22:30 Редактировалось 15.07.2010 22:32 Сообщение: 7
Sol
0

Пункты: 578
Регистрация: 01.07.2010
Цитата
С наскоку не могу вспомнить чтобы такое вообще было и не знаю как можно дергать из ядра юзерспейсный код - просто не встречался с такой задачей. А что конкретно делаете с gpio в юзерспейс что даже прерывания потребовались ? может драйвер проще написать ?


Делаю то же самое - общаюсь с mcp2515. Ее драйвер есть в ядре начиная с 33 версии, у меня 31-я. Бэк-портинг драйвера с наскоку не удался (авторы ядра что-то заметно перелопатили в самой CAN-подсистеме ядра), да и драйвер из ядра - не совсем то что мне надо т.к. построен по логике сетевого адаптера, а мне от mcp нужен функционал тихого сниффера всех пакетов. Поэтому поднял spidev и общаюсь с mcp2515 как с char-девайсом, быстро и удобно. Вот единственное что омрачает - mcp сигнализирует о приходе новой посылки падением в ноль уровня на ноге INT, это падение и хотелось бы ловить не как сейчас поллингом через gpio, а как-то более изящно.
Когда например работаешь с UART-ом в асинхронном режиме - то как раз примерно как хочется так и сделано - отдал драйверу адрес нужной callback-функции, и он ее честно вызывает при приходе строки в порт. Идеально было бы найти способ сделать так же при появлении INT от mcp. Переходить только ради этого на новое ядро или перелопачивать родной драйвер от 33 ядра - вроде не стоит оно того
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 16.07.2010 11:32 Сообщение: 8
sasamy
4.71

Пункты: 83552
Регистрация: 14.08.2009
Цитата

да и драйвер из ядра - не совсем то что мне надо т.к. построен по логике сетевого адаптера, а мне от mcp нужен функционал тихого сниффера всех пакетов.


Я с CAN вообще не имел дела но например ethernet сетевой интерфейс в linux может работать в promiscuous mode - будет принимать все пакеты.

Цитата

Поэтому поднял spidev и общаюсь с mcp2515 как с char-девайсом, быстро и удобно. Вот единственное что омрачает - mcp сигнализирует о приходе новой посылки падением в ноль уровня на ноге INT, это падение и хотелось бы ловить не как сейчас поллингом через gpio, а как-то более изящно.


Мне кажется проще всего написать тогда небольшой драйвер раз уж вы им умеете управлять и работать с ним как с символьным устройством и прерывания как и полагается обрабатывать в ядре. Я бы занялся этим но времени сейчас нет

Цитата

Когда например работаешь с UART-ом в асинхронном режиме - то как раз примерно как хочется так и сделано - отдал драйверу адрес нужной callback-функции, и он ее честно вызывает при приходе строки в порт..


Посмотрите про обработку сигналов в unix - в частности SIGIO мне кажется это было бы для вас подходящим решением но пока я не знаю c какого боку в вашем случае подойти :)
Спуститься к концу Подняться к началу
Персональная информация
sasamy
Добавлено 18.07.2010 20:39 Редактировалось 18.07.2010 20:42 Сообщение: 9
sasamy
4.71

Пункты: 83552
Регистрация: 14.08.2009
Цитата

Делаю то же самое - общаюсь с mcp2515. Ее драйвер есть в ядре начиная с 33 версии, у меня 31-я. Бэк-портинг драйвера с наскоку не удался (авторы ядра что-то заметно перелопатили в самой CAN-подсистеме ядра)


Попробовал сегодня сделать бэкпорт подсистемы CAN с 2.6.34 на 2.6.31 - в теории все прошло достаточно гладко, ядро собралось, но практически проверить работу CAN не могу за не имением оного :)

1 Сносим директорию linux-2.6.31/drivers/net/can и копируем вместо нее linux-2.6.34/drivers/net/can
2 Повторяем то же самое с директорией linux-2.6.31/include/linux/can
3 Меняем тип возвращаемого значения ф-ции mcp251x_hard_start_xmit вместо netdev_tx_t на int, соотвественно return NETDEV_TX_OK; на return 0;

Скорей всего нужно повторить пункт 2 (usr/include/linux/can)и с заголовками тулчейна если будет что-то собираться специальное для CAN.
Спуститься к концу Подняться к началу
Персональная информация
Strijar
Добавлено 20.07.2010 10:47 Редактировалось 20.07.2010 10:51 Сообщение: 10
Strijar
Ранг
5

Группа: Клиенты
Пункты: 1618
Регистрация: 21.04.2009
Пол: Мужчина
Когда например работаешь с UART-ом в асинхронном режиме - то как раз примерно как хочется так и сделано - отдал драйверу адрес нужной callback-функции, и он ее честно вызывает при приходе строки в порт


Штатно это делается через select, реализуйте poll в драйвере - там делов то, дергать очередь ожидания через прерывание. Вот как у меня идет реагирование на посылку по spi

Код

static unsigned int drv_poll(struct file *file, poll_table *wait) {
drv_t *drv = file->private_data;
unsigned int res = POLLOUT | POLLWRNORM;

poll_wait(file, &drv->wq, wait);

if (drv->msg_tail) {
res |= POLLIN | POLLRDNORM;
}

return res;
}

static irqreturn_t interrupt(int irq, drv_t *dev) {
if (gpio_get_value(dev->irq_pin)) {
schedule_work(&dev->work);
}

return IRQ_HANDLED;
}

static void irq_work(struct work_struct *work) {
...
wake_up_interruptible(&drv->wq);
...
}

Спуститься к концу Подняться к началу
Персональная информация
Форум » starterkit.ru » Отладочные платы » SK-MAT91SAM9XXXXX