ЗАО «ЗЭО»

Пожалуйста, войдите или зарегистрируйтесь.

Расширенный поиск  

Новости:

Автор Тема: Быстродействие GPIO  (Прочитано 5566 раз)

0 Пользователей и 1 Гость просматривают эту тему.

KDM

  • Newbie
  • *
  • Оффлайн Оффлайн
  • Сообщений: 46
Быстродействие GPIO
« : 14 Декабря, 2011, 15:44:19 »

Здравствуйте!

В процессе разработки возникла необходимость создания собственного протокола обмена данными, для чего используются GPIO.
Для установки уровней GPIO тестировалось несколько вариантов:
1) Вариант 1. На уровне приложения с помощью /dev/mem
// CONSTANTS
#define MAP_SIZE 4096
#define UINT unsigned long int
#define GPIO  *(volatile UINT *)
#define GPIO_BASE       0x40E00000

#define GPLR0 0x0000
#define GPDR0 0x000C
#define GPSR0 0x0018
#define GPCR0 0x0024


// MEMORY
//open /dev/mem with read and write mode
fd = open ("/dev/mem", O_RDWR|O_SYNC);
//map physical memory
start = (char *)mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED , fd, GPIO_BASE);

// CONFIGURING
//GPIO  9, 13, 21, 22 are configured as OUTPUTs
GPIO(start+GPDR0)|= ((1<<9)|(1<<13)|(1<<21)|(1<<22));
//GPIO 90, 91, 93, 94 are configured as INPUTs
GPIO(start+GPDR2)&= ~((1<<26)|(1<<27)|(1<<29)|(1<<30));

// WRITING/READING
//Writing 0
GPIO(start + GPCR0) = (1<<9)|(1<<13)|(1<<21);
//Writing 1
GPIO(start + GPSR0) = (1<<22);
//Reading
UINT DeviceReady = GPIO(start + GPLR0)
На выходе генерировался меандр с периодом 8 мкс, по битам получается 2,5 МГц или 305 кБайт/с.

2) Вариант 2. На уровне драйвера с использованием заголовочного файла с функциями и макросами.
#include <asm/gpio.h>
int pin=9;
gpio_direction_input(26);
gpio_direction_output(pin, 1);
gpio_set_value(pin, 0);
gpio_set_value(pin, 1);
По скорости получился такой же результат.

Быстрее выставлять значения не получается, загрузка процессора под 100%. Итого с 512МГц процессором на выставление уровня одного GPIO (?= регистру из 32 GPIO) уходит 200 машинных тактов. Результат вызывает некоторые сомнения в достоверности. Подскажите, можно ли работать с единичным значением GPIO (или регистром) быстрее?

