11 #include <sys/types.h>
15 #include <sys/socket.h>
16 #include <netinet/in.h>
17 #include <arpa/inet.h>
18 #include <sys/ioctl.h>
20 #include <net/if_arp.h>
26 #include <sys/ioctl.h>
27 #include <linux/spi/spidev.h>
44 int socketMac = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
48 printf(
"Lookup socket creation failed");
58 ifc.ifc_len =
sizeof(buf);
62 if (ioctl(socketMac, SIOCGIFCONF, &ifc) < 0)
65 struct ifreq* it = ifc.ifc_req;
66 const struct ifreq*
const end = it + (ifc.ifc_len /
sizeof(
struct ifreq));
68 for (; it != end; ++it)
70 strcpy(ifr.ifr_name, it->ifr_name);
72 if (ioctl(socketMac, SIOCGIFFLAGS, &ifr))
75 if (ifr.ifr_flags & IFF_LOOPBACK)
78 if (ioctl(socketMac, SIOCGIFHWADDR, &ifr))
81 if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER)
84 memcpy(_macAddress, ifr.ifr_hwaddr.sa_data, IFHWADDRLEN);
86 ioctl(socketMac, SIOCGIFADDR, &ifr);
88 struct sockaddr_in* ipaddr = (
struct sockaddr_in*)&ifr.ifr_addr;
89 _ipAddress = ntohl(ipaddr->sin_addr.s_addr);
92 ioctl(socketMac, SIOCGIFNETMASK, &ifr);
93 struct sockaddr_in* netmask = (
struct sockaddr_in*)&ifr.ifr_netmask;
94 _netmask = ntohl(netmask->sin_addr.s_addr);
103 char line[100], *p, *c, *g, *saveptr;
105 f = fopen(
"/proc/net/route",
"r");
107 while (fgets(line, 100, f))
109 p = strtok_r(line,
" \t", &saveptr);
110 c = strtok_r(NULL,
" \t", &saveptr);
111 g = strtok_r(NULL,
" \t", &saveptr);
113 if (p != NULL && c != NULL)
115 if (strcmp(c,
"00000000") == 0)
121 _defaultGateway = ntohl(strtol(g, &pEnd, 16));
139 struct timespec spec;
141 clock_gettime(CLOCK_MONOTONIC, &spec);
142 return spec.tv_sec * 1000 + round(spec.tv_nsec / 1.0e6);
148 ts.tv_sec =
millis / 1000;
149 ts.tv_nsec = (
millis % 1000) * 1000000;
150 nanosleep(&ts, NULL);
155 execv(_args[0], _args);
160 printf(
"A fatal error occured. Stopping.\n");
168 if (_multicastSocketFd >= 0)
171 _multicastAddr = addr;
172 _multicastPort = port;
174 struct ip_mreq command;
177 struct sockaddr_in sin;
178 memset(&sin, 0,
sizeof(sin));
179 sin.sin_family = AF_INET;
180 sin.sin_addr.s_addr = htonl(INADDR_ANY);
181 sin.sin_port = htons(port);
183 _multicastSocketFd = socket(AF_INET, SOCK_DGRAM, 0);
185 if (_multicastSocketFd == -1)
194 if (setsockopt(_multicastSocketFd, SOL_SOCKET, SO_REUSEADDR, &loop,
sizeof(loop)) < 0)
196 perror(
"setsockopt:SO_REUSEADDR");
200 if (bind(_multicastSocketFd, (
struct sockaddr*)&sin,
sizeof(sin)) < 0)
209 if (setsockopt(_multicastSocketFd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop,
sizeof(loop)) < 0)
211 perror(
"setsockopt:IP_MULTICAST_LOOP");
216 command.imr_multiaddr.s_addr = htonl(addr);
217 command.imr_interface.s_addr = htonl(INADDR_ANY);
219 if (setsockopt(_multicastSocketFd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &command,
sizeof(command)) < 0)
221 perror(
"setsockopt:IP_ADD_MEMBERSHIP");
225 uint32_t flags = fcntl(_multicastSocketFd, F_GETFL);
227 fcntl(_multicastSocketFd, F_SETFL, flags);
232 struct ip_mreq command;
233 command.imr_multiaddr.s_addr = htonl(_multicastAddr);
234 command.imr_interface.s_addr = htonl(INADDR_ANY);
236 if (setsockopt(_multicastSocketFd,
239 &command,
sizeof(command)) < 0)
241 perror(
"setsockopt:IP_DROP_MEMBERSHIP");
244 close(_multicastSocketFd);
245 _multicastSocketFd = -1;
250 struct sockaddr_in address = {0};
251 address.sin_family = AF_INET;
252 address.sin_addr.s_addr = htonl(_multicastAddr);
253 address.sin_port = htons(_multicastPort);
259 retVal = sendto(_multicastSocketFd, buffer, len, 0, (
struct sockaddr*)&address,
sizeof(address));
263 if (errno != EAGAIN && errno != EWOULDBLOCK)
266 }
while (retVal == -1);
275 struct sockaddr_in sin;
277 sin_len =
sizeof(sin);
278 ssize_t len = recvfrom(_multicastSocketFd, buffer, maxLen, 0, (
struct sockaddr*)&sin, &sin_len);
290 return _mappedFile + 2;
301 #define FLASHSIZE 0x10000
302 void LinuxPlatform::doMemoryMapping()
304 _fd = open(_flashFilePath.c_str(), O_RDWR | O_CREAT, S_IRWXU | S_IRGRP | S_IROTH);
308 puts(
"Error in file opening");
314 uint32_t ret = fstat(_fd, &st);
318 puts(
"Error in fstat");
322 size_t len_file = st.st_size;
324 if (len_file < FLASHSIZE)
326 if (ftruncate(_fd, FLASHSIZE) != 0)
328 puts(
"Error extending file");
332 len_file = FLASHSIZE;
335 unsigned char* addr = (
unsigned char*)mmap(NULL, len_file, PROT_READ | PROT_WRITE, MAP_SHARED, _fd, 0);
337 if (addr[0] != 0xAF || addr[1] != 0xFE)
339 memset(addr, 0, FLASHSIZE);
344 if (addr == MAP_FAILED)
346 puts(
"Error in mmap");
356 printf(
"SPI device closed.\r\n");
361 uint16_t spiDelay = 0;
362 uint32_t spiSpeed = 8000000;
365 struct spi_ioc_transfer spi;
370 memset(&spi, 0,
sizeof(spi));
372 spi.tx_buf = (uint64_t)data;
373 spi.rx_buf = (uint64_t)data;
375 spi.delay_usecs = spiDelay;
376 spi.speed_hz = spiSpeed;
377 spi.bits_per_word = spiBPW;
379 return ioctl(_spiFd, SPI_IOC_MESSAGE(1), &spi);
384 if ((_spiFd = open(
"/dev/spidev0.0", O_RDWR)) < 0)
386 printf(
"ERROR: SPI setup failed! Could not open SPI device!\r\n");
395 if (ioctl(_spiFd, SPI_IOC_WR_MODE, &mode) < 0)
397 printf(
"ERROR: SPI Mode Change failure: %s\n", strerror(errno));
402 if (ioctl(_spiFd, SPI_IOC_WR_BITS_PER_WORD, &spiBPW) < 0)
404 printf(
"ERROR: SPI BPW Change failure: %s\n", strerror(errno));
409 if (ioctl(_spiFd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) < 0)
411 printf(
"ERROR: SPI Speed Change failure: %s\n", strerror(errno));
416 printf(
"SPI device setup ok.\r\n");
421 _flashFilePath = path;
426 return _flashFilePath;
433 return read(_uartFd, buffer, length);
440 if (read(_uartFd, &x, 1) != 1)
445 return ((
int)x) & 0xFF ;
450 return write(_uartFd, buffer, size) ;
455 return write(_uartFd, &data, 1) ;
462 if (ioctl(_uartFd, FIONREAD, &result) == -1)
483 struct termios options;
486 _uartFd = open(
"/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
491 fcntl(_uartFd, F_SETFL, 0);
493 if (tcgetattr(_uartFd, &options) != 0)
500 memset(&options, 0,
sizeof(options));
503 cfsetispeed(&options, B19200);
504 cfsetospeed(&options, B19200);
507 options.c_cflag |= PARENB;
508 options.c_cflag &= ~PARODD;
509 options.c_cflag &= ~CSTOPB;
510 options.c_cflag &= ~CSIZE;
511 options.c_cflag |= CS8;
514 options.c_cflag |= (CLOCAL | CREAD);
517 options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
518 options.c_iflag = IGNPAR;
519 options.c_oflag &= ~OPOST;
520 options.c_cc[VMIN] = 0;
521 options.c_cc[VTIME] = 10;
522 tcflush(_uartFd, TCIOFLUSH);
524 if (tcsetattr(_uartFd, TCSAFLUSH, &options) != 0)
536 char buf[8 *
sizeof(uint64_t) + 1];
537 char* str = &buf[
sizeof(buf) - 1];
547 *--str = c < 10 ? c +
'0' : c +
'A' - 10;
567 void print(
unsigned char num,
int base)
593 void print(
unsigned int num,
int base)
619 void print(
unsigned long num,
int base)
632 void print(
unsigned long long num,
int base)
698 printf(
"%lX\n", num);
700 printf(
"%ld\n", num);
711 printf(
"%lX\n", num);
713 printf(
"%ld\n", num);
722 void println(
unsigned long long num,
int base)
770 _args =
new char* [argc + 1];
771 memcpy(_args, argv, argc *
sizeof(
char*));
776 #define MAX_STRBUF_SIZE 100
777 #define MAX_NUM_GPIO 64
779 static int gpioFds[MAX_NUM_GPIO] =
853 char buffer[MAX_STRBUF_SIZE];
858 fprintf(stderr,
"Export GPIO pin %d\n", pin);
860 fd = open(
"/sys/class/gpio/export", O_WRONLY);
864 perror(
"Could not export GPIO pin(open)!\n");
868 bytes = snprintf(buffer, MAX_STRBUF_SIZE,
"%d", pin);
869 res =
write(fd, buffer, bytes);
873 perror(
"Could not export GPIO pin(write)!\n");
889 char buffer[MAX_STRBUF_SIZE];
894 fprintf(stderr,
"Unexport GPIO pin %d\n", pin);
898 fd = open(
"/sys/class/gpio/unexport", O_WRONLY);
902 perror(
"Could not unexport GPIO pin(open)!\n");
906 bytes = snprintf(buffer, MAX_STRBUF_SIZE,
"%d", pin);
907 res =
write(fd, buffer, bytes);
911 perror(
"Could not unexport GPIO pin(write)!\n");
926 char path[MAX_STRBUF_SIZE];
930 fprintf(stderr,
"Set GPIO direction for pin %d to %s\n", pin, (dir == INPUT) ?
"INPUT" :
"OUTPUT");
932 snprintf(path, MAX_STRBUF_SIZE,
"/sys/class/gpio/gpio%d/direction", pin);
933 fd = open(path, O_WRONLY);
937 perror(
"Could not set mode for GPIO pin(open)!\n");
944 res =
write(fd,
"in", 2);
948 res =
write(fd,
"out", 3);
958 perror(
"Could not set mode for GPIO pin(write)!\n");
971 char path[MAX_STRBUF_SIZE];
974 snprintf(path, MAX_STRBUF_SIZE,
"/sys/class/gpio/gpio%d/value", pin);
976 if (gpioFds[pin] < 0)
977 gpioFds[pin] = open(path, O_RDWR);
979 if (gpioFds[pin] < 0)
981 perror(
"Could not read from GPIO(open)!\n");
985 lseek(gpioFds[pin], 0L, SEEK_SET);
987 if (read(gpioFds[pin], &c, 1) < 0)
989 perror(
"Could not read from GPIO(read)!\n");
993 return (c ==
'0') ? LOW : HIGH;
1001 char path[MAX_STRBUF_SIZE];
1004 snprintf(path, MAX_STRBUF_SIZE,
"/sys/class/gpio/gpio%d/value", pin);
1006 if (gpioFds[pin] < 0)
1007 gpioFds[pin] = open(path, O_RDWR);
1009 if (gpioFds[pin] < 0)
1011 perror(
"Could not write to GPIO(open)!\n");
1018 res =
write(gpioFds[pin],
"0\n", 2);
1022 res =
write(gpioFds[pin],
"1\n", 2);
1032 perror(
"Could not write to GPIO(write)!\n");
1046 char path[MAX_STRBUF_SIZE];
1049 snprintf(path, MAX_STRBUF_SIZE,
"/sys/class/gpio/gpio%d/edge", pin);
1051 fd = open(path, O_WRONLY | O_NONBLOCK);
1055 perror(
"Could not set GPIO edge detection(open)!\n");
1062 strncpy(path,
"rising", 8);
1066 strncpy(path,
"falling", 8);
1070 strncpy(path,
"both", 8);
1074 strncpy(path,
"none", 8);
1082 write(fd, path, strlen(path) + 1);
1096 char path[MAX_STRBUF_SIZE];
1098 struct pollfd polldat[1];
1099 char buf[MAX_STRBUF_SIZE];
1103 snprintf(path, MAX_STRBUF_SIZE,
"/sys/class/gpio/gpio%d/value", pin);
1104 fd = open(path, O_RDONLY | O_NONBLOCK);
1108 perror(
"Could not wait for GPIO edge(open)!\n");
1113 memset((
void*)buf, 0,
sizeof(buf));
1114 memset((
void*)polldat, 0,
sizeof(polldat));
1116 polldat[0].events = POLLPRI;
1119 lseek(fd, 0, SEEK_SET);
1120 rc = read(fd, buf, MAX_STRBUF_SIZE - 1);
1122 rc = poll(polldat, 1, timeout);
1127 perror(
"Could not wait for GPIO edge(poll)!\n");
1139 if (polldat[0].revents & POLLPRI)
1144 perror(
"Could not wait for GPIO edge(read)!\n");
1151 return (1 + atoi(buf));
1160 struct timeval tNow, tLong, tEnd;
1162 gettimeofday(&tNow, NULL);
1163 tLong.tv_sec = howLong / 1000000;
1164 tLong.tv_usec = howLong % 1000000;
1165 timeradd(&tNow, &tLong, &tEnd);
1167 while (timercmp(&tNow, &tEnd, < ))
1168 gettimeofday(&tNow, NULL);
1173 struct timespec sleeper;
1174 unsigned int uSecs = howLong % 1000000;
1175 unsigned int wSecs = howLong / 1000000;
1179 else if (howLong < 100)
1183 sleeper.tv_sec = wSecs;
1184 sleeper.tv_nsec = (long)(uSecs * 1000L);
1185 nanosleep(&sleeper, NULL);
1191 struct sockaddr_in address = {0};
1192 address.sin_family = AF_INET;
1193 address.sin_addr.s_addr = htonl(addr);
1194 address.sin_port = htons(port);
1200 retVal = sendto(_multicastSocketFd, buffer, len, 0, (
struct sockaddr*)&address,
sizeof(address));
1204 if (errno != EAGAIN && errno != EWOULDBLOCK)
1207 }
while (retVal == -1);
1215 memcpy(mac_address, _macAddress, IFHWADDRLEN);
1230 return _defaultGateway;