Библиотека MRAA для работы с платами Intel Edison и Intel Galileo

в 11:05, , рубрики: adc, diy или сделай сам, Edison, galileo, I2C, Intel Edison, intel galileo, IoT, mraa, PWM, uart, ацп, Блог компании Intel, программирование микроконтроллеров, Разработка для интернета вещей

Эта статья описывает библиотеку MRAA, которая может существенно упростить работу с различными типами устройств, использующими:

  • аналоговый ввод;
  • цифровой ввод и вывод;
  • широтно-импульсную модуляцию (ШИМ);
  • двухпроводную шину I2C;
  • Universal Asynchronous Receiver-Transmitter (UART);
  • прерывания при изменении уровня входного сигнала.

Библиотека MRAA для работы с платами Intel Edison и Intel Galileo - 1

Вместо примеров с полными программами, мы рассмотрим небольшие фрагменты на языке C, которые покажут основные принципы MRAA API. Чтобы получить больше информации из этой статьи, вы должны знать следующие вещи:

  • легко владеть ОС Linux и языком C;
  • иметь базовые знания в цифровой электронике и использования GPIO (general-purpose input/output — входов и выходов общего назначения);
  • иметь документацию на устройства, которые вы используете.

В этой статье не объясняется, как выполнить компиляцию, сборку программы и установку приложений на данную платформу.

1. Обзор MRAA

MRAA (произносится «эм-ра») это низкоуровневая библиотека, написанная на языке C. Она предназначена для абстрагирования от деталей, связанных с доступом и управлением вводом-выводом на платформе, такой как Intel Galileo или Intel Edison, при помощи введения одного небольшого API.

  • MRAA работает как переходный слой для базовых возможностей по работе с портами ввода/вывода (GPIO) в Linux. Несмотря на то, что Linux предлагает довольно богатую инфраструктуру для управления GPIO, и типичные команды для работы с GPIO стандартны, всё же, может быть сложно их использовать.
  • Все платформы различны. Каждая имеет различные возможности, чисто пинов и типов GPIO. Например, пин может не поддерживать одинаковые возможности для двух разных платформ. Пин может не существовать на данной платформе. Ещё и способ, которым он настраивается, может зависеть от множества факторов. Например, использование пина в одном режиме, может препятствовать работе другого пина в другом режиме или вообще запретить его использование. А так как библиотека MRAA позволяет создавать платформонезависимый код, то она делает разработку менее сложной.
  • Надо помнить, что хотя MRAA может быть использована для написания платформонезависимого кода, разработчик всё ещё отвечает за то, чтобы код был устойчивым к ограничениям всех платформ, на которых он может быть запущен.

1.1 Загрузка библиотеки MRAA и документации по API

Пакет MRAA уже установлен на Intel Galileo и Intel Edison и может быть подключен к вашему коду как будет показано ниже. Последнюю версию исходных кодов можно также загрузить из репозитория Intel.
Документация на API доступна по адресу http://iotdk.intel.com/docs/master/mraa/

1.2 Имена GPIO пинов

В этой статье есть различные «пины». На аппаратные пины обычно ссылаются по номеру. Номер пина также может начинаться с буквы «D» для цифрового типа и буквы «A» для аналогово типа. Например, «D0» будет указывать на цифровой пин №0, а «A3» на аналоговой входной пин №3. Пин также может быть указан как GPIO6, т.е. это GPIO-пин номер 6, без указания его типа «D» или «A», т.е. он может быть и цифровым и аналоговым.

1.3 Линковка библиотеки

При компиляции прилинковывайте библиотеку командой –lmraa, например:

gcc -g blink.c -o blink -lmraa

1.4 Использование MRAA

Перед написанием кода помните следующее.

1. В начале программы MRAA должна быть проинициализирована следующим образом:

mraa_result_t rv;
rv = mraa_init();
if (rv != MRAA_SUCCESS)
	сообщение об ошибке
	. . .

