У меня возникли проблемы с получением программы SPI я работаю на себя правильно, и это, кажется, какой-то вопрос с SPI_IOC_MESSAGE (N) макро.SPI_IOC_MESSAGE (N) макрос дает мне подходит
Вот пример кода, который не работает (IOCTL возвращает EINVAL (22)):
std::vector<spi_ioc_transfer> tr;
<code that fills tr with 1+ transfers>
// Hand the transmission(s) off to the SPI driver
if (tr.size() > 0)
{
int ret = ioctl(fd, SPI_IOC_MESSAGE(tr.size()), tr.data());
if (ret < 1)
{
int err = errno;
}
}
Мой тестовый код прямо сейчас создает вектор длины 1. Если я явно изменить код:
int ret = ioctl(fd, SPI_IOC_MESSAGE(1), tr.data());
... тогда ioctl (...) преуспевает, а мои биты идут по трубе. Глядя на расширение макроса SPI_IOC_MESSAGE в Eclipse, я не понимаю, почему это недовольство.
Предложения?
Я кросс-компиляции для Linux/ARM (Beaglebone Black) из 64-битной Linux VM, но я не могу видеть, что затрагивая макрос.
EDIT: Вот два макроса разложения из С препроцессора
int ret = ioctl(fd, (((1U) << (((0 +8)+8)+14)) | ((('k')) << (0 +8)) | (((0)) << 0) | ((((sizeof(char[((((tr.size())*(sizeof (struct spi_ioc_transfer))) < (1 << 14)) ? ((tr.size())*(sizeof (struct spi_ioc_transfer))) : 0)])))) << ((0 +8)+8))), tr.data());
и буквальным:
int ret = ioctl(fd, (((1U) << (((0 +8)+8)+14)) | ((('k')) << (0 +8)) | (((0)) << 0) | ((((sizeof(char[((((1)*(sizeof (struct spi_ioc_transfer))) < (1 << 14)) ? ((1)*(sizeof (struct spi_ioc_transfer))) : 0)])))) << ((0 +8)+8))), tr.data());
Абсолютно отвратительные, но я не вижу ничего удивительного в как tr.size()
будет использоваться там.
Редактировать, чтобы включить то, что, кажется, ответ
#ifdef __cplusplus /* If this is a C++ compiler, use C linkage */
extern "C" {
#endif
#include <linux/spi/spidev.h>
#ifdef __cplusplus /* If this is a C++ compiler, use C linkage */
}
#endif
Обертывание Линукс SPI включают файл в «экстерном C» инструктирует систему, чтобы рассматривать этот раздел как обычный старый C, и это, кажется, позвольте мне позвонить SPI_IOC_MESSAGE(tr.size())
или SPI_IOC_MESSAGE(an_int)
и иметь правильную вещь (проверено с помощью GDB stepthrough и анализатора сигналов).
Похоже, что это где-то близко к первопричине. Я изменил свой код, чтобы обернуть файл SPI Linux, включенный в директиву «extern C» и, похоже, исправил поведение. –