Raspberry Pi IoT In C Using Linux Drivers

Programs

Cdrivers360

We have decided not to make the programs available as a download because this is not the point of the book - the programs are not finished production code but something you should type in and study.

The best solution is to provide the source code of the programs in a form that can be copied and pasted into a NetBeans of VS Code project. 

 

Note: The VS Code task listings are at the very end of this page.

The only downside is that you have to create a project to paste the code into.

To do this follow the instructionin the book-- in particular make sure you have added any libraries to the link step and are running as root if required. 

All of the programs below were copy and pasted from working programs in the IDE. They have been formatted using the built in formatter and hence are not identical in layout to the programs in the book. This is to make copy and pasting them easier. The programs in the book are formatted to be easy to read on the page.

If anything you consider important is missing or if you have any requests or comments  contact:

This email address is being protected from spambots. You need JavaScript enabled to view it. 

Page 22

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
    printf("Hello C World");
    int test = 42;
    printf("%d\n", test);
    return (EXIT_SUCCESS);
}

 

Page 32

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>

int main(int argc, char **argv)
{
    int fd = open("/sys/class/leds/led0/trigger", O_WRONLY);
    write(fd, "none",4);
    close(fd);
    fd = open("/sys/class/leds/led0/brightness", O_WRONLY);
    while (1)
    {
        write(fd, "0",1);
        sleep(2);
        write(fd, "1",1);
        sleep(2);
    }
}

Page 32

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char **argv)
{
    int fd = open("/sys/class/leds/led0/trigger", O_WRONLY);
    write(fd, "timer",5);
    close(fd);
    fd = open("/sys/class/leds/led0/delay_on", O_WRONLY);
    write(fd, "2000",4);
    close(fd);
    fd = open("/sys/class/leds/led0/delay_off", O_WRONLY);
    write(fd, "3000",4);
}

 

Page 42

#define _GNU_SOURCE
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int res;
int main(int argc, char **argv)
{
    for (;;)
    {
        res = gpiod_ctxless_set_value("0", 4, 1, 1, "output test", NULL, NULL);
    }
}

  

Page 43 

#define _DEFAULT_SOURCE
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
int res;

int delayms(int ms)
{
    struct timespec delay = {0, ms * 1000 * 1000};
    return nanosleep(&delay, NULL);
}