2. Многие MRAA функции возвращают результат типа mraa_result_t. Очень важно убедиться, что вызов функции произошел без ошибок.

3. Примеры в данной статье не выполняют проверку ошибок, но всё же очень рекомендуется это делать.

4. После инициализации надо указать MRAA, каким способом вы хотите использовать пин (ввод/вывод, цифровой/аналоговый/ШИМ/AURT). Ниже будет показано, как это сделать.

5. Когда работа закончена (например, в конце программы), надо сказать MRAA освободить занимаемые пины, чтобы она сбросила все внутренние состояния и настройки. Ниже будет показано, как это сделать.

1.5 Подключение заголовочных файлов MRAA

Главный подключаемый файл MRAA это mraa.h. Он подключается вместе с другими аппаратно-зависимыми заголовочными файлами. Например:
Код для аналогового устройства должен подключать:

#include <mraa.h>
#include <mraa/aio.h>

Код для цифрового устройства должен подключать:

#include <mraa.h>
#include <mraa/gpio.h>

2. Использование MRAA с аналоговыми устройствами

Аналоговое устройство, это такое устройство, которое получает данные, измеряя значение напряжения на пине, меняющееся от 0 до максимально поддерживаемого. Это максимальное значение напряжения называется опорным напряжением (AREF – Analog Reference Voltage). Например, аналоговый сенсор давления может выдавать значение напряжения, начинающееся с 0 (соответствует отсутствию давления), и увеличивающееся при возрастании давления. Это напряжение на сенсоре переводится в число устройством, которое называется АЦП (Аналогово-цифровой преобразователь, ADC – analog-to-digital converter). Программа, которая работает с сенсором, считывает это число, выдаваемое с АЦП.

2.1 Опорное напряжение

Опорное напряжение обычно составляет 3.3 В или 5.0 В постоянного тока. Тем не менее, опорное напряжение может отличаться, так как некоторые платформы, например Intel Edison, позволяет устанавливать другое значение опорного напряжения вместо использования встроенного значения. Следовательно, надо знать точное значение опорного напряжения перед тем, как получать данные с устройства.

2.2 Разрядность АЦП

Разрядность АЦП очень важна, так как она определяет точность ваших измерений. Все АЦП, которые используются на платформе Intel, имеют разрядность 10 бит (1024 значения). И по крайней мере в случае с Intel Edison 12 бит (4096 значений).

Вы можете определить примерный шаг точности измерения напряжения, разделив значение опорного напряжения на количество доступных значений. Это значение потом можно использовать в приложении. Например, при опорном напряжении 5 В и разрядности 10 бит, получаем, что шаг АЦП равен примерно 5 мВ. Т.к. 5.0 / 1024 = 0.00488 В

2.3 Интерпретирование данных

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

2.4 Аналоговый пример

Датчик влажности от Grove это пример простого аналогово устройства. Это просто резистор, который изменяет уровень напряжения на аналоговом входе в соответствии с тем, какой уровень влажности был определен. Следующий пример показывает, как работает сенсор при подключении его к пину A0. В программе видно как инициализировать MRAA и пин A0, считать значение, распечатать его и затем освободить пин.

int main()
{
	/* initialize MRAA */
	mraa_init();
	/* create an MRAA analog context */
	mraa_aio_context m_aio;
	/* initialize A0 for use as an analog input */
	m_aio = mraa_aio_init(0);

	/* read the value, an integer */
	int value;
	value = mraa_aio_read(m_aio);

	/* print the value */
	printf(“The value returned was: %dn”, value);

	/* now release (close) the pin and exit */
	mraa_aio_close(m_aio);
	return(0)	;
}

С АЦП разрядностью 10 бит, возвращаемое значение будет от 0 до 1023. Как интерпретировать значение, зависит от устройства сенсора. Для сенсора Grove и разрядностью АЦП 10 бит, документация даёт следующие диапазоны для состояния сухо, влажно и сыро.

  • 0-299= сухо
  • 300-699 = влажно
  • 700-1023 = сыро