Пробовал на уровне пользовательского загружаемого модуля  (отдельная менюшка в menuconfig'е — компилится, отладочные сообщения при загрузке и выключении модуля выдает) "достучаться" напрямую по адресам с использованием макросов GPCR, GPSR, GPDR, GPLR из linux-kernel/include/asm-arm/arch-pxa/pxa-regs.h — не получилось: Segmentation fault, хотя в linux-kernel/arch/arm/mach-pxa/tion270.c такие конструкции используются и работают. В чем заключаются мои ошибки?
Записан

asv

  • Hero Member
  • *****
  • Оффлайн Оффлайн
  • Сообщений: 1405
Re: Быстродействие GPIO
« Ответ #1 : 14 Декабря, 2011, 20:15:58 »

> единичным значением GPIO (или регистром) быстрее?

Максимум что получалось у меня это 1.6MHz. У PXA270 GPIO-контроллер не очень быстрый.

> В чем заключаются мои ошибки?

В Segmentation fault. См. вложения, как есть.
Записан

KDM

  • Newbie
  • *
  • Оффлайн Оффлайн
  • Сообщений: 46
Re: Быстродействие GPIO
« Ответ #2 : 16 Декабря, 2011, 12:24:39 »

Спасибо, для правильной работы макросов GPSR и т.д. не хватало заголовочного файла <asm/hardware.h>. После его подключения все описанные в <asm-arch/arch-pxa/pxa-regs> конструкции заработали! Там же (в <asm/hardware.h>) обнаружил причину, по которой обращения к памяти проходили с Segmentation fault:
/* Intel PXA2xx internal register mapping:
 * 0x40000000 - 0x41ffffff <--> 0xf2000000 - 0xf3ffffff*/

Вроде бы самым быстрым способом работы с GPIO получается следующий (на уровне драйвера, напрямую обращаемся к памяти, работаем сразу с несколькими GPIO, к тому же экономим машинные такты на преобразования адресов памяти при вызове __REG(x), __REG2(x,y), io_p2v(x) и остальных). Само собой, убирая проверки на правильность адреса необходимо будет тщательно отслеживать записываемые в регистры биты и адреса.
//PREPARING
#include <asm/hardware.h>
#include <asm/arch/pxa2xx-gpio.h>
#define MyGPSR0 0xF2E00018
#define MyGPCR0 0xF2E00024
#define UINT unsigned long int
#define GPIO  *(volatile UINT *)
// CONFIGURING
pxa_gpio_mode(9 | GPIO_OUT);
pxa_gpio_mode(13 | GPIO_OUT);
pxa_gpio_mode(21 | GPIO_OUT);
//GENERATING
for (i=0; i<KCycle; i++)
{
          GPIO(MyGPSR0) = (1<<9)|(1<<13)|(1<<21);
          GPIO(MyGPCR0) = (1<<9)|(1<<13)|(1<<21);
}
Проверил, биты выставляет. Хотя на осциллографе разница по скорости не заметна.

> GPIO-контроллер не очень быстрый.
Ну и ладно, по скорости самих GPIO пока что вроде пролезаю. Тогда "узким местом" является уже даже не сам GPIO контроллер, а процессор - все приходящие данные надо же еще и обработать, сохранить, вывести на экран...

Когда проводил тестирование на уровне приложения, загрузка процессора достигала 100%. Сейчас, на уровне драйвера, отследить этот показатель не получилось - top из отладочного терминала, повешенного на ком порт просто не получает управления во время запуска модуля (запускаю top из одного терминала, insmod модуль из другого -> и вижу, что пока модуль не запустится (меандр генерится именно при запуске), top не обновляет данные).

Хочется посмотреть, сколько же ресурсов системы будут доступны приложению при работе драйвера GPIO (есть очень неприятное подозрение, что будет 100% ). Подскажите, пожалуйста, показатель загрузки процессора во время работы драйвера как-нибудь проверить можно?
Записан

asv

  • Hero Member
  • *****
  • Оффлайн Оффлайн
  • Сообщений: 1405
Re: Быстродействие GPIO
« Ответ #3 : 16 Декабря, 2011, 14:22:39 »

> На выходе генерировался меандр с периодом 8 мкс
> Хотя на осциллографе разница по скорости не заметна.

f = 1/8e-6 = 125 kHz

У меня с кодом gpio_toogle.c 1.27 MHz
Записан

asv

  • Hero Member
  • *****
  • Оффлайн Оффлайн
  • Сообщений: 1405
Re: Быстродействие GPIO
« Ответ #4 : 16 Декабря, 2011, 14:26:08 »

> insmod модуль из другого -> и вижу, что пока модуль не запустится (меандр генерится именно при запуске)

Так перенесите генерацию меандра куда-нибудь.

Кроме того, вы можете занять процессор между переключением состояния GPIO.
Т.е. если вы устанавливаете GPIO в 0, а потом в 1, то процессор будет ожидать,
пока не завершит работу контроллер GPIO устанавливая GPIO в 0.
Записан

KDM

  • Newbie
  • *
  • Оффлайн Оффлайн
  • Сообщений: 46
Re: Быстродействие GPIO
« Ответ #5 : 16 Декабря, 2011, 17:36:42 »

> На выходе генерировался меандр с периодом 8 мкс
> Хотя на осциллографе разница по скорости не заметна.
Прошу прощения. 0,8мкс, немного ошибся.

Ваш код тоже компилил и пробовал, результаты получились идентичны.

> Так перенесите генерацию меандра куда-нибудь.
> Кроме того, вы можете занять процессор между переключением состояния GPIO.

Попробую в понедельник это проделать, но очень хотелось бы увидеть насколько загружается ЦП только при переключении GPIO и сколько будет оставаться для прикладной программы.

Записан

KDM

  • Newbie
  • *
  • Оффлайн Оффлайн
  • Сообщений: 46
Re: Быстродействие GPIO
« Ответ #6 : 23 Декабря, 2011, 11:30:41 »

Смысл разработки заключается в опросе некоторого количеста (N<=8) устройств через какую-либо шину. При этом считывание и запись информации производится через промежуточные буферы. Скорость потока данных - 120 кБ/с.

Под шину выделено 16 GPIO, из них 8 - данные. Максимальная скорость протокола = [320 кБ/с через один GPIO] * [8 GPIO с данными] / [5...6 полных циклов выставления GPIO для считывания байта (выставление адреса - 1...2 операции по GPIO (GPSR и GPCR), считывание готовности и наличия данных, запись RD=0, прием данных, запись RD=1)] = 420 кБ/с через шину.

Итого при [скорости потока данных = 120 кБ/с] и [максимальной пропускной способности шины = 420 кБ/с через шину] получается, что на считывание информации тратится грубо 1/3 всего времени работы программы и всего лишь 2/3 остается на обработку, отрисовку и т.д.

Даже по прикидкам такой результат устраивает не сильно; других же быстродействующих интерфейсов, которые могли бы помочь в решении этой задачи, не нашлось или они были исключены по тем или иным причинам. А "точка невозврата", вообще говоря, уже пройдена.

С учетом того, что полка на меандре = 0,4 мкс, а время переключения между потоками в Linux ~50 мкс (конкретной информации не нашлось, но слышал такие цифры, так ли это?), "занять" процессор чем либо на этапе получения информации весьма проблематично. (?)


> У PXA270 GPIO-контроллер не очень быстрый.
Как-то странно видеть на 520МГц процессоре частоту на ножках всего в 1,27 МГц.
С чем это связано не подскажите? Можно ли от этого как-то избавиться?

Возможно, текущие скорости считывания и будут достаточны - пока сказать наверняка очень сложно. Но в любом случае получается впритык - никакого резерва не остается, а без этого продолжать разработку очень опасно.
Записан

asv

  • Hero Member
  • *****
  • Оффлайн Оффлайн
  • Сообщений: 1405
Re: Быстродействие GPIO
« Ответ #7 : 23 Декабря, 2011, 13:00:33 »

> Как-то странно видеть на 520МГц процессоре частоту на ножках всего в 1,27 МГц.
> С чем это связано не подскажите?

Он так сделан.

> Можно ли от этого как-то избавиться?

Используйте другой интерфейс.
Записан