пятница, 27 сентября 2013 г.

Урок 6. USB. Сторона компьютера

<< Назад к оглавлению

В прошлом уроке мы собирали прошивку для контроллера, чтобы он работал через USB. Но для взаимодействия с компьютером нам нужна еще и специальная программа, которая будет запускаться на компьютере.
Вот сейчас мы и будем ее создавать.
Опять же в пакете Microchip solutions есть пример, для нашего контроллера, но я переписал его по своему. Во-первых я сделал без использования графического интерфейса, и размер кода уменьшился раза в 3-4. Что намного лучше для изучения. Тем не менее, принцип работы один. код в стандартном примере от microchip работает так же как этот.
Программа написана в C++. Проект собран в бесплатной студенческой версии Visual C++ express 2010. Я буду давать общие идеи и комментарии по коду, но подразумеваю, что вы уже имеете хоть какой-то опыт программирования в C++.
Итак, начинаем

Здесь находится весь проект, включая исходный текст ссылка

Для того, чтобы читать и записывать данные через USB порт нам нужно получить указатель на наше устройство. Поскольку в отличие от старых портов, подключено может быть устройств свыше сотни, то получить этот указатель не так-то просто. Для того, чтобы это сделать мы будем обращаться к драйверам windows, а именно SetupAPI. Кстати, как только мы получим указатель, то будем общаться с USB портом, будто бы это файл.
Передача данных будет занимать лишь пару команд. Но вот подготовка!
Поскольку мы программируем в С++ то нам нужно быть очень аккуратными с типами данных.
Создаем консольный проект win32. И добавляем туда единственный файл main.cpp

Итак, нам необходимо подключить некоторые библиотеки.
#include <iostream>
#include <Windows.h>
#include <setupapi.h>

Так же подключаем внешнюю библиотеку:
#pragma comment (lib, "Setupapi.lib")

Первая описанная функция в программе - это getUSBHandle(). Ее описание - в комментариях кода. Да и вообще основные комментарии приведены в коде. Она служит для того, чтобы найти наше устройство и подготовить указатели, чтобы мы могли записывать в устройство и читать из него.
Если в двух словах, то она использует стандартные windows функции для доступа к драйверам USB и через них получает указатель на само устройство.
Если интересно, что все эти функции делают и как, то обращайтесь к MSDN или к книге Агурова, что лежит в оглавлении. Что важно знать: у каждого устройства есть путь, и нам важно получить его. Мы сначала проверяем, совпадает ли ID с устройством, что мы ищем. А потом находим путь устройства.Мы ищем только среди устройств HID класса. это определяется в переменной Guid. Остальное см в комментариях программы
Следующая функция - writeReadUSB. Это просто вспомогательная функция, которая записывает в наше устройство. Обращаю внимание, что запись и чтение устройства после того, как мы создали указатель на него реализуется с помощью стандартных комманд WriteFile и ReadFile
И после этого уже мы видим функцию main с которой и начинается выполнение программы. Она вызывает getUSBHandle, пока мы не получим указатель на устройство, потом читает с клавиатуры комманду и в зависимости от нее, передает и читает данные с USB устройства.
В проекте по ссылке выше лежит исходный код с комментариями и сама скомпилированная программа. Удачи.

В процессе поиска ошибки я наткнулся на библиотеку hidapi. Она является кроссплатформенной. И Только для работы с hid устройствами. Очень проста в использовании. Привожу проект под нее. ссылка.
Hidapi скачан с официального сайта. Для того чтобы начать проект нужно добавить setupapi.lib в линковщик. project->properties->linker->input и подписать туда setupapi.lib;
Удачи.
Нашел пристойное описание библиотеки здесь: http://microsin.net/programming/PC/multi-platform-hid-api.html.
Спасибо!