Важно помнить, что все сенсоры различны, и их значения бывает сложно декодировать. Учитывайте следующее:

1. У некоторых сенсоров есть джиттер (дрожание сигнала). В таком случае надо получить несколько последовательных значений с сенсора и найти среднее значение.

2. Если вы пишете MRAA драйвер для использования на различных платформах, важно, чтобы вы правильно указывали опорное напряжение и разрешение АЦП, которые будет использованы в вычислениях. Иначе получаемые данные могут быть бесполезны. В предыдущем примере нам не надо было знать опорное напряжение, но это не относится к другим более сложным аналоговым устройствам. На некоторых устройствах точное значение опорного напряжения и разрешение АЦП требуется, чтобы определить значение, получаемое с сенсора.

3. Значение на сенсоре не всегда бывает линейно связано с измеряемым параметром. В таком случае надо смотреть в документацию за формулами перевода значений или воспользоваться дополнительными библиотеками, например, UPM.

3. Использование MRAA с цифровыми устройствами

Цифровые устройства имеют дело с высоким и низким значением сигнала. Используются только эти два значения. Например, в системе работающей при напряжении 5 В, низкий уровень может соответствовать 0 В, а высокий 5 В. Обычно высокий уровень обозначается 1, а низкий 0.
Цифровые устройства могут быть настроены на ввод и вывод. Для использования в качестве входного устройства, вам надо использовать MRAA для чтения с цифрового пина и возвращать значение, показывающее каким было напряжение, высоким или низким.

MRAA предоставляет API для чтения и записи состояния цифрового пина. Дополнительно, можно подключить обработчик прерывания на цифровом входе. Для использования возможностей цифрового ввода и вывода в MRAA, надо подключить заголовочный файл.

#include <mraa/gpio.h>

3.1 Пример использования цифрового входа

Для примера возьмем простое цифровое устройство, кнопку. Когда кнопка не нажата, на ней высокое напряжение, при нажатии низкое.

int main()
{
	/* initialize MRAA */
	mraa_init();

	/* create an MRAA digital context */
	mraa_ai	o_context m_aio;

	/* initialize D2 for use as a digital pin */
	m_gpio = mraa_gpio_init(2);

	/* configure the digital pin as an input */
	mraa_gpio_dir(m_gpio, MRAA_GPIO_IN);

	/* read the value into an integer */
	int value = mraa_gpio_read(m_gpio);

	/* print the value */
	if (value != 0)
		printf(“The button is being pushedn”);
	else
		printf(“The button is not being pushedn”);

	/* now release (close) the pin and exit */
	mraa_gpio_close(m_gpio);
	return(0);
}

Как вы можете видеть, всё достаточно просто. Обратите внимание как мы указываем MRAA настроить пин на ввод с использованием функции mraa_gpio_dir(). Цифровые пины могут быть использованы и на ввод и на выход, в отличие от аналоговых, которые могут работать только на ввод.

3.2. Обработчики прерываний

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

MRAA предлагает возможность создать обработчик прерывания и соединить его с пином. В таком случае MRAA гарантирует, что ваша функция будет вызвана всякий раз, когда произойдет заданное изменение состояния пина (с 0 на 1 или с 1 на 0).

Используя такую возможность, легко написать функцию подсчета, и сказать MRAA, чтобы она вызывала её при изменении состояния. Ниже приведён простой пример подсчета числа переходов с высокого состояния сигнала на низкое.

/* first, create our counting variable */
volatile int counter = 0;

/* Now our simple counting function. */
/* This will be our interrupt handler. */
void intrHandler(void *arg)
{
	counter++;
}

/* now in our main() function */