int main(int argc, char **argv)
{

    for (;;)
    {
        res = gpiod_ctxless_set_value("0", 4, 1, 1, "output test",
                                      (gpiod_ctxless_set_value_cb)delayms, (void *)100);
        res = gpiod_ctxless_set_value("0", 4, 0, 1, "output test",
                                      (gpiod_ctxless_set_value_cb)delayms, (void *)100);
    }

 

Page 44 

#define _DEFAULT_SOURCE
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
int res;
int delayms(int ms)
{
    struct timespec delay = {0, ms * 1000 * 1000};
    return nanosleep(&delay, NULL);
}
int main(int argc, char **argv)
{
    int offsets[] = {4, 27};
    int state1[] = {1, 0};
    int state2[] = {0, 1};
    for (;;)
    {
        gpiod_ctxless_set_value_multiple("0", offsets, state1, 2, 1,
                                         "output test", (gpiod_ctxless_set_value_cb)delayms, (void *)1);
        gpiod_ctxless_set_value_multiple("0", offsets, state2, 2, 1,
                                         "output test", (gpiod_ctxless_set_value_cb)delayms, (void *)2);
    }

Page 46

#define _GNU_SOURCE
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    int res;
    struct gpiod_chip *chip = gpiod_chip_open_by_number(0);
    const char *name = gpiod_chip_name(chip);
    int num = gpiod_chip_num_lines(chip);
    printf("%s %d", name, num);
    gpiod_chip_close(chip);

 

Page 48 

#define _GNU_SOURCE
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    int res;
    struct gpiod_chip *chip = gpiod_chip_open_by_number(0);
    struct gpiod_line *line4 = gpiod_chip_get_line(chip, 4);
    res = gpiod_line_request_output(line4, "test output", 0);

    for (;;)
    {
        res = gpiod_line_set_value(line4, 1);
        res = gpiod_line_set_value(line4, 0);
    };

 

Page 52 

#define _GNU_SOURCE
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    int res;
    struct gpiod_chip *chip = gpiod_chip_open_by_number(0);
    struct gpiod_line_bulk bulk;
    gpiod_line_bulk_init(&bulk);
    gpiod_line_bulk_add(&bulk, gpiod_chip_get_line(chip, 4));
    gpiod_line_bulk_add(&bulk, gpiod_chip_get_line(chip, 17));

    res = gpiod_line_request_bulk_output(&bulk, "test", 0);
    for (;;)
    {
        gpiod_line_set_value_bulk(&bulk, (int[2]){0, 1});
        gpiod_line_set_value_bulk(&bulk, (int[2]){1, 0});
    };
}

Page 54 

#define _GNU_SOURCE
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>

void gpiod_line_release(struct gpiod_line *line);

int main(int argc, char **argv)
{
    int res;
    struct timespec delay = {0, 10 * 1000 * 1000};
    struct timespec time1, time2;

    struct gpiod_chip *chip = gpiod_chip_open_by_number(0);
    struct gpiod_line *line4 = gpiod_chip_get_line(chip, 4);

    res = gpiod_line_request_input(line4, "RMeasure");
    nanosleep(&delay, NULL);
    gpiod_line_release(line4);

    res = gpiod_line_request_output(line4, "RMeasure", 0);
    nanosleep(&delay, NULL);
    gpiod_line_release(line4);

    clock_gettime(CLOCK_REALTIME, &time1);
    gpiod_line_request_input(line4, "RMeasure");
    while (gpiod_line_get_value(line4) == 0)
    {
    };
    clock_gettime(CLOCK_REALTIME, &time2);
    printf("Time=%d", (time2.tv_nsec - time1.tv_nsec) / 1000);
}  

Page 58

#define __ARM_PCS_VFP
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/gpio.h>
int main(int argc, char **argv)
{
    int fd;
    struct gpiochip_info info;

    fd = open("/dev/gpiochip0", O_RDONLY);

    int ret = ioctl(fd, GPIO_GET_CHIPINFO_IOCTL, &info);
    close(fd);

    printf("label: %s\n name: %s\n number of lines: %u\n",
           info.label, info.name, info.lines);
    return 0;
}

Page 61

#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/gpio.h>

int main(int argc, char **argv)
{
    int fd, ret;

    struct gpiohandle_request req;
    req.lineoffsets[0] = 4;
    req.lineoffsets[1] = 17;
    req.flags = GPIOHANDLE_REQUEST_OUTPUT;
    req.default_values[0] = 0;
    req.default_values[1] = 0;
    strcpy(req.consumer_label, "Output test");
    req.lines = 2;

    fd = open("/dev/gpiochip0", O_RDONLY);
    ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
    close(fd);

    struct gpiohandle_data data;
    data.values[0] = 0;
    data.values[1] = 1;
    while (1)
    {
        data.values[0] = !data.values[0];
        data.values[1] = !data.values[1];
        ret = ioctl(req.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
    }
    return 0;

Page 62 

#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/gpio.h>
int main(int argc, char **argv)
{
    int fd, ret;
    struct gpiohandle_request req;
    req.lineoffsets[0] = 4;
    req.lineoffsets[1] = 17;
    req.flags = GPIOHANDLE_REQUEST_INPUT;
    strcpy(req.consumer_label, "Input test");
    req.lines = 2;
    fd = open("/dev/gpiochip0", O_RDONLY);
    ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
    close(fd);
    struct gpiohandle_data data;
    ret = ioctl(req.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);
    printf("%hhu , %hhu", data.values[0], data.values[1]);
    close(req.fd);
    return 0;
}

Page 63 

#define _GNU_SOURCE
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/gpio.h>
#include <sys/ioctl.h>
#include <time.h>
int main(int argc, char **argv)
{
    int fd, ret;
    struct timespec delay = {0, 10 * 1000 * 1000};
    struct timespec time1, time2;
    fd = open("/dev/gpiochip0", O_RDONLY);
    struct gpiohandle_request req;
    req.lineoffsets[0] = 4;
    strcpy(req.consumer_label, "RC Measure");
    req.lines = 1;

    req.flags = GPIOHANDLE_REQUEST_INPUT;
    ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
    nanosleep(&delay, NULL);
    close(req.fd);

    req.flags = GPIOHANDLE_REQUEST_OUTPUT;
    struct gpiohandle_data data;
    data.values[0] = 0;
    ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
    ret = ioctl(req.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
    nanosleep(&delay, NULL);
    close(req.fd);

    req.flags = GPIOHANDLE_REQUEST_INPUT;
    clock_gettime(CLOCK_REALTIME, &time1);
    ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
    ret = ioctl(req.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);

    while (data.values[0] == 0)
    {
        ret = ioctl(req.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data)
    }
    clock_gettime(CLOCK_REALTIME, &time2);
    printf("Time=%d", (time2.tv_nsec - time1.tv_nsec) / 1000);
    return 0;

Page 71

#define _GNU_SOURCE
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    int res;
    struct gpiod_chip *chip = gpiod_chip_open_by_number(0);
    struct gpiod_line *line4 = gpiod_chip_get_line(chip, 4);
    gpiod_line_request_both_edges_events(line4, "event test");
    gpiod_line_event_wait(line4, NULL);
    printf("Event on line 4");
}

Page 72

#define _GNU_SOURCE
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>

void gpiod_line_release(struct gpiod_line *line);
int main(int argc, char **argv)
{
    int res;

    struct timespec delay = {0, 10 * 1000 * 1000};
    struct timespec time1;

    struct gpiod_chip *chip = gpiod_chip_open_by_number(0);
    struct gpiod_line *line4 = gpiod_chip_get_line(chip, 4);

    res = gpiod_line_request_input(line4, "RMeasure");
    nanosleep(&delay, NULL);
    gpiod_line_release(line4);

    res = gpiod_line_request_output(line4, "RMeasure", 0);
    nanosleep(&delay, NULL);
    gpiod_line_release(line4);
    clock_gettime(CLOCK_REALTIME, &time1);

    gpiod_line_request_rising_edge_events(line4, "RMeasuret");
    struct gpiod_line_event event;
    gpiod_line_event_read(line4, &event);
    printf("Event on line 4 %d, %d", event.event_type,
           (event.ts.tv_nsec - time1.tv_nsec) / 1000);
}

 

Page 73 

#define _GNU_SOURCE
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>

void gpiod_line_release(struct gpiod_line *line);
int main(int argc, char **argv)
{
    int res;
    struct timespec time1;

    struct gpiod_chip *chip = gpiod_chip_open_by_number(0);
    struct gpiod_line *line4 = gpiod_chip_get_line(chip, 4);

    res = gpiod_line_request_both_edges_events(line4, "Measure");

    struct gpiod_line_event event;
    while (true)
    {
        do
        {
            res = gpiod_line_event_read(line4, &event);
        } while (event.event_type != GPIOD_LINE_EVENT_RISING_EDGE);

        time1.tv_nsec = event.ts.tv_nsec;

        do
        {
            res = gpiod_line_event_read(line4, &event);
        } while (event.event_type != GPIOD_LINE_EVENT_FALLING_EDGE);

        printf("Pulse Width %d \r\n",
               (event.ts.tv_nsec - time1.tv_nsec) / 1000);
        fflush(stdout);
    }

Page 74

#define _GNU_SOURCE
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>

void gpiod_line_release(struct gpiod_line *line);
int main(int argc, char **argv)
{
    int res;
    struct gpiod_chip *chip = gpiod_chip_open_by_number(0);
    struct gpiod_line *line4 = gpiod_chip_get_line(chip, 4);

    res = gpiod_line_request_input(line4, "button");
    printf("Press button \n\r");
    fflush(stdout);
    sleep(20);
    if (gpiod_line_get_value(line4) == 1)
    {
        printf("button pressed");
    }
    else
    {
        printf("button not pressed");
    }
}

Page 75

#define _GNU_SOURCE
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>

void gpiod_line_release(struct gpiod_line *line);
int main(int argc, char **argv)
{
    int res;
    struct timespec timeout = {0, 0};

    struct gpiod_chip *chip = gpiod_chip_open_by_number(0);
    struct gpiod_line *line4 = gpiod_chip_get_line(chip, 4);

    res = gpiod_line_request_both_edges_events(line4, "button");

    printf("Press button \n\r");
    fflush(stdout);
    sleep(20);
    struct gpiod_line_event event;

    res = gpiod_line_event_wait(line4, &timeout);
    if (res > 0)
    {
        res = gpiod_line_event_read(line4, &event);
        printf("button pressed %d", event.ts.tv_nsec);
    }
    else
    {
        printf("button not pressed");
    }

Page 276

#define _GNU_SOURCE
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>

int gpiod_line_event_poll(struct gpiod_line *line,
                          struct gpiod_line_event *event);

int main(int argc, char **argv)
{
    int res;

    struct gpiod_chip *chip = gpiod_chip_open_by_number(0);
    struct gpiod_line *line4 = gpiod_chip_get_line(chip, 4);

    res = gpiod_line_request_both_edges_events(line4, "button");

    struct gpiod_line_event event;

    while (true)
    {
        res = gpiod_line_event_poll(line4, &event);
        if (res > 0)
        {
            gpiod_line_event_read(line4, &event);
            printf("Event on line 4 %d,%d \n\r ",
                   event.event_type, event.ts);
            fflush(stdout);
        }
    }
}

int gpiod_line_event_poll(struct gpiod_line *line,
                          struct gpiod_line_event *event)
{
    struct timespec timeout = {0, 0};
    int res = gpiod_line_event_wait(line, &timeout);
    if (res > 0)
        res = gpiod_line_event_read(line, event);
    if (res == 0)
        res = 1;
    return res;
}

 

Page 80

#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/gpio.h>
#include <sys/epoll.h>

int main(int argc, char **argv)
{
    int fd, ret;

    struct gpioevent_request req;
    req.lineoffset = 4;
    req.handleflags = GPIOHANDLE_REQUEST_INPUT;
    req.eventflags = GPIOEVENT_REQUEST_RISING_EDGE;
    strcpy(req.consumer_label, "Event test");

    fd = open("/dev/gpiochip0", O_RDONLY);
    ret = ioctl(fd, GPIO_GET_LINEEVENT_IOCTL, &req);
    close(fd);

    static struct epoll_event ev;
    ev.events = EPOLLIN;
    ev.data.fd = req.fd;
    int epfd = epoll_create(1);
    int res = epoll_ctl(epfd, EPOLL_CTL_ADD, req.fd, &ev);

    int nfds = epoll_wait(epfd, &ev, 1, 20000);
    if (nfds != 0)
    {
        struct gpioevent_data edata;
        read(req.fd, &edata, sizeof edata);
        printf("%u,%llu", edata.id, edata.timestamp);
    }
}

Page 81

#define _GNU_SOURCE
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/gpio.h>
#include <sys/epoll.h>
#include <gpiod.h>

int main(int argc, char **argv)
{
    int res;

    struct gpiod_chip *chip = gpiod_chip_open_by_number(0);
    struct gpiod_line *line4 = gpiod_chip_get_line(chip, 4);

    res = gpiod_line_request_rising_edge_events(line4, "button");
    int fd = gpiod_line_event_get_fd(line4);

    static struct epoll_event ev;
    ev.events = EPOLLIN;
    ev.data.fd = fd;
    int epfd = epoll_create(1);
    res = epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev);

    int nfds = epoll_wait(epfd, &ev, 1, 20000);
    if (nfds != 0)
    {
        struct gpioevent_data edata;
        read(fd, &edata, sizeof edata);
        printf("%u,%llu", edata.id, edata.timestamp);
    }
}

Page 85

#define _GNU_SOURCE
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <gpiod.h>
#include <sys/epoll.h>
#include <pthread.h>

typedef void (*eventHandler)(struct gpiod_line_event *);
typedef struct
{
    struct gpiod_line *line;
    eventHandler func;
} intVec;
void myHandler(struct gpiod_line_event *event)
{
    printf("%d,%d \n\r", event->event_type,
           event->ts.tv_nsec / 1000);
    fflush(stdout);
}

void *waitInterrupt(void *arg)
{
    intVec *intData = (intVec *)arg;
    struct gpiod_line_event event;
    while (true)
    {
        int res = gpiod_line_event_read(intData->line, &event);
        if (res == 0)
            intData->func(&event);
    }
}

int main(int argc, char **argv)
{
    int fd, ret, res;

    struct gpiod_chip *chip = gpiod_chip_open_by_number(0);
    struct gpiod_line *line4 = gpiod_chip_get_line(chip, 4);

    res = gpiod_line_request_rising_edge_events(line4, "button");

    intVec intData;
    intData.line = line4;
    intData.func = &myHandler;

    pthread_t intThread;
    if (pthread_create(&intThread, NULL, waitInterrupt,
                       (void *)&intData))
    {
        fprintf(stderr, "Error creating thread\n");
        return 1;
    }
    for (;;)
    {
        printf("Working\n\r");
        fflush(stdout);
        sleep(2);
    }

Page 88

#define _GNU_SOURCE
#include <gpiod.h>
#include <stdio.h> 
#include <unistd.h>
#include <stdlib.h>

int event_cb(int event, unsigned int offset, 
               const struct timespec *timestamp, void *unused)
{
   printf("[%ld.%09ld] %s\n",
     timestamp->tv_sec, timestamp->tv_nsec,
     (event == GPIOD_CTXLESS_EVENT_CB_RISING_EDGE)? "rising" :
     (event == GPIOD_CTXLESS_EVENT_CB_FALLING_EDGE)? "falling" :
     (event == GPIOD_CTXLESS_EVENT_CB_TIMEOUT) ? "timeout" : "??");
     fflush(stdout);
     return GPIOD_CTXLESS_EVENT_CB_RET_OK;
}


int main(int argc, char **argv) {
    int res;
    struct timespec time;
    time.tv_nsec=0;
    time.tv_sec=20;
    res = gpiod_ctxless_event_monitor("0",
            GPIOD_CTXLESS_EVENT_BOTH_EDGES, 4, 0, "monitor test",
               &time, NULL, event_cb, NULL);
}

Page 97 

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>

int main(int argc, char **argv)
{
    char buffer[25];

    int fd = open("/sys/bus/iio/devices/iio:device0/name", O_RDONLY);
    read(fd, buffer, 25);
    close(fd);
    printf("%s", buffer);

    fd = open("/sys/bus/iio/devices/iio:device0/in_temp_input", O_RDONLY);
    read(fd, buffer, 25);
    close(fd);
    int temp;
    sscanf(buffer, "%d", &temp);

    printf("%f\n\r", temp / 1000.0);
    fd = open("/sys/bus/iio/devices/iio:device0/in_humidityrelative_input", O_RDONLY);
    read(fd, buffer, 25);
    close(fd);
    int hum;
    sscanf(buffer, "%d", &hum);
    printf("%f\n\r", hum / 1000.0);
}

Page 100

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>

FILE *doCommand(char *cmd)
{
    FILE *fp = popen(cmd, "r");
    if (fp == NULL)
    {
        printf("Failed to run command %s \n\r", cmd);
        exit(1);
    }
    return fp;
}
void checkDht11()
{
    FILE *fd = doCommand("sudo  dtparam -l");
    char output[1024];
    int txfound = 0;

    char indicator[] = "dht11  gpiopin=4";
    char command[] = "sudo dtoverlay dht11 gpiopin=4";
    while (fgets(output, sizeof(output), fd) != NULL)
    {
        printf("%s\n\r", output);
        fflush(stdout);
        if (strstr(output, indicator) != NULL)
        {
            txfound = 1;
        }
    }
    if (txfound == 0)
    {
        fd = doCommand(command);
    }

    pclose(fd);
}

int main(int argc, char **argv)
{
    char buffer[25];
    checkDht11();
    int fd = open(
        "/sys/bus/iio/devices/iio:device0/name", O_RDONLY);
    read(fd, buffer, 25);
    close(fd);
    printf("%s", buffer);

    fd = open(
        "/sys/bus/iio/devices/iio:device0/in_temp_input", O_RDONLY);
    read(fd, buffer, 25);
    close(fd);
    int temp;
    sscanf(buffer, "%d", &temp);

    printf("%f\n\r", temp / 1000.0);

    fd = open("/sys/bus/iio/devices/iio:device0/in_humidityrelative_input", O_RDONLY);
    read(fd, buffer, 25);
    close(fd);
    int hum;
    sscanf(buffer, "%d", &hum);
    printf("%f\n\r", hum / 1000.0);

 

Page 121

#define _GNU_SOURCE
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>

void pwm(struct gpiod_line *line, int);

int main(int argc, char **argv)
{
    int period = 20;
    int duty = 25;
    int res;
    struct gpiod_chip *chip = gpiod_chip_open_by_number(0);
    struct gpiod_line *line4 = gpiod_chip_get_line(chip, 4);
    res = gpiod_line_request_output(line4, "test output", 0);

    struct timespec ontime = {0, 0};
    struct timespec offtime = {0, 0};
    ontime.tv_nsec = period * duty * 10 * 1000;
    offtime.tv_nsec = (period - period * duty / 100) * 1000 * 1000;

    for (;;)
    {
        res = gpiod_line_set_value(line4, 1);
        nanosleep(&ontime, NULL);
        res = gpiod_line_set_value(line4, 0);
        nanosleep(&offtime, NULL);
    };
}

Page  122

#define _GNU_SOURCE
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>

struct pwmargs
{
    struct gpiod_line *line;
    struct timespec ontime;
    struct timespec offtime;
};

void *pwmrun(void *arg)
{
    struct pwmargs *pwmdata = (struct pwmargs *)arg;
    int res;
    for (;;)
    {
        res = gpiod_line_set_value(pwmdata->line, 1);
        nanosleep(&(pwmdata->ontime), NULL);
        res = gpiod_line_set_value(pwmdata->line, 0);
        nanosleep(&(pwmdata->offtime), NULL);
    };
}

int pwm(struct gpiod_line *line, int period, int duty)
{
    static struct pwmargs pwmdata;
    pwmdata.line = line;
    pwmdata.ontime.tv_sec = 0;
    pwmdata.ontime.tv_nsec = period * duty * 10;
    pwmdata.offtime.tv_sec = 0;
    pwmdata.offtime.tv_nsec = (period - period * duty / 100) * 1000;

    pthread_t pwmThread;
    if (pthread_create(&pwmThread, NULL, pwmrun, (void *)&pwmdata))
    {
        fprintf(stderr, "Error creating thread\n");
        return 1;
    }
    return 0;
};

int main(int argc, char **argv)
{
    int res;
    struct gpiod_chip *chip = gpiod_chip_open_by_number(0);
    struct gpiod_line *line4 = gpiod_chip_get_line(chip, 4);
    res = gpiod_line_request_output(line4, "test output", 0);

    pwm(line4, 20 * 1000, 25);
    for (;;)
    {
    };
}

Page 126

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <fcntl.h>

FILE *doCommand(char *cmd)
{
    FILE *fp = popen(cmd, "r");
    if (fp == NULL)
    {
        printf("Failed to run command %s \n\r", cmd);
        exit(1);
    }
    return fp;
}
void checkPWM()
{
    FILE *fd = doCommand("sudo  dtparam -l");
    char output[1024];
    int txfound = 0;

    char indicator[] = "pwm-2chan";
    char command[] = "sudo dtoverlay pwm-2chan";
    while (fgets(output, sizeof(output), fd) != NULL)
    {
        printf("%s\n\r", output);
        fflush(stdout);
        if (strstr(output, indicator) != NULL)
        {
            txfound = 1;
        }
    }
    if (txfound == 0)
    {
        fd = doCommand(command);
        sleep(2);
    }

    pclose(fd);
}

int main(int argc, char **argv)
{
    checkPWM();

    int fd = open("/sys/class/pwm/pwmchip0/export", O_WRONLY);
    write(fd, "0", 1);
    close(fd);
    sleep(2);
    fd = open("/sys/class/pwm/pwmchip0/pwm0/period", O_WRONLY);
    write(fd, "10000000", 8);
    close(fd);
    fd = open("/sys/class/pwm/pwmchip0/pwm0/duty_cycle", O_WRONLY);
    write(fd, "8000000", 7);
    close(fd);
    fd = open("/sys/class/pwm/pwmchip0/pwm0/enable", O_WRONLY);
    write(fd, "1", 1);
    close(fd);
}

  

Page 127

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

FILE *doCommand(char *cmd)
{
    FILE *fp = popen(cmd, "r");
    if (fp == NULL)
    {
        printf("Failed to run command %s \n\r", cmd);
        exit(1);
    }
    return fp;
}
void checkPWM()
{
    FILE *fd = doCommand("sudo  dtparam -l");
    char output[1024];
    int txfound = 0;

    char indicator[] = "pwm-2chan";
    char command[] = "sudo dtoverlay pwm-2chan";
    while (fgets(output, sizeof(output), fd) != NULL)
    {
        printf("%s\n\r", output);
        fflush(stdout);
        if (strstr(output, indicator) != NULL)
        {
            txfound = 1;
        }
    }
    if (txfound == 0)
    {
        pclose(fd);
        fd = doCommand(command);
    }

    pclose(fd);
}
enum pwm
{
    OpenChan,
    SetFreq,
    SetDuty,
    EnableChan,
    DisableChan,
    CloseChan
};

int pwmAction(enum pwm action, int chan, int param)
{
    static int fdf[2];
    static int fdd[2];

    int fd;
    char buf[150];
    char schan[2];

    int L;

    if (chan != 0 && chan != 1)
        return -1;
    snprintf(schan, 2, "%d", chan);

    switch (action)
    {
    case OpenChan:
        checkPWM();
        fd = open("/sys/class/pwm/pwmchip0/export", O_WRONLY);
        write(fd, schan, 1);
        close(fd);
        sleep(2);
        snprintf(buf, 150, "%s%s%s", "/sys/class/pwm/pwmchip0/pwm",
                 schan, "/period");
        fdf[chan] = open(buf, O_WRONLY);
        snprintf(buf, 150, "%s%s%s", "/sys/class/pwm/pwmchip0/pwm",
                 schan, "/duty_cycle");
        fdd[chan] = open(buf, O_WRONLY);
        break;
    case SetFreq:
        L = snprintf(buf, 150, "%d", param);
        write(fdf[chan], buf, L);
        break;
    case SetDuty:
        L = snprintf(buf, 150, "%d", param);
        write(fdd[chan], buf, L);
        break;
        return 0;
    case EnableChan:
        snprintf(buf, 150, "%s%s%s", "/sys/class/pwm/pwmchip0/pwm",
                 schan, "/enable");
        fd = open(buf, O_WRONLY);
        write(fd, "1", 1);
        close(fd);
        break;
    case DisableChan:
        snprintf(buf, 150, "%s%s%s", "/sys/class/pwm/pwmchip0/pwm",
                 schan, "/enable");
        fd = open(buf, O_WRONLY);
        write(fd, "0", 1);
        close(fd);
        break;
    case CloseChan:
        close(fdf[chan]);
        close(fdd[chan]);
        fd = open("/sys/class/pwm/pwmchip0/unexport", O_WRONLY);
        write(fd, schan, 1);
        close(fd);
        break;
    }

    return 0;
}

Page 140

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>

#include <stdarg.h>

FILE *doCommand(char *cmd)
{
    FILE *fp = popen(cmd, "r");
    if (fp == NULL)
    {
        printf("Failed to run command %s \n\r", cmd);
        exit(1);
    }
    return fp;
}
void checkPWM()
{
    FILE *fd = doCommand("sudo  dtparam -l");
    char output[1024];
    int txfound = 0;

    char indicator[] = "pwm-2chan";
    char command[] = "sudo dtoverlay pwm-2chan";
    while (fgets(output, sizeof(output), fd) != NULL)
    {
        printf("%s\n\r", output);
        fflush(stdout);
        if (strstr(output, indicator) != NULL)
        {
            txfound = 1;
        }
    }
    if (txfound == 0)
    {
        pclose(fd);
        fd = doCommand(command);
    }

    pclose(fd);
}
enum pwm
{
    OpenChan,
    SetFreq,
    SetDuty,
    EnableChan,
    DisableChan,
    CloseChan,
    InvertChan
};

int pwmAction(enum pwm action, int chan, ...)
{
    static int fdf[2];
    static int fdd[2];

    int fd;
    int param;
    char buf[150];
    char schan[2];
    va_list params;

    int status;

    int L;

    if (chan != 0 && chan != 1)
        return -1;
    snprintf(schan, 2, "%d", chan);

    switch (action)
    {
    case OpenChan:
        checkPWM();
        fd = open("/sys/class/pwm/pwmchip0/export", O_WRONLY);
        if (fd < 0)
            printf("failed to open PWM Chip");
        write(fd, schan, 1);
        close(fd);
        sleep(3);
        snprintf(buf, 150, "%s%s%s", "/sys/class/pwm/pwmchip0/pwm", schan, "/period");
        fdf[chan] = open(buf, O_WRONLY);
        if (fdf < 0)
            printf("failed to open period");
        snprintf(buf, 150, "%s%s%s", "/sys/class/pwm/pwmchip0/pwm", schan, "/duty_cycle");
        fdd[chan] = open(buf, O_WRONLY);
        if (fdd < 0)
            printf("failed to open duty");
        break;

    case SetFreq:
        va_start(params, chan);
        param = va_arg(params, int);
        L = snprintf(buf, 150, "%d", param);
        write(fdf[chan], buf, L);
        break;

    case SetDuty:
        va_start(params, chan);
        param = va_arg(params, int);
        L = snprintf(buf, 150, "%d", param);
        write(fdd[chan], buf, L);
        break;
        return 0;

    case EnableChan:
        snprintf(buf, 150, "%s%s%s", "/sys/class/pwm/pwmchip0/pwm", schan, "/enable");
        fd = open(buf, O_WRONLY);
        if (fd < 0)
            printf("failed to open enable");
        write(fd, "1", 1);
        close(fd);
        break;

    case DisableChan:
        snprintf(buf, 150, "%s%s%s", "/sys/class/pwm/pwmchip0/pwm", schan, "/enable");
        fd = open(buf, O_WRONLY);
        write(fd, "0", 1);
        close(fd);
        break;

    case CloseChan:
        close(fdf[chan]);
        close(fdd[chan]);
        fd = open("/sys/class/pwm/pwmchip0/unexport", O_WRONLY);
        write(fd, schan, 1);
        close(fd);
        break;

    case InvertChan:
        va_start(params, chan);
        param = va_arg(params, int);

        snprintf(buf, 150, "%s%s%s", "/sys/class/pwm/pwmchip0/pwm", schan, "/polarity");
        fd = open(buf, O_WRONLY);
        if (param == 0)
        {
            L = snprintf(buf, 150, "%s", "normal");
            write(fd, buf, L);
        }
        if (param == 1)
        {
            L = snprintf(buf, 150, "%s", "inversed");
            write(fd, buf, L);
        }
        close(fd);
        break;
    }

    return 0;
}

int main(int argc, char **argv)
{
    pwmAction(OpenChan, 0);

    struct timespec delay = {0, 6667 * 2};

    int t = 20 * 1000000;
    pwmAction(SetFreq, 0, t);
    int d1 = t * 2.5 / 100;
    int d2 = t * 12 / 100;
    pwmAction(InvertChan, 0, 1);
    pwmAction(EnableChan, 0);

    for (;;)
    {
        pwmAction(SetDuty, 0, d1);
        sleep(1);
        pwmAction(SetDuty, 0, d2);
        sleep(1);
    }
}

Page 163 

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>
#include <stdint.h>

FILE *doCommand(char *cmd)
{
    FILE *fp = popen(cmd, "r");
    if (fp == NULL)
    {
        printf("Failed to run command %s \n\r", cmd);
        exit(1);
    }
    return fp;
}
void checkSPI0()
{
    FILE *fd = doCommand("sudo  dtparam -l");
    char output[1024];
    int txfound = 0;

    char indicator[] = "spi=on";
    char command[] = "sudo dtparam spi=on";
    while (fgets(output, sizeof(output), fd) != NULL)
    {
        printf("%s\n\r", output);
        fflush(stdout);
        if (strstr(output, indicator) != NULL)
        {
            txfound = 1;
        }
    }
    if (txfound == 0)
    {
        fd = doCommand(command);
        sleep(2);
    }

    pclose(fd);
}

int main(int argc, char **argv)
{
    checkSPI0();

    uint8_t tx[] = {0x01, 0x80, 0x00};
    uint8_t rx[3];

    struct spi_ioc_transfer tr =
        {
            .tx_buf = (unsigned long)tx,
            .rx_buf = (unsigned long)rx,
            .len = 3,
            .delay_usecs = 0,
            .speed_hz = 0,
            .bits_per_word = 0,
        };

    int fd = open("/dev/spidev0.0", O_RDWR);

    static uint8_t mode = 0;
    int status = ioctl(fd, SPI_IOC_WR_MODE, &mode);
    if (status == -1)
        printf("can't set spi mode");

    static uint8_t bits = 8;
    status = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
    if (status == -1)
        printf("can't set bits per word");

    static uint32_t speed = 100000;
    status = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
    if (status == -1)
        printf("can't set max speed hz");

    status = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
    if (status < 0)
        printf("can't send data");

    int data = ((int)rx[1] & 0x03) << 8 | (int)rx[2];
    float volts = (((float)data) * 3.3f) / 1023.0f;
    printf("%f V\n\r", volts);

    close(fd);

Page 181

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>

void checkI2CBus();
FILE *doCommand(char *cmd);

int main(int argc, char **argv)
{
    checkI2CBus();
    int i2cfd = open("/dev/i2c-1", O_RDWR);
    ioctl(i2cfd, I2C_SLAVE, 0x40);
    char buf[4] = {0xE7};
    write(i2cfd, buf, 1);
    read(i2cfd, buf, 1);
    close(i2cfd
    return (EXIT_SUCCESS);
}

Page 191

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>

void checkI2CBus();
FILE *doCommand(char *cmd);
uint8_t crcCheck(uint8_t msb, uint8_t lsb, uint8_t check);

int main(int argc, char **argv)
{

    checkI2CBus();

    int i2cfd = open("/dev/i2c-1", O_RDWR);
    ioctl(i2cfd, I2C_SLAVE, 0x40);
    char buf[3] = {0xF3};
    write(i2cfd, buf, 1);

    while (1)
    {
        int result = read(i2cfd, buf, 3);
        if (result > 0)
            break;
        usleep(10 * 1000);
    }
    uint8_t msb = buf[0];
    uint8_t lsb = buf[1];
    uint8_t check = buf[2];
    printf("msb %d \n\rlsb %d \n\rchecksum %d \n\r", msb, lsb, check);

    unsigned int data16 = ((unsigned int)msb << 8) | (unsigned int)(lsb & 0xFC);
    float temp = (float)(-46.85 + (175.72 * data16 / (float)65536));
    printf("Temperature %f C \n\r", temp);
    printf("crc = %d\n\r", crcCheck(msb, lsb, check));
    buf[0] = 0xF5;
    write(i2cfd, buf, 1);

    while (1)
    {
        int result = read(i2cfd, buf, 3);
        if (result > 0)
            break;
        usleep(10 * 1000);
    }
    msb = buf[0];
    lsb = buf[1];
    check = buf[2];
    printf("crc = %d\n\r", crcCheck(msb, lsb, check));
    data16 = ((unsigned int)msb << 8) | (unsigned int)(lsb & 0xFC);
    float hum = -6 + (125.0 * (float)data16) / 65536;
    printf("Humidity %f %% \n\r", hum);
    close(i2cfd);
    return (EXIT_SUCCESS);
}

uint8_t crcCheck(uint8_t msb, uint8_t lsb, uint8_t check)
{
    uint32_t data32 = ((uint32_t)msb << 16) | ((uint32_t)lsb << 8) | (uint32_t)check;
    uint32_t divisor = 0x988000;
    for (int i = 0; i < 16; i++)
    {
        if (data32 & (uint32_t)1 << (23 - i))
            data32 ^= divisor;
        divisor >>= 1;
    };
    return (uint8_t)data32;
}

void checkI2CBus()
{
    FILE *fd = doCommand("sudo dtparam -l");
    char output[1024];
    int txfound = 0;
    while (fgets(output, sizeof(output), fd) != NULL)
    {
        printf("%s\n\r", output);
        fflush(stdout);
        if (strstr(output, "i2c_arm=on") != NULL)
        {
            txfound = 1;
        }
        if (strstr(output, "i2c_arm=off") != NULL)
        {
            txfound = 0;
        }
    }
    pclose(fd);
    if (txfound == 0)
    {
        fd = doCommand("sudo dtparam i2c_arm=on");
        pclose(fd);
    }
}

FILE *doCommand(char *cmd)
{
    FILE *fp = popen(cmd, "r");
    if (fp == NULL)
    {
        printf("Failed to run command %s \n\r", cmd);
        exit(1);
    }
    return fp;
}

Page 204

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdint.h>
#include <linux/i2c-dev.h>
#include <sys/mman.h>

void checkI2CBus();
FILE *doCommand(char *cmd);
void setTimeout(uint32_t timeout);
uint8_t crcCheck(uint8_t msb, uint8_t lsb, uint8_t check);

int main(int argc, char **argv)
{
    checkI2CBus();
    setTimeout(10000);

    int i2cfd = open("/dev/i2c-1", O_RDWR);
    ioctl(i2cfd, I2C_SLAVE, 0x40);

    char buf[3] = {0xE3};
    write(i2cfd, buf, 1);
    int result = read(i2cfd, buf, 3);
    uint8_t msb = buf[0];
    uint8_t lsb = buf[1];
    uint8_t check = buf[2];
    printf("msb %hhu \n\rlsb %hhu \n\rchecksum %d \n\r", msb, lsb, check);

    printf("crc = %hhu\n\r", crcCheck(msb, lsb, check));
    unsigned int data16 = ((unsigned int)msb << 8) | (unsigned int)(lsb & 0xFC);
    float temp = (float)(-46.85 + (175.72 * data16 / (float)65536));
    printf("Temperature %f C \n\r", temp);

    buf[0] = 0xE5;
    write(i2cfd, buf, 1);
    result = read(i2cfd, buf, 3);
    msb = buf[0];
    lsb = buf[1];
    check = buf[2];
    printf("crc = %hhu\n\r", crcCheck(msb, lsb, check));
    data16 = ((unsigned int)msb << 8) | (unsigned int)(lsb & 0xFC);
    float hum = -6 + (125.0 * (float)data16) / 65536;
    printf("Humidity %f %% \n\r", hum);
    close(i2cfd);
    return (EXIT_SUCCESS);
}

void setTimeout(uint32_t timeout)
{
    uint32_t *bcm2835_peripherals_base = (uint32_t *)0x20000000;
    FILE *fp;
    unsigned char buf[16];
    if ((fp = fopen("/proc/device-tree/soc/ranges", "rb")))
    {
        if (fread(buf, 1, sizeof(buf), fp) == sizeof(buf))
            bcm2835_peripherals_base =
                (uint32_t *)(buf[4] << 24 |
                             buf[5] << 16 |
                             buf[6] << 8 |
                             buf[7] << 0);
        fclose(fp);
    }
    if (!bcm2835_peripherals_base)
    {
        bcm2835_peripherals_base =
            (uint32_t *)(buf[8] << 24 |
                         buf[9] << 16 |
                         buf[10] << 8 |
                         buf[11] << 0);
    }

    int memfd;
    if ((memfd = open("/dev/mem", O_RDWR | O_SYNC)) < 0)
    {
        printf("Unable to open /dev/mem - are you running as root? \n");
    }
    uint32_t *map;
    if ((map = (uint32_t *)mmap(NULL, 4 * 1024, (PROT_READ | PROT_WRITE), MAP_SHARED, memfd,
                                (uint32_t)bcm2835_peripherals_base + 0x804000)) < 0)
    {
        printf("memory mapping failed \n");
    };
    close(memfd);
    volatile uint32_t *stimeout = map + 0x1C / 4;
    __sync_synchronize();
    *stimeout = timeout;
    __sync_synchronize();
    munmap(map, 4 * 1024);
}

uint8_t crcCheck(uint8_t msb, uint8_t lsb, uint8_t check)
{
    uint32_t data32 = ((uint32_t)msb << 16) | ((uint32_t)lsb << 8) | (uint32_t)check;
    uint32_t divisor = 0x988000;
    for (int i = 0; i < 16; i++)
    {
        if (data32 & (uint32_t)1 << (23 - i))
            data32 ^= divisor;
        divisor >>= 1;
    };
    return (uint8_t)data32;
}

void checkI2CBus()
{
    FILE *fd = doCommand("sudo dtparam -l");
    char output[1024];
    int txfound = 0;
    while (fgets(output, sizeof(output), fd) != NULL)
    {
        printf("%s\n\r", output);
        fflush(stdout);
        if (strstr(output, "i2c_arm=on") != NULL)
        {
            txfound = 1;
        }
        if (strstr(output, "i2c_arm=off") != NULL)
        {
            txfound = 0;
        }
    }
    pclose(fd);
    if (txfound == 0)
    {
        fd = doCommand("sudo dtparam i2c_arm=on");
        pclose(fd);
    }
}

FILE *doCommand(char *cmd)
{
    FILE *fp = popen(cmd, "r");
    if (fp == NULL)
    {
        printf("Failed to run command %s \n\r", cmd);
        exit(1);
    }
    return fp;
}

Page 210

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdint.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>

void checkI2CBus();
int i2cReadRegister(int i2cfd, uint8_t slaveaddr, uint8_t reg, uint8_t *buf, int len);

int main(int argc, char **argv)
{
    checkI2CBus();
    int i2cfd = open("/dev/i2c-1", O_RDWR);
    char buf2[1] = {0};
    i2cReadRegister(i2cfd, 0x40, 0xE7, buf2, 1);
    printf("%d \n\r", buf2[0]);
    return (EXIT_SUCCESS);
}

  

Page 215

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>

int main(int argc, char **argv)
{
    int fd = open("/sys/class/hwmon/hwmon0/temp1_input", O_RDONLY);
    char buf[100] = {0};
    read(fd, buf, 100);
    printf("%s\n\r", buf);
    float temp;
    sscanf(buf, "%f", &temp);
    temp = temp / 1000;
    printf("%f\n\r", temp);
}

Page 222

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdint.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>

void loadHTU21();

int main(int argc, char **argv)
{
    loadHTU21();
    float temp;
    float hum;

    {
        char output[1024] = {0};
        int fdtemp = open("/sys/bus/iio/devices/iio:device0/in_temp_input", O_RDWR);
        read(fdtemp, output, sizeof(output));
        close(fdtemp);
        printf("%s\n\r", output);
        sscanf(output, "%f", &temp);
        temp = temp / 1000;
        fflush(stdout);
    }

    {
        char output[1024] = {0};
        int fdhum = open("/sys/bus/iio/devices/iio:device0/in_humidityrelative_input", O_RDWR);
        read(fdhum, output, sizeof(output));
        close(fdhum);
        printf("%s\n\r", output);
        sscanf(output, "%f", &hum);
        hum = hum / 1000;
        fflush(stdout);
    }
    printf("%f\n\r", temp);
    printf("%f\n\r", hum);

    return (EXIT_SUCCESS);
}

void loadHTU21()
{
    FILE *fd = doCommand("sudo dtparam -l");
    char output[1024];
    int txfound = 0;
    while (fgets(output, sizeof(output), fd) != NULL)
    {
        printf("%s\n\r", output);
        fflush(stdout);
        if (strstr(output, "i2c-sensor  htu21=true") != NULL)
        {
            txfound = 1;
        }
    }
    pclose(fd);
    if (txfound == 0)
    {
        fd = doCommand("sudo dtoverlay i2c-sensor htu21");
        pclose(fd);
    }
}

Page 237

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <fcntl.h>

FILE *doCommand(char *cmd)
{
    FILE *fp = popen(cmd, "r");
    if (fp == NULL)
    {
        printf("Failed to run command %s \n\r", cmd);
        exit(1);
    }
    return fp;
}

void load1w(int pin)
{
    FILE *fd = doCommand("sudo dtparam -l");
    char output[1024];
    int txfound = 0;
    while (fgets(output, sizeof(output), fd) != NULL)
    {
        printf("%s\n\r", output);
        fflush(stdout);
        if (strstr(output, "w1-gpio") != NULL)
        {
            txfound = 1;
        }
    }
    pclose(fd);
    if (txfound == 0)
    {
        char cmd[100];
        snprintf(cmd, 100, "sudo dtoverlay w1-gpio gpiopin=%d", pin);

        fd = doCommand(cmd);
        pclose(fd);
    }
}

int getDevices(char path[][100], int *num)
{
    char buffer[500];
    int fd = open("/sys/bus/w1/drivers/w1_master_driver/w1_bus_master1/w1_master_slaves", O_RDONLY);
    read(fd, buffer, 500);
    close(fd);
    *num = 0;
    for (char *p = strtok(buffer, "\n"); p != NULL; p = strtok(NULL, "\n"))
    {
        snprintf(path[(*num)++], 100, "/sys/bus/w1/devices/%s", p);
    }
    num--;
}

int getData(char path[], char name[], char data[], int n)
{
    char file[100];
    snprintf(file, 100, "%s/%s", path, name);
    int fd = open(file, O_RDONLY);
    int c = read(fd, data, n);
    close(fd);
    data[c] = 0;
    return c;
}

int main(int argc, char **argv)
{
    load1w(4);
    char path[10][100];
    int num;
    getDevices(path, &num);
    printf("%d  %s\n\r", num, path[0]);
    if (num < 1)
        exit(-1);

    char output[1024] = {0};
    char file[100];

    getData(path[0], "name", output, 100);
    printf("Name %s\n\r", output);

    getData(path[0], "resolution", output, 100);
    printf("Resolution %s\n\r", output);

    getData(path[0], "w1_slave", output, 100);
    printf("w1_slave %s\n\r", output);

    getData(path[0], "temperature", output, 100);
    printf("temperature %s\n\r", output);
    float temp;
    sscanf(output, "%f", &temp);
    temp = temp / 1000;
    printf("temperature %f C\n\r", temp);

    getData(path[0], "alarms", output, 100);
    printf("alarms %s\n\r", output);
}

Page 247

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>

#include <sys/socket.h>
#include <sys/poll.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

#include <sys/socket.h>
#include <sys/poll.h>

#include <stdint.h>
#include <arm-linux-gnueabihf/asm/byteorder.h>
#include <linux/netlink.h>

#include "w1_netlink.h"

uint32_t nl_seq = 0;

int main(int argc, char *argv[])
{

    char buf[1024] = {0};
    //SET UP TRANSMIT BUFFER
    struct nlmsghdr *cnh = (struct nlmsghdr *)buf;
    cnh->nlmsg_seq = nl_seq++;
    cnh->nlmsg_pid = getpid();
    cnh->nlmsg_type = NLMSG_DONE;
    cnh->nlmsg_flags = 0;

    struct cn_msg *cmsg = NLMSG_DATA(cnh);
    cmsg->id.idx = CN_W1_IDX;
    cmsg->id.val = CN_W1_VAL;
    cmsg->seq = cnh->nlmsg_seq;
    cmsg->ack = 0;

    struct w1_netlink_msg *msg = (struct w1_netlink_msg *)(cmsg + 1);
    msg->type = W1_MASTER_CMD;
    msg->id.mst.id = 1;

    struct w1_netlink_cmd *w1_cmd = (struct w1_netlink_cmd *)(msg + 1);
    w1_cmd->cmd = W1_CMD_SEARCH;
    //w1_cmd->cmd = W1_CMD_ALARM_SEARCH;
    w1_cmd->len = 0;
    msg->len = sizeof(struct w1_netlink_cmd) + w1_cmd->len;
    cmsg->len = sizeof(struct w1_netlink_msg) + msg->len;
    cnh->nlmsg_len = NLMSG_LENGTH(sizeof(struct cn_msg) + cmsg->len);

    //SET UP SOCKET
    int s = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);

    struct sockaddr_nl sa;
    sa.nl_family = AF_NETLINK;
    sa.nl_pid = getpid();
    sa.nl_groups = 0;

    //int b = bind(s, (struct sockaddr *)&sa, sizeof(sa));
    connect(s, (struct sockaddr *)&sa, sizeof(sa));
    //SEND DATA
    int len = send(s, cnh, cnh->nlmsg_len, 0);
    printf("length of data sent %d\n\r", len);
    //RECEIVE DATA
    char buf2[1024] = {0};
    len = recv(s, buf2, sizeof(buf2), 0);
    printf("length of data received %d\n\r", len);
    //DECODE DATA
    struct nlmsghdr *cnhr = (struct nlmsghdr *)buf2;
    struct cn_msg *cmsgr = (struct cn_msg *)(cnhr + 1);
    struct w1_netlink_msg *msgr = (struct w1_netlink_msg *)(cmsgr + 1);
    struct w1_netlink_cmd *w1_cmdr = (struct w1_netlink_cmd *)(msgr + 1);
    //DISPLAY SERIAL NUMBERS
    int num = (w1_cmdr->len) / 8;
    uint64_t slave[25];
    if (num > 25)
        exit(-1);
    printf("number of slaves found %d\n\r", num);
    for (int i = 0; i < num; i++)
    {
        slave[i] = *(uint64_t *)&(w1_cmdr->data[i * 8]);
        printf("slave %d  %llx\n\r", i, slave[i]);
    }
    //GET ACK
    len = recv(s, buf2, sizeof(buf2), 0);
    printf("length of ack received %d\n\r", len);

    ///READ TEMPERATURE
    //SET UP SLAVE COMMAND
    msg->type = W1_SLAVE_CMD;
    for (int i = 0; i < 8; i++)
    {
        msg->id.id[i] = w1_cmdr->data[i];
    }

    //SETUP AND SEND WRITE 0x44 = CONVERT
    w1_cmd->cmd = W1_CMD_WRITE;
    w1_cmd->data[0] = 0x44;
    w1_cmd->len = 1;
    cnh->nlmsg_seq = nl_seq++;
    cmsg->seq = cnh->nlmsg_seq;

    msg->len = sizeof(struct w1_netlink_cmd) + w1_cmd->len;
    cmsg->len = sizeof(struct w1_netlink_msg) + msg->len;
    cnh->nlmsg_len = NLMSG_LENGTH(sizeof(struct cn_msg) + cmsg->len);

    len = send(s, cnh, cnh->nlmsg_len, 0);
    printf("length of data sent %d\n\r", len);
    //GET ACK
    len = recv(s, buf2, sizeof(buf2), 0);
    printf("length of ack received %d\n\r", len);

    sleep(1);
    //READ SCRATCH PAD
    w1_cmd->cmd = W1_CMD_WRITE;
    w1_cmd->data[0] = 0xBE;
    w1_cmd->len = 1;

    struct w1_netlink_cmd *w1_cmd2 = (struct w1_netlink_cmd *)((char *)(w1_cmd + 1) + w1_cmd->len);
    w1_cmd2->cmd = W1_CMD_READ;
    w1_cmd2->len = 9;

    msg->len = sizeof(struct w1_netlink_cmd) + w1_cmd->len + sizeof(struct w1_netlink_cmd) + w1_cmd2->len;
    cmsg->len = sizeof(struct w1_netlink_msg) + msg->len;
    cnh->nlmsg_len = NLMSG_LENGTH(sizeof(struct cn_msg) + cmsg->len);

    cnh->nlmsg_seq = nl_seq++;
    cmsg->seq = cnh->nlmsg_seq;

    len = send(s, cnh, cnh->nlmsg_len, 0);
    printf("write read length of data sent %d\n\r", len);

    len = recv(s, buf2, sizeof(buf2), 0);
    printf("length of ack received %d\n\r", len);

    len = recv(s, buf2, sizeof(buf2), 0);
    printf("number of bytes found %d\n\r", w1_cmdr->len);

    int t1 = w1_cmdr->data[0];
    int t2 = w1_cmdr->data[1];
    int16_t temp1 = (t2 << 8 | t1);
    float temp = (float)temp1 / 16;
    printf("temperature = %f C \n", temp);
}

 

 

Page 269

launch.json

{
  "configurations": [    
    {
      "name": "Remote C Debug",
      "type": "cppdbg",
      "request": "launch",
      "program": "${config:remoteDirectory}/${relativeFileDirname}/${fileBasenameNoExtension}",
      "args": [],
      "stopAtEntry": false,
      "cwd": "${config:remoteDirectory}/${relativeFileDirname}",
      "environment": [],
      "externalConsole": false,
      "pipeTransport": {
           "debuggerPath": "/usr/bin/gdb",
           "pipeProgram": "C:/Windows/System32/OpenSSH/ssh",
           "pipeArgs": [
                    "${config:sshUser}@${config:sshEndpoint}"
                ],
           "pipeCwd": "${workspaceFolder}"
      },
      "MIMode": "gdb",
      "setupCommands": [
       {
           "description": "Enable pretty-printing for gdb",
           "text": "-enable-pretty-printing",
           "ignoreFailures": true
       }
      ],
      "sourceFileMap": {
                "${config:remoteDirectory}/${relativeFileDirname}": "${fileDirname}"
       },
      "preLaunchTask": "CopyBuildRemote",
     }
  ]
}

tasks.json

{
   "version": "2.0.0",
   "tasks": [
      {
         "label": "copyToRemote",
         "type": "shell",
         "command": "scp -r ${fileDirname} ${config:sshUser}@${config:sshEndpoint}:${config:remoteDirectory}/",
         "problemMatcher": [],
         "presentation": {
            "showReuseMessage": false,
            "clear": true
         }
      },
      {
         "label": "copyHeader",
         "type": "shell",
         "command": "mkdir ${workspaceFolder}/headers/;scp -r  ${config:sshUser}@${config:sshEndpoint}:${config:header} ${workspaceFolder}/headers/ ",
         "problemMatcher": [],
         "presentation": {
            "showReuseMessage": false,
            "clear": true
         }
      },
      {
         "label": "buildRemote",
         "type": "shell",
         "command": "ssh ${config:sshUser}@${config:sshEndpoint} 'gcc  -g -std=${config:std} ${config:remoteDirectory}/${relativeFileDirname}/${fileBasename} ${config:libs} -o${config:remoteDirectory}/${relativeFileDirname}/${fileBasenameNoExtension}'",
         "problemMatcher": [],
         "presentation": {
            "showReuseMessage": false,
            "clear": false
         }
      },
      {
         "label": "runRemote",
         "type": "shell",
         "command": "ssh ${config:sshUser}@${config:sshEndpoint} '${config:remoteDirectory}/${relativeFileDirname}/${fileBasenameNoExtension}'",
         "problemMatcher": [
            "$gcc"
         ],
         "presentation": {
            "showReuseMessage": true,
            "clear": false
         }
      },
      {
         "label": "CopyBuildRunRemote",
         "dependsOrder": "sequence",
         "dependsOn": [
            "copyToRemote",
            "buildRemote",
            "runRemote"
         ],
         "problemMatcher": [],
         "group": {
            "kind": "build",
            "isDefault": true
         }
      },
      {
         "label": "CopyBuildRemote",
         "dependsOrder": "sequence",
         "dependsOn": [
            "copyToRemote",
            "buildRemote",
         ],
         "problemMatcher": [],
      },
      {
         "label": "StopREmoteC",
         "type": "shell",
         "command": "ssh ${config:sshUser}@${config:sshEndpoint} 'pkill ${fileBasenameNoExtension}'",
         "problemMatcher": [],
         "presentation": {
            "showReuseMessage": true,
         }
      },
      {
         "label": "copyARMheaders",
         "type": "shell",
         "command": "mkdir ${workspaceFolder}/include/; scp -r  ${config:sshUser}@${config:sshEndpoint}:/usr/include ${workspaceFolder}/include/ ",
         "problemMatcher": [],
         "presentation": {
            "showReuseMessage": true,
            "clear": true
         }
      },
   ],
}

c_cpp_properties.json for Mingw 

{
    "configurations": [
      {
        "name": "Win32",
        "includePath": [
                  "${workspaceFolder}/**",
                  "C:/Program Files (x86)/mingw-w64/i686-8.1.0-posix-dwarf-rt_v6-rev0/mingw32/i686-w64-mingw32/include"
                  ],
        "defines": [
                  "_DEBUG",
                  "UNICODE",
                  "_UNICODE"
                  ],
        "cStandard": "c99",
        "intelliSenseMode": "gcc-arm"
      }
    ],
   "version": 4
  }