int main()
{

	/* initialize MRAA */
	mraa_init();

	/* create an MRAA digital context */
	mraa_aio_context m_aio;

	/* initialize D2 for use as digital pin */
	m_gpio = mraa_gpio_init(2);

	/* configure the digital pin as an input */
	mraa_gpio_dir(m_gpio, MRAA_GPIO_IN);

	/* now, setup an interrupt handler. */
	/* Our function (intrHandler()) above will */
	/* be called whenever the pin goes from */
	/* HIGH to LOW */
	 */
	mraa_gpio_isr(m_gpio, MRAA_GPIO_EDGE_FALLING, intrHandler, NULL);

	/* sleep for 5 seconds, and then print out the current */
	/* value of counter */
	sleep(5);

	printf(“Counter = %dn”, counter);

	/* now, stop the interrupt handler and cleanup */
	mraa_gpio_isr_exit(m_gpio);

	/* now release (close) the pin and exit */
	mraa_gpio_close(m_gpio);
	return(0);
}

Обратите внимание на следующее в этом примере:

  • Переменная-счетчик определена с ключевым словом volatile. Это очень важно. Ключевое слово volatile говорит компилятору C, что переменная может быть изменена без его ведома и запрещает ему делать с ней какие-либо оптимизации. Без volatile компилятор может решить, что переменная совсем не изменяется, и будет всегда выводить «0». Любая переменная, с которой работают внутри обработчика прерывания и одновременно вне его, должна быть помечена как volatile.
  • В дополнение к MRAA_GPIO_EDGE_FALLING, функция mraa_gpio_isr() также поддерживает MRAA_GPIO_EDGE_RISING (для определения перехода с LOW на HIGH), и MRAA_GPIO_EDGE_BOTH (для определения обоих переходов). Обратите внимание, что не все типы переходов поддерживаются всеми платформами. Наиболее простой способ определить, что поддерживается, это проверить код ошибки, возвращаемый функцией mraa_gpio_isr().
  • Последний аргумент, передаваемый в mraa_gpio_isr() это указатель. Этот аргумент будет передан в обработчик прерывания intrHandler(). Он не обязательный и может быть использован для передачи дополнительных параметров в функцию-обработчик. В нашем примере нам не нужны такие возможности, и мы просто передадим NULL.
  • Вызов mraa_gpio_isr_exit() отключает обработчик прерываний, и его обязательно рекомендуется вызывать, чтобы исключить всякие неожиданные сюрпризы.
  • Только один обработчик прерываний может быть подключен к конкретному пину. Полное число пинов, которые могут управлять прерываниями в одно время, зависит от платформы, как и тип прерываний, который может быть использован (MRAA_GPIO_EDGE_RISING, MRAA_GPIO_EDGE_FALLING или MRAA_GPIO_EDGE_BOTH). Это ещё одна причина, чтобы проверять код ошибки при вызове функций MRAA.

3.3 Пример цифрового вывода

Использовать цифровой выход достаточно просто. Следующий пример меняет сигнал с высокого (1) на низкий (0) на цифровом выходе с периодом в 1 секунду. Нечто подобное можно использовать, чтобы помигать светодиодом, подключенным к пину.

int main()
{
	/* initialize MRAA */
	mraa_init();

	/* create an MRAA digital context */
	mraa_aio_context m_aio;

	/* initialize D13 for use as a digital pin */
	m_gpio = mraa_gpio_init(13);

	/* configure the digital pin as an output */
	mraa_gpio_dir(m_gpio, MRAA_GPIO_OUT);

	/* now run in a loop 10 times, blinking the output each second */
	int i;
	for (i=0; i<10; i++)
	{
		/* turn output on (HIGH) */
		mraa_gpio_write(m_gpio, 1);
		sleep(1);
		/* turn output off (LOW) */
		mraa_gpio_write(m_gpio, 0);
		sleep(1);
	}


	/* now release (close) the pin and exit */
	mraa_gpio_close(m_gpio);
	return(0);
}

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

4. Использование MRAA для широтно-импульсной модуляции (ШИМ)

Широтно-импульсная модуляция (ШИМ, PWM — Pulse-width modulation) это тип цифрового вывода. ШИМ задается двумя параметрами, периодом и коэффициентом заполнения:

  • период задает, как часто надо генерировать импульс;
  • коэффициент заполнения показывает, какая часть от периода должна находиться в высоком состоянии.

Например, если вы установите период в 2 мс, а коэффициент заполнения 50%, тогда вы получите повторяющиеся изменения: 1 мс значение сигнала будет высоким и 1 мс – низким. Изменение коэффициента заполнения может быть использовано для различных функций, например, управление яркостью светодиода или скоростью вращения мотора.

4.1 Основные правила использования

  • MRAA предлагает возможность сконфигурировать цифровой выход для использования в ШИМ режиме. Важно проверить вашу платформу, чтобы выяснить какой пин может работать в таком режиме. Это может отличаться на разных платформах.
  • Платформы могут отличаться по продолжительности периода, который доступен. Поэтому важно проверять ошибки вызова функций MRAA.
  • У некоторых устройств есть требования на длину периода, который может быть использован. Например, сервомотор обычно работает с периодом 20 мс.
  • Заголовочный файл, который надо подключить для работы с ШИМ:

#include <mraa/pwm.h>

4.2. Пример работы с ШИМ

В следующем примере будем изменять яркость светодиода. Мы сделаем это, установив период в 10 мс и будем увеличивать и уменьшать коэффициент заполнения каждые 100 мс.

int main()
{
	/* initialize MRAA */
	mraa_init();

	/* create an MRAA PWM context */
	mraa_pwm_context m_pwm;

	/* initialize D3 for use as a digital pin */
	m_pwm = mraa_gpio_init(3);

	/* set the period to 10ms */
	mraa_pwm_period_ms(m_pwm, 10);

	/* set the initial duty cycle to 0 */
	mraa_pwm_write(m_pwm, 0.0);

	/* enable PWM output */
	mraa_pwm_enable(m_pwm, 1);
/* now run in a loop 10 times, dimming or brightening /*
	/* the LED every 100ms */
	int i;
	float duty = 0.0;
	for (i=0; i<10; i++)
	{
		/* first, start at 0% duty cycle and increase to 100% */
		for (duty= 0.0; duty < 1.0; duty+=0.1)
		{
			mraa_pwm_write(m_pwm, duty);
			usleep(100000);
		}
		sleep(1);
		/* now decrease it to 0% */
		for (duty= 1.0; duty > 0.0; duty-=0.1)
		{
			mraa_pwm_write(m_pwm, duty);
			usleep(100000);
		}
		sleep(1);
	}

	/* disable PWM output and clean up */
	mraa_pwm_enable(m_pwm, 0);

	mraa_pwm_close(m_pwm);
	return(0);
}

Обратите внимание на следующее в этом примере:

  • Мы использовали функцию mraa_pwm_write() которая принимает значение в формате плавающей точки со значением 0.0 (выключено, или коэффициент заполнения 0%) и 1.0 (включено, или коэффициент заполнения 100%).
  • MRAA также предоставляет набор функций, которые позволяют непосредственно задавать длительность коэффициента заполнения, а не как проценты. Это может быть полезно для устройств, которые имеют специфические требования на период и величину времени, когда сигнал находится в состоянии HIGH, например, сервомотор.
  • В MRAA есть функции для задания периода в секундах, миллисекундах (как в примере ранее) и микросекундах. В MRAA также есть функция, которая позволяет задавать одним вызовом период и коэффициент заполнения.
  • Основная проблема в том, чтобы узнать поддерживает ли ваша платформа требуемый период. MRAA возвратит соответствующую ошибку если данный период не поддерживается.

5. Использование MRAA с Inter-Integrated Circuits (I2C)

Используя I2C, помните следующее:

  • I2C это двухпроводная двунаправленна шина. Она может работать с частотой 100 кГц, 400 кГц, 3.4 МГц.
  • I2C состоит из двух сигнальных линий – SCL (тактирование) и SDA (данные).
  • Устройства I2C имеют адрес, который должен быть уникальным на шине I2C. Несколько устройств может быть подключено к одной шине, но каждое должно иметь уникальный адрес, и только с одним из них можно соединяться в один момент времени.
  • В дополнение к адресу, I2C устройства могут иметь набор регистров (иногда называемые командами) в которые можно писать или читать. Запись и чтение этих регистров дает возможность коммуникации и управления.
  • Заголовочный файл для работы с I2C

#include <mraa/i2c.h>

5.1 Пример работы с I2C

В следующем примере мы будем работать с I2C-часами реального времени (DS1307) и считывать значение из регистра секунд. Мы установим контекст I2C MRAA на I2C-шине 0, используя адрес 0x68, и прочитаем секундный регистр. Полученное значение будем печатать каждые 10 секунд.

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

int main()
{
	/* initialize MRAA */
	mraa_init();

	/* create an MRAA I2C context */
	mraa_i2c_context m_i2c;

	/* initialize I2C on bus 0 */
	m_i2c = mraa_i2c_init(0);

	/* now run in a loop 10 times, reading the seconds */
	/* register and printing it.*/
	int i;
	for (i=0; i<10; i++)
	{
		char buf;

		/* always specify the address */
		mraa_i2c_address(m_i2c, 0x68);
		/* read in 1 byte.  mraa_i2c_read() always reads */
		/* starting at register 0x00 */
		mraa_i2c_read(m_i2c, &buf, 1); 

		printf(“The seconds returned was: %dn”, buf);
		sleep(1);
	}
	mraa_i2c_stop(m_pwm);
	return(0);
 }

Посмотрите пример выше:

  • Мы использовали функцию mraa_i2c_read(), которая начинает чтение из регистра 0x00. Для более гибкого использования, MRAA предлагает ещё несколько функций для чтения и записи в регистры. Также есть возможность писать и читать данные шириной 16 бит. Метод, который следует использовать, зависит от вашего устройства и программных требований.
  • Когда вы читаете слово шириной 16 бит, возможно, вам придется поменять порядок байтов, если такое требование есть у устройства.
  • Некоторые способы доступа работают лучше на некоторых устройствах. Например, на одном из нами проверенных устройств неправильно работала функция mraa_i2c_read(), и потребовалось использовать mraa_i2c_read_byte_data(). Поэтому, при разработке могут потребоваться дополнительные эксперименты.

6. Использование MRAA с Universal Asynchronous Receivers/Transmitters (UART)

  • Устройство на основе UART это, по существу, обычное устройство с последовательным портом. Как те устройства, которые мы подключали к COM-порту в прошлом. Обычно это дуплексное соединение (full duplex), которое работает на определенной скорости, измеряемой в бодах. Стандартная скорость для многих сенсоров 9600 бод (или 9600 бит в секунду).
  • Фактически у вас есть два провода. TX для передачи и RX для приема. Надо учитывать, что в случае большинства сенсоров, вы будете использовать другие уровни напряжения, чем те, которые используются на традиционном COM порту, который совместим со стандартом RS232. Обычно эти напряжения 5 В или 3.3 В, тогда как RS232 COM порт использует -15В…15В. Не присоединяйте такое устройство с низким напряжением непосредственно к COM-порту, если оно специально не поддерживается производителем сенсора. Так как вы можете испортить ваше устройство.
  • MRAA предлагает механизм, когда два пина D0 и D1 (Intel Galileo и Intel Edison) могут реализовывать аппаратный UART, позволяющий программе просто читать и писать данные на устройство с UART доступом. Когда MRAA настроен на правильные пины, вы можете общаться с устройством через /dev/ttyX, используя стандартные функции read() и write() из ОС Linux. Учтите, что MRAA только настраивает правильный роутинг пинов для подключения UART, и ваша программа сама должна открыть и правильно настроить TTY устройство и начать работать с ним.
  • Заголовочный файл для использования UART:

#include <mraa/uart.h>

6.1 Пример использования UART

В следующем примере мы используем вымышленный сенсор на основе UART, подключенный к D0 и D1. Он будет обозначаться UART 0.

Важно, чтобы после открытия устройства были правильно изменены настройки, которые были сделаны автоматически ядром Linux. Мы добавили функцию setupTTY() которая выполняет эти действия после открытия TTY устройства.

int setupTTY(int fd, speed_t baud)
{
  if (fd < 0)
	return 0; 
  
  struct termios termio;

  /* get current modes */
  tcgetattr(fd, &termio);

 /* setup for a 'raw' mode.  8bit, 1 stop bit, no parity, */
 /* no echo or special character handling, */
 /* no flow control or line editing semantics. */

  cfmakeraw(&termio);

  // set our baud rates
  cfsetispeed(&termio, baud);
  cfsetospeed(&termio, baud);

  // make it so
  if (tcsetattr(fd, TCSAFLUSH, &termio) < 0)
	{
	  fprintf(stderr, “%sn”, “tcsetattr failed”);
	  return 0;
	}

  return 1;
}

/* now our main function */
int main()
{
	/* initialize MRAA */
	mraa_init();

	/* create an MRAA UART context */
	mraa_uart_context m_uart;

	/* initialize UART 0 (pins D0 and D1 used for TX and RX) */
	m_uart = mraa_uart_init(0);

	/* now that we have our context, query MRAA */
	/* to get the file name of the TTY device we need to open. */

	char *devPath = mraa_uart_get_dev_path(m_uart);

	/* if this fails, we can go no further */
	if (!devPath)
	{
		fprintf(stderr, “%sn”, “Could not get device path”);
		return 0;
	}

	/* now that we have a device path, open it and set it up */
	int fd;
	if ((fd = open(devPath, O_RDWR)) == -1)
	{
		fprintf(stderr, “%sn”, “Could not open device path”);
		return 0;
	}

	/* now we are almost ready, call setupTTY() and from then on */
	/* we can read/write to the device normally. */
	/* We assume a baud rate of 9600/ */
if (!setupTTY(fd, B9600))
	{
		fprintf(stderr, “%sn”, “Could not setup TTY port”);
		return 0;
	}

	/* now we can use standard read and write calls */
	/* read(fd, ...) or write(fd, …) */

	/* when we are done, close the device and exit */
	close(fd);

	return(0);
}

Посмотрите предыдущий пример:

  • Используя UART-устройство, важно правильно настроить пины, запросить у MRAA путь к устройству, открыть и инициализировать устройство и затем использовать стандартные Unix функции, такие как read() и write().
  • Функции read() и write() блокируются, если нечего читать. Для того, чтобы исключить такое поведение, в большинстве случаев можно создать функцию, которая проверяет если ли доступные для чтения данные. Этого можно сделать с использованием системного вызова select(). Посмотрите драйвер UPM wt5001 для примера. Эта возможность реализована в функции dataAvailable().
  • В нашем примере мы предполагали, что скорость 9600 бод. Константа B9600 определена в заголовочном файле Linux’а. Конечно доступны и другие скорости. Вам надо выбрать правильную скорость в зависимости от устройства, которое вы используете.
  • Функция setupTTY(), используемая в примере, предполагает обычные установки. Если у вас будет устройство с другими требованиями, то возможно вам придётся её изменить.

7. Заключение

Библиотека MRAA упрощает процесс доступа и управления основными возможностями ввода-вывода на платформе Intel Galileo и Intel Edison. Мощная библиотека, MRAA предлагает последовательный подход для использования аналоговых, цифровых, ШИМ, I2C и UART устройств на этих и подобных платформах. Это дополнительный ключ к ящику с инструментами для интернета вещей.

Автор: varerysan

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js