Extending & Embedding Python Using C

extendPython360

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 an editor. 

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

To do this follow the instructions in the book.

Notice that indents have been removed but you can put them back in by auto formatting the code after pasting.

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 23

Hello.c

#include
int main(int argc, char **argv)
{
printf("Hello C World\n");
return 0;
}

tasks.json

{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: gcc build active file",
"command": "/usr/bin/gcc",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}

launch.json

{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "enter program name, for example ${workspaceFolder}/a.out",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
}
]
}

 

 

Page 24

arith.c

#define PY_SSIZE_T_CLEAN
#include

static PyObject *add(PyObject *self, PyObject *args)
{
int x, y, sts;
if (!PyArg_ParseTuple(args, "ii", &x, &y))
return NULL;
sts = x + y;
return PyLong_FromLong(sts);
}

static PyMethodDef AddMethods[] = {
{"add", add, METH_VARARGS, "add two numbers"},
{NULL, NULL, 0, NULL} // sentinel
};

static struct PyModuleDef addmodule = {
PyModuleDef_HEAD_INIT,
"arith",
"C library for sum",
-1,
AddMethods};

PyMODINIT_FUNC PyInit_arith(void)
{
return PyModule_Create(&addmodule);
}

tasks.json

{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: gcc-10 build active file",
"command": "/usr/bin/gcc-10",
"args": [
"-fdiagnostics-color=always",
"-g",
"-shared",
"${file}",
"-o",
"arith.so",
"-I/usr/local/include/python3.11"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}

c_cpp_properties.json

{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"/usr/local/include/**"
],

"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "c17",
"cppStandard": "gnu++14",
"intelliSenseMode": "linux-gcc-arm"
}
],
"version": 4
}

test.py

import arith
print(arith.add(1,2))
print(dir(arith))

Page 30

launch.json

{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
},
{
"name": "(gdb) Attach",
"type": "cppdbg",
"request": "attach",
"program": "/usr/local/bin/python3.11",
"processId": "${command:pickProcess}",
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}

 


Page 38

 hello.c

#include <stdio.h>

int main(int argc, char **argv)

{

    printf("Hello C World\n");

    return 0;

}

 tasks.json

{

    "tasks": [

        {

            "type": "cppbuild",

            "label": "C/C++: cl.exe build active file",

            "command": "cl.exe",

            "args": [

                "/Zi",

                "/EHsc",

                "/nologo",

                "/Fe${fileDirname}\\${fileBasenameNoExtension}.exe",

                "${file}"

            ],

            "options": {

                "cwd": "${fileDirname}"

            },

            "problemMatcher": [

                "$msCompile"

            ],

            "group": {

                "kind": "build",

                "isDefault": true

            },

            "detail": "Task generated by Debugger."

        }

    ],

    "version": "2.0.0"

}

Page 30

Change mike.james in the quoted paths to your own user name

arith.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyObject *add(PyObject *self, PyObject *args)

{

    int x, y, sts;

    if (!PyArg_ParseTuple(args, "ii", &x, &y))

        return NULL;

    sts = x + y;

    return PyLong_FromLong(sts);

}

static PyMethodDef AddMethods[] = {

    {"add", add, METH_VARARGS, "add two numbers"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "arith",

    "C library for sum",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_arith(void)

{

    return PyModule_Create(&addmodule);

}

tasks.json

{

    "tasks": [

        {

            "type": "cppbuild",

            "label": "C/C++: cl.exe build active file",

            "command": "cl.exe",

            "args": [

                "/Zi",

                "/EHsc",

                "/nologo",            

                "/IC:/Users/mike.james/AppData/Local/Programs/Python/Python311/include",              

                "${file}",

                "/link /dll /OUT:arith.pyd /LIBPATH:C:/Users/mike.james/AppData/Local/Programs/Python/Python311/libs"

            ],

            "options": {

                "cwd": "${fileDirname}"

            },

            "problemMatcher": [

                "$msCompile"

            ],

            "group": {

                "kind": "build",

                "isDefault": true

            },

            "detail": "Task generated by Debugger."

        }

    ],

    "version": "2.0.0"

}

 launch.json

{

    "version": "0.2.0",

    "configurations": [

        {

            "name": "(Windows) Attach",

            "type": "cppvsdbg",

            "request": "attach",

            "processId": "${command:pickProcess}",

            "symbolSearchPath": "C:/Users/mike.james/AppData/Local/Programs/Python/Python-3.11.4",

            "sourceFileMap":{"D:/a/1/s/":"C:/Users/mike.james/AppData/Local/Programs/Python/Python311"},

        },

        {

            "name": "Python: Current File",

            "type": "python",

            "request": "launch",

            "program": "${file}",

            "console": "integratedTerminal"

        }

    ]

}

c_cpp_properties.json

{

    "configurations": [

        {

            "name": "Win32",

            "includePath": [

                "${workspaceFolder}/**",

                "C:/Users/mike.james/AppData/Local/Programs/Python/Python311/include/"

            ],

            "defines": [

                "_DEBUG",

                "UNICODE",

                "_UNICODE"

            ],

            "windowsSdkVersion": "10.0.22000.0",

            "compilerPath": "cl.exe",

            "cStandard": "c17",

            "cppStandard": "c++17",

            "intelliSenseMode": "windows-msvc-x64"

        }

    ],

    "version": 4

}

test.py

import arith

print(arith.add(1,2))

print(dir(arith))

 

 Page 44

launch.json

{

    "version": "0.2.0",

    "configurations": [

        {

            "name": "(Windows) Attach",

            "type": "cppvsdbg",

            "request": "attach",

            "processId": "${command:pickProcess}",

        },

        {

            "name": "Python: Current File",

            "type": "python",

            "request": "launch",

            "program": "${file}",

            "console": "integratedTerminal"

        }

    ]

}


 

 

Page 53

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyObject * add(PyObject *self, PyObject *args)

{

    int x, y, sts;

    if (!PyArg_ParseTuple(args, "ii", &x, &y))

        return NULL;

    sts = x+y;

    return PyLong_FromLong(sts);

}

static PyMethodDef AddMethods[] = {

    {"add", add, METH_VARARGS, "add two numbers"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

  PyModuleDef_HEAD_INIT,

  "arith",                              

  "C library for sum",  

  -1,                                  

  AddMethods                          

};

PyMODINIT_FUNC PyInit_arith(void) {    

     return PyModule_Create(&addmodule);

}

Page 54 and on

Arith.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyObject * Pi(PyObject *self, PyObject *args)

{

    int m, n;

    double pi,s;

    if (!PyArg_ParseTuple(args, "ii", &m, &n))

        return NULL;

    pi=0;

    for(int k=m;k<n;k++){

        s=1;

        if(k%2==0)s=-1;

        pi=pi+s/(2*k-1);

    }    

    return PyFloat_FromDouble(4*pi);

}

static PyMethodDef AddMethods[] = {

    {"myPi", Pi, METH_VARARGS, "Compute Pi"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

  PyModuleDef_HEAD_INIT,

  "Pi",                              

  "C library to compute Pi",  

  -1,                                  

  AddMethods                          

};

PyMODINIT_FUNC PyInit_Pi(void) {    

     return PyModule_Create(&addmodule);

}

tasks.json   LINUX

{

    "tasks": [

        {

            "type": "cppbuild",

            "label": "C/C++: gcc-10 build active file",

            "command": "/usr/bin/gcc-10",

            "args": [

                "-fdiagnostics-color=always",

                "-g",

                "-shared",

                "${file}",

                "-o",

                "Pi.so",

                "-I/usr/local/include/python3.11"  

            ],

            "options": {

                "cwd": "${fileDirname}"

            },

            "problemMatcher": [

                "$gcc"

            ],

            "group": {

                "kind": "build",

                "isDefault": true

            },

            "detail": "Task generated by Debugger."

        }

    ],

    "version": "2.0.0"

}

c_cpp_properties.json LINUX

{

    "configurations": [

        {

            "name": "Linux",

            "includePath": [

                "${workspaceFolder}/**",

                "/usr/local/include/**"

            ],

            "defines": [],

            "compilerPath": "/usr/bin/gcc",

            "cStandard": "c17",

            "cppStandard": "gnu++14",

            "intelliSenseMode": "linux-gcc-arm"

        }

    ],

    "version": 4

}

launch.json LINUX

{

    "version": "0.2.0",

    "configurations": [

      {

          "name": "Python: Current File",

          "type": "python",

          "request": "launch",

          "program": "${file}",

          "console": "integratedTerminal"

      },

      {

          "name": "(gdb) Attach",

          "type": "cppdbg",

          "request": "attach",

          "program": "/usr/local/bin/python3.11",

          "processId": "${command:pickProcess}",

          "MIMode": "gdb",

          "setupCommands": [

              {

                  "description": "Enable pretty-printing for gdb",

                  "text": "-enable-pretty-printing",

                  "ignoreFailures": true

              }

          ]

      }

    ]

  }

tasks.json   WINDOWS - CHANGE USER IN PATH

{

    "tasks": [

        {

            "type": "cppbuild",

            "label": "C/C++: cl.exe build active file",

            "command": "cl.exe",

            "args": [

                "/Zi",

                "/EHsc",

                "/nologo",            

                "/IC:/Users/mike.james/AppData/Local/Programs/Python/Python311/include",              

                "${file}",

                "/link /dll /OUT:arith.pyd /LIBPATH:C:/Users/mike.james/AppData/Local/Programs/Python/Python311/libs"

            ],

            "options": {

                "cwd": "${fileDirname}"

            },

            "problemMatcher": [

                "$msCompile"

            ],

            "group": {

                "kind": "build",

                "isDefault": true

            },

            "detail": "Task generated by Debugger."

        }

    ],

    "version": "2.0.0"

}

 c_cpp_properties.json WINDOWS CHANGE USER IN PATH

{

    "configurations": [

        {

            "name": "Win32",

            "includePath": [

                "${workspaceFolder}/**",

                "C:/Users/mike.james/AppData/Local/Programs/Python/Python311/include/"

            ],

            "defines": [

                "_DEBUG",

                "UNICODE",

                "_UNICODE"

            ],

            "windowsSdkVersion": "10.0.22000.0",

            "compilerPath": "cl.exe",

            "cStandard": "c17",

            "cppStandard": "c++17",

            "intelliSenseMode": "windows-msvc-x64"

        }

    ],

    "version": 4

}

launch.json WINDOWS CHANGE USER IN PATH 

{

    "version": "0.2.0",

    "configurations": [

        {

            "name": "(Windows) Attach",

            "type": "cppvsdbg",

            "request": "attach",

            "processId": "${command:pickProcess}",

            "symbolSearchPath": "C:/Users/mike.james/AppData/Local/Programs/Python/Python-3.11.4",

            "sourceFileMap":{"D:/a/1/s/":"C:/Users/mike.james/AppData/Local/Programs/Python/Python311"},

        },

        {

            "name": "Python: Current File",

            "type": "python",

            "request": "launch",

            "program": "${file}",

            "console": "integratedTerminal"

        }

    ]

}

Py.py

import time

def myPi(m,n):

    pi=0

    for k in range(m,n+1):

        s= 1 if k%2 else -1

        pi += s / (2 * k - 1)

    return 4*pi

if __name__ == '__main__':

    N=10000000

    t1=time.perf_counter()

    pi=myPi(1,N)

    t2=time.perf_counter()

    print((t2-t1)*1000)

    print(pi)

Py1.py

import Pi

import time

if __name__ == '__main__':

    N=10000000

    t1=time.perf_counter()

    pi=Pi.myPi(1,N)

    t2=time.perf_counter()

    print((t2-t1)*1000)

    print(pi)

Page 57

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyObject* exampleFunction(PyObject *self, PyObject *args)

{  

     //example function code

}

static PyMethodDef AddMethods[] = {

    {"exampleFunction", exampleFunction, METH_VARARGS, "an example"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

  PyModuleDef_HEAD_INIT,

  "example",                              

  "C library to test API",  

  -1,                                  

  AddMethods                          

};

PyMODINIT_FUNC PyInit_example(void) {    

     return PyModule_Create(&addmodule);

}

tasks.json LINUX

{

    "tasks": [

        {

            "type": "cppbuild",

            "label": "C/C++: gcc-10 build active file",

            "command": "/usr/bin/gcc-10",

            "args": [

                "-fdiagnostics-color=always",

                "-g",

                "-shared",

                "${file}",

                "-o",

                "example.so",

                "-I/usr/local/include/python3.11"  

            ],

            "options": {

                "cwd": "${fileDirname}"

            },

            "problemMatcher": [

                "$gcc"

            ],

            "group": {

                "kind": "build",

                "isDefault": true

            },

            "detail": "Task generated by Debugger."

        }

    ],

    "version": "2.0.0"

}

launch.json LINUX

{

    "version": "0.2.0",

    "configurations": [

      {

          "name": "Python: Current File",

          "type": "python",

          "request": "launch",

          "program": "${file}",

          "console": "integratedTerminal"

      },

      {

          "name": "(gdb) Attach",

          "type": "cppdbg",

          "request": "attach",

          "program": "/usr/local/bin/python3.11",

          "processId": "${command:pickProcess}",

          "MIMode": "gdb",

          "setupCommands": [

              {

                  "description": "Enable pretty-printing for gdb",

                  "text": "-enable-pretty-printing",

                  "ignoreFailures": true

              }

          ]

      }

    ]

  }

c_cpp_properties.json LINUX

{

    "configurations": [

        {

            "name": "Linux",

            "includePath": [

                "${workspaceFolder}/**",

                "/usr/local/include/**"

            ],

            "defines": [],

            "compilerPath": "/usr/bin/gcc",

            "cStandard": "c17",

            "cppStandard": "gnu++14",

            "intelliSenseMode": "linux-gcc-arm"

        }

    ],

    "version": 4

}

tasks.json   WINDOWS - CHANGE USER IN PATH

{

    "tasks": [

        {

            "type": "cppbuild",

            "label": "C/C++: cl.exe build active file",

            "command": "cl.exe",

            "args": [

                "/Zi",

                "/EHsc",

                "/nologo",            

                "/IC:/Users/mike.james/AppData/Local/Programs/Python/Python311/include",              

                "${file}",

                "/link /dll /OUT:example.pyd /LIBPATH:C:/Users/mike.james/AppData/Local/Programs/Python/Python311/libs"

            ],

            "options": {

                "cwd": "${fileDirname}"

            },

            "problemMatcher": [

                "$msCompile"

            ],

            "group": {

                "kind": "build",

                "isDefault": true

            },

            "detail": "Task generated by Debugger."

        }

    ],

    "version": "2.0.0"

}

 

 c_cpp_properties.json WINDOWS CHANGE USER IN PATH

{

    "configurations": [

        {

            "name": "Win32",

            "includePath": [

                "${workspaceFolder}/**",

                "C:/Users/mike.james/AppData/Local/Programs/Python/Python311/include/"

            ],

            "defines": [

                "_DEBUG",

                "UNICODE",

                "_UNICODE"

            ],

            "windowsSdkVersion": "10.0.22000.0",

            "compilerPath": "cl.exe",

            "cStandard": "c17",

            "cppStandard": "c++17",

            "intelliSenseMode": "windows-msvc-x64"

        }

    ],

    "version": 4

}

 

launch.json WINDOWS CHANGE USER IN PATH 

{

    "version": "0.2.0",

    "configurations": [

        {

            "name": "(Windows) Attach",

            "type": "cppvsdbg",

            "request": "attach",

            "processId": "${command:pickProcess}",

            "symbolSearchPath": "C:/Users/mike.james/AppData/Local/Programs/Python/Python-3.11.4",

            "sourceFileMap":{"D:/a/1/s/":"C:/Users/mike.james/AppData/Local/Programs/Python/Python311"},

        },

        {

            "name": "Python: Current File",

            "type": "python",

            "request": "launch",

            "program": "${file}",

            "console": "integratedTerminal"

        }

    ]

}

 


 

Page 72

example.c

This is the combined code from the chapter - the json files are as for example given ealier

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyObject *stringRaw(PyObject *self, PyObject *args)

{

     char *name;

     if (!PyArg_ParseTuple(args, "s", &name))

          return NULL;

     printf("%s\n", name);

     for (int i = 0; name[i]; i++)

     {

          printf("%02X ", (unsigned char)name[i]);

     }

     printf("\n");

     Py_RETURN_NONE;

}

static PyObject *stringRawLen(PyObject *self, PyObject *args)

{

     char *name;

     Py_ssize_t len;

     if (!PyArg_ParseTuple(args, "s#", &name, &len))

          return NULL;

     printf("%s\n", name);

     printf("%d\n", (int)len);

     for (int i = 0; i < len; i++)

     {

          printf("%02X ", (unsigned char)name[i]);

     }

     printf("\n");

     Py_RETURN_NONE;

}

static PyObject *stringPBuffer(PyObject *self, PyObject *args)

{

     Py_buffer myBuf;

     if (!PyArg_ParseTuple(args, "s*", &myBuf))

          return NULL;

     char *myString = (char *)myBuf.buf;

     printf("%s\n", myString);

     for (int i = 0; i < myBuf.len; i++)

     {

          printf("%02X ", (unsigned char)myString[i]);

     }

     printf("\n");

     PyBuffer_Release(&myBuf);

     Py_RETURN_NONE;

}

static PyObject *stringEncode(PyObject *self, PyObject *args)

{

     char *name = NULL;

     if (!PyArg_ParseTuple(args, "es", "cp1252", &name))

          return NULL;

     printf("%s \n", name);

     for (int i = 0; name[i]; i++)

     {

          printf("%02X ", (unsigned char)name[i]);

     }

     printf("\n");

     PyMem_Free(name);

     Py_RETURN_NONE;

}

static PyObject *stringEncode2(PyObject *self, PyObject *args)

{

     char *name = NULL;

     Py_ssize_t len;

     if (!PyArg_ParseTuple(args, "es#", "utf-16", &name, &len))

          return NULL;

     printf("%s \n", name);

     for (int i = 0; i < len; i++)

     {

          printf("%02X ", (unsigned char)name[i]);

     }

     printf("\n");

     PyMem_Free(name);

     Py_RETURN_NONE;

}

static PyObject *stringEncodeAllocate(PyObject *self,

                                      PyObject *args)

{

     Py_ssize_t len = 25;

     char *name = malloc(sizeof(char) * (len + 1));

     if (!PyArg_ParseTuple(args, "es#", "cp1252", &name, &len))

          return NULL;

     printf("%d\n", (int)len);

     printf("%s \n", name);

     for (int i = 0; i < len; i++)

     {

          printf("%02X ", (unsigned char)name[i]);

     }

     printf("\n");

     free(name);

     Py_RETURN_NONE;

}

static PyObject *sequenceElements(PyObject *self, PyObject *args)

{

     int number;

     double x, y;

     char *name = NULL;

     if (!PyArg_ParseTuple(args, "(idds)", &number, &x, &y, &name))

          return NULL;

     printf("%d %f %f %s \n", number, x, y, name);

     Py_RETURN_NONE;

}

static PyMethodDef AddMethods[] = {

    {"stringRaw", stringRaw, METH_VARARGS, "an example"},

    {"stringRawLen", stringRawLen, METH_VARARGS, "an example"},

    {"stringPBuffer", stringPBuffer, METH_VARARGS, "an example"},

    {"stringEncode", stringEncode, METH_VARARGS, "an example"},

    {"stringEncode2", stringEncode2, METH_VARARGS, "an example"},

    {"stringEncodeAllocate", stringEncodeAllocate, METH_VARARGS, "an example"},

    {"sequenceElements", sequenceElements, METH_VARARGS, "an example"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_example(void)

{

     return PyModule_Create(&addmodule);

}

test.py

import example

example.stringRaw("Hello World")

example.stringRawLen("Hello \0 World")

example.stringPBuffer("Hello \0 World")

example.stringEncode("Hello World")

example.stringEncode("\u2020")

example.stringEncode2("Hello World")

example.stringEncodeAllocate("Hello World")

example.sequenceElements((2,1.2,1.3,"test"))


 Page 81

example.c

This is the combined code from the chapter - the json files are as for example given ealier

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyObject *retInt(PyObject *self, PyObject *args)

{

     int value = -1;

     return Py_BuildValue("I", value);

}

static PyObject *strTostr(PyObject *self, PyObject *args)

{

     char *name = "Brian";

     return Py_BuildValue("s", name);

}

static PyObject *strTostr2(PyObject *self, PyObject *args)

{

     char name[] = "    Brian";

     name[0] = 0xCE;

     name[1] = 0x94;

     return Py_BuildValue("s", name);

}

static PyObject *strTostrLen(PyObject *self, PyObject *args)

{

     char name[] = "   Brian";

     Py_ssize_t len = 5;

     name[0] = 0xCE;

     name[1] = 0x94;

     return Py_BuildValue("s#", name, len);

}

static PyObject *strTobytesLen(PyObject *self, PyObject *args)

{

     char name[] = "   Brian";

     Py_ssize_t len = 5;

     name[0] = 0xCE;

     name[1] = 0x94;

     return Py_BuildValue("y#", name, len);

}

static PyObject *wcharTostrLen(PyObject *self, PyObject *args)

{

     wchar_t name[] = L"   Brian";

     Py_ssize_t len = 5;

     name[0] = 0x0394;

     return Py_BuildValue("u#", name, len);

}

static PyObject *wcharTostrLen2(PyObject *self, PyObject *args)

{

  wchar_t name[] = L"   Brian";

  Py_ssize_t len = 5;

  name[0] = 0xD83E;

  name[1] = 0xDD10;

  return Py_BuildValue("u#", name, len);

}

static PyObject *retTuple(PyObject *self, PyObject *args)

{

  int number = 42;

  double x = 1.2, y = 1.1;

  char *name = "brian";

  return Py_BuildValue("(isdd)", number, name, x, y);

}

static PyObject *retList(PyObject *self, PyObject *args)

{

  int number = 42;

  double x = 1.2, y = 1.1;

  char *name = "brian";

  return Py_BuildValue("[isdd]", number, name, x, y);

}

static PyObject *retDict(PyObject *self, PyObject *args)

{

  int number = 42;

  double x = 1.2, y = 1.1;

  char *name = "brian";

  return Py_BuildValue("{sisssdsd}", "first", number,"second", name,"x", x,"y", y);

}

static PyMethodDef AddMethods[] = {

    {"retInt", retInt, METH_VARARGS, "an example"},

    {"strTostr", strTostr, METH_VARARGS, "an example"},

    {"strTostr2", strTostr2, METH_VARARGS, "an example"},

    {"strTostrLen", strTostrLen, METH_VARARGS, "an example"},

    {"strTobytesLen", strTobytesLen, METH_VARARGS, "an example"},

    {"wcharTostrLen", wcharTostrLen, METH_VARARGS, "an example"},

    {"wcharTostrLen2", wcharTostrLen2, METH_VARARGS, "an example"},

    {"retTuple", retTuple, METH_VARARGS, "an example"},

    {"retList", retList, METH_VARARGS, "an example"},

    {"retDict", retDict, METH_VARARGS, "an example"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_example(void)

{

     return PyModule_Create(&addmodule);

}

test.py

import example
print(example.retInt())
print(example.strTostr())
print(example.strTostr2())
print(example.strTostrLen())
print(example.strTobytesLen())
print(example.wcharTostrLen())
#print(example.wcharTostrLen2())
print(example.retTuple())
print(example.retList())
print(example.retDict())
print("end")


 Page 96

example.c

This is the combined code from the chapter - the json files are as for example given ealier

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyObject *Attributes1(PyObject *self, PyObject *args)

{

     PyObject *myObject;

     if (!PyArg_ParseTuple(args, "O", &myObject))

          return NULL;

     PyObject *attribName = Py_BuildValue("s", "myAttribute1");

     PyObject *myAtt1 = PyObject_GetAttr(myObject, attribName);

     Py_XDECREF(attribName);

     return myAtt1;

}

static PyObject *displayAttributes(PyObject *self, PyObject *args)

{

     PyObject *myObject;

     PyObject *myString;

     if (!PyArg_ParseTuple(args, "OO", &myObject, &myString))

          return NULL;

     PyObject *myAtt1 = PyObject_GetAttr(myObject, myString);

     if (PyUnicode_Check(myAtt1))

     {

          const char *mytext = PyUnicode_AsUTF8(myAtt1);

          printf("%s\n", mytext);

     }

     if (PyLong_Check(myAtt1))

     {

          int myValue = PyLong_AsLong(myAtt1);

          printf("%d\n", myValue);

     }

     return myAtt1;

}

static PyObject *Attributes2(PyObject *self, PyObject *args)

{

     PyObject *myObject;

     if (!PyArg_ParseTuple(args, "O", &myObject))

          return NULL;

     PyObject *newValue = PyLong_FromLong(42);

     if (PyObject_SetAttrString(myObject, "myAttribute1", newValue))

          return NULL;

     Py_RETURN_NONE;

}

static PyObject *Attributes3(PyObject *self, PyObject *args)

{

     PyObject *myObject;

     if (!PyArg_ParseTuple(args, "O", &myObject))

          return NULL;

     if (PyObject_HasAttrString(myObject, "myAttribute1"))

     {

          PyObject *myAtt1 = PyObject_GetAttrString(myObject, "myAttribute1");

          if (PyLong_Check(myAtt1))

          {

               int myValue = PyLong_AsLong(myAtt1);

               printf("%d\n", myValue);

          }

     }

     Py_RETURN_NONE;

}

static PyObject *Attributes4(PyObject *self, PyObject *args)

{

  PyObject *myObject;

  if (!PyArg_ParseTuple(args, "O", &myObject))

    return NULL;

  PyObject *main = PyImport_AddModule("__main__");

  PyObject *maindict = PyModule_GetDict(main);

  PyObject *myclass = PyDict_GetItemString(maindict, "myClass");

  if (PyObject_IsInstance(myObject, myclass))

  {

    PyObject *myAtt1 = PyObject_GetAttrString(myObject, "myAttribute1");

    if (PyLong_Check(myAtt1))

    {

      int myValue = PyLong_AsLong(myAtt1);

      printf("%d\n", myValue);

    }

    Py_XDECREF(myAtt1);

  }

  Py_RETURN_NONE;

}

static PyMethodDef AddMethods[] = {

    {"Attributes1", Attributes1, METH_VARARGS, "an example"},

    {"displayAttributes", displayAttributes, METH_VARARGS, "an example"},

    {"Attributes2", Attributes2, METH_VARARGS, "an example"},

    {"Attributes3", Attributes3, METH_VARARGS, "an example"},

    {"Attributes4", Attributes4, METH_VARARGS, "an example"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_example(void)

{

     return PyModule_Create(&addmodule);

}

test.py

import example

class myClass:

    myAttribute1=10

    myAttribute2="Brian"

myInstance=myClass()

print(example.Attributes1(myInstance))

value=example.displayAttributes(myInstance,"myAttribute1")

print(value)

value=example.displayAttributes(myInstance,"myAttribute2")

print(value)

example.Attributes2(myInstance)

print(myInstance.myAttribute1)

example.Attributes3(myInstance)

example.Attributes4(myInstance)


Page 113

example.c

This is the combined code from the chapter - the json files are as for example given ealier

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyObject *tuple1(PyObject *self, PyObject *args)

{

     PyObject *myTuple = PyTuple_New(10);

     for (int i = 0; i < 10; i++)

     {

          PyObject *item = PyLong_FromLong(i);

          PyTuple_SET_ITEM(myTuple, i, item);

     }

     return myTuple;

}

static PyObject *list1(PyObject *self, PyObject *args)

{

     PyObject *mylist = PyList_New(10);

     for (int i = 0; i < 10; i++)

     {

          PyObject *item = PyLong_FromLong(i);

          PyList_SetItem(mylist, i, item);

     }

     return mylist;

}

static PyObject *list2(PyObject *self, PyObject *args)

{

     PyObject *itemlist = PyList_New(0);

     for (int i = 0; i < 10; i++)

     {

          PyObject *item = PyLong_FromLong(i);

          PyList_Append(itemlist, PyLong_FromLong(i));

          Py_DECREF(PyList_GetItem(itemlist, i));

     }

     return itemlist;

}

static PyObject *dict1(PyObject *self, PyObject *args)

{

     PyObject *mydict = PyDict_New();

     PyObject *val = PyLong_FromLong(42333);

     PyObject *key = PyUnicode_DecodeUTF8("Item0", 5, NULL);

     PyDict_SetItem(mydict, key, val);

     Py_DECREF(val);

     Py_DECREF(key);

     return mydict;

}

static PyObject *tuple2(PyObject *self, PyObject *args)

{

     PyObject *myTuple;

     if (!PyArg_ParseTuple(args, "O", &myTuple))

          return NULL;

     int myarray[10];

     for (int i = 0; i < 10; i++)

     {

          PyObject *item = PyTuple_GetItem(myTuple, i);

          myarray[i] = PyLong_AsLong(item);

          printf("%d ", myarray[i]);

     }

     printf("\n");

     Py_RETURN_NONE;

}

static PyObject *list3(PyObject *self, PyObject *args)

{

     PyObject *mylist;

     if (!PyArg_ParseTuple(args, "O", &mylist))

          return NULL;

     PyObject *itemlist = PyList_New(4);

     PyList_SetItem(itemlist, 0, PyLong_FromLong(10));

     PyList_SetItem(itemlist, 1, PyLong_FromLong(11));

     PyList_SetItem(itemlist, 2, PyLong_FromLong(12));

     PyList_SetItem(itemlist, 3, PyLong_FromLong(13));

     PyList_SetSlice(mylist, 3, 5, itemlist);

     Py_DECREF(itemlist);

     Py_RETURN_NONE;

}

static PyObject *listIterator(PyObject *self, PyObject *args)

{

     PyObject *mylist;

     if (!PyArg_ParseTuple(args, "O", &mylist))

          return NULL;

     PyObject *myIter = PyObject_GetIter(mylist);

     printf("%d ", PyLong_AsLong((PyIter_Next(myIter))));

     printf("%d ", PyLong_AsLong((PyIter_Next(myIter))));

     printf("%d ", PyLong_AsLong((PyIter_Next(myIter))));

     printf("%d ", PyLong_AsLong((PyIter_Next(myIter))));

     printf("\n");

     Py_DECREF(myIter);

     Py_RETURN_NONE;

}

static PyObject *listFor(PyObject *self, PyObject *args)

{

     PyObject *myList;

     if (!PyArg_ParseTuple(args, "O", &myList))

          return NULL;

     PyObject *myIter = PyObject_GetIter(myList);

     for (PyObject *item = PyIter_Next(myIter); item != NULL; item = PyIter_Next(myIter))

     {

          printf("%d ", PyLong_AsLong(item));

          Py_DECREF(item);

     }

     printf("\n");

     Py_DECREF(myIter);

     Py_RETURN_NONE;

}

static PyObject *listWhile(PyObject *self, PyObject *args)

{

     PyObject *myList;

     if (!PyArg_ParseTuple(args, "O", &myList))

          return NULL;

     PyObject *myIter = PyObject_GetIter(myList);

     PyObject *item;

     while (item = PyIter_Next(myIter))

     {

          printf("%d ", PyLong_AsLong(item));

          Py_DECREF(item);

     }

     Py_DECREF(myIter);

     printf("\n");

     Py_DECREF(myIter);

     Py_RETURN_NONE;

}

static PyMethodDef AddMethods[] = {

    {"tuple1", tuple1, METH_VARARGS, "an example"},

    {"list1", list1, METH_VARARGS, "an example"},

    {"list2", list2, METH_VARARGS, "an example"},

    {"dict1", dict1, METH_VARARGS, "an example"},

    {"tuple2", tuple2, METH_VARARGS, "an example"},

    {"list3", list3, METH_VARARGS, "an example"},

    {"listIterator", listIterator, METH_VARARGS, "an example"},

    {"listFor", listFor, METH_VARARGS, "an example"},

    {"listWhile", listWhile, METH_VARARGS, "an example"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_example(void)

{

     return PyModule_Create(&addmodule);

}

test.py

import example

import sys

#print(example.tuple1())

print(example.list1())

myList=example.list2()

print(myList)

print("ref count=",sys.getrefcount(myList[0])-1)

myDict=example.dict1()

print(myDict)

print("ref count=",sys.getrefcount(myDict["Item0"])-1)

print("ref count=",sys.getrefcount(myDict)-1)



myTuple=example.tuple1()

print(myTuple)

example.tuple2(myTuple)

mylist=[0,1,2,3,4,5,6,7,8,9]

example.list3(mylist)

print(myList)

mylist=[0,1,2,3,4,5,6,7,8,9]

example.listIterator(mylist)

example.listFor(mylist)

example.listWhile(mylist)

 


Page 118

 

exception.py

total=0

class MyNumberError(ArithmeticError):

    def __init__(self, message,):

        super(MyNumberError, self).__init__(message)



def myFunc(x,y):

    global total

    total=total+1

    print("in myFunc")

    raise MyNumberError("Number not 42")

    return 1

result=myFunc(1,1)

try:

    result=myFunc(1,1)

except MyNumberError:

    print("Can't divide by zero")

    total=total-1

  #  result=myFunc(1,1)

#print(result)

print(total)

Page 123

example.c

This is the combined code from the chapter - the json files are as for example given ealier

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyObject *exception1(PyObject *self, PyObject *args)

{

     PyObject *x = PyLong_FromLong(1);

     PyObject *y = PyLong_FromLong(0);

     PyObject *ans = PyNumber_TrueDivide(x, y);

     if (ans == NULL)

     {

          Py_DECREF(x);

          Py_DECREF(y);

          return NULL;

     }

     PyObject *z = PyLong_FromLong(1);

     PyObject *ans2 = PyNumber_TrueDivide(x, z);

     Py_DECREF(x);

     Py_DECREF(y);

     Py_DECREF(z);

     return ans;

}

static PyObject *exception2(PyObject *self, PyObject *args)

{

     PyErr_SetString(PyExc_ZeroDivisionError, "A Dummy divide error has occurred");

     return NULL;

}

static PyObject *myCustomException;

static PyObject *exception3(PyObject *self, PyObject *args)

{

     PyErr_SetString(myCustomException, "A Custom error has occurred");

     return NULL;

}

static PyObject *exception4(PyObject *self, PyObject *args)

{

     PyObject *x = PyLong_FromLong(1);

     PyObject *y = PyLong_FromLong(0);

     PyObject *ans = PyNumber_TrueDivide(x, y);

     if (ans == NULL)

     {

          PyErr_Clear();

          PyObject *z = PyLong_FromLong(1);

          ans = PyNumber_TrueDivide(x, z);

          Py_DECREF(z);

     }

     Py_DECREF(x);

     Py_DECREF(y);

     return ans;

}

static PyObject *exception5(PyObject *self, PyObject *args)

{

     PyObject *x = PyLong_FromLong(1);

     PyObject *y = PyLong_FromLong(0);

     PyObject *ans = PyNumber_TrueDivide(x, y);

     if (PyErr_Occurred() != NULL)

     {

          if(PyErr_ExceptionMatches(PyExc_ZeroDivisionError)){

               PyErr_Clear();

               PyObject *z = PyLong_FromLong(1);

               ans = PyNumber_TrueDivide(x, z);

               Py_DECREF(z);

          }

     }

     Py_DECREF(x);

     Py_DECREF(y);

     return ans;

}

static PyObject *list1(PyObject *self, PyObject *args)

{

  PyObject *myList;

  if (!PyArg_ParseTuple(args, "O", &myList))

    return NULL;

  printf("myList %ld\n", Py_REFCNT(myList));

  PyObject *temp = PyList_GetItem(myList, 0);

  printf("item zero %ld\n", Py_REFCNT(temp));

  PyObject *myList2 = PySequence_InPlaceConcat(myList, myList);

  temp = PyList_GetItem(myList, 0);

  temp = PyList_GetItem(myList, 0);

  printf("myList %ld\n", Py_REFCNT(myList));

  printf("item zero %ld\n", Py_REFCNT(temp));

  Py_RETURN_NONE;

}



static PyMethodDef AddMethods[] = {

    {"exception1", exception1, METH_VARARGS, "an example"},

    {"exception2", exception2, METH_VARARGS, "an example"},

    {"exception3", exception3, METH_VARARGS, "an example"},

    {"exception4", exception4, METH_VARARGS, "an example"},

    {"exception5", exception5, METH_VARARGS, "an example"},

    {"list1", list1, METH_VARARGS, "an example"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_example(void)

{

     PyObject *m;

     m = PyModule_Create(&addmodule);

     if (m == NULL)

          return NULL;

     myCustomException = PyErr_NewException("example.myCustomException", NULL, NULL);

     if (PyModule_AddObjectRef(m, "myCustomException", myCustomException) < 0)

     {

          Py_CLEAR(myCustomException);

          Py_DECREF(m);

          return NULL;

     }

     return m;

}

test.py

import example

import gc

#ans=example.exception1()

#print(ans)

#try:

#    ans=example.exception2()

#except ZeroDivisionError as err:

#    print(err)

try:

   ans=example.exception3()

except example.myCustomException as err:

    print(err)



try:

    ans=example.exception4()

except ZeroDivisionError as err:

    print(err)

print(ans)

try:

    ans=example.exception5()

except ZeroDivisionError as err:

    print(err)

print(ans)

print(gc.get_objects())

gc.collect()

myList=[257,1,2,3,4,5,6,7,8,9]

gc.collect()

example.list1(myList)

print(myList)


Page 148

example.c

This is the combined code from the chapter - the json files are as for example given ealier

 

 

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyObject *bytes1(PyObject *self, PyObject *args)

{

     char *myString = "Hello World";

     PyObject *myBytes = PyBytes_FromString(myString);

     return myBytes;

}

static PyObject *bytes2(PyObject *self, PyObject *args)

{

     PyObject *myBytes;

     if (!PyArg_ParseTuple(args, "O", &myBytes))

          return NULL;

     Py_ssize_t len = PyBytes_Size(myBytes);

     for (int i = 1; i < len; i++)

     {

          PyObject *item = PySequence_GetItem(myBytes, i);

          char c = (char)PyLong_AsLong(item);

          printf("%X  ", c);

     }

     printf("\n");

     PyObject *myByteArray = PyByteArray_FromStringAndSize(PyBytes_AsString(myBytes), PyBytes_Size(myBytes));

     char *HelloMessage = "Hello World";

     PyObject *insert = PyByteArray_FromStringAndSize(HelloMessage, strlen(HelloMessage));

     PySequence_SetSlice(myByteArray, 3, 7, insert);

     return myByteArray;

}

static PyObject *string1(PyObject *self, PyObject *args)

{

     PyObject *uni1 = PyUnicode_New(10, 255);

     PyUnicode_Fill(uni1, 0, 10, 120);

     PyUnicode_WriteChar(uni1, 0, 72);

     return uni1;

}

static PyObject *string2(PyObject *self, PyObject *args)

{

     PyObject *myString = PyUnicode_FromString("Spam, Spam, Spam, Spam… Lovely Spam! Wonderful Spam!");

     int len = PyUnicode_GET_LENGTH(myString);

     Py_UCS4 *buf = PyMem_Malloc(sizeof(Py_UCS4) * (len + 1));

     PyUnicode_AsUCS4(myString, buf, 100, 1);

     for (int i = 0; buf[i]; i++)

     {

          printf("%04X ", buf[i]);

     }

     PyMem_Free(buf);

     printf("\n\n");

     buf = PyUnicode_AsUCS4Copy(myString);

     for (int i = 0; buf[i]; i++)

     {

          printf("%04X ", buf[i]);

     }

     printf("\n\n");

     PyMem_Free(buf);

     Py_DECREF(myString);

     Py_RETURN_NONE;

}

static PyObject *string3(PyObject *self, PyObject *args)

{

     PyObject *myString = PyUnicode_FromString("Spam, Spam, Spam, Spam… Lovely Spam! Wonderful Spam!");

     int len = PyUnicode_GET_LENGTH(myString);

     PyObject *substr = PyUnicode_FromString("Lovely");

     Py_ssize_t pos = PyUnicode_Find(myString, substr, 0, len, 1);

     printf("position of Lovely = %ld\n", pos);

     pos = PyUnicode_FindChar(myString, 0x0000006D, 0, len, 1);

     printf("position of first m %ld\n", pos);

     substr = PyUnicode_FromString("Spam");

     Py_ssize_t result = PyUnicode_Tailmatch(myString, substr, 0, len, -1);

     printf("prefix match %ld\n", result);

     substr = PyUnicode_FromString("Spam");

     result = PyUnicode_Contains(myString, substr);

     printf("Contains Spam %ld\n", result);

     Py_ssize_t count = PyUnicode_Count(myString, substr, 0, len);

     printf("Count of how many spam(s) %ld\n", count);

     PyObject *test = PyUnicode_FromString("Spam");

     result = PyUnicode_Compare(substr, test);

     printf("compare to Spam %ld\n", result);

     result = PyUnicode_CompareWithASCIIString(substr, "Spam");

     printf("compare to Spam %ld\n", result);

     PyObject *logic = PyUnicode_RichCompare(substr, test, Py_EQ);

     if (Py_IsTrue(logic))

     {

          printf("Strings are equal\n");

     }

     else

     {

          printf("Strings are not equal\n");

     }

     Py_RETURN_NONE;

}

static PyObject *string4(PyObject *self, PyObject *args)

{

     PyObject *myString = PyUnicode_FromString("Spam, Spam, Spam, Spam . . .Lovely Spam! Wonderful Spam!");

     PyObject *bytesUTF8 = PyUnicode_AsUTF8String(myString);

     PyObject *bytesUTF16 = PyUnicode_AsUTF16String(myString);

     PyObject *bytesUTF32 = PyUnicode_AsUTF32String(myString);

     Py_ssize_t len = PyBytes_Size(bytesUTF32);

     for (int i = 0; i < len; i++)

     {

          PyObject *item = PySequence_GetItem(bytesUTF32, i);

          int c = PyLong_AsLong(item);

          printf("%02X  ", c);

     }

     printf("\n");

     char *buffer;

     PyBytes_AsStringAndSize(bytesUTF32, &buffer, &len);

     PyObject *decodeStr = PyUnicode_DecodeUTF32(buffer, len, NULL, NULL);

     return decodeStr;

}

static PyObject *string5(PyObject *self, PyObject *args)

{

     PyObject *myString = PyUnicode_New(1, 1114111);

     PyUnicode_WriteChar(myString, 0, 0x2020);

     PyObject *myBytes = PyUnicode_AsEncodedString(myString, "cp1252", NULL);

     char *buffer;

     Py_ssize_t len;

     PyBytes_AsStringAndSize(myBytes, &buffer, &len);

     printf("%X \n", buffer[0]);

     printf("%s \n", buffer);

     Py_DECREF(myBytes);

     return myString;

}

static PyObject *string6(PyObject *self, PyObject *args)

{

  PyObject *myString = PyUnicode_FromString("† Spam, Spam, Spam, Spam . . .Lovely Spam! Wonderful Spam!");

  PyObject *myBytes = PyUnicode_AsEncodedString(myString, "raw_unicode_escape", NULL);

  Py_DECREF(myString);

  return myBytes;

}

static PyMethodDef AddMethods[] = {

    {"bytes1", bytes1, METH_VARARGS, "an example"},

    {"bytes2", bytes2, METH_VARARGS, "an example"},

    {"string1", string1, METH_VARARGS, "an example"},

    {"string2", string2, METH_VARARGS, "an example"},

    {"string3", string3, METH_VARARGS, "an example"},

    {"string4", string4, METH_VARARGS, "an example"},

    {"string5", string5, METH_VARARGS, "an example"},

    {"string6", string6, METH_VARARGS, "an example"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_example(void)

{

     return PyModule_Create(&addmodule);

}

 test.py

import example
mybytes=example.bytes1()
print(mybytes)
print()

mybytes=example.bytes2(b"My long message")
print(mybytes)

print(example.string1())
print()
example.string2()
print()
example.string3()
print()
print(example.string4())

print()
result=example.string5()
print(result)
print()
result=example.string6()
print(result)


 

Page 157

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyObject *exampleFunction(PyObject *self, PyObject *args)

{

     // example function code

}

static PyMethodDef AddMethods[] = {

    {"exampleFunction", exampleFunction, METH_VARARGS, "an example"},

    {NULL, NULL, 0, NULL} // sentinel

};

static PyObject *myFunc(PyObject *self, PyObject *args)

{

     printf("hello world\n");

     Py_RETURN_NONE;

}

static PyObject *myFunc2(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)

{

     for (int i = 0; i < nargs; i++)

     {

          const char *myString = PyUnicode_AsUTF8(args[i]);

          printf("%s\n", myString);

     }

     Py_ssize_t nKwds = PyTuple_Size(kwnames);

     for (int i = 0; i < nKwds; i++)

     {

          const char *myValue = PyUnicode_AsUTF8(args[i + nargs]);

          const char *myKeyword = PyUnicode_AsUTF8(PyTuple_GetItem(kwnames, i));

          printf("Keyword = %s, Value = %s \n", myKeyword, myValue);

     }

     Py_RETURN_NONE;

}

static PyMethodDef myFunc_def = {

    "myFunc",

    myFunc,

    METH_VARARGS,

    "the doc string"};

static PyMethodDef myFunc2_def = {

    "myFunc2",

    (PyCFunction)myFunc2,

    METH_FASTCALL | METH_KEYWORDS,

    "the doc string"};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

     PyObject *m = PyModule_Create(&myModule);

     if (m == NULL)

          return NULL;

     // Add a int

     PyObject *myValue = PyLong_FromLong(42);

     PyModule_AddObject(m, "myValue", myValue);

     // Add a list

     PyObject *myList = PyList_New(0);

     PyModule_AddObject(m, "myList", myList);

     // Add a function

     PyObject *myPyFun = PyCFunction_New(&myFunc_def, m);

     PyModule_AddObject(m, "myFunc1", myPyFun);

     // Add a fastcall function

     PyObject *myPyFun2 = PyCFunction_New(&myFunc2_def, m);

     PyModule_AddObject(m, "myFunc2", myPyFun2);

     //Add a function in another module

     PyObject *math=PyImport_ImportModule("math");

     PyObject *mathdict = PyModule_GetDict(math);

     PyObject *myFunction = PyDict_GetItemString(mathdict, "sqrt");

     PyModule_AddObject(m, "myFunc3", myFunction);

     return m;

}

test.py

import example
print("module constant",example.myValue)
example.myValue=43
print("module constant",example.myValue)
print(example.myList)
example.myList.append("spam")
print(example.myList)
print(example.myFunc1())
example.myFunc2("Hello","World",MyKeyWord="myValue")
print(example.myFunc3(2))
print(example.myFunc3.__name__)

 

 

Page 160

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

int exec(PyObject *m)

{

  PyObject *myValue = PyLong_FromLong(42);

  PyModule_AddObject(m, "myValue", myValue);

  return 0;

}

PyObject *create(PyObject *spec, PyModuleDef *def)

{

  PyObject *res=PyObject_GetAttrString(spec,"origin");

  printf("%s\n",PyUnicode_AsUTF8(res));

  PyObject *m= PyModule_New("example");

  return m;

}

PyModuleDef_Slot twoPhase[] = {

    {Py_mod_create, create},

    {Py_mod_exec, exec},

    {0, 0}};

static struct PyModuleDef myModuledef = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    0,

    NULL,

    twoPhase};

PyMODINIT_FUNC PyInit_example(void)

{

  return PyModuleDef_Init(&myModuledef);

}

test.py

import example
print(example.myValue)

Page 164

 example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

struct myData

{

  int count;

  char name[20];

};

static struct myData myModuleData = {42, "spam"};

static PyObject *myFunc(PyObject *self, PyObject *args)

{

  printf("module data %d , %s\n", myModuleData.count, myModuleData.name);

  myModuleData.count++;

  struct myData *myModData = (struct myData *)PyModule_GetState(self);

  printf("module data %d , %s\n", myModData->count, myModData->name);

  myModData->count++;

  Py_RETURN_NONE;

}

static PyMethodDef myFunc_def = {

    "myFunc",

    myFunc,

    METH_VARARGS,

    "the doc string"};

int exec(PyObject *m)

{

  struct myData *myModData = (struct myData *)PyModule_GetState(m);

  myModData->count = 42;

  strcpy(myModData->name, "spam");

  PyObject *myValue = PyLong_FromLong(42);

  PyModule_AddObject(m, "myValue", myValue);

  PyObject *myPyFun = PyCFunction_New(&myFunc_def, m);

  PyModule_AddObject(m, "myFunc", myPyFun);

  return 0;

}

PyObject *create(PyObject *spec, PyModuleDef *def)

{

  PyObject *res = PyObject_GetAttrString(spec, "origin");

  printf("%s\n", PyUnicode_AsUTF8(res));

  PyObject *m = PyModule_New("example");  

  return m;

}



void freeModule(void *m){

    struct myData *myModData = (struct myData *)PyModule_GetState(m);

    PyMem_Free(myModData);

}

PyModuleDef_Slot twoPhase[] = {

    {Py_mod_create, create},

    {Py_mod_exec, exec},

    {0, 0}};

static struct PyModuleDef myModuledef = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    sizeof(struct myData),

    NULL,

    twoPhase,

    NULL,

    NULL,

    freeModule};

PyMODINIT_FUNC PyInit_example(void)

{

  return PyModuleDef_Init(&myModuledef);

}

test.py

import example
example.myFunc()
example.myFunc()

 


 Page 172

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyTypeObject MyType1 = {

    PyVarObject_HEAD_INIT(NULL, 0)

    .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT |  Py_TPFLAGS_DISALLOW_INSTANTIATION

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  int res = PyType_Ready(&MyType1);

  PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

  return m;

}

test.py

import example
myclass=example.MyClass
print(myclass)
print(myclass.__dict__)

Page 173

example.c
 

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyTypeObject MyType1 = {

    PyVarObject_HEAD_INIT(NULL, 0)

    .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT,

    .tp_basicsize = sizeof(PyObject),

    .tp_itemsize = 0,

    .tp_new = PyType_GenericNew,

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  int res = PyType_Ready(&MyType1);

  PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

  return m;

}

test.py

import example
myInst=example.MyClass()
print(myInst)
print(myInst.__dir__())
print(myInst.__sizeof__())

Page 176

exampe.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyObject *myFunc(PyObject *self, PyObject *args)

{

  printf("hello world\n");

  Py_RETURN_NONE;

}

static PyMethodDef myFunc_def = {

    "myFunc",

    myFunc,

    METH_VARARGS,

    "the doc string"};

static PyTypeObject MyType1 = {

    PyVarObject_HEAD_INIT(NULL, 0)

        .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT,

    .tp_basicsize = sizeof(PyObject),

    .tp_itemsize = 0,

    .tp_new = PyType_GenericNew,

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  PyObject *mydict = PyDict_New();

  PyObject *val = PyLong_FromLong(42);

  PyDict_SetItemString(mydict, "myValue", val);

  Py_DECREF(val);

  PyObject *myPyFun = PyCFunction_New(&myFunc_def, (PyObject *)&MyType1);

  PyDict_SetItemString(mydict, "myFunc", myPyFun);

  MyType1.tp_dict = mydict;

  int res = PyType_Ready(&MyType1);

  PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

  return m;

}

 

test.py

import example
example.MyClass.myFunc()
myInst=example.MyClass()
myInst.myFunc()

 Page 177

 example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

typedef struct

{

  PyObject_HEAD

      PyObject *dict;

} MyObject;

static PyObject *myFunc(PyObject *self, PyObject *args)

{

  printf("hello world\n");

  Py_RETURN_NONE;

}

static PyMethodDef myFunc_def = {

    "myFunc",

    myFunc,

    METH_VARARGS,

    "the doc string"};

static PyTypeObject MyType1 = {

    PyVarObject_HEAD_INIT(NULL, 0)

        .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT,

    .tp_basicsize = sizeof(MyObject),

    .tp_itemsize = 0,

    .tp_dictoffset=offsetof(MyObject, dict),

    .tp_new = PyType_GenericNew,

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  PyObject *mydict = PyDict_New();

  PyObject *val = PyLong_FromLong(42);

  PyDict_SetItemString(mydict, "myValue", val);

  Py_DECREF(val);

  PyObject *myPyFun = PyCFunction_New(&myFunc_def, (PyObject *)&MyType1);

  PyDict_SetItemString(mydict, "myFunc", myPyFun);

  MyType1.tp_dict = mydict;

  int res = PyType_Ready(&MyType1);

  PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

  return m;

}

test.py 

import example
example.MyClass.myFunc()
myInst=example.MyClass()
myInst.myFunc()
myInst.myValue=43
print(myInst.myValue)
myInst.myVal1=42
print(myInst.myVal1)

Page  180

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

typedef struct

{

  PyObject_HEAD

      PyObject *dict;

} MyObject;

static PyObject *myFunc(PyObject *self, PyObject *args)

{

  printf("hello world\n");

  Py_RETURN_NONE;

}

static PyMethodDef myFunc_def = {

    "myFunc",

    myFunc,

    METH_VARARGS,

    "the doc string"};

static PyObject *Custom_new(PyTypeObject *type, PyObject *args, PyObject *kwds)

{

  MyObject *self;

  self = (MyObject *)type->tp_alloc(type, 0);

  return (PyObject *)self;

}

static int Custom_init(MyObject *self, PyObject *args, PyObject *kwds)

{

  PyObject *myPyFunc = PyCFunction_New(&myFunc_def, (PyObject *)self);

  PyObject *myPyMethod = PyInstanceMethod_New(myPyFunc);

  int res = PyObject_SetAttrString((PyObject *)self, "MyMethod", myPyMethod);

  return 0;

}

static PyTypeObject MyType1 = {

    PyVarObject_HEAD_INIT(NULL, 0)

        .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT,

    .tp_basicsize = sizeof(MyObject),

    .tp_itemsize = 0,

    .tp_dictoffset = offsetof(MyObject, dict),

    .tp_new = Custom_new,

    .tp_init = (initproc)Custom_init,

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  PyObject *mydict = PyDict_New();

  PyObject *val = PyLong_FromLong(42);

  PyDict_SetItemString(mydict, "myValue", val);

  Py_DECREF(val);

  PyObject *myPyFun = PyCFunction_New(&myFunc_def, (PyObject *)&MyType1);

  PyDict_SetItemString(mydict, "myFunc", myPyFun);

  MyType1.tp_dict = mydict;

  int res = PyType_Ready(&MyType1);

  PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

  return m;

}

test.py

import example
example.MyClass.myFunc()
myInst=example.MyClass()
myInst.myFunc()
myInst.myValue=43
print(myInst.myValue)
myInst.myVal1=42
print(myInst.myVal1)
myInst.MyMethod()

Page 185

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

#include "structmember.h"

typedef struct

{

  PyObject_HEAD

  int myVal;

} MyObject;

static PyObject *myFunc(MyObject *self, PyObject *args)

{

  printf("%d\n", self->myVal);

  printf("hello world\n");

  Py_RETURN_NONE;

};



static PyMemberDef myMemberdef = {

    "MyVar",

    T_INT,

    offsetof(MyObject, myVal),

    0,

    "MyInstanceAttr"};

static PyMethodDef myFunc_def = {

    "myFunc",

    (PyCFunction)myFunc,

    METH_VARARGS,

    "the doc string"};

static PyTypeObject MyType1 = {

    .ob_base = PyVarObject_HEAD_INIT(NULL, 0)

                   .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT,

    .tp_basicsize = sizeof(MyObject),

    .tp_itemsize = 0,

    .tp_new =PyType_GenericNew,

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  PyObject *mydict=PyDict_New();

  PyObject *myMethodDesc = PyDescr_NewMethod(&MyType1, &myFunc_def);

  int res = PyDict_SetItemString(mydict, "MyMethod", myMethodDesc);

  PyObject *myMemberDesc = PyDescr_NewMember(&MyType1, &myMemberdef);

  res = PyDict_SetItemString(mydict, "MyVar", myMemberDesc);

  MyType1.tp_dict=mydict;

  res = PyType_Ready(&MyType1);

  PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

  return m;

}

 test.py

import example

myInst=example.MyClass()
myInst.MyMethod()
myInst.MyVar=43
print(myInst.MyVar)

Page  187

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

#include "structmember.h"

typedef struct

{

  PyObject_HEAD

  int myVal;

} MyObject;

static PyObject *myFunc(MyObject *self, PyObject *args)

{

  printf("%d\n", self->myVal);

  printf("hello world\n");

  Py_RETURN_NONE;

};



static PyMemberDef myMemberdef[] = {

   { "MyVar",T_INT,offsetof(MyObject, myVal),0,"MyInstanceAttr"},

   {NULL}

    };

static PyMethodDef myMethodDef[] = {

  {"MyMethod",(PyCFunction)myFunc,METH_VARARGS,"the doc string"},

  {NULL}

    };

static PyTypeObject MyType1 = {

    .ob_base = PyVarObject_HEAD_INIT(NULL, 0)

    .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT,

    .tp_basicsize = sizeof(MyObject),

    .tp_itemsize = 0,

    .tp_new = PyType_GenericNew,

    .tp_members = myMemberdef,

    .tp_methods = myMethodDef,

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  int res = PyType_Ready(&MyType1);

  PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

  return m;

}

test.py

import example

myInst=example.MyClass()
myInst.MyMethod()
myInst.MyVar=43
print(myInst.MyVar)

Page 190

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

#include "structmember.h"

typedef struct

{

  PyObject_HEAD

      PyObject *myProp;

} MyObject;

static PyObject *getVal(MyObject *self, void *extra)

{

  return Py_NewRef(self->myProp);

}

int setVal(MyObject *self, PyObject *val, void *extra)

{

  Py_XSETREF(self->myProp, Py_XNewRef(val));

  return 0;

}

static PyGetSetDef myGetSetDef[] = {

    {"myProperty", (getter)getVal, (setter)setVal, "Example get set", NULL},

    {NULL}};

static PyTypeObject MyType1 = {

    .ob_base = PyVarObject_HEAD_INIT(NULL, 0)

                   .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT,

    .tp_basicsize = sizeof(MyObject),

    .tp_itemsize = 0,

    .tp_new = PyType_GenericNew,

    .tp_getset = myGetSetDef,

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  int res = PyType_Ready(&MyType1);

  PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

  return m;

}

test.py

import example

myInst=example.MyClass()
myInst.myProperty=42
print(myInst.myProperty)


 Page 194

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

#include "structmember.h"

typedef struct

{

     PyObject_HEAD int myVal;

} MyObject;

static void Custom_dealloc(MyObject *self)

{

     printf("destructor called\n");

     Py_TYPE(self)->tp_free((PyObject *)self);

}

static PyObject *myFunc(MyObject *self, PyObject *args)

{

     printf("%d\n", self->myVal);

     printf("hello world\n");

     Py_RETURN_NONE;

};

static PyMemberDef myMemberdef[] = {

    {"MyVar", T_INT, offsetof(MyObject, myVal), 0, "MyInstanceAttr"},

    {NULL}};

static PyMethodDef myMethodDef[] = {

    {"MyMethod", (PyCFunction)myFunc, METH_VARARGS, "the doc string"},

    {NULL}};

static PyTypeObject MyType1 = {

    .ob_base = PyVarObject_HEAD_INIT(NULL, 0)

                   .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT,

    .tp_basicsize = sizeof(MyObject),

    .tp_itemsize = 0,

    .tp_new = PyType_GenericNew,

    .tp_members = myMemberdef,

    .tp_methods = myMethodDef,

    .tp_dealloc = (destructor)Custom_dealloc,

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

     PyObject *m = PyModule_Create(&myModule);

     if (m == NULL)

          return NULL;

     int res = PyType_Ready(&MyType1);

     PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

     return m;

}

test.py

import example
myinst1=example.MyClass()
myinst1.MyVar=42
print(myinst1.MyVar)
myInst1=None

Page 196

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

#include "structmember.h"

typedef struct

{

  PyObject_HEAD

  int myVal;

  PyObject *myAttr;

} MyObject;

static void Custom_dealloc(MyObject *self)

{

     printf("destructor called\n");

     Py_TYPE(self)->tp_free((PyObject *)self);

}

static PyObject *myFunc(MyObject *self, PyObject *args)

{

     printf("%d\n", self->myVal);

     printf("hello world\n");

     Py_RETURN_NONE;

};

static PyMemberDef myMemberdef[] = {

    {"MyVar", T_INT, offsetof(MyObject, myVal), 0,"MyInstanceAttr"},

    {"MyAttr", T_OBJECT_EX, offsetof(MyObject, myAttr), 0,"MyInstandeAttr"},

    {NULL}};

static PyMethodDef myMethodDef[] = {

    {"MyMethod", (PyCFunction)myFunc, METH_VARARGS, "the doc string"},

    {NULL}};

static PyTypeObject MyType1 = {

    .ob_base = PyVarObject_HEAD_INIT(NULL, 0)

                   .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT,

    .tp_basicsize = sizeof(MyObject),

    .tp_itemsize = 0,

    .tp_new = PyType_GenericNew,

    .tp_members = myMemberdef,

    .tp_methods = myMethodDef,

    .tp_dealloc = (destructor)Custom_dealloc,

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

     PyObject *m = PyModule_Create(&myModule);

     if (m == NULL)

          return NULL;

     int res = PyType_Ready(&MyType1);

     PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

     return m;

}

 test.py

import example
myInst1=example.MyClass()
myInst1.MyAttr=myInst1
myInst1=None
print("end")
while True:
     pass

Page 197

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

#include "structmember.h"

typedef struct

{

    PyObject_HEAD int myVal;

    PyObject *myAttr;

    PyObject *weaklist;

} MyObject;

static void Custom_dealloc(MyObject *self)

{

    printf("destructor called\n");

    Py_TYPE(self)->tp_free((PyObject *)self);

}

static PyObject *myFunc(MyObject *self, PyObject *args)

{

    printf("%d\n", self->myVal);

    printf("hello world\n");

    Py_RETURN_NONE;

};

static PyMemberDef myMemberdef[] = {

    {"MyVar", T_INT, offsetof(MyObject, myVal), 0, "MyInstanceAttr"},

    {"MyAttr", T_OBJECT_EX, offsetof(MyObject, myAttr), 0, "MyInstandeAttr"},

    {NULL}};

static PyMethodDef myMethodDef[] = {

    {"MyMethod", (PyCFunction)myFunc, METH_VARARGS, "the doc string"},

    {NULL}};

static PyTypeObject MyType1 = {

    .ob_base = PyVarObject_HEAD_INIT(NULL, 0)

                   .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT,

    .tp_basicsize = sizeof(MyObject),

    .tp_itemsize = 0,

    .tp_new = PyType_GenericNew,

    .tp_members = myMemberdef,

    .tp_methods = myMethodDef,

    .tp_dealloc = (destructor)Custom_dealloc,

    .tp_weaklistoffset = offsetof(MyObject, weaklist),

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

    PyObject *m = PyModule_Create(&myModule);

    if (m == NULL)

        return NULL;

    int res = PyType_Ready(&MyType1);

    PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

    return m;

}

test.py

import example
import weakref
myInst1=example.MyClass()
myInst1.MyAttr=weakref.ref(myInst1)
myInst1=None
print("end")
while True:
    pass

 Page 199

example.c 

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

#include "structmember.h"

typedef struct

{

  PyObject_HEAD int myVal;

  PyObject *myAttr;

} MyObject;

static void Custom_dealloc(MyObject *self)

{

  printf("destructor called\n");

  PyObject *error_type,*error_value, *error_traceback;

  PyErr_Fetch(&error_type, &error_value, &error_traceback);

  PyObject_GC_UnTrack(self);

  Py_TYPE(self)->tp_clear((PyObject *)self);

  PyObject_GC_Del(self);

  PyErr_Restore(error_type, error_value, error_traceback);  

}

static int Custom_clear(MyObject *self)

{

  printf("clear called\n");

  Py_CLEAR(self->myAttr);

  return 0;

}

static int Custom_traverse(MyObject *self, visitproc visit, void *arg)

{

  printf("traverse called\n");

  Py_VISIT(self->myAttr);

  return 0;

}

static int Custom_init(MyObject *self, PyObject *args, PyObject *kwds)

{

  self->myVal = 0;

  self->myAttr = Py_None;

  Py_XINCREF(Py_None);

  return 0;

}

static PyObject *myFunc(MyObject *self, PyObject *args)

{

  printf("%d\n", self->myVal);

  printf("hello world\n");

  Py_RETURN_NONE;

};

static PyMemberDef myMemberdef[] = {

    {"MyVar", T_INT, offsetof(MyObject, myVal), 0, "MyInstanceAttr"},

    {"MyAttr", T_OBJECT_EX, offsetof(MyObject, myAttr), 0, "MyInstandeAttr"},

    {NULL}};

static PyMethodDef myMethodDef[] = {

    {"MyMethod", (PyCFunction)myFunc, METH_VARARGS, "the doc string"},

    {NULL}};

static PyTypeObject MyType1 = {

    .ob_base = PyVarObject_HEAD_INIT(NULL, 0)

                   .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,

    .tp_basicsize = sizeof(MyObject),

    .tp_itemsize = 0,

    .tp_new = PyType_GenericNew,

    .tp_init = (initproc)Custom_init,

    .tp_members = myMemberdef,

    .tp_methods = myMethodDef,

    .tp_clear = (inquiry)Custom_clear,

    .tp_traverse = (traverseproc)Custom_traverse,

    .tp_dealloc = (destructor)Custom_dealloc,

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  int res = PyType_Ready(&MyType1);

  PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

  return m;

}

 

test.py

import example
import gc

myInst1=example.MyClass()
print(gc.is_tracked(myInst1))
myInst1.MyAttr=myInst1
myInst1=None
print(gc.get_count())
gc.collect()
print(gc.get_count())

Page 203

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

#include "structmember.h"

static PyTypeObject MyType1;

typedef struct

{

  PyObject_HEAD int myVal;

  PyObject *myAttr;

} MyObject;

static void Custom_dealloc(MyObject *self)

{

  printf("destructor called\n");

  PyObject *error_type,

      *error_value, *error_traceback;

  PyErr_Fetch(&error_type, &error_value, &error_traceback);

  PyObject_GC_UnTrack(self);

  Py_TYPE(self)->tp_clear((PyObject *)self);

  PyObject_GC_Del(self);

  PyErr_Restore(error_type, error_value, error_traceback);

}

static void Custom_finalizer(MyObject *self)

{

  printf("finalizer called\n");

  if (PyObject_GC_IsFinalized((PyObject *)self))

    return;

  PyObject *error_type,

      *error_value, *error_traceback;

  PyErr_Fetch(&error_type, &error_value, &error_traceback);

  PyObject_GC_UnTrack(self);

  Py_TYPE(self)->tp_clear((PyObject *)self);

  PyObject_GC_Del(self);

  PyErr_Restore(error_type, error_value, error_traceback);

}

static int Custom_clear(MyObject *self)

{

  printf("clear called\n");

  Py_CLEAR(self->myAttr);

  return 0;

}

static int Custom_traverse(MyObject *self, visitproc visit, void *arg)

{

  printf("traverse called\n");

  Py_VISIT(self->myAttr);

  return 0;

}

static int Custom_init(MyObject *self, PyObject *args, PyObject *kwds)

{

  self->myVal = 0;

  self->myAttr = Py_None;

  Py_XINCREF(Py_None);

  return 0;

}

static PyObject *myFunc(MyObject *self, PyObject *args)

{

  printf("%d\n", self->myVal);

  printf("hello world\n");

  Py_RETURN_NONE;

};

static PyMemberDef myMemberdef[] = {

    {"MyVar", T_INT, offsetof(MyObject, myVal), 0, "MyInstanceAttr"},

    {"MyAttr", T_OBJECT_EX, offsetof(MyObject, myAttr), 0, "MyInstandeAttr"},

    {NULL}};

static PyMethodDef myMethodDef[] = {

    {"MyMethod", (PyCFunction)myFunc, METH_VARARGS, "the doc string"},

    {NULL}};

static PyTypeObject MyType1 = {

    .ob_base = PyVarObject_HEAD_INIT(NULL, 0)

                   .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,

    .tp_basicsize = sizeof(MyObject),

    .tp_itemsize = 0,

    .tp_new = PyType_GenericNew,

    .tp_init = (initproc)Custom_init,

    .tp_members = myMemberdef,

    .tp_methods = myMethodDef,

    .tp_clear = (inquiry)Custom_clear,

    .tp_traverse = (traverseproc)Custom_traverse,

    .tp_finalize = (destructor)Custom_finalizer,

    .tp_dealloc = (destructor)Custom_dealloc,

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  int res = PyType_Ready(&MyType1);

  PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

  return m;

}

test.py

import example
import gc

myInst1=example.MyClass()
print(gc.is_tracked(myInst1))
myInst1.MyAttr=myInst1
myInst1=None
print(gc.get_count())
gc.collect()
print(gc.get_count())

Page 205

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

#include "structmember.h"

typedef struct

{

     PyObject_HEAD

     int myVal;

} MyObject;

static PyObject *myFunc(MyObject *self, PyObject *args)

{

     printf("%d\n", self->myVal);

     printf("hello world\n");

     Py_RETURN_NONE;

};

static PyMemberDef myMemberdef[] = {

    {"MyVar", T_INT, offsetof(MyObject, myVal), 0, "MyInstanceAttr"},

    {NULL}};

static PyMethodDef myMethodDef[] = {

    {"MyMethod", (PyCFunction)myFunc, METH_VARARGS, "the doc string"},

    {NULL}};

static struct PyModuleDef myModule = {PyModuleDef_HEAD_INIT, "example", "C library to test API", -1, NULL};

PyMODINIT_FUNC PyInit_example(void)

{

     PyObject *m = PyModule_Create(&myModule);

     if (m == NULL)

          return NULL;

     static PyType_Slot mySlots[] = {

         {Py_tp_doc, "My Custom object"},

         {Py_tp_members, myMemberdef},

         {Py_tp_methods, myMethodDef},

         {0, NULL}};

     PyType_Spec mySpec = {

         "example.myObject",

         sizeof(MyObject),

         0,

         Py_TPFLAGS_DEFAULT,

         mySlots};

     PyTypeObject *MyType1 = (PyTypeObject *)PyType_FromSpec(&mySpec);

     PyModule_AddObject(m, "MyClass", (PyObject *)MyType1);

     return m;

}

test.py

import example
myInst1=example.MyClass()
myInst1.MyVar=42
print(myInst1.MyVar)
myInst1.MyMethod()
example.MyClass.myNewVar=43
print(example.MyClass.myNewVar)

 

 

 

Page 206

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

#include "structmember.h"

typedef struct

{

  PyObject_HEAD int myVal;

  PyObject *myAttr;

} MyObject;

static void Custom_dealloc(MyObject *self)

{

  printf("destructor called\n");

  PyObject *error_type, *error_value, *error_traceback;

  PyErr_Fetch(&error_type, &error_value, &error_traceback);

  PyObject_GC_UnTrack(self);

  Py_TYPE(self)->tp_clear((PyObject *)self);

  PyObject_GC_Del(self);

  PyErr_Restore(error_type, error_value, error_traceback);

}

static void Custom_finalizer(MyObject *self)

{

  printf("finalizer called\n");

  if (PyObject_GC_IsFinalized((PyObject *)self))

    return;

  PyObject *error_type,

      *error_value, *error_traceback;

  PyErr_Fetch(&error_type, &error_value, &error_traceback);

  PyObject_GC_UnTrack(self);

  Py_TYPE(self)->tp_clear((PyObject *)self);

  PyObject_GC_Del(self);

  PyErr_Restore(error_type, error_value, error_traceback);

}

static int Custom_clear(MyObject *self)

{

  printf("clear called\n");

  Py_CLEAR(self->myAttr);

  return 0;

}

static int Custom_traverse(MyObject *self, visitproc visit, void *arg)

{

  printf("traverse called\n");

  Py_VISIT(self->myAttr);

  return 0;

}

static int Custom_init(MyObject *self, PyObject *args, PyObject *kwds)

{

  self->myVal = 0;

  self->myAttr = Py_None;

  Py_XINCREF(Py_None);

  return 0;

}

static PyObject *myFunc(MyObject *self, PyObject *args)

{

  printf("%d\n", self->myVal);

  printf("hello world\n");

  Py_RETURN_NONE;

};

static PyMemberDef myMemberdef[] = {

    {"MyVar", T_INT, offsetof(MyObject, myVal), 0, "MyInstanceAttr"},

    {"MyAttr", T_OBJECT_EX, offsetof(MyObject, myAttr), 0, "MyInstandeAttr"},

    {NULL}};

static PyMethodDef myMethodDef[] = {

    {"MyMethod", (PyCFunction)myFunc, METH_VARARGS, "the doc string"},

    {NULL}};

static PyType_Slot mySlots[] = {

    {Py_tp_doc, "My Custom object"},

    {Py_tp_members, myMemberdef},

    {Py_tp_methods, myMethodDef},

    {Py_tp_clear, (inquiry)Custom_clear},

    {Py_tp_traverse, (traverseproc)Custom_traverse},

    {Py_tp_dealloc, (destructor)Custom_dealloc},

    {Py_tp_finalize,(destructor)Custom_finalizer},

    {0, NULL}};

PyType_Spec mySpec = {

    "example.myObject",

    sizeof(MyObject),

    0,

    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,

    mySlots};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  PyTypeObject *MyType1 = (PyTypeObject *)PyType_FromSpec(&mySpec);

  PyModule_AddObject(m, "MyClass", (PyObject *)MyType1);

  return m;

}

test.py

import example
import gc

myInst1=example.MyClass()
print(gc.is_tracked(myInst1))
#myInst1.MyAttr=myInst1
myInst1=None
print(gc.get_count())
gc.collect()
print(gc.get_count())

example.MyClass.myNewVar=43
print(example.MyClass.myNewVar)

Page 209

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

#include "structmember.h"

typedef struct

{

  PyUnicodeObject str;

  int myVal;

  PyObject *myAttr;

} MyObject;

static PyObject *myFunc(MyObject *self, PyObject *args)

{

  printf("%d\n", self->myVal);

  printf("hello world\n");

  Py_RETURN_NONE;

};

static PyMemberDef myMemberdef[] = {

    {"MyVar", T_INT, offsetof(MyObject, myVal), 0, "MyInstanceAttr"},

    {"MyAttr", T_OBJECT_EX, offsetof(MyObject, myAttr), 0, "MyInstandeAttr"},

    {NULL}};

static PyMethodDef myMethodDef[] = {

    {"MyMethod", (PyCFunction)myFunc, METH_VARARGS, "the doc string"},

    {NULL}};

static PyTypeObject MyType1 = {

    .ob_base = PyVarObject_HEAD_INIT(NULL, 0)

                   .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,

    .tp_basicsize = sizeof(MyObject),

    .tp_itemsize = 0,

    .tp_members = myMemberdef,

    .tp_methods = myMethodDef,

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  MyType1.tp_base = &PyUnicode_Type;

  int res = PyType_Ready(&MyType1);

  PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

  return m;

}

test.py

import example
myInst1=example.MyClass("Hello")
print(len(myInst1))
myInst1.MyVar=42
print(myInst1.MyVar)
myInst1.MyMethod()
print("myInst=",myInst1)

Page 211

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

#include "structmember.h"

typedef struct

{

  PyListObject list;

  int myVal;

  PyObject *myAttr;

} MyObject;

static PyObject *myFunc(MyObject *self, PyObject *args)

{

  printf("%d\n", self->myVal);

  printf("hello world\n");

  Py_RETURN_NONE;

};

static PyMemberDef myMemberdef[] = {

    {"MyVar", T_INT, offsetof(MyObject, myVal), 0, "MyInstanceAttr"},

    {"MyAttr", T_OBJECT_EX, offsetof(MyObject, myAttr), 0, "MyInstandeAttr"},

    {NULL}};

static PyMethodDef myMethodDef[] = {

    {"MyMethod", (PyCFunction)myFunc, METH_VARARGS, "the doc string"},

    {NULL}};

static PyTypeObject MyType1 = {

    .ob_base = PyVarObject_HEAD_INIT(NULL, 0)

                   .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,

    .tp_basicsize = sizeof(MyObject),

    .tp_itemsize = 0,

    .tp_members = myMemberdef,

    .tp_methods = myMethodDef,

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  MyType1.tp_base = &PyList_Type;

  int res = PyType_Ready(&MyType1);

  PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

  return m;

}

test.py

import example
myInst1=example.MyClass(["brian","spam",42])
print(myInst1)
print(len(myInst1))

Page 213

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

#include "structmember.h"

typedef struct

{

  PyListObject list;

  int myVal;

  PyObject *myAttr;

} MyObject;

static PyObject *myFunc(MyObject *self, PyObject *args)

{

  printf("%d\n", self->myVal);

  printf("hello world\n");

  Py_RETURN_NONE;

};

static int Custom_init(MyObject *self, PyObject *args, PyObject *kwds)

{

  int res = Py_TYPE(self)->tp_base->tp_init((PyObject *)self, args, kwds);

  self->myVal = PyList_Size((PyObject *)self);

  return 0;

}

static void Custom_dealloc(MyObject *self)

{

  printf("destructor called\n");

  PyObject *error_type, *error_value, *error_traceback;

  PyErr_Fetch(&error_type, &error_value, &error_traceback);

  Py_TYPE(self)->tp_clear((PyObject *)self);

  Py_TYPE(self)->tp_base->tp_dealloc((PyObject *)self);

  PyErr_Restore(error_type, error_value, error_traceback);

}

static int Custom_clear(MyObject *self)

{

  printf("clear called\n");

  Py_CLEAR(self->myAttr);

  return 0;

}

static int Custom_traverse(MyObject *self, visitproc visit, void *arg)

{

  printf("traverse called\n");

  Py_VISIT(self->myAttr);

  PyList_Type.tp_traverse((PyObject *)self, visit, arg);

  return 0;

}

static PyMemberDef myMemberdef[] = {

    {"MyVar", T_INT, offsetof(MyObject, myVal), 0, "MyInstanceAttr"},

    {"MyAttr", T_OBJECT_EX, offsetof(MyObject, myAttr), 0, "MyInstandeAttr"},

    {NULL}};

static PyMethodDef myMethodDef[] = {

    {"MyMethod", (PyCFunction)myFunc, METH_VARARGS, "the doc string"},

    {NULL}};

static PyTypeObject MyType1 = {

    .ob_base = PyVarObject_HEAD_INIT(NULL, 0)

                   .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,

    .tp_basicsize = sizeof(MyObject),

    .tp_itemsize = 0,

    .tp_members = myMemberdef,

    .tp_methods = myMethodDef,

    .tp_init = (initproc)Custom_init,

    .tp_clear = (inquiry)Custom_clear,

    .tp_traverse = (traverseproc)Custom_traverse,

    .tp_dealloc = (destructor)Custom_dealloc,

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  MyType1.tp_base = &PyList_Type;

  int res = PyType_Ready(&MyType1);

  PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

  return m;

}

test.py

import example
myInst1=example.MyClass(["brian","spam",42])
print(myInst1)
print(len(myInst1))
print(myInst1.MyVar)

Page 216

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <stddef.h>

#include "structmember.h"



static PyObject *myFactory(PyObject *self, PyObject *args)

{

  args = Py_BuildValue("()");

  PyObject *result = PyObject_Call((PyObject *)self, args, NULL);

  return result;

}

static PyMethodDef myFactory_def = {

    "myFactory",

    (PyCFunction)myFactory,

    METH_FASTCALL | METH_KEYWORDS,

    "the doc string"};

typedef struct

{

  PyObject_HEAD

  int myVal;

} MyObject;

static int Custom_init(MyObject *self, PyObject *args, PyObject *kwds)

{

  self->myVal = 0;

  return 0;

};



static PyMemberDef myMemberdef[] = {

    {"MyVar", T_INT, offsetof(MyObject, myVal), 0, "MyInstanceAttr"},

    {NULL}};



static PyTypeObject MyType1= {

    .ob_base = PyVarObject_HEAD_INIT(NULL, 0)

                   .tp_name = "example.myObject",

    .tp_doc = PyDoc_STR("My Custom object"),

    .tp_flags = Py_TPFLAGS_DEFAULT,

    .tp_basicsize = sizeof(MyObject),

    .tp_itemsize = 0,

    .tp_new = PyType_GenericNew,

    .tp_init = (initproc)Custom_init,

    .tp_members = myMemberdef,

};

static struct PyModuleDef myModule = {

    PyModuleDef_HEAD_INIT,

    "example",

    "C library to test API",

    -1,

    NULL};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  PyObject *myPyFactory = PyCFunction_New(&myFactory_def,(PyObject*) &MyType1);

  PyModule_AddObject(m, "myFactory", myPyFactory);

  int res = PyType_Ready(&MyType1);

  PyModule_AddObject(m, "MyClass", (PyObject *)&MyType1);

  return m;

}

test.py

import example
myInst=example.myFactory()
print(myInst)
print(myInst.MyVar)
myInst.MyVar=42
print(myInst.MyVar)

Page 217

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyObject *call(PyObject *self, PyObject *args)

{

  PyObject *math = PyImport_AddModule("math");

  PyObject *mathdict = PyModule_GetDict(math);

  PyObject *myFunction = PyDict_GetItemString(mathdict, "sqrt");

  args = Py_BuildValue("(I)", 2);

  PyObject *result = PyObject_Call(myFunction, args, NULL);

  return result;

}



static PyObject *object1(PyObject *self, PyObject *args)

{

  PyObject *main = PyImport_AddModule("__main__");

  PyObject *maindict = PyModule_GetDict(main);

  PyObject *myclass = PyDict_GetItemString(maindict, "myClass");

  args = Py_BuildValue("()");

  PyObject *result = PyObject_Call(myclass, args, NULL);

  PyObject *newValue = PyLong_FromLong(43);

  PyObject_SetAttrString(result, "myAttribute1", newValue);

  return result;

}

static PyMethodDef AddMethods[] = {

    {"call", call, METH_VARARGS, "an example"},

    {"object1", object1, METH_VARARGS, "an example"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef myModule = {

  PyModuleDef_HEAD_INIT,

  "example",                              

  "C library to test API",  

  -1,                                  

  AddMethods                          

};

PyMODINIT_FUNC PyInit_example(void)

{

  PyObject *m = PyModule_Create(&myModule);

  if (m == NULL)

    return NULL;

  return m;

}

test.py

import example

import math

class myClass:

    myAttribute1=0

print(example.call())

inst=example.object1()

print(inst)

print(inst.myAttribute1)


Page 226

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#if defined(_WIN32) || defined(_WIN64)

#define SCALE 1000

#else

#define SCALE 1

#endif

static PyObject *Pi(PyObject *self, PyObject *args)

{

     int m, n;

     double pi, s;

     if (!PyArg_ParseTuple(args, "ii", &m, &n))

          return NULL;

     Py_BEGIN_ALLOW_THREADS

     pi = 0;

     for (int k = m; k < n; k++)

     {

          s = 1;

          if (k % 2 == 0)

               s = -1;

          pi = pi + s / (2 * k - 1);

     }

     sleep(5 * SCALE);

     Py_END_ALLOW_THREADS

     return PyFloat_FromDouble(4 * pi);

}

static PyMethodDef AddMethods[] = {

    {"myPi", (PyCFunction)Pi, METH_VARARGS, "Compute Pi"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "Pi",

    "C library to compute Pi",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_Pi(void)

{

     return PyModule_Create(&addmodule);

}

 test.py

import Pi

import time

import concurrent.futures

N=10000000

with concurrent.futures.ThreadPoolExecutor() as executor:

    t1=time.perf_counter()    

    f1 = executor.submit(Pi.myPi,1,N)

    t2=time.perf_counter()

    print("do some additional work")

    print("waiting for result")

    print(f1.result())

    print((t2-t1)*1000)

Page 227 LINUX VERSION

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

typedef struct

{

     int m;

     int n;

} range;

static pthread_mutex_t mutex;

static double PiShared = 0;

void *PartPi(void *args)

{

     range *range1 = (range *)args;

     double pi, s;

     int m = range1->m;

     int n = range1->n;

     pi = 0;

     for (int k = m; k < n; k++)

     {

          s = 1;

          if (k % 2 == 0)

               s = -1;

          pi = pi + s / (2 * k - 1);

     }

     pthread_mutex_lock(&mutex);

     PiShared += pi;

     pthread_mutex_unlock(&mutex);

     return NULL;

}

static PyObject *Pi(PyObject *self, PyObject *args)

{

     int m, n;

     if (!PyArg_ParseTuple(args, "ii", &m, &n))

          return NULL;

     Py_BEGIN_ALLOW_THREADS

         range range1 = {m, n / 2};

     range range2 = {n / 2 + 1, n};

     int threadId;

     pthread_mutex_init(&mutex, NULL);

     pthread_t thread1, thread2;

     pthread_create(&thread1, NULL, PartPi, &range1);

     pthread_create(&thread2, NULL, PartPi, &range2);

     pthread_join(thread1, NULL);

     pthread_join(thread2, NULL);

     Py_END_ALLOW_THREADS return PyFloat_FromDouble(4 * PiShared);

}

static PyMethodDef AddMethods[] = {

    {"myPi", (PyCFunction)Pi, METH_VARARGS, "Compute Pi"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "Pi",

    "C library to compute Pi",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_Pi(void)

{

     return PyModule_Create(&addmodule);

}

Page 229 WINDOWS VERSION

example.c

 

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <Windows.h>

typedef struct

{

    int m;

    int n;

} range;

static int *Mutex;

static double PiShared = 0;

int PartPi(void *args)

{

    range *range1 = (range *)args;

    double pi, s;

    int m = range1->m;

    int n = range1->n;

    pi = 0;

    for (int k = m; k < n; k++)

    {

        s = 1;

        if (k % 2 == 0)

            s = -1;

        pi = pi + s / (2 * k - 1);

    }

    WaitForSingleObject(Mutex, INFINITE);

    PiShared += pi;

    ReleaseMutex(Mutex);

    return 0;

}

static PyObject *Pi(PyObject *self, PyObject *args)

{

    int m, n;

    int *handles[2];

    if (!PyArg_ParseTuple(args, "ii", &m, &n))

        return NULL;

    Py_BEGIN_ALLOW_THREADS

        range range1 = {m, n / 2};

    range range2 = {n / 2 + 1, n};

    int threadId;

    Mutex = CreateMutex(NULL, FALSE, NULL);

    handles[0] = CreateThread(NULL, 0, PartPi, (void *)&range1, 0, &threadId);

    handles[1] = CreateThread(NULL, 0, PartPi, (void *)&range2, 0, &threadId);

    WaitForMultipleObjects(2, handles, TRUE, INFINITE);

    Py_END_ALLOW_THREADS return PyFloat_FromDouble(4 * PiShared);

}

static PyMethodDef AddMethods[] = {

    {"myPi", (PyCFunction)Pi, METH_VARARGS, "Compute Pi"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "Pi",

    "C library to compute Pi",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_Pi(void)

{

    PyObject *m = PyModule_Create(&addmodule);

    if (m == NULL)

        return NULL;

    return m;

}

 

 test.py

import Pi

import time

import concurrent.futures

N=10000000

with concurrent.futures.ThreadPoolExecutor() as executor:

    t1=time.perf_counter()    

    f1 = executor.submit(Pi.myPi,1,N)

    t2=time.perf_counter()

    print("do some additional work")

    print("waiting for result")

    print(f1.result())

    print((t2-t1)*1000)

Page 231 LINUX VERSION

example.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>

typedef struct

{

     int m;

     int n;

} range;

static pthread_mutex_t mutex;

static double PiShared = 0;

void *PartPi(void *args)

{

     range *range1 = (range *)args;

     double pi, s;

     int m = range1->m;

     int n = range1->n;

     pi = 0;

     for (int k = m; k < n; k++)

     {

          s = 1;

          if (k % 2 == 0)

               s = -1;

          pi = pi + s / (2 * k - 1);

     }

     pthread_mutex_lock(&mutex);

     PiShared += pi;

     pthread_mutex_unlock(&mutex);

     PyGILState_STATE gstate = PyGILState_Ensure();

     PyObject *pimod = PyImport_AddModule("Pi");

     PyObject *myVal = PyObject_GetAttrString(pimod, "myValue");

     PyObject *myOne = PyLong_FromLong(1);

     PyObject *myInc = PyNumber_Add(myVal, myOne);

     int res = PyObject_SetAttrString((PyObject *)pimod, "myValue", myInc);

     PyGILState_Release(gstate);

     return NULL;

}

static PyObject *Pi(PyObject *self, PyObject *args)

{

     int m, n;

     if (!PyArg_ParseTuple(args, "ii", &m, &n))

          return NULL;

     Py_BEGIN_ALLOW_THREADS

         range range1 = {m, n / 2};

     range range2 = {n / 2 + 1, n};

     pthread_mutex_init(&mutex, NULL);

     pthread_t thread1, thread2;

     pthread_create(&thread1, NULL, PartPi, &range1);

     pthread_create(&thread2, NULL, PartPi, &range2);

     pthread_join(thread1, NULL);

     pthread_join(thread2, NULL);

     Py_END_ALLOW_THREADS return PyFloat_FromDouble(4 * PiShared);

}

static PyMethodDef AddMethods[] = {

    {"myPi", (PyCFunction)Pi, METH_VARARGS, "Compute Pi"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "Pi",

    "C library to compute Pi",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_Pi(void)

{

     PyObject *m = PyModule_Create(&addmodule);

     if (m == NULL)

          return NULL;

     PyObject *myValue = PyLong_FromLong(42);

     PyModule_AddObject(m, "myValue", myValue);

     return m;

}

Page 233 WINDOWS VERSION

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <Windows.h>

typedef struct

{

    int m;

    int n;

} range;

static int *Mutex;

static double PiShared = 0;

int PartPi(void *args)

{

    range *range1 = (range *)args;

    double pi, s;

    int m = range1->m;

    int n = range1->n;

    pi = 0;

    for (int k = m; k < n; k++)

    {

        s = 1;

        if (k % 2 == 0)

            s = -1;

        pi = pi + s / (2 * k - 1);

    }

    WaitForSingleObject(Mutex, INFINITE);

    PiShared += pi;

    ReleaseMutex(Mutex);

    PyGILState_STATE gstate = PyGILState_Ensure();

    PyObject *pimod = PyImport_AddModule("Pi");

    PyObject *myVal = PyObject_GetAttrString(pimod, "myValue");

    PyObject *myOne = PyLong_FromLong(1);

    PyObject *myInc = PyNumber_Add(myVal, myOne);

    int res = PyObject_SetAttrString((PyObject *)pimod, "myValue", myInc);

    PyGILState_Release(gstate);

    return 0;

}

static PyObject *Pi(PyObject *self, PyObject *args)

{

    int m, n;

    int *handles[2];

    if (!PyArg_ParseTuple(args, "ii", &m, &n))

         return NULL;

    Py_BEGIN_ALLOW_THREADS

    range range1 = {m, n / 2};

    range range2 = {n / 2 + 1, n};

    int threadId;

    Mutex = CreateMutex(NULL, FALSE, NULL);

    handles[0] = CreateThread(NULL, 0, PartPi, (void *)&range1, 0, &threadId);

    handles[1] = CreateThread(NULL, 0, PartPi, (void *)&range2, 0, &threadId);

    WaitForMultipleObjects(2, handles, TRUE, INFINITE);

    Py_END_ALLOW_THREADS

    return PyFloat_FromDouble(4 * PiShared);

}

static PyMethodDef AddMethods[] = {

    {"myPi", (PyCFunction)Pi, METH_VARARGS, "Compute Pi"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "Pi",

    "C library to compute Pi",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_Pi(void)

{

    PyObject *m = PyModule_Create(&addmodule);

    if (m == NULL)

        return NULL;

    PyObject *myValue = PyLong_FromLong(42);

    PyModule_AddObject(m, "myValue", myValue);

    return m;

}

test.py

import Pi

import time

import concurrent.futures

N=10000000

print("go")

with concurrent.futures.ThreadPoolExecutor() as executor:    

    t1=time.perf_counter()    

    f1 = executor.submit(Pi.myPi,1,N)

    print("do some additional work")

    print("waiting for result")

    r=f1.result()

    t2=time.perf_counter()

    print((t2-t1)*1000)

    print(r)

    print(Pi.myValue)

Page 238 LINUX VERSION

#define PY_SSIZE_T_CLEAN

#include <Python.h>

typedef struct

{

    int m;

    int n;

    double Pi;

    PyObject *cb;

}State;

int Ccb(void *args)

{

    State *state = (State *)args;

    printf("C callback called \n");

    PyObject *pi=Py_BuildValue("(f)",state->Pi);

    PyObject_CallObject((PyObject *)(state->cb), pi);

    free(state);

    return 0;

}

static void *ComputePi(void *args)

{

    State *state = (State *)args;

    double pi, s;

    pi = 0;

    for (int k = state->m; k < state->n; k++)

    {

        s = 1;

        if (k % 2 == 0)

            s = -1;

        pi = pi + s / (2 * k - 1);

    }  

    state->Pi=4*pi;

    int res = Py_AddPendingCall(Ccb, (void *)state);

    return NULL;

}

static PyObject *Pi(PyObject *self, PyObject *args)

{

    int m, n;

    PyObject *cb;

    if (!PyArg_ParseTuple(args, "iiO:myPi", &m, &n, &cb))

        return NULL;

    State *state=(State*)malloc(sizeof(State));

    state->m = m;

    state->n = n;

    state->cb = cb;

    state->Pi = 0;

    pthread_t thread1;

    pthread_create(&thread1, NULL, ComputePi, (void *)state);

    return PyLong_FromLong(0);

}

static PyMethodDef AddMethods[] = {

    {"myPi", (PyCFunction)Pi, METH_VARARGS, "Compute Pi"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "Pi",

    "C library to compute Pi",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_Pi(void)

{

    PyObject *m = PyModule_Create(&addmodule);

    if (m == NULL)

        return NULL;    

    return m;

}

 

Page 238 WINDOWS VERSION

 

#define PY_SSIZE_T_CLEAN

#include <Python.h>

#include <Windows.h>

typedef struct

{

    int m;

    int n;

    double Pi;

    PyObject *cb;

}State;

int Ccb(void *args)

{

    State *state = (State *)args;

    printf("C callback called \n");

    PyObject *pi=Py_BuildValue("(f)",state->Pi);

    PyObject_CallObject((PyObject *)state->cb, pi);

    free(state);

    return 0;

}

static int ComputePi(void *args)

{

    State *state = (State *)args;

    double pi, s;

    pi = 0;

    for (int k = state->m; k < state->n; k++)

    {

        s = 1;

        if (k % 2 == 0)

            s = -1;

        pi = pi + s / (2 * k - 1);

    }  

    state->Pi=4*pi;

    int res = Py_AddPendingCall(Ccb, (void *)state);

    return 0;

}

static PyObject *Pi(PyObject *self, PyObject *args)

{

    int m, n;

    PyObject *cb;

    if (!PyArg_ParseTuple(args, "iiO:myPi", &m, &n, &cb))

        return NULL;

    State *state=(State*)malloc(sizeof(State));

    state->m = m;

    state->n = n;

    state->cb = cb;

    state->Pi = 0;

    int threadId;

    int *handle = CreateThread(NULL, 0, ComputePi, (void *)state, 0, &threadId);

    return PyLong_FromLong(0);

}

static PyMethodDef AddMethods[] = {

    {"myPi", (PyCFunction)Pi, METH_VARARGS, "Compute Pi"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "Pi",

    "C library to compute Pi",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_Pi(void)

{

    PyObject *m = PyModule_Create(&addmodule);

    if (m == NULL)

        return NULL;    

    return m;

}

 test.py

import Pi

import time

def myCallback(pi):

    t2 = time.perf_counter()

    print((t2-t1)*1000)

    print("python callback")

    print(pi)

N = 10000000

t1 = time.perf_counter()    

Pi.myPi(1,N,myCallback)

print("do some additional work")

while True:

    time.sleep(0.00001)


 

 Page 244

main.c

#define PY_SSIZE_T_CLEAN

#include <Python.h>



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

{

      Py_Initialize();

      PyRun_SimpleString("from time import time,ctime\n"

                         "print('Today is', ctime(time()))\n");

      Py_FinalizeEx();    

  return 0;

}

 

 tasks.json WINDOWS

 Change user name

{

    "tasks": [

        {

            "type": "cppbuild",

            "label": "C/C++: cl.exe build active file",

            "command": "cl.exe",

            "args": [

                "/Zi",

                "/EHsc",

                "/nologo",

                "/IC:/Users/mike.james/AppData/Local/Programs/Python/Python311/include",

                "/Fe${fileDirname}\\${fileBasenameNoExtension}.exe",

                "${file}",

                "/link /LIBPATH:C:/Users/mike.james/AppData/Local/Programs/Python/Python311/libs"

            ],

            "options": {

                "cwd": "${fileDirname}"

            },

            "problemMatcher": [

                "$msCompile"

            ],

            "group": {

                "kind": "build",

                "isDefault": true

            },

            "detail": "Task generated by Debugger."

        }

    ],

    "version": "2.0.0"

}

 tasks.json LINUX

 

{

    "tasks": [

        {

            "type": "cppbuild",

            "label": "C/C++: gcc-10 build active file",

            "command": "/usr/bin/gcc-10",

            "args": [

                "-fdiagnostics-color=always",

                "-g",                

                "${file}",

                "-o",

                "${fileDirname}/${fileBasenameNoExtension}",

                "-I/usr/local/include/python3.11",

                "-L/usr/local/lib/python3.11/config-3.11-arm-linux-gnueabihf",

                "-L/usr/local/lib",

                "-Xlinker",

                "-export-dynamic",

                "-lpython3.11",

                "-lpthread",

                "-ldl",

                "-lutil",

                "-lm",

            ],

            "options": {

                "cwd": "${fileDirname}"

            },

            "problemMatcher": [

                "$gcc"

            ],

            "group": {

                "kind": "build",

                "isDefault": true

            },

            "detail": "Task generated by Debugger."

        }

    ],

    "version": "2.0.0"

}

Page 247

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyObject *Pi(PyObject *self, PyObject *args)

{

  int m, n;

  double pi, s;

  if (!PyArg_ParseTuple(args, "ii", &m, &n))

    return NULL;

  pi = 0;

  for (int k = m; k < n; k++)

  {

    s = 1;

    if (k % 2 == 0)

      s = -1;

    pi = pi + s / (2 * k - 1);

  }

  return PyFloat_FromDouble(4 * pi);

};

static PyMethodDef AddMethods[] = {

    {"myPi", Pi, METH_VARARGS, "Compute Pi"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "Pi",

    "C library to compute Pi",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_Pi(void)

{

  return PyModule_Create(&addmodule);

};

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

{

  PyImport_AppendInittab("Pi", &PyInit_Pi);

  Py_Initialize();

  PyRun_SimpleString("import Pi\n"

    "print(Pi.myPi(1,1000))\n");

  Py_FinalizeEx();

  return 0;

}

Page 248

#define PY_SSIZE_T_CLEAN

#include <Python.h>



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

{

  Py_Initialize();

  PyObject *math =PyImport_ImportModule("math");

  PyObject *mathdict = PyModule_GetDict(math);

  PyObject *myFunction = PyDict_GetItemString(mathdict, "sqrt");

  PyObject *args = Py_BuildValue("(I)", 2);

  PyObject *result = PyObject_Call(myFunction, args, NULL);

  double res=PyFloat_AS_DOUBLE(result);

  printf("%f\n",res);

  PyRun_SimpleString(

    "import math\n"

    "print(math.sqrt(2))\n");

  Py_FinalizeEx();

  return 0;

}

Page 249

#define PY_SSIZE_T_CLEAN

#include <Python.h>

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

{

  Py_Initialize();

  {

    PyObject *g = PyDict_New();

    PyObject *l = PyDict_New();

    PyDict_SetItemString(l, "X", PyLong_FromLong(2));

    PyDict_SetItemString(l, "Y", PyLong_FromLong(2));

    PyObject *pyResult = PyRun_String("X+Y", Py_eval_input, g, l);

    int Cresult = PyLong_AS_LONG(pyResult);

    printf("%d\n", Cresult);

  }

  {

    PyObject *g = PyDict_New();  

    PyObject *l = PyDict_New();

    PyObject *math = PyImport_ImportModule("math");

    PyDict_SetItemString(g, "math", math);

    PyObject *pyResult = PyRun_String("math.sqrt(2)", Py_eval_input, g, l);

    double res2 = PyFloat_AS_DOUBLE(pyResult);

    printf("%f\n", res2);

  }

  Py_FinalizeEx();

  return 0;

}

Page 250

#define PY_SSIZE_T_CLEAN

#include <Python.h>

static PyObject *Pi(PyObject *self, PyObject *args)

{

    int m, n;

    double pi, s;

    if (!PyArg_ParseTuple(args, "ii", &m, &n))

        return NULL;

    pi = 0;

    for (int k = m; k < n; k++)

    {

        s = 1;

        if (k % 2 == 0)

            s = -1;

        pi = pi + s / (2 * k - 1);

    }

    return PyFloat_FromDouble(4 * pi);

}

static PyMethodDef AddMethods[] = {

    {"myPi", Pi, METH_VARARGS, "Compute Pi"},

    {NULL, NULL, 0, NULL} // sentinel

};

static struct PyModuleDef addmodule = {

    PyModuleDef_HEAD_INIT,

    "Pi",

    "C library to compute Pi",

    -1,

    AddMethods};

PyMODINIT_FUNC PyInit_Pi(void)

{

    return PyModule_Create(&addmodule);

}

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

{

    PyImport_AppendInittab("Pi", &PyInit_Pi);

    Py_Initialize();

    PyObject *main = PyImport_AddModule("__main__");

    PyObject *mainDict = PyModule_GetDict(main);

    FILE *fp = fopen("Pi.py", "r");

    PyObject *l = PyDict_New();

    PyObject *result = PyRun_File(fp, "Pi.py", Py_file_input, mainDict, l);

    Py_FinalizeEx();

    return 0;

}

Pi,py

import Pi
import time
N=10000000
t1=time.perf_counter()
pi=Pi.myPi(1,N)
t2=time.perf_counter()
print((t2-t1)*1000)
print(pi)

 

 

 

 

 

 

 

Programs

Raspberry Pi IoT in C Third Edition

 

piciot3e360

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 VS Code project.  

Note: The VS Code task listings are in Appendix II.

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

To do this follow the instructions in the book - in particular remember to add the bcm2835 library and also any library references that may be needed. The majority of the programs also need to be run with root permissions.

All of the programs below were copy and pasted from working programs in the IDE.

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

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


Chapter  2

Page 28

#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);
}
 

Chapter  3

Page 47

#include <bcm2835.h>
#include <stdio.h>
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_OUTP);
    while (1)
    {
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, HIGH);
        bcm2835_delay(500);
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, LOW);
        bcm2835_delay(500);
    }
    bcm2835_close();
    return 0;
}

Chapter  4

Page 50

#include <bcm2835.h>
#include <stdio.h>
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_OUTP);
    for (;;)
    {
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, HIGH);
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, LOW);
    }
    bcm2835_close();
    return 0;
}
 

Page 62

#define _DEFAULT_SOURCE
#include <bcm2835.h>
#include <stdio.h>
#include <time.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_OUTP);
    volatile int i;
    struct timespec delay = {0, 10 * 1000};
    for (;;)
    {
        bcm2835_gpio_set(RPI_BPLUS_GPIO_J8_07);
        nanosleep(&delay, NULL);
        bcm2835_gpio_clr(RPI_BPLUS_GPIO_J8_07);
        nanosleep(&delay, NULL);
    }
    bcm2835_close();
    return 0;
}
 

Page 64

#include <bcm2835.h>
#include <stdio.h>
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_OUTP);
    volatile int i;
    int n = 10;
    for (;;)
    {
        for (i = 0; i < n; i++)
        {
        };
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, HIGH);
        for (i = 0; i < n; i++)
        {
        };
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, LOW);
    }
    bcm2835_close();
    return 0;
}
 

Page 65

 
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
#include <time.h> 

#define BILLION 1000000000L 

int main(int argc, char** argv) {
    struct timespec btime, etime;

    volatile int i;
    clock_gettime(CLOCK_REALTIME, &btime);
    for (i = 0; i < 10000000; i++) {
    };
    clock_gettime(CLOCK_REALTIME, &etime);
    double nseconds =  (double) ((etime.tv_sec - btime.tv_sec)* BILLION)+(double) (etime.tv_nsec - btime.tv_nsec);
    int n = (int) 10 /nseconds * BILLION + 0.5;
    printf("time = %f (s)  \n \r",nseconds / BILLION);
    printf("n= %d \n\r", n);
    return (EXIT_SUCCESS);
}

Page 66

 
#include <bcm2835.h>
#include <stdio.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07,
                      BCM2835_GPIO_FSEL_OUTP);
    for (;;)
    {
        bcm2835_gpio_set(RPI_BPLUS_GPIO_J8_07);
        bcm2835_delayMicroseconds(1);
        bcm2835_gpio_clr(RPI_BPLUS_GPIO_J8_07);
        bcm2835_delayMicroseconds(1);
    }
    bcm2835_close();
    return 0;
}
 

Page 67

 
#include <bcm2835.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07,BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_11,BCM2835_GPIO_FSEL_OUTP);
    volatile int i;
    for (;;)
    {
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, HIGH);
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, HIGH);
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, LOW);
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, LOW);
    }
    return (EXIT_SUCCESS);
}
 

Page 68

 
#include <bcm2835.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_11, BCM2835_GPIO_FSEL_OUTP);
    uint32_t mask = (1 << RPI_BPLUS_GPIO_J8_07) | (1 << RPI_BPLUS_GPIO_J8_11);
    for (;;)
    {
        bcm2835_gpio_set_multi(mask);
        bcm2835_gpio_clr_multi(mask);
    }

    return (EXIT_SUCCESS);
}
 

Chapter 6

 Page 89

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_PUD_UP);

    while (1)
    {
        if (0 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07))
        {
            printf("Line Low \n\r");
            fflush(stdout);
        };
    }
    return 0;
}
 

Page 90

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_PUD_UP);

    while (1)
    {
        while (1 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07));
        bcm2835_delayMicroseconds(1000);
        while (0 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07));
        bcm2835_delayMicroseconds(1000);
        printf("Button Push \n\r");
        fflush(stdout);
    }
    return 0;
}
 

Page 91

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_PUD_UP);
    uint64_t t;
    while (1)
    {
        while (1 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07)) ;
        t = bcm2835_st_read();
        bcm2835_delayMicroseconds(1000);
        while (0 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07)) ;
        t = bcm2835_st_read() - t;
        bcm2835_delayMicroseconds(1000);
        if (t > 5000000)
        {
            printf("Putton held \n\r");
        }
        else
        {
            printf("Button Push \n\r");
        }
        fflush(stdout);
    }
    return 0;
}
 

Page 92

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

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

    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);

    volatile int i;
    while (1)
    {
        while (1 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07)) ;
        while (0 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07)) ;
        for (i = 0; i < 5000; i++)
        {
            if (0 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07))
                break;
        }
        printf("%d\n\r", i);
        fflush(stdout);
    }
    return (EXIT_SUCCESS);
}
 

Page 93

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    volatile int i;
    uint64_t t;
    while (1)
    {
        while (1 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07)) ;
        while (0 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07)) ;
        t = bcm2835_st_read();
        for (i = 0; i < 5000; i++)
        {
            if (0 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07))
                break;
        }
        t = bcm2835_st_read() - t;
        printf("%d,%llu\n\r", i, t);
        fflush(stdout);
    }
    return (EXIT_SUCCESS);
}
 

Page 94

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_11, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, LOW);

    uint64_t t;
    while (1)
    {
        while (0 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07));
        t = bcm2835_st_read();
        while (1 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07));
        t = bcm2835_st_read() - t;
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, HIGH);
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, LOW);
    }
    return (EXIT_SUCCESS);
}
 

 Page 97 

 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_PUD_UP);
    uint64_t t;
    int s = 0;
    int i;
    while (1)
    {
        t = bcm2835_st_read();
        i = bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07);
        switch (s)
        {
        case 0: //Button not pushed
            if (!i)
            {
                s = 1;
                printf("Button Push \n\r");
                fflush(stdout);
            }
            break;
        case 1: //Button pushed
            if (i)
            {
                s = 0;
            }
            break;
        default:
            s = 0;
        }
        t = bcm2835_st_read() - t;
        bcm2835_delayMicroseconds(1000 - t);
    }
    return 0;
}

Page 99

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_PUD_UP);
    uint64_t t, tpush = 0;
    int s = 0, i;
    while (1)
    {
        t = bcm2835_st_read();
        i = bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07);
        switch (s)
        {
        case 0: //Button not pushed
            if (!i)
            {
                s = 1;
                tpush = t;
            }
            break;
        case 1: //Button pushed
            if (i)
            {
                s = 0;
                if ((t - tpush) > 5000000)
                {
                    printf("Button held \n\r");
                }
                else
                {
                    printf("Button pushed \n\r");
                }
                fflush(stdout);
            }
            break;
        default:
            s = 0;
        }
        t = bcm2835_st_read() - t;
        bcm2835_delayMicroseconds(1000 - t);
    }
    return 0;
}
 

Page 100

 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_PUD_UP);

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_11, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_13, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_15, BCM2835_GPIO_FSEL_OUTP);

    bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, HIGH);
    bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_13, LOW);
    bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_15, LOW);

    uint64_t t;
    int buttonState = bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07);

    int state = 0;
    while (1)
    {
        t = bcm2835_st_read();
        int buttonNow = bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07);
        int edge = buttonState - buttonNow;
        buttonState = buttonNow;

        switch (state)
        {
        case 0:
            if (edge)
            {
                state = 1;
                bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, LOW);
                bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_13, HIGH);
                bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_15, LOW);
            }
            break;
        case 1:
            if (edge)
            {
                state = 2;
                bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, LOW);
                bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_13, LOW);
                bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_15, HIGH);
            }
            break;
        case 2:
            if (edge)
            {
                state = 0;
                bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, HIGH);
                bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_13, LOW);
                bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_15, LOW);
            }
            break;
        }

        t = bcm2835_st_read() - t;
        bcm2835_delayMicroseconds(1000 - t);
    }
    return 0;
}
 

Chapter 7

 

Page 111

#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 114

#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 116

#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;
}

Chapter 8

Page 122

Not a full program just a function definition
 
#define _DEFAULT_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

void checkIRQ()
{
    FILE *fp = popen("sudo dtparam -l", "r");
    if (fp == NULL)
    {
        printf("Failed to run command\n\r");
        exit(1);
    }
    char output[1024];
    int txfound = 0;
    while (fgets(output, sizeof(output), fp) != NULL)
    {
        printf("%s\n\r", output);
        fflush(stdout);
        if (strstr(output, "gpio-no-irq") != NULL)
        {
            txfound = 1;
        }
    }
    pclose(fp);

    if (txfound == 0)
    {
        fp = popen("sudo dtoverlay gpio-no-irq", "r");
        if (fp == NULL)
        {
            printf("Failed to run command\n\r");
            exit(1);
        }
        pclose(fp);
    }
}
 

Page 126

 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_fen(RPI_BPLUS_GPIO_J8_07);
    bcm2835_gpio_ren(RPI_BPLUS_GPIO_J8_07);

    volatile int i;
    uint64_t t;
    while (1)
    {
        bcm2835_gpio_set_eds(RPI_BPLUS_GPIO_J8_07);
        while (0 == bcm2835_gpio_eds(RPI_BPLUS_GPIO_J8_07)) ;
        t = bcm2835_st_read();
        bcm2835_gpio_set_eds(RPI_BPLUS_GPIO_J8_07);
        for (i = 0; i < 5000; i++)
        {
            if (1 == bcm2835_gpio_eds(RPI_BPLUS_GPIO_J8_07))
                break;
        }
        t = bcm2835_st_read() - t;
        printf("%d,%llu\n\r", i, t);
        fflush(stdout);
    }
    return (EXIT_SUCCESS);
}
 

Page 127

 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_fen(RPI_BPLUS_GPIO_J8_07);
    bcm2835_gpio_clr_fen(RPI_BPLUS_GPIO_J8_07);
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_11, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, LOW);

    uint64_t t;
    while (1)
    {
        bcm2835_gpio_set_eds(RPI_BPLUS_GPIO_J8_07);
        t = bcm2835_st_read();
        for (;;)
        {
            if (1 == bcm2835_gpio_eds(RPI_BPLUS_GPIO_J8_07))
                break;
        }
        t = bcm2835_st_read() - t;
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, HIGH);
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, LOW);
    }
    return (EXIT_SUCCESS);
}
 

 Page 128

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
#include <unistd.h>
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_PUD_UP);
    printf("Press button \n\r");
    fflush(stdout);
    sleep(20);
    if (0 == bcm2835_gpio_lev(RPI_BPLUS_GPIO_J8_07))
    {
        printf("Button pressed \n\r");
    }
    else
    {
        printf("No Button press\n\r");
    };
    return 0;
}
 

Page 129

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
#include <unistd.h>
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_gpio_set_pud(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_PUD_UP);
    bcm2835_gpio_fen(RPI_BPLUS_GPIO_J8_07);
    bcm2835_gpio_set_eds(RPI_BPLUS_GPIO_J8_07);
    printf("Press button \n\r");
    fflush(stdout);
    sleep(20);
    if (bcm2835_gpio_eds(RPI_BPLUS_GPIO_J8_07))
    {
        printf("Button pressed \n\r");
    }
    else
    {
        printf("No Button press\n\r");
    };
    return 0;
}
 

 Page 132

 
#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 137 

#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 <pthread.h>
uint64_t t[20];
typedef void (*eventHandler)(int);

typedef struct
{
    int epfd;
    int fd;
    eventHandler func;
} intVec;

void myHandler(int fd)
{
    struct gpioevent_data edata;
    read(fd, &edata, sizeof edata);
    printf("%u,%llu \n\r", edata.id, edata.timestamp);
    fflush(stdout);
}
void *waitInterrupt(void *arg)
{
    intVec *intData = (intVec *)arg;
    struct epoll_event ev;
    for (;;)
    {
        int nfds = epoll_wait(intData->epfd, &ev, 1, 20000);

        if (nfds != 0)
        {
            intData->func(intData->fd);
        }
    }
}
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);
    intVec intData;
    intData.epfd = epfd;
    intData.fd = req.fd;
    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 140

#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <bcm2835.h>
#include <fcntl.h>
#include <unistd.h>
#include <poll.h>

#define BUFFER_MAX 50

typedef void (*eventHandler)();

int openGPIO(int pin, int direction);
int writeGPIO(int gpio, int value);
int readGPIO(int gpio);
int setEdgeGPIO(int gpio, char *edge);
void *waitInterrupt(void *arg);
int attachGPIO(int gpio, char *edge, eventHandler func);

int fd[32] = {0};
typedef struct
{
    int fd;
    int gpio;
    eventHandler func;
} intVec;

intVec intData;
static int count;

void myIntHandler()
{
    count++;
};
int main(int argc, char **argv)
{
    attachGPIO(4, "both", myIntHandler);
    for (;;)
    {
        printf("Interrupt %d\n\r", count);
        fflush(stdout);
    };
    return 0;
}

int openGPIO(int gpio, int direction)
{
    if (gpio < 0 || gpio > 31)
        return -1;
    if (direction < 0 || direction > 1)
        return -2;
    int len;
    char buf[BUFFER_MAX];
    if (fd[gpio] != 0)
    {
        close(fd[gpio]);
        fd[gpio] = open("/sys/class/gpio/unexport", O_WRONLY);
        len = snprintf(buf, BUFFER_MAX, "%d", gpio);
        write(fd[gpio], buf, len);
        close(fd[gpio]);
        fd[gpio] = 0;
    }

    fd[gpio] = open("/sys/class/gpio/export", O_WRONLY);
    len = snprintf(buf, BUFFER_MAX, "%d", gpio);
    write(fd[gpio], buf, len);
    close(fd[gpio]);
    len = snprintf(buf, BUFFER_MAX,
                   "/sys/class/gpio/gpio%d/direction", gpio);
    fd[gpio] = open(buf, O_WRONLY);
    if (direction == 1)
    {
        write(fd[gpio], "out", 4);
        close(fd[gpio]);
        len = snprintf(buf, BUFFER_MAX,
                       "/sys/class/gpio/gpio%d/value", gpio);
        fd[gpio] = open(buf, O_WRONLY);
    }
    else
    {
        write(fd[gpio], "in", 3);
        close(fd[gpio]);
        len = snprintf(buf, BUFFER_MAX,
                       "/sys/class/gpio/gpio%d/value", gpio);
        fd[gpio] = open(buf, O_RDONLY);
    }
    return 0;
}

int writeGPIO(int gpio, int b)
{
    if (b == 0)
    {
        write(fd[gpio], "0", 1);
    }
    else
    {
        write(fd[gpio], "1", 1);
    }

    lseek(fd[gpio], 0, SEEK_SET);
    return 0;
}

int readGPIO(int gpio)
{
    char value_str[3];
    int c = read(fd[gpio], value_str, 3);
    lseek(fd[gpio], 0, SEEK_SET);

    if (value_str[0] == '0')
    {
        return 0;
    }
    else
    {
        return 1;
    }
}

int setEdgeGPIO(int gpio, char *edge)
{
    char buf[BUFFER_MAX];
    int len = snprintf(buf, BUFFER_MAX,
                       "/sys/class/gpio/gpio%d/edge", gpio);
    int fd = open(buf, O_WRONLY);
    write(fd, edge, strlen(edge) + 1);
    close(fd);
    return 0;
}

int attachGPIO(int gpio, char *edge, eventHandler func)
{
    openGPIO(gpio, 0);
    setEdgeGPIO(gpio, edge);
    readGPIO(gpio);
    intData.fd = fd[gpio];
    intData.gpio = gpio;
    intData.func = func;
    pthread_t intThread;
    if (pthread_create(&intThread,
                       NULL, waitInterrupt, (void *)&intData))
    {
        fprintf(stderr, "Error creating thread\n");
        return 1;
    }
    return 0;
}
void *waitInterrupt(void *arg)
{

    intVec *intData = (intVec *)arg;
    int gpio = intData->gpio;
    struct pollfd fdset[1];
    fdset[0].fd = intData->fd;
    fdset[0].events = POLLPRI;
    fdset[0].revents = 0;
    for (;;)
    {
        int rc = poll(fdset, 1, -1);
        if (fdset[0].revents & POLLPRI)
        {
            intData->func();
            lseek(fdset[0].fd, 0, SEEK_SET);
            readGPIO(gpio);
        }
    }
    pthread_exit(0);
}

Chapter 9

Page 151

#include <bcm2835.h>
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock(2);
    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 2);
    bcm2835_pwm_set_data(0, 1);
    return (0);
}
 

Page 152

 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_gpio_fsel(13, BCM2835_GPIO_FSEL_ALT0);
    bcm2835_pwm_set_clock(2);

    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 2);
    bcm2835_pwm_set_data(0, 1);

    bcm2835_pwm_set_mode(1, 1, 1);
    bcm2835_pwm_set_range(1, 8);
    bcm2835_pwm_set_data(1, 2);
    return (EXIT_SUCCESS);
}
 

Page 153

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock(2);
    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 256);
    for (;;)
    {
        bcm2835_pwm_set_data(0, 16);
        bcm2835_delayMicroseconds((int)26.666 * 8);
        bcm2835_pwm_set_data(0, 128);
        bcm2835_delayMicroseconds((int)26.666 * 8);
    }
    return (EXIT_SUCCESS);
}
 

Page 155

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char** argv) {
    if (!bcm2835_init())
        return 1;


    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock(2);
    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 256);
    for (;;) {
        for (int i = 0; i < 256; i = i + 10) {
            bcm2835_pwm_set_data(0, i);
            bcm2835_delayMicroseconds(100);
        }
    }
    return (EXIT_SUCCESS);
}
 

Page 156

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock(2);
    bcm2835_pwm_set_mode(0, 1, 1);
    int C = 34091;
    bcm2835_pwm_set_range(0, C);
    bcm2835_pwm_set_data(0, C / 2);
    return (EXIT_SUCCESS);
}

Page 158

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv){
    if (!bcm2835_init())
            return 1;
    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock(2);
    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 1024);
    int w = 1;
    int inc = 1;
    for (;;)
    {
        bcm2835_pwm_set_data(0, w);
        w = w + inc;
        if (w > 1024 || w <= 0)
            inc = -inc;
        bcm2835_delayMicroseconds(5000);
    }
    return (EXIT_SUCCESS);
}
    bcm2835_delayMicroseconds(5000);
    }
    return (EXIT_SUCCESS);
}
 

Page 159

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock(2);
    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 1024);
    int w = 0;
    int inc = 1;
    for (;;)
    {
        bcm2835_pwm_set_data(0, w * w * w);
        w = w + inc;
        if (w > 10 || w <= 0)
            inc = -inc;
        bcm2835_delayMicroseconds(50000);
    }
    return (EXIT_SUCCESS);
}
 

Page 160

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock(2);
    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 1024);
    int w = 0;
    int inc = 1;

    for (;;)
    {
        bcm2835_pwm_set_data(0, (w * w * w) >> 3);
        w = w + inc;
        if (w > 20 || w <= 0)
            inc = -inc;
        bcm2835_delayMicroseconds(50000);
    }
    return (EXIT_SUCCESS);
}
 

Page 163 

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock(375);
    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 1024);

    for (;;)
    {
        bcm2835_pwm_set_data(0, 25);
        bcm2835_delayMicroseconds(2000000);
        bcm2835_pwm_set_data(0, 50);
        bcm2835_delayMicroseconds(2000000);
        bcm2835_pwm_set_data(0, 128);
        bcm2835_delayMicroseconds(2000000);
    }
    return (EXIT_SUCCESS);
}
 

Page 164 

 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock(375);
    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 1024);

    for (;;)
    {
        bcm2835_pwm_set_data(0, 52 * 0 / 180 + 920);
        bcm2835_delayMicroseconds(2000000);
        bcm2835_pwm_set_data(0, 52 * 90 / 180 + 920);
        bcm2835_delayMicroseconds(2000000);
        bcm2835_pwm_set_data(0, 52 * 180 / 180 + 920);
        bcm2835_delayMicroseconds(2000000);
    }
    return (EXIT_SUCCESS);
}

Page 166

Function only - needs to run as root.
 
void bcm2835_pwm_set_clock_source(
    uint32_t source,
    uint32_t divisorI,
    uint32_t divisorF)
{
    divisorI &= 0xfff;
    divisorF &= 0xfff;
    source &= 0xf;
    uint8_t mask = bcm2835_peri_read(bcm2835_clk + BCM2835_PWMCLK_CNTL) & 0xffffffef;
    bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_CNTL, BCM2835_PWM_PASSWRD | mask);
    while ((bcm2835_peri_read(bcm2835_clk + BCM2835_PWMCLK_CNTL) & 0x80) != 0)
    {
    };
    bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_DIV, BCM2835_PWM_PASSWRD | (divisorI << 12) | divisorF);
    bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_CNTL, BCM2835_PWM_PASSWRD | source | 0x200);
    bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_CNTL, BCM2835_PWM_PASSWRD | 0x210 | source);
}
 

Page 168

 This needs to be run as root.
 
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <bcm2835.h>

void bcm2835_pwm_set_clock_source(uint32_t source,uint32_t divisorI,uint32_t divisorF)
{
    divisorI &= 0xfff;
    divisorF &= 0xfff;
    source &= 0xf;
    uint8_t mask = bcm2835_peri_read(bcm2835_clk + BCM2835_PWMCLK_CNTL) &  0xffffffef;
    bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_CNTL,  BCM2835_PWM_PASSWRD | mask);
    while ((bcm2835_peri_read(bcm2835_clk + BCM2835_PWMCLK_CNTL) & 0x80) != 0)
    {
    };
    bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_DIV, BCM2835_PWM_PASSWRD | (divisorI << 12) | divisorF);
    bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_CNTL, BCM2835_PWM_PASSWRD | source | 0x200);
    bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_CNTL, BCM2835_PWM_PASSWRD | 0x210 | source);
}

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT5);
    bcm2835_pwm_set_clock_source(6, 2, 0);
    bcm2835_pwm_set_mode(0, 1, 1);
    bcm2835_pwm_set_range(0, 256);
    int i;
    for (;;)
    {
        for (i = 0; i < 256; i = i + 10)
        {
            bcm2835_pwm_set_data(0, i);
            bcm2835_delayMicroseconds(2);
        }
    }
    return (EXIT_SUCCESS);
}
 

Chapter 10

Page 184 

 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    char buf[] = {0xE7};
    bcm2835_i2c_begin();
    bcm2835_i2c_setClockDivider(BCM2835_I2C_CLOCK_DIVIDER_148);
    bcm2835_i2c_setSlaveAddress(0x40);
    bcm2835_i2c_write(buf, 1);
    bcm2835_i2c_read(buf, 1);
    printf("User Register = %X \r\n", buf[0]);
    bcm2835_i2c_end();
    return (EXIT_SUCCESS);
}
 

 Page 186

 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

void setTimeout(uint32_t timeout) {
    volatile uint32_t* stimeout = bcm2835_bsc1 + BCM2835_BSC_CLKT / 4;
    bcm2835_peri_write(stimeout, timeout);
}

int main(int argc, char** argv) {
    if (!bcm2835_init())
        return 1;

    bcm2835_i2c_begin();
    bcm2835_i2c_setClockDivider(BCM2835_I2C_CLOCK_DIVIDER_150);
    setTimeout(0);
    char buf[4] = {0xE3};
    uint8_t status = bcm2835_i2c_read_register_rs(buf, buf, 3);
    uint8_t msb = buf[0];
    uint8_t lsb = buf[1];
    uint8_t check = buf[2];
    printf("msb %d \n\r lsb %d \n\r checksum %d \n\r", msb, lsb, check);
    bcm2835_i2c_end();
    return (EXIT_SUCCESS);
}
 

Page 188 

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

void setTimeout(uint32_t timeout)
{
    volatile uint32_t *stimeout = bcm2835_bsc1 + BCM2835_BSC_CLKT / 4;
    bcm2835_peri_write(stimeout, timeout);
}

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_i2c_begin();
    bcm2835_i2c_setClockDivider(BCM2835_I2C_CLOCK_DIVIDER_2500);
    setTimeout(20000);
    char buf[3] = {0xE3};
    uint8_t status = bcm2835_i2c_read_register_rs(buf, buf, 3);
    uint8_t msb = buf[0];
    uint8_t lsb = buf[1];
    uint8_t check = buf[2];
    printf("msb %d \n\r lsb %d \n\r checksum %d \n\r", msb, lsb, check);
    bcm2835_i2c_end();
    return (EXIT_SUCCESS);
}
 

Page 192

 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

void setTimeout(uint16_t timeout);
uint8_t crcCheck(uint8_t msb, uint8_t lsb, uint8_t check);
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;

    bcm2835_i2c_begin();
    bcm2835_i2c_setClockDivider(BCM2835_I2C_CLOCK_DIVIDER_2500);
    setTimeout(20000);
    char buf[4] = {0xE3};
    uint8_t status = bcm2835_i2c_read_register_rs(buf, buf, 3);
    uint8_t msb = buf[0];
    uint8_t lsb = buf[1];
    uint8_t check = buf[2];

    printf("crc = %d\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] = 0xF5;
    bcm2835_i2c_write(buf, 1);
    while (bcm2835_i2c_read(buf, 3) == BCM2835_I2C_REASON_ERROR_NACK)
    {
        bcm2835_delayMicroseconds(500);
    };
    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);
    bcm2835_i2c_end();

    return (EXIT_SUCCESS);
}

void setTimeout(uint16_t timeout)
{
    volatile uint32_t *stimeout = bcm2835_bsc1 + BCM2835_BSC_CLKT / 4;
    bcm2835_peri_write(stimeout, timeout);
}

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;
}
 

Chapter 11

Page 203 

#include <bcm2835.h>
#include <stdio.h>
#include <sched.h>
#include <sys/mman.h>

uint8_t getByte(int b, int buf[]);
void GetDHT22data(uint8_t pin);

int main(int argc, char **argv)
{
    const struct sched_param priority = {1};
    sched_setscheduler(0, SCHED_FIFO, &priority);
    mlockall(MCL_CURRENT | MCL_FUTURE);
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);
    bcm2835_delayMicroseconds(1000);
    GetDHT22data(RPI_BPLUS_GPIO_J8_07);
    return 0;
}

void GetDHT22data(uint8_t pin)
{
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(pin, LOW);
    bcm2835_delayMicroseconds(1000);
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);
    int i;
    for (i = 1; i < 2000; i++)
    {
        if (bcm2835_gpio_lev(pin) == 0)
            break;
    };
    uint64_t t;
    int buf[41];
    int j;
    bcm2835_delayMicroseconds(1);
    for (j = 0; j < 41; j++)
    {
        for (i = 1; i < 2000; i++)
        {
            if (bcm2835_gpio_lev(pin) == 1)
                break;
        };
        t = bcm2835_st_read();
        for (i = 1; i < 2000; i++)
        {
            if (bcm2835_gpio_lev(pin) == 0)
                break;
        }
        buf[j] = (bcm2835_st_read() - t) > 50;
    }

    int byte1 = getByte(1, buf);
    int byte2 = getByte(2, buf);
    int byte3 = getByte(3, buf);
    int byte4 = getByte(4, buf);
    int byte5 = getByte(5, buf);
    printf("Checksum %d %d \n\r", byte5, (byte1 + byte2 + byte3 + byte4) & 0xFF);
    float humidity = (float)(byte1 << 8 | byte2) / 10.0;
    printf("Humidity= %f \n\r", humidity);
    float temperature;
    int neg = byte3 & 0x80;
    byte3 = byte3 & 0x7F;
    temperature = (float)(byte3 << 8 | byte4) / 10.0;
    if (neg > 0)
        temperature = -temperature;
    printf("Temperature= %f \n\r", temperature);
    return;
}

uint8_t getByte(int b, int buf[])
{
    int i;
    uint8_t result = 0;
    b = (b - 1) * 8 + 1;
    for (i = b; i <= b + 7; i++)
    {
        result = result << 1;
        result = result | buf[i];
    }
    return result;
}

Chapter 13 

Page 223

#include <bcm2835.h>
#include <stdio.h>
#include <sched.h>
#include <sys/mman.h>

int presence(uint8_t pin);
void writeByte(uint8_t pin, int byte);
uint8_t crc8(uint8_t *data, uint8_t len);
int readByte(uint8_t pin);
int readiButton(uint8_t pin, uint8_t *data);

int main(int argc, char **argv)
{
    const struct sched_param priority = {1};
    sched_setscheduler(0, SCHED_FIFO, &priority);
    mlockall(MCL_CURRENT | MCL_FUTURE);

    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_INPT);

    int i;
    uint8_t code[8];
    for (;;)
    {
        int p = readiButton(RPI_BPLUS_GPIO_J8_07, code);
        if (p == 1)
        {
            for (i = 0; i < 8; i++)
            {
                printf("%hhX ", code[i]);
            }
            printf("\n\r");
            fflush(stdout);
        }
        bcm2835_delayMicroseconds(100000);
    };
    bcm2835_close();
    return 0;
}

int presence(uint8_t pin)
{
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(pin, LOW);
    bcm2835_delayMicroseconds(480);
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);
    bcm2835_delayMicroseconds(70);
    uint8_t b = bcm2835_gpio_lev(pin);
    bcm2835_delayMicroseconds(410);
    return b;
}

void writeBit(uint8_t pin, int b)
{

    int delay1, delay2;
    if (b == 1)
    {
        delay1 = 6;
        delay2 = 64;
    }
    else
    {
        delay1 = 80;
        delay2 = 10;
    }
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(pin, LOW);
    bcm2835_delayMicroseconds(delay1);
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);
    bcm2835_delayMicroseconds(delay2);
}

uint8_t readBit(uint8_t pin)
{
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(pin, LOW);
    bcm2835_delayMicroseconds(6);
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);
    bcm2835_delayMicroseconds(9);
    uint8_t b = bcm2835_gpio_lev(pin);
    bcm2835_delayMicroseconds(55);
    return b;
}

void writeByte(uint8_t pin, int byte)
{
    int i;
    for (i = 0; i < 8; i++)
    {
        if (byte & 1)
        {
            writeBit(pin, 1);
        }
        else
        {
            writeBit(pin, 0);
        }
        byte = byte >> 1;
    }
}

int readByte(uint8_t pin)
{
    int byte = 0;
    int i;
    for (i = 0; i < 8; i++)
    {
        byte = byte | readBit(pin) << i;
    };
    return byte;
}
uint8_t crc8(uint8_t *data, uint8_t len)
{

    uint8_t i;
    uint8_t j;
    uint8_t temp;
    uint8_t databyte;
    uint8_t crc = 0;
    for (i = 0; i < len; i++)
    {
        databyte = data[i];
        for (j = 0; j < 8; j++)
        {
            temp = (crc ^ databyte) & 0x01;
            crc >>= 1;
            if (temp)
                crc ^= 0x8C;

            databyte >>= 1;
        }
    }

    return crc;
}

int readiButton(uint8_t pin, uint8_t *data)
{
    int b = presence(pin);
    if (b != 0)
        return 0;
    writeByte(pin, 0x33);
    int i;
    for (i = 0; i < 8; i++)
    {
        data[i] = readByte(pin);
    }
    uint8_t crc = crc8(data, 8);
    if (crc == 0)
        return 1;
    return 0;
}

Chapter 14

 Page 233

#include <bcm2835.h>
#include <stdio.h>

int presence(uint8_t pin);
void writeBit(uint8_t pin, int b);
void writeByte(uint8_t pin, int byte);
uint8_t readBit(uint8_t pin);
int convert(uint8_t pin);
int readByte(uint8_t pin);
float getTemperature(uint8_t pin);
uint8_t crc8(uint8_t *data, uint8_t len);

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    if (presence(RPI_BPLUS_GPIO_J8_07) == 1)
    {
        printf("No device \n");
    }
    else
    {
        printf("Device present \n");
    }
    fflush(stdout);
    float t;
    for (;;)
    {
        do
        {
            t = getTemperature(RPI_BPLUS_GPIO_J8_07);
        } while (t < -999);
        printf("%f\r\n", t);
        fflush(stdout);
    };
    bcm2835_close();

    return 0;
}

int presence(uint8_t pin)
{
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(pin, LOW);
    bcm2835_delayMicroseconds(480);
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);
    bcm2835_delayMicroseconds(70);
    uint8_t b = bcm2835_gpio_lev(pin);
    bcm2835_delayMicroseconds(410);
    return b;
}

void writeBit(uint8_t pin, int b)
{
    int delay1, delay2;
    if (b == 1)
    {
        delay1 = 6;
        delay2 = 64;
    }
    else
    {

        delay1 = 60;
        delay2 = 10;
    }
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(pin, LOW);
    bcm2835_delayMicroseconds(delay1);
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);
    bcm2835_delayMicroseconds(delay2);
}

void writeByte(uint8_t pin, int byte)
{
    int i;
    for (i = 0; i < 8; i++)
    {
        if (byte & 1)
        {
            writeBit(pin, 1);
        }
        else
        {

            writeBit(pin, 0);
        }
        byte = byte >> 1;
    }
}

uint8_t readBit(uint8_t pin)
{
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);
    bcm2835_gpio_write(pin, LOW);
    bcm2835_delayMicroseconds(8);
    bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);
    bcm2835_delayMicroseconds(2);
    uint8_t b = bcm2835_gpio_lev(pin);
    bcm2835_delayMicroseconds(60);
    return b;
}

int convert(uint8_t pin)
{
    int i;
    writeByte(pin, 0x44);
    for (i = 0; i < 5000; i++)
    {
        bcm2835_delayMicroseconds(100000);
        if (readBit(pin) == 1)
            break;
    }
    return i;
}

float getTemperature(uint8_t pin)
{
    if (presence(pin) == 1)
        return -1000;
    writeByte(pin, 0xCC);
    if (convert(pin) == 5000)
        return -3000;
    presence(pin);
    writeByte(pin, 0xCC);
    writeByte(pin, 0xBE);
    int i;
    uint8_t data[9];
    for (i = 0; i < 9; i++)
    {
        data[i] = readByte(pin);
    }
    uint8_t crc = crc8(data, 9);
    if (crc != 0)
        return -2000;
    int t1 = data[0];
    int t2 = data[1];
    int16_t temp1 = (t2 << 8 | t1);
    float temp = (float)temp1 / 16;
    return temp;
}

int readByte(uint8_t pin)
{
    int byte = 0;
    int i;
    for (i = 0; i < 8; i++)
    {
        byte = byte | readBit(pin) << i;
    };
    return byte;
}

uint8_t crc8(uint8_t *data, uint8_t len)
{
    uint8_t i;
    uint8_t j;
    uint8_t temp;
    uint8_t databyte;
    uint8_t crc = 0;
    for (i = 0; i < len; i++)
    {
        databyte = data[i];
        for (j = 0; j < 8; j++)
        {
            temp = (crc ^ databyte) & 0x01;
            crc >>= 1;
            if (temp)
                crc ^= 0x8C;
            databyte >>= 1;
        }
    }
    return crc;
}

Chapter 15

Page 246

function only - needs a main program to call it

int oneWireScan(uint8_t pin, uint64_t serial[])
{
    static int bitcount = 0;
    static int deviceCount = 0;

    if (bitcount > 63)
    {
        bitcount = 0;
        deviceCount++;
        return deviceCount;
    }

    if (bitcount == 0)
    {
        if (presence(pin) == 1)
        {
            bitcount = 0;
            return deviceCount;
        }
        deviceCount = 0;
        serial[deviceCount] = 0;
        writeByte(pin, 0xF0);
    };

    int b1 = readBit(pin);
    int b2 = readBit(pin);

    if (b1 == 0 && b2 == 1)
    {
        serial[deviceCount] >>= 1;
        writeBit(pin, 0);
        bitcount++;
        oneWireScan(pin, serial);
    };

    if (b1 == 1 && b2 == 0)
    {
        serial[deviceCount] >>= 1;
        serial[deviceCount] |= 0x8000000000000000LL;
        writeBit(pin, 1);
        bitcount++;
        oneWireScan(pin, serial);
    };

    if (b1 == 1 && b2 == 1)
    {
        bitcount = 0;
        return deviceCount;
    };
    if (b1 == 0 && b2 == 0)
    {
        serial[deviceCount] >>= 1;
        writeBit(pin, 0);
        int bitposition = bitcount;
        bitcount++;
        oneWireScan(pin, serial);

        bitcount = bitposition;
        if (presence(pin) == 1)
        {
            bitposition = 0;
            return 0;
        }

        writeByte(pin, 0xF0);
        uint64_t temp = serial[deviceCount - 1] | (0x1LL << (bitcount));
        int i;
        uint64_t bit;
        for (i = 0; i < bitcount + 1; i++)
        {
            bit = temp & 0x01LL;
            temp >>= 1;
            b1 = readBit(pin);
            b2 = readBit(pin);
            writeBit(pin, bit);
            serial[deviceCount] >>= 1;
            serial[deviceCount] |= (bit << 63);
        }
        bitcount++;
        oneWireScan(pin, serial);
    };

    return deviceCount;
}

Chapter 16

Page 268

On a Pi 5 serial0 opens the debug port. If you want to use GPIO14 and 15 use /dev/ttyAMA0 or any UART you have enabled.

#include <unistd.h>

#include <fcntl.h>

#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

int main(int argc, char **argv)
{
    int sfd = open("/dev/serial0", O_RDWR | O_NOCTTY);
    if (sfd == -1)
    {
        printf("Error no is : %d\n", errno);
        printf("Error description is : %s\n", strerror(errno));
        return (-1);
    };
    return 0;
}
 

Page 268

On a Pi 5 serial0 opens the debug port. If you want to use GPIO14 and 15 use /dev/ttyAMA0 or any UART you have enabled.

This loopback most likely wont work unless the serial port is already configured - see next program.

 

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

int main(int argc, char **argv)
{
    int sfd = open("/dev/serial0", O_RDWR | O_NOCTTY);
    if (sfd == -1)
    {
        printf("Error no is : %d\n", errno);
        printf("Error description is : %s\n", strerror(errno));
        return (-1);
    };
    char buf[] = "hello world";
    char buf2[11];
    int count = write(sfd, buf, 11);
    count = read(sfd, buf2, 11);
    buf2[11] = 0;
    printf("%s", buf2);
    close(sfd);
    return 0;
}

Page 278

On a Pi 5 serial0 opens the debug port. If you want to use GPIO14 and 15 use /dev/ttyAMA0 or any UART you have enabled.

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

int main(int argc, char **argv)
{
    int sfd = open("/dev/serial0", O_RDWR | O_NOCTTY);
    if (sfd == -1)
    {
        printf("Error no is : %d\n", errno);
        printf("Error description is : %s\n", strerror(errno));
        return (-1);
    };
    struct termios options;
    tcgetattr(sfd, &options);
    cfsetspeed(&options, B9600);
    cfmakeraw(&options);
    options.c_cflag &= ~CSTOPB;
    options.c_cflag |= CLOCAL;
    options.c_cflag |= CREAD;
    options.c_cc[VTIME] = 0;
    options.c_cc[VMIN] = 1;
    tcsetattr(sfd, TCSANOW, &options);
    char buf[] = "hello world";
    char buf2[11];
    int count = write(sfd, buf, 11);
    count = read(sfd, buf2, 11);
    buf2[11] = 0;
    printf("%s", buf2);
    close(sfd);
    return 0;
}
 

Page 279

On a Pi 5 serial0 opens the debug port. If you want to use GPIO14 and 15 use /dev/ttyAMA0 or any UART you have enabled.

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

int main(int argc, char **argv)
{
    system("sudo systemctl stop serial-getty@serial0 .service");
    int sfd = open("/dev/serial0", O_RDWR | O_NOCTTY);
    if (sfd == -1)
    {
        printf("Error no is : %d\n", errno);
        printf("Error description is : %s\n", strerror(errno));
        return (-1);
    };
    struct termios options;
    tcgetattr(sfd, &options);
    cfsetspeed(&options, B9600);
    cfmakeraw(&options);
    options.c_cflag &= ~CSTOPB;
    options.c_cflag |= CLOCAL;
    options.c_cflag |= CREAD;
    options.c_cc[VTIME] = 1;
    options.c_cc[VMIN] = 100;
    tcsetattr(sfd, TCSANOW, &options);
    char buf[] = "hello world";
    char buf2[100];
    int count = write(sfd, buf, strlen(buf));
    usleep(100000);
    int bytes;
    ioctl(sfd, FIONREAD, &bytes);
    if (bytes != 0)
    {
        count = read(sfd, buf2, 100);
    }
    printf("%s\n\r", buf2);
    close(sfd);
    return (EXIT_SUCCESS);
}
 

Page 281

On a Pi 5 serial0 opens the debug port. If you want to use GPIO14 and 15 use /dev/ttyAMA0 or any UART you have enabled.

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

int main(int argc, char **argv)
{
    system("sudo systemctl stop serial-getty@serial0 .service");
    int sfd = open("/dev/serial0", O_RDWR | O_NOCTTY);
    if (sfd == -1)
    {
        printf("Error no is : %d\n", errno);
        printf("Error description is : %s\n", strerror(errno));
        return (-1);
    };

    struct termios options;
    tcgetattr(sfd, &options);
    cfsetspeed(&options, B9600);
    cfmakeraw(&options);
    options.c_cflag &= ~CSTOPB;
    options.c_cflag |= CLOCAL;
    options.c_cflag |= CREAD;
    options.c_cc[VTIME] = 0;
    options.c_cc[VMIN] = 0;
    tcsetattr(sfd, TCSANOW, &options);

    char buf[] = "hello world";
    char buf2[100];
    char c;
    int count = write(sfd, buf, strlen(buf) + 1);

    int i = 0;
    while (1)
    {
        count = read(sfd, &c, 1);
        if (count != 0)
        {
            buf2[i] = c;
            i++;
            if (c == 0)
                break;
        };
    };
    printf("%s\n\r", buf2);
    close(sfd);
    return (EXIT_SUCCESS);
}
 

Page 287

 

On a Pi 5 serial0 opens the debug port. If you want to use GPIO14 and 15 use /dev/ttyAMA0 or any UART you have enabled.

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

int openPort(char port[]);
int presence(int sfd);
void writeBit(int sfd, int b);
uint8_t readBit(int sfd);
void writeByte(int sfd, int byte);
int readByte(int sfd);
int readByte(int sfd);
float getTemperature(int sfd);
int convert(int sfd);

uint8_t crc8(uint8_t *data, uint8_t len);

int main(int argc, char **argv)
{
    int sfd = openPort("/dev/ttyAMA1");
    if (presence(sfd) == 0)
    {
        printf("Device Present\n\r");
    }
    else
    {
        printf("No Device\n\r");
    }
    for (;;)
    {
        float temp = getTemperature(sfd);
        printf("%f \n\r", temp);

        fflush(stdout);
    }
    close(sfd);
    return 0;
}

int openPort(char port[])
{
    int sfd = open(port, O_RDWR | O_NOCTTY);
    if (sfd == -1)
    {
        printf("Error no is : %d\n", errno);
        printf("Error description is : %s\n", strerror(errno));
        return (-1);
    };
    struct termios options;
    tcgetattr(sfd, &options);
    cfsetspeed(&options, B115200);
    cfmakeraw(&options);
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;
    options.c_cflag |= PARENB;
    options.c_cflag &= ~PARENB;
    options.c_cflag &= ~CSTOPB;
    options.c_cflag |= CLOCAL;
    options.c_cflag |= CREAD;
    options.c_cc[VTIME] = 0;
    options.c_cc[VMIN] = 1;
    tcsetattr(sfd, TCSADRAIN, &options);
    return sfd;
}

int presence(int sfd)
{
    struct termios options;
    tcgetattr(sfd, &options);
    cfsetspeed(&options, B9600);
    tcsetattr(sfd, TCSADRAIN, &options);

    char buf = 0xF0;
    int count = write(sfd, &buf, 1);
    count = read(sfd, &buf, 1);

    tcgetattr(sfd, &options);
    cfsetspeed(&options, B115200);
    tcsetattr(sfd, TCSADRAIN, &options);
    if (buf == 0xF0)
        return -1;
    return 0;
}

void writeBit(int sfd, int b)
{
    char buf;
    if (b == 0)
    {
        buf = 0x00;
    }
    else
    {
        buf = 0xFF;
    }
    int count = write(sfd, &buf, 1);
    count = read(sfd, &buf, 1);
}

uint8_t readBit(int sfd)
{
    char buf;
    buf = 0xFF;
    int count = write(sfd, &buf, 1);
    count = read(sfd, &buf, 1);
    if (buf == 0xFF)
        return 1;
    return 0;
}

void writeByte(int sfd, int byte)
{
    for (int i = 0; i < 8; i++)
    {
        if (byte & 1)
        {
            writeBit(sfd, 1);
        }
        else
        {
            writeBit(sfd, 0);
        }
        byte = byte >> 1;
    }
}

int readByte(int sfd)
{
    int byte = 0;
    for (int i = 0; i < 8; i++)
    {
        byte = byte | readBit(sfd) << i;
    };
    return byte;
}

int convert(int sfd)
{
    int i;
    writeByte(sfd, 0x44);
    for (i = 0; i < 5000; i++)
    {
        usleep(100000);
        if (readBit(sfd) != 0)
            break;
    }
    return i;
}

uint8_t crc8(uint8_t *data, uint8_t len)
{
    uint8_t i;
    uint8_t j;
    uint8_t temp;
    uint8_t databyte;
    uint8_t crc = 0;
    for (i = 0; i < len; i++)
    {
        databyte = data[i];
        for (j = 0; j < 8; j++)
        {
            temp = (crc ^ databyte) & 0x01;
            crc >>= 1;
            if (temp)
                crc ^= 0x8C;
            databyte >>= 1;
        }
    }
    return crc;
}

float getTemperature(int sfd)
{
    if (presence(sfd) == -1)
        return -1000;
    writeByte(sfd, 0xCC);
    if (convert(sfd) == 5000)
        return -3000;

    presence(sfd);
    writeByte(sfd, 0xCC);
    writeByte(sfd, 0xBE);

    uint8_t data[9];
    for (int i = 0; i < 9; i++)
    {
        data[i] = readByte(sfd);
    }

    uint8_t crc = crc8(data, 9);
    if (crc != 0)
        return -2000;
    int t1 = data[0];
    int t2 = data[1];
    int16_t temp1 = (t2 << 8 | t1);
    float temp = (float)temp1 / 16;
    return temp;
}

Chapter 17

Page 303 

#include <bcm2835.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
    {
        return 1;
    }
    if (!bcm2835_spi_begin())
    {
        return 1;
    }

    bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);
    bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);
    bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_65536);
    bcm2835_spi_chipSelect(BCM2835_SPI_CS0);
    bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW);
    uint8_t read_data = bcm2835_spi_transfer(0xAA);
    if (read_data == 0xAA)
    {
        printf("data received correctly");
    }
    else
    {
        printf("data error");
    };
    bcm2835_spi_end();
    bcm2835_close();
    return (EXIT_SUCCESS);
}

Chapter 18

 Page 312

 
#include <bcm2835.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    if (!bcm2835_init())
    {
        return 1;
    }
    if (!bcm2835_spi_begin())
    {
        return 1;
    }
    bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);
    bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_8192);
    bcm2835_spi_chipSelect(BCM2835_SPI_CS0);
    bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW);
    bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);

    char buf[] = {0x01, 0x80, 0x00};
    char readBuf[3];
    bcm2835_spi_transfernb(buf, readBuf, 3);
    int data = ((int)readBuf[1] & 0x03) << 8 | (int)readBuf[2];
    float volts = (float)data * 3.3f / 1023.0f;

    printf("%f", volts);
    bcm2835_spi_end();
    bcm2835_close();
    return (EXIT_SUCCESS);
}

 

Chapter 19

Page 324

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

#include <sys/socket.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(80);
    addr.sin_addr.s_addr = 0x22d8b85d;
    if (connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
        return -1;
    char header[] = "GET /index.html HTTP/1.1\r\nHost:example.org\r\n\r\n";
    int n = write(sockfd, header, strlen(header));
    char buffer[2048];
    n = read(sockfd, buffer, 2048);
    printf("%s", buffer);
    return (EXIT_SUCCESS);
}
 

Page 326

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <unistd.h>
#include <netdb.h>

int main(int argc, char **argv)
{
    struct addrinfo hints;
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    struct addrinfo *servinfo;
    int status = getaddrinfo("www.example.com", "80", &hints, &servinfo);
    int sockfd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol);
    connect(sockfd, servinfo->ai_addr, servinfo->ai_addrlen);
    char header[] = "GET /index.html HTTP/1.1\r\nHost:example.org\r\n\r\n";
    int n = write(sockfd, header, strlen(header));
    char buffer[2048];
    n = read(sockfd, buffer, 2048);
    printf("%s", buffer);
    return (EXIT_SUCCESS);
}
 

Page 331

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netdb.h>
#include <time.h>

int main(int argc, char **argv)
{
    struct addrinfo hints, *server;
    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;
    getaddrinfo(NULL, "80", &hints, &server);
    int sockfd = socket(server->ai_family, server->ai_socktype | SOCK_NONBLOCK, server->ai_protocol);
    bind(sockfd, server->ai_addr, server->ai_addrlen);
    listen(sockfd, 10);

    char buffer[2048];
    char html[] = "<html><head><title>Temperature</title></head><body><p>{\"humidity\":81%, \"airtemperature\":23.5C}</p></body></html>\r\n";

    char headers[1024] = {0};

    char Status[] = "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\nServer:CPi\r\n";

    char Date[100];
    time_t now = time(NULL);
    struct tm *t = gmtime(&now);
    strftime(Date, sizeof(Date), "Date: %a, %d %b %Y %k:%M:%S %Z\r\n", t);

    char ContLen[100] = {0};
    snprintf(ContLen, sizeof ContLen, "Content-Length:%d \r\n", strlen(html));

    snprintf(headers, sizeof headers, "%s%s%s\r\n", Status, Date, ContLen);

    char data[2048] = {0};
    snprintf(data, sizeof data, "%s%s", headers, html);

    for (;;)
    {
        struct sockaddr_storage client_addr;
        socklen_t addr_size = sizeof client_addr;

        int client_fd = accept(sockfd, (struct sockaddr *)&client_addr, &addr_size);
        if (client_fd > 0)
        {
            int n = read(client_fd, buffer, 2048);
            printf("%s", buffer);
            fflush(stdout);
            n = write(client_fd, data, strlen(data));
            close(client_fd);
        }
    }
    return (EXIT_SUCCESS);
}

Chapter 20

Page 350

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    int memfd = open("/dev/mem", O_RDWR | O_SYNC);
    uint32_t *map = (uint32_t *)mmap(
        NULL,
        4 * 1024,
        (PROT_READ | PROT_WRITE),
        MAP_SHARED,
        memfd,
        (off_t)bcm2835_peripherals_base + BCM2835_GPIO_BASE);
    if (map == MAP_FAILED)
        printf("mmap failed: %s\n", strerror(errno));
    close(memfd);
    volatile uint32_t *paddr = map;
    *paddr = 0x1000;
    volatile uint32_t *paddr1 = map + 0x1C / 4;
    volatile uint32_t *paddr2 = map + 0x28 / 4;
    for (;;)
    {
        *paddr1 = 0x10;
        *paddr2 = 0x10;
    };
    return (EXIT_SUCCESS);
}
 

Page 355

#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>
int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    uint32_t *gpioBASE = bcm2835_regbase(BCM2835_REGBASE_GPIO);
    bcm2835_peri_write(gpioBASE, 0x1000);
    for (;;)
    {
        bcm2835_peri_write(gpioBASE + BCM2835_GPSET0 / 4, 0x10);
        bcm2835_peri_write(gpioBASE + BCM2835_GPCLR0 / 4, 0x10);
    }
    return 0;
}
 

Page 360

 
#include <stdio.h>
#include <stdlib.h>
#include <bcm2835.h>

#define CLK_GP0_CTL 28
#define CLK_GP0_DIV 29
void bcm2835_GPIO4_set_clock_source(uint32_t, uint32_t, uint32_t);

int main(int argc, char **argv)
{
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(4, BCM2835_GPIO_FSEL_ALT0);
    bcm2835_GPIO4_set_clock_source(6, 50, 0);
}

void bcm2835_GPIO4_set_clock_source(
    uint32_t source,
    uint32_t divisorI,
    uint32_t divisorF)
{
    divisorI &= 0xfff;
    divisorF &= 0xfff;
    source &= 0xf;

    uint8_t mask = bcm2835_peri_read(bcm2835_clk + CLK_GP0_CTL) & 0xffffffef;

    bcm2835_peri_write(bcm2835_clk + CLK_GP0_CTL, BCM2835_PWM_PASSWRD | mask);

    while ((bcm2835_peri_read(bcm2835_clk + CLK_GP0_CTL) & 0x80) != 0)
    {
    };

    bcm2835_peri_write(bcm2835_clk + CLK_GP0_DIV, BCM2835_PWM_PASSWRD | (divisorI << 12) | divisorF);
    bcm2835_peri_write(bcm2835_clk + CLK_GP0_CTL, BCM2835_PWM_PASSWRD | source | 0x200);
    bcm2835_peri_write(bcm2835_clk + CLK_GP0_CTL, BCM2835_PWM_PASSWRD | 0x0210 | source);
}
 

Page 362 

#include <bcm2835.h>
#include <stdio.h>
#include <stdlib.h>

#define BCM2835_SPI6_BASE 0x204C00
volatile uint32_t *bcm2835_spiOLD;

int bcm2835_spi6_begin(void)
{
    volatile uint32_t *paddr;
    bcm2835_spiOLD = bcm2835_spi0;
    bcm2835_spi0 = bcm2835_peripherals + BCM2835_SPI6_BASE / 4;

    bcm2835_gpio_fsel(27, BCM2835_GPIO_FSEL_ALT3); /* CE1 */
    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_ALT3); /* CE0 */
    bcm2835_gpio_fsel(19, BCM2835_GPIO_FSEL_ALT3); /* MISO */
    bcm2835_gpio_fsel(20, BCM2835_GPIO_FSEL_ALT3); /* MOSI */
    bcm2835_gpio_fsel(21, BCM2835_GPIO_FSEL_ALT3); /* CLK */

    paddr = bcm2835_spi0 + BCM2835_SPI0_CS / 4;
    bcm2835_peri_write(paddr, 0); /* All 0s */

    bcm2835_peri_write_nb(paddr, BCM2835_SPI0_CS_CLEAR);
    return 1;
}

void bcm2835_spi6_end(void)
{
    bcm2835_spi0 = bcm2835_spiOLD;
    /* Set all the SPI0 pins back to input */
    bcm2835_gpio_fsel(27, BCM2835_GPIO_FSEL_INPT); /* CE1 */
    bcm2835_gpio_fsel(18, BCM2835_GPIO_FSEL_INPT); /* CE0 */
    bcm2835_gpio_fsel(19, BCM2835_GPIO_FSEL_INPT); /* MISO */
    bcm2835_gpio_fsel(20, BCM2835_GPIO_FSEL_INPT); /* MOSI */
    bcm2835_gpio_fsel(21, BCM2835_GPIO_FSEL_INPT); /* CLK */
}

int main(int argc, char **argv)
{
    if (!bcm2835_init())
    {
        return 1;
    }

    if (!bcm2835_spi6_begin())
    {
        return 1;
    }

    bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);
    bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_8192);
    bcm2835_spi_chipSelect(BCM2835_SPI_CS0);
    bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW);
    bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);

    char buf[] = {0x01, 0x80, 0x00};
    char readBuf[3];
    bcm2835_spi_transfernb(buf, readBuf, 3);
    int data = ((int)readBuf[1] & 0x03) << 8 | (int)readBuf[2];
    float volts = (float)data * 3.3f / 1023.0f;

    printf("%f \n \r", volts);
    bcm2835_spi6_end();
    bcm2835_close();
    return (EXIT_SUCCESS);
}
 

Page 370

 
#include <bcm2835.h>
#include <stdio.h>
#include <sched.h>
int main(int argc, char **argv)
{
    const struct sched_param priority = {1};
    sched_setscheduler(0, SCHED_FIFO, &priority);
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_OUTP);
    while (1)
    {
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, HIGH);
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, LOW);
    }
    bcm2835_close();
    return 0;
}

Chapter 21

Page  372

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>

typedef struct{
    uint32_t status;
    uint32_t ctrl;
}GPIOregs;

#define GPIO ((GPIOregs*)GPIOBase)

typedef struct
{
    uint32_t Out;
    uint32_t OE;
    uint32_t In;
    uint32_t InSync;
} rioregs;

#define rio ((rioregs *)RIOBase)
#define rioXOR ((rioregs *)(RIOBase + 0x1000 / 4))
#define rioSET ((rioregs *)(RIOBase + 0x2000 / 4))
#define rioCLR ((rioregs *)(RIOBase + 0x3000 / 4))


int main(int argc, char **argv)
{
    int memfd = open("/dev/mem", O_RDWR | O_SYNC);
    uint32_t *map = (uint32_t *)mmap(
        NULL,
        64 * 1024 * 1024,
        (PROT_READ | PROT_WRITE),
        MAP_SHARED,
        memfd,
        0x1f00000000
    );
    if (map == MAP_FAILED)
    {
        printf("mmap failed: %s\n", strerror(errno));
        return (-1);
    };
    close(memfd);

    uint32_t *PERIBase = map;
    uint32_t *GPIOBase = PERIBase + 0xD0000 / 4;
    uint32_t *RIOBase = PERIBase + 0xe0000 / 4;
    uint32_t *PADBase = PERIBase + 0xf0000 / 4;
    uint32_t *pad = PADBase + 1;  
   
    uint32_t pin = 2;
    uint32_t fn = 5;

    GPIO[pin].ctrl=fn;
    pad[pin] = 0x10;
    rioSET->OE = 0x01<<pin;
    rioSET->Out = 0x01<<pin;
   
    for (;;)
    {
        rioXOR->Out = 0x04;
    }
    return (EXIT_SUCCESS);
}
 

Page  378

#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>

typedef struct
{
    uint32_t status;
    uint32_t ctrl;
} GPIOregs;

#define GPIO ((GPIOregs *)GPIOBase)

typedef struct{
    uint32_t Ctrl;
    uint32_t Range;
    uint32_t Phase;
    uint32_t Duty;
} PWMregs;

#define PWM ((PWMregs *) (PWMBase+0x14/4))

typedef struct
{
    uint32_t Out;
    uint32_t OE;
    uint32_t In;
    uint32_t InSync;
} rioregs;

#define rio ((rioregs *)RIOBase)
#define rioXOR ((rioregs *)(RIOBase + 0x1000 / 4))
#define rioSET ((rioregs *)(RIOBase + 0x2000 / 4))
#define rioCLR ((rioregs *)(RIOBase + 0x3000 / 4))

uint32_t *PERIBase;
uint32_t *GPIOBase;
uint32_t *RIOBase;
uint32_t *PADBase;
uint32_t *pad;
uint32_t *PWMBase;


int rp1_Init()
{
    int memfd = open("/dev/mem", O_RDWR | O_SYNC);
    uint32_t *map = (uint32_t *)mmap(
        NULL,
        64 * 1024 * 1024,
        (PROT_READ | PROT_WRITE),
        MAP_SHARED,
        memfd,
        0x1f00000000);
    if (map == MAP_FAILED)
    {

        return (-1);
    };
    close(memfd);
    PERIBase = map;
    GPIOBase = PERIBase + 0xD0000 / 4;
    RIOBase = PERIBase + 0xe0000 / 4;
    PADBase = PERIBase + 0xf0000 / 4;
    PWMBase = PERIBase + 0x98000 / 4;
    pad = PADBase + 1;
    return 0;
};


int main(int argc, char **argv)
{
    if (rp1_Init())
        return (1);
    GPIO[12].ctrl = 0x0;
    pad[12] = 0x10;
    PWM[0].Ctrl=0x1;
    PWM[0].Range=0xFFFFF;
    PWM[0].Duty=0x8FFFF;
    PWM[0].Phase=0x0;
    *PWMBase=0x80000001;
    return (EXIT_SUCCESS);
}

Chapter 22

Page  395

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <linux/sched.h>
#include <pthread.h>
#include <stdint.h>

struct sched_attr
{
    uint32_t size;
    uint32_t sched_policy;
    uint64_t sched_flags;
    int32_t sched_nice;
    uint32_t sched_priority;
    uint64_t sched_runtime;
    uint64_t sched_deadline;
    uint64_t sched_period;
};

int sched_setattr(pid_t pid, const struct sched_attr *attr,
                  unsigned int flags)
{
    return syscall(__NR_sched_setattr, pid, attr, flags);
}

void *threadA(void *p)
{
    struct sched_attr attr = {
        .size = sizeof(attr),
        .sched_policy = SCHED_DEADLINE,
        .sched_runtime = 10 * 1000 * 1000,
        .sched_period = 2 * 1000 * 1000 * 1000,
        .sched_deadline = 11 * 1000 * 1000};
    sched_setattr(0, &attr, 0);
    for (;;)
    {
        printf("sensor\n");
        fflush(0);
        sched_yield();
    };
}

int main(int argc, char **argv)
{
    pthread_t pthreadA;
    pthread_create(&pthreadA, NULL, threadA, NULL);
    pthread_exit(0);
    return (EXIT_SUCCESS);
}
 

Page 399

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

#include <pthread.h>
#include <sched.h>
#include <unistd.h>

volatile int j;
volatile int i;

void *threadA(void *p)
{
    for (i = 0;; i++)
    {
    };
}

void *threadB(void *p)
{
    for (j = 0;; j++)
    {
    };
}

int main(int argc, char **argv)
{
    cpu_set_t cpuset;
    CPU_ZERO(&cpuset);
    CPU_SET(1, &cpuset);

    pthread_t pthreadA;
    pthread_create(&pthreadA, NULL, threadA, NULL);
    pthread_setaffinity_np(pthreadA, sizeof(cpu_set_t), &cpuset);

    CPU_ZERO(&cpuset);
    CPU_SET(2, &cpuset);
    pthread_t pthreadB;
    pthread_create(&pthreadB, NULL, threadB, NULL);
    pthread_setaffinity_np(pthreadB, sizeof(cpu_set_t), &cpuset);

    sleep(5);

    printf("%d %d", i, j);
    return (EXIT_SUCCESS);
}
 

 Page 402

 
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sched.h>
#include <unistd.h>
#include <bcm2835.h>
#include <stdio.h>

int main(int argc, char **argv)
{
    cpu_set_t cpuset;
    CPU_ZERO(&cpuset);
    CPU_SET(3, &cpuset);
    int res = sched_setaffinity(getpid(), sizeof(cpu_set_t), &cpuset);

    const struct sched_param priority = {1};
    sched_setscheduler(0, SCHED_FIFO, &priority);
    if (!bcm2835_init())
        return 1;
    bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_OUTP);
    while (1)
    {
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, HIGH);
        bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, LOW);
    }
    bcm2835_close();
    return 0;
}

Appendix I

 

Page 406

#include <stdio.h>
#include <string.h>
 int main(int argc, char** argv) {
    int gpio = 4;
    FILE* fd = fopen("/sys/class/gpio/export", "w");
    fprintf(fd, "%d", gpio);
    fclose(fd);
    return 0;
}
 

Page 407


#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
    int gpio = 4;
    char buf[100];

    FILE *fd = fopen("/sys/class/gpio/export", "w");
    fprintf(fd, "%d", gpio);
    fclose(fd);

    sprintf(buf, "/sys/class/gpio/gpio%d/direction", gpio);
    fd = fopen(buf, "w");
    fprintf(fd, "out");
    fclose(fd);

    sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio);
    fd = fopen(buf, "w");

    for (;;)
    {
        fd = fopen(buf, "w");
        fprintf(fd, "1");
        fclose(fd);
        fd = fopen(buf, "w");
        fprintf(fd, "0");
        fclose(fd);
    }
    return 0;
}

Appendix II

All files have to be stored in the .vscode folder

settings,json (typical) 

{
    "sshUser": "root",
    "sshEndpoint": "192.168.11.151",
    "remoteDirectory": "/home/pi/Documents/${workspaceFolderBasename}",
    "std": "c99",
    "libs":"-lbcm2835",
    "header":"/usr/local/include/bcm2835.h"
}
 

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",
        }
    ]
}
 

c_cpp_properties.json for Mingw

 
{
    "configurations": [
        {
            "name": "Win32",
            "includePath": [
                "${workspaceFolder}/**",
                "C:/MinGW/include"
            ],
            "defines": [
                "_DEBUG",
                "UNICODE",
                "_UNICODE"
            ],
            "cStandard":"c99",
            "intelliSenseMode":"gcc-arm" 
                }
    ],
    "version": 4
}
 
 

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}.exe'",
            "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
            }
        },
    ],
}
"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
}
},
],
}
 
 
 
 

Raspberry Pi IoT In Python Using Linux Drivers 
Second Edition

Programs

DriverPython2e360

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 41

import io
from time import sleep

fd = io.open("/sys/class/leds/ACT/trigger","w")
fd.write("none")
fd.close()

fd = io.open("/sys/class/leds/ACT/brightness", "w")
while(True):
    fd.write("0")
    fd.flush()
    sleep(1)
    fd.write("1")
    fd.flush()
    sleep(1)

 

Page 43

import io
from time import sleep

fd = io.open("/sys/class/leds/ACT/trigger","w")
fd.write("timer")
fd.close()
fd = io.open("/sys/class/leds/ACT/delay_on", "w")
fd.write("2000")
fd.close()
fd = io.open("/sys/class/leds/ACT/delay_off", "w")
fd.write("3000")
fd.close()
 

 

Page 53

import gpiod
chip = gpiod.Chip("0")
print(chip.label())
print(chip.name())
print(chip.num_lines())
chip.close()
 
change 0 to 4 for a Pi 5

Page 57

import gpiod

chip = gpiod.Chip("0")
line = chip.get_line(4)

line.request(consumer="myprog.py", type=gpiod.LINE_REQ_DIR_OUT, default_vals=[0])
while(True):
    line.set_value(1)
    line.set_value(0)
 
change 0 to 4 for a Pi 5
 

Page 57

import gpiod

chip = gpiod.Chip("0")
lines = chip.get_lines([4, 17])

lines.request(consumer="myprog.py", type=gpiod.LINE_REQ_DIR_OUT, default_vals=[0, 1])
while(True):
    lines.set_values([1, 0])
    lines.set_values([0, 1])
 

Remember the need to change the chip number to "4" for a Pi 5.

Page 59

import gpiod
from time import sleep, time_ns

chip = gpiod.Chip("0")
line = chip.get_line(4)

line.request(consumer="resistor.py", type=gpiod.LINE_REQ_DIR_IN)
sleep(0.010)
line.release()

line.request(consumer="resistor.py", type=gpiod.LINE_REQ_DIR_OUT, default_vals=[0])
sleep(0.010)
line.release()

line.request(consumer="resistor.py", type=gpiod.LINE_REQ_DIR_IN)
t = time_ns()
while(line.get_value() == 0):
    pass
print((time_ns()-t)/1000)

 

Remember the need to change the chip number to "4" for a Pi 5. 

 


Page 67

import fcntl
import struct
import io
GPIO_GET_CHIPINFO_IOCTL = 0x8044B401

f = io.open("/dev/gpiochip0", "rb", buffering=0)

gpiochip_info = struct.Struct("32s 32s L")
buffer = gpiochip_info.pack(b' ', b' ', 0)

result = fcntl.ioctl(f, GPIO_GET_CHIPINFO_IOCTL, buffer)

name, label, lines = gpiochip_info.unpack(result)

print(name.rstrip(b'\0').decode("utf-8"))
print(label.rstrip(b'\0').decode("utf-8"))
print(lines)
 
To run it on a Pi 5 change gpiochip0 to gpiochip4

Page 70

import fcntl
import struct
import io

GPIO_GET_CHIPINFO_IOCTL = 0x8044B401
GPIO_GET_LINEHANDLE_IOCTL = 0xC16CB403
GPIOHANDLE_SET_LINE_VALUES_IOCTL = 0xC040B409
GPIOHANDLE_GET_LINE_VALUES_IOCTL = 0xC040B408

GPIOHANDLE_REQUEST_OUTPUT = 0x02
GPIOHANDLE_REQUEST_INPUT = 0x01
GPIOHANDLE_REQUEST_ACTIVE_LOW = 0x04
GPIOHANDLE_REQUEST_OPEN_DRAIN = 0x08
GPIOHANDLE_REQUEST_OPEN_SOURCE = 0x10

gpiochip_info = struct.Struct("32s 32s L")
gpiohandle_request = struct.Struct("64L L 64B 32s L L")
gpiohandle_data = struct.Struct("64B")

lines = [0]*64
lines[0] = 4
lines[1] = 17
values = [0]*64
buffer = gpiohandle_request.pack(*lines, GPIOHANDLE_REQUEST_OUTPUT, *values, b"Output test", 2, 0)

f = io.open("/dev/gpiochip0", "rb", buffering=0)
result = fcntl.ioctl(f, GPIO_GET_LINEHANDLE_IOCTL, buffer)
f.close()
fL = struct.unpack_from("L", buffer, 360)[0]

values[0] = 1
values[1] = 0
state1 = gpiohandle_data.pack(*values)

values[0] = 0
values[1] = 1
state2 = gpiohandle_data.pack(*values)

while(True):
    result = fcntl.ioctl(fL, GPIOHANDLE_SET_LINE_VALUES_IOCTL, state1)
    result = fcntl.ioctl(fL, GPIOHANDLE_SET_LINE_VALUES_IOCTL, state2)
 

Remember to change gpiochip0 to gpiochip4 if you are running on a Pi 5.

Page 72

import fcntl
import struct
import io
import os

GPIO_GET_CHIPINFO_IOCTL = 0x8044B401
GPIO_GET_LINEHANDLE_IOCTL = 0xC16CB403
GPIOHANDLE_SET_LINE_VALUES_IOCTL = 0xC040B409
GPIOHANDLE_GET_LINE_VALUES_IOCTL = 0xC040B408

GPIOHANDLE_REQUEST_OUTPUT = 0x02
GPIOHANDLE_REQUEST_INPUT = 0x01
GPIOHANDLE_REQUEST_ACTIVE_LOW = 0x04
GPIOHANDLE_REQUEST_OPEN_DRAIN = 0x08
GPIOHANDLE_REQUEST_OPEN_SOURCE = 0x10

gpiochip_info = struct.Struct("32s 32s L")
gpiohandle_request = struct.Struct("64L L 64B 32s L L")
gpiohandle_data = struct.Struct("64B")

lines = [0]*64
lines[0] = 4
lines[1] = 17
values = [0]*64
buffer = gpiohandle_request.pack(*lines, GPIOHANDLE_REQUEST_INPUT, *values, b"Input test", 2, 0)

f = io.open("/dev/gpiochip0", "rb", buffering=0)
result = fcntl.ioctl(f, GPIO_GET_LINEHANDLE_IOCTL, buffer)
f.close()
fL = struct.unpack_from("L", result, 360)[0]
inputBuffer = gpiohandle_data.pack(*values)
result = fcntl.ioctl(fL, GPIOHANDLE_GET_LINE_VALUES_IOCTL, inputBuffer)
os.close(fL)
print(result[0], result[1])
 

Remember to change gpiochip0 to gpiochip4 if you are running on a Pi 5.

Page 73

import fcntl
import struct
import io
import os
from time import sleep, time_ns
GPIO_GET_CHIPINFO_IOCTL = 0x8044B401
GPIO_GET_LINEHANDLE_IOCTL = 0xC16CB403
GPIOHANDLE_SET_LINE_VALUES_IOCTL = 0xC040B409
GPIOHANDLE_GET_LINE_VALUES_IOCTL = 0xC040B408

GPIOHANDLE_REQUEST_OUTPUT = 0x02
GPIOHANDLE_REQUEST_INPUT = 0x01
GPIOHANDLE_REQUEST_ACTIVE_LOW = 0x04
GPIOHANDLE_REQUEST_OPEN_DRAIN = 0x08
GPIOHANDLE_REQUEST_OPEN_SOURCE = 0x10

gpiochip_info = struct.Struct("32s 32s L")
gpiohandle_request = struct.Struct("64L L 64B 32s L L")
gpiohandle_data = struct.Struct("64B")

lines = [0]*64
lines[0] = 4
values = [0]*64

buffer = gpiohandle_request.pack(*lines, GPIOHANDLE_REQUEST_INPUT,*values, b"Resistance test", 1, 0)

f = io.open("/dev/gpiochip0", "rb", buffering=0)
result = fcntl.ioctl(f, GPIO_GET_LINEHANDLE_IOCTL, buffer)
fL = struct.unpack_from("L", result, 360)[0]
state = gpiohandle_data.pack(*values)
result = fcntl.ioctl(fL, GPIOHANDLE_GET_LINE_VALUES_IOCTL, state)
sleep(0.01)
os.close(fL)

buffer = gpiohandle_request.pack(*lines, GPIOHANDLE_REQUEST_OUTPUT, *values, b"Resistance test", 1, 0)
result = fcntl.ioctl(f, GPIO_GET_LINEHANDLE_IOCTL, buffer)
fL = struct.unpack_from("L", result, 360)[0]
fcntl.ioctl(fL, GPIOHANDLE_SET_LINE_VALUES_IOCTL, state)
sleep(0.01)
os.close(fL)

buffer = gpiohandle_request.pack(*lines, GPIOHANDLE_REQUEST_INPUT,*values, b"Resistance test", 1, 0)
result = fcntl.ioctl(f, GPIO_GET_LINEHANDLE_IOCTL, buffer)
fL = struct.unpack_from("L", result, 360)[0]
t = time_ns()
result = fcntl.ioctl(fL, GPIOHANDLE_GET_LINE_VALUES_IOCTL, state)
while(result[0] == 0):
    result = fcntl.ioctl(fL, GPIOHANDLE_GET_LINE_VALUES_IOCTL, state)
print((time_ns()-t)/1000)
os.close(fL)
f.close()
 

Remember to change gpiochip0 to gpiochip4 if you are running on a Pi 5.


 

Page 80

import gpiod

chip = gpiod.Chip("0")
line = chip.get_line(4)

line.request(consumer="myprog.py", type=gpiod.LINE_REQ_EV_BOTH_EDGES)

event = line.event_wait(sec=1)
if event:
    print("Event on line 4")
else:
    print("Time out")
 

Remember to change the chip number from 0” to “4” if running on a Pi 5.

Page 81

import gpiod
from time import sleep, time_ns

chip = gpiod.Chip("0")
line = chip.get_line(4)

line.request(consumer="resistor.py", type=gpiod.LINE_REQ_DIR_IN)
sleep(0.010)
line.release()

line.request(consumer="resistor.py", type=gpiod.LINE_REQ_DIR_OUT, default_vals=[0])
sleep(0.010)
line.release()

line.request(consumer="resistor.py", type=gpiod.LINE_REQ_EV_RISING_EDGE)
t = time_ns()
event = line.event_read()
print((event.sec*1000000000+event.nsec-t)/1000)
 

Remember to change the chip number from 0” to “4” if running on a Pi 5.

 

Page 82

import gpiod

chip = gpiod.Chip("0")
line = chip.get_line(4)

line.request(consumer="myprog.py", type=gpiod.LINE_REQ_EV_BOTH_EDGES)

while(True):
    while True:
        event1 = line.event_read()
        if event1.type == event1.RISING_EDGE:
            break
    while True:
        event2 = line.event_read()
        if event2.type == gpiod.LineEvent.FALLING_EDGE:
            break
    print((event2.sec-event2.sec)*1000000000 +
          (event2.nsec-event1.nsec))
 

Remember to change the chip number from 0” to “4” if running on a Pi 5.

 

Page 783a

import gpiod
from time import sleep

chip = gpiod.Chip("0")
line = chip.get_line(4)

line.request(consumer="myprog.py", type=gpiod.LINE_REQ_DIR_IN)
print("Press the button", flush=True)
sleep(20)
if line.get_value() == 1:
    print("button pressed")
else:
    print("button not pressed")
 

Don’t forget to change "0" to "4" if running on a Pi 5.

Page 83b

import gpiod
from time import sleep

chip = gpiod.Chip("0")
line = chip.get_line(4)

line.request(consumer="myprog.py", type=gpiod.LINE_REQ_EV_BOTH_EDGES)
print("Press the button", flush=True)
sleep(20)
event = line.event_wait(sec=0)
if event:
    print("button pressed")
else:
    print("button not pressed")
 

Don’t forget to change "0" to "4" if running on a Pi 5.

Page 84

import gpiod

def event_poll(line):
    event = line.event_wait(sec=0)
    if event:
        event = line.event_read()
    return event


chip = gpiod.Chip("0")
line = chip.get_line(4)
line.request(consumer="myprog.py", type=gpiod.LINE_REQ_EV_BOTH_EDGES)
while True:
    event = event_poll(line)
    if event:
        print(event.sec, flush=True)
 

Don’t forget to change "0" to "4" if running on a Pi 5.

Page 87

import fcntl
import struct
import io
import os
from time import sleep, time_ns
import select

GPIO_GET_CHIPINFO_IOCTL = 0x8044B401
GPIO_GET_LINEHANDLE_IOCTL = 0xC16CB403
GPIOHANDLE_SET_LINE_VALUES_IOCTL = 0xC040B409
GPIOHANDLE_GET_LINE_VALUES_IOCTL = 0xC040B408
GPIO_GET_LINEEVENT_IOCTL = 0xC030B404

GPIOHANDLE_REQUEST_OUTPUT = 0x02
GPIOHANDLE_REQUEST_INPUT = 0x01
GPIOHANDLE_REQUEST_ACTIVE_LOW = 0x04
GPIOHANDLE_REQUEST_OPEN_DRAIN = 0x08
GPIOHANDLE_REQUEST_OPEN_SOURCE = 0x10

GPIOEVENT_REQUEST_RISING_EDGE = 0x01
GPIOEVENT_REQUEST_FALLING_EDGE = 0x02
GPIOEVENT_REQUEST_BOTH_EDGES = 0x03

gpiochip_info = struct.Struct("32s 32s L")
gpiohandle_request = struct.Struct("64L L 64B 32s L L")
gpiohandle_data = struct.Struct("64B")
gpioevent_request = struct.Struct("L L L 32s L")
gpioevent_data = struct.Struct("Q L")

buffer = gpioevent_request.pack(4, GPIOHANDLE_REQUEST_INPUT, GPIOEVENT_REQUEST_BOTH_EDGES, b"Event test", 0)

f = io.open("/dev/gpiochip0", "rb", buffering=0)
result = fcntl.ioctl(f, GPIO_GET_LINEEVENT_IOCTL, buffer)
f.close()
fL = struct.unpack_from("L", result, 44)[0]

e = select.epoll()
e.register(fL)
while True:
    events = e.poll(1)
    if len(events) > 0:
        buffer = os.read(fL, 100)
        timestamp, id = gpioevent_data.unpack(buffer[0:12])
        print(timestamp, id, flush=True)
 

Don’t forget to change "0" to "4" if running on a Pi 5.

Page 88

import gpiod
import struct
import io
import os
import select

gpioevent_data = struct.Struct("Q L")

chip = gpiod.Chip("0")
line = chip.get_line(4)

line.request(consumer="myprog.py", type=gpiod.LINE_REQ_EV_BOTH_EDGES)

fL = line.event_get_fd()
e = select.epoll()
e.register(fL)
while True:
    events = e.poll(1)
    if len(events) > 0:
        buffer = os.read(fL, 100)
        timestamp, id = gpioevent_data.unpack(buffer[0:12])
        print(timestamp, id, flush=True)
 

Don’t forget to change "0" to "4" if running on a Pi 5.

Page 90

import gpiod
from time import sleep
import threading


def waitForInterrupt(line):
    while(True):
        event = line.event_read()
        print(event.sec*1000000000+event.nsec, flush=True)


chip = gpiod.Chip("0")
line = chip.get_line(4)

line.request(consumer="myprog.py", type=gpiod.LINE_REQ_EV_BOTH_EDGES)

IntThread = threading.Thread(target=waitForInterrupt, args=(line,))
IntThread.start()


while True:
    sleep(2)
    print("running", flush=True)
 
Don’t forget to change "0" to "4" if running on a Pi 5.

 

Page 100

import io

fdr = io.open("/sys/bus/iio/devices/iio:device0/name", "rb", buffering=0)
name = fdr.readline().decode("utf-8")
print("name=", name)
fdr.close()

fdr = io.open("/sys/bus/iio/devices/iio:device0/in_temp_input",  "rb", buffering=0)
temp = fdr.readline().decode("utf-8")
print("temp=", int(temp)/1000, "C")
fdr.close()

fdr = io.open("/ sys/bus/iio/devices/iio: device0 /in_humidityrelative_input", "rb", buffering=0)
hum = fdr.readline().decode("utf-8")
print("Humidity=", int(hum)/1000, "%")
fdr.close()

Page 102

import subprocess
import io
import fcntl


def checkDht11():
    indicator = "dht11  gpiopin=4"
    command = ["sudo", "dtoverlay", "dht11", "gpiopin=4"]
    temp = subprocess.Popen(["sudo", "dtparam", "-l"], stdout=subprocess.PIPE)
    output = str(temp.communicate())
    print(output)
    if output.find(indicator) == -1:
        temp = subprocess.Popen(command, stdout=subprocess.PIPE)
        output = str(temp.communicate())
        print(output)
    return


checkDht11()

fdr = io.open("/sys/bus/iio/devices/iio:device0/name", "rb", buffering=0)
name = fdr.readline().decode("utf-8")
print("name=", name)
fdr.close()

fdr = io.open("/sys/bus/iio/devices/iio:device0/in_temp_input",  "rb", buffering=0)
temp = fdr.readline().decode("utf-8")
print("temp=", int(temp)/1000, "C")
fdr.close()

fdr = io.open( "/sys/bus/iio/devices/iio:device0/in_humidityrelative_input", "rb", buffering=0)
hum = fdr.readline().decode("utf-8")
print("Humidity=", int(hum)/1000, "%")
fdr.close()
 

 

Page 123a

import gpiod
from time import sleep

chip = gpiod.Chip("0")
line = chip.get_line(4)

line.request(consumer="myprog.py", type=gpiod.LINE_REQ_DIR_OUT, default_vals=[0])

period = 20
duty = 25

ontime = period/1000 * duty / 100
offtime = period/1000 - ontime

while(True):
    line.set_value(1)
    sleep(ontime)
    line.set_value(0)
    sleep(offtime)
 

Remember to change "0" to "4" if you are running on a Pi 5.

Page 123b

import gpiod
from time import sleep
import threading


def softPWM(line, period, duty):
    ontime = period/1000 * duty / 100
    offtime = period/1000 - ontime
    while(True):
        line.set_value(1)
        sleep(ontime)
        line.set_value(0)
        sleep(offtime)


chip = gpiod.Chip("0")
line = chip.get_line(4)

line.request(consumer="myprog.py", type=gpiod.LINE_REQ_DIR_OUT, default_vals=[0])

period = 20
duty = 75

IntThread = threading.Thread(target=softPWM, args=(line, period, duty))
IntThread.start()

while(True):
    print("working", flush=True)
    sleep(2)
 

Remember to change "0" to "4" if you are running on a Pi 5.

 

Page 127

import subprocess
import io

def checkPWM():
    indicator = "pwm-2chan"
    command = ["sudo", "dtoverlay", "pwm-2chan"]
    temp = subprocess.Popen(["sudo", "dtparam", "-l"], stdout=subprocess.PIPE)
    output = str(temp.communicate())
    print(output)
    if output.find(indicator) == -1:
        temp = subprocess.Popen(command, stdout=subprocess.PIPE)
        output = str(temp.communicate())
        print(output)
    return


checkPWM()

fdw = io.open("/sys/class/pwm/pwmchip0/export", "wb", buffering=0)
fdw.write(b"0")
fdw.close()

fdw = io.open("/sys/class/pwm/pwmchip0/pwm0/period", "wb", buffering=0)
fdw.write(b"10000000")
fdw.close()

fdw = io.open("/sys/class/pwm/pwmchip0/pwm0/duty_cycle", "wb", buffering=0)
fdw.write(b"8000000")
fdw.close()

fdw = io.open("/sys/class/pwm/pwmchip0/pwm0/enable", "wb", buffering=0)
fdw.write(b"1")
fdw.close()

Page 128

import subprocess
import io

def checkPWM():
    indicator = "pwm-2chan"
    command =["sudo", "dtoverlay", "pwm-2chan","pin=18", "func=2", "pin2=12","func2=4"]
    temp = subprocess.Popen(["sudo", "dtparam", "-l"], stdout = subprocess.PIPE)
    output = str(temp.communicate())
    print(output)
    if output.find(indicator)!=-1:
        temp = subprocess.Popen(["sudo","dtoverlay", "-R", "pwm-2chan"], stdout = subprocess.PIPE)
    temp = subprocess.Popen(command, stdout = subprocess.PIPE)
    output = str(temp.communicate())
    print(output)
    return

checkPWM()

fdw = io.open("/sys/class/pwm/pwmchip2/export", "wb", buffering=0)
fdw.write(b"0")
fdw.close()

fdw = io.open("/sys/class/pwm/pwmchip2/pwm0/period","wb", buffering=0)
fdw.write(b"10000000")
fdw.close()

fdw = io.open("/sys/class/pwm/pwmchip2/pwm0/duty_cycle", "wb", buffering=0)
fdw.write(b"8000000")
fdw.close()

fdw = io.open("/sys/class/pwm/pwmchip2/pwm0/enable", "wb", buffering=0)
fdw.write(b"1")
fdw.close()

fdw = io.open("/sys/class/pwm/pwmchip2/export", "wb", buffering=0)
fdw.write(b"2")
fdw.close()

fdw = io.open("/sys/class/pwm/pwmchip2/pwm2/period",  "wb", buffering=0)
fdw.write(b"10000000")
fdw.close()

fdw = io.open("/sys/class/pwm/pwmchip2/pwm2/duty_cycle", "wb", buffering=0)
fdw.write(b"8000000")
fdw.close()

fdw = io.open("/sys/class/pwm/pwmchip2/pwm2/enable","wb", buffering=0)
fdw.write(b"1")
fdw.close()
 
 

Page 130

import subprocess
import io
from time import sleep
import os
 
Pi5=True
 
class Pwm:
    def __init__(self, channel,f,duty,Pi5=False):
        if not(channel==0 or channel==1):
            return
        if Pi5:
            self.path="/sys/class/pwm/pwmchip2/"
        else:
            self.path="/sys/class/pwm/pwmchip0/"

        self.chan = str(channel)
   
        indicator = "pwm-2chan  pin=12 func=4 pin2=13 func2=4"
        command =["sudo", "dtoverlay", "pwm-2chan","pin=12", "func=4", "pin2=13","func2=4"]
        temp = subprocess.Popen(["sudo", "dtparam", "-l"],  stdout = subprocess.PIPE)
        output = str(temp.communicate())
        print(output)
        if output.find(indicator)==-1:
            temp = subprocess.Popen(command, stdout = subprocess.PIPE)
            output = str(temp.communicate())
            print(output)    

        if not(os.path.exists(self.path+"pwm"+self.chan)):
            fdw = io.open(self.path+"export", "w")
            fdw.write(self.chan)
            fdw.close()

        while not(os.path.exists(self.path+"pwm"+self.chan+  "/enable")):
            pass
             
        self.fdwp = io.open(self.path+"pwm"+self.chan+ "/period", "w")
        self.setFreq(f)
        self.fdwd = io.open(self.path+"pwm"+self.chan+ "/duty_cycle", "w")
        self.setDuty(duty)

    def setFreq(self,f):
        self.f=int(1000000000/f)  
        self.fdwp.write(str(self.f))
        self.fdwp.flush()
   
    def setDuty(self,duty):
        self.duty=int(self.f*duty/100)
        self.fdwd.write(str(self.duty))
        self.fdwd.flush()

    def enableChan(self):
        fdw = io.open(self.path+"pwm"+self.chan+"/enable", "w")
        fdw.write("1")
        fdw.close()
   
    def disableChan(self):
        fdw = io.open(self.path+"pwm"+self.chan+"/enable", "w")
        fdw.write("0")
        fdw.close()
   
    def closeChan(self):
        self.fdwd.close()
        self.fdwp.close()
        fdw = io.open(self.path+"unexport", "w")
        fdw.write(self.chan)        
        fdw.close()
 

Page 141

import subprocess
import io
from time import sleep
import os
 
Pi5=True
 
class Pwm:
    def __init__(self, channel,f,duty,Pi5=False):
        if not(channel==0 or channel==1):
            return
        if Pi5:
            self.path="/sys/class/pwm/pwmchip2/"
        else:
            self.path="/sys/class/pwm/pwmchip0/"

        self.chan = str(channel)
        indicator = "pwm-2chan"
        command =["sudo", "dtoverlay", "pwm-2chan"]
        temp = subprocess.Popen(["sudo", "dtparam", "-l"],  stdout = subprocess.PIPE)
        output = str(temp.communicate())
        print(output,flush=True)

        indicator = "pwm-2chan  pin=12 func=4 pin2=13 func2=4"
        command =["sudo", "dtoverlay", "pwm-2chan"]
        temp = subprocess.Popen(["sudo", "dtparam", "-l"], stdout = subprocess.PIPE)
        output = str(temp.communicate())
        print(output,flush=True)
        command =["sudo", "dtoverlay", "pwm-2chan","pin=12", "func=4", "pin2=13","func2=4"]
        temp = subprocess.Popen(["sudo", "dtparam", "-l"],  stdout = subprocess.PIPE)
        output = str(temp.communicate())
        print(output)
        if output.find(indicator)==-1:
            temp = subprocess.Popen(command,
                                         stdout = subprocess.PIPE)
            output = str(temp.communicate())
            print(output)
   
        if not(os.path.exists(self.path+"pwm"+self.chan)):
            fdw = io.open(self.path+"export", "w")
            fdw.write(self.chan)
            fdw.close()
        while not(os.path.exists(self.path+"pwm"+self.chan+"/enable")):
            pass
             
        self.fdwp = io.open(self.path+"pwm"+self.chan+"/period", "w")
        self.setFreq(f)
        self.fdwd = io.open(self.path+"pwm"+self.chan+"/duty_cycle", "w")
        self.setDuty(duty)

    def setFreq(self,f):
        self.f=int(1000000000/f)  
        t=str(self.f)
        self.fdwp.write(str(self.f))
        self.fdwp.flush()
   
    def setDuty(self,duty):
        self.duty=int(self.f*duty/100)
        self.fdwd.write(str(self.duty))
        self.fdwd.flush()

    def enableChan(self):
        fdw = io.open(self.path+"pwm"+self.chan+"/enable", "w")
        fdw.write("1")
        fdw.close()
   
    def disableChan(self):
        fdw = io.open(self.path+"pwm"+self.chan+"/enable", "w")
        fdw.write("0")
        fdw.close()
   
    def closeChan(self):
        self.fdwd.close()
        self.fdwp.close()
        fdw = io.open(self.path+"unexport", "w")
        fdw.write(self.chan)        
        fdw.close()
   
    def inverChan(self):
        fdw = io.open(self.path+ "pwm"+self.chan+"/polarity", "w")
        fdw.write("inversed")
        fdw.close()
   
    def normalChan(self):
        fdw = io.open(self.path+ "pwm"+self.chan+"/polarity", "w")
        fdw.write("normal")
        fdw.close(

 


Page 151

import subprocess
import spidev
from time import sleep


def checkSPI():
    temp = subprocess.Popen(["sudo", "dtparam", "-l"], stdout=subprocess.PIPE)
    output = str(temp.communicate())
    lastSPI = output.rfind("spi")
    if lastSPI != -1:
        lastSPI = output.find("spi=on", lastSPI)
    if lastSPI == -1:
        temp = subprocess.Popen(
            ["sudo", "dtparam", "spi=on"], stdout=subprocess.PIPE)
        output = str(temp.communicate())


checkSPI()

spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 5000
Data = [0xAA]
print(hex(Data[0]))
data = spi.xfer(Data)
print(hex(Data[0]))
if Data == 0xAA:
    print("match")
spi.close()

Page 161

import subprocess
import spidev

def checkSPI():
    temp = subprocess.Popen(["sudo", "dtparam", "-l"], stdout=subprocess.PIPE)
    output = str(temp.communicate())
    lastSPI = output.rfind("spi")
    if lastSPI != -1:
        lastSPI = output.find("spi=on", lastSPI)
    if lastSPI == -1:
        temp = subprocess.Popen(
            ["sudo", "dtparam", "spi=on"], stdout=subprocess.PIPE)
        output = str(temp.communicate())


checkSPI()

spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 100000
spi.mode = 0
spi.bits_per_word = 8

Data = [0x01, 0x80, 0x00]
spi.xfer(Data)
raw = (Data[1] & 0x03) << 8 | Data[2]
print(raw)
volts = raw * 3.3 / 1023.0
print(volts, "V")
spi.close()
 

 

Page 181

import subprocess
import io
import fcntl


def checkI2CBus():
    temp = subprocess.Popen(["sudo", "dtparam", "-l"], stdout=subprocess.PIPE)
    output = str(temp.communicate())
    lasti2c = output.rfind("i2c_arm")
    if lasti2c != -1:
        lasti2c = output.find("i2c_arm=on", lasti2c)
    if lasti2c == -1:
        temp = subprocess.Popen(["sudo", "dtparam", "i2c_arm=on"],  stdout=subprocess.PIPE)
        output = str(temp.communicate())
    return


checkI2CBus()

I2C_SLAVE = 0x0703

fdr = io.open("/dev/i2c-1", "rb", buffering=0)
fdw = io.open("/dev/i2c-1", "wb", buffering=0)
fcntl.ioctl(fdr, I2C_SLAVE, 0x40)
fcntl.ioctl(fdw, I2C_SLAVE, 0x40)
fdw.write(bytearray([0xE7]))
data = fdr.read(1)
print(data)
fdr.close()
fdw.close()

Page 183

import subprocess
import io
import fcntl
from time import sleep

checkI2CBus()
I2C_SLAVE = 0x0703

fdr = io.open("/dev/i2c-1", "rb", buffering=0)
fdw = io.open("/dev/i2c-1", "wb", buffering=0)
fcntl.ioctl(fdr, I2C_SLAVE, 0x40)
fcntl.ioctl(fdw, I2C_SLAVE, 0x40)

fdw.write(bytearray([0xF3]))
while(True):
    try:
        data = fdr.read(3)
        break
    except:
        sleep(0.01)
msb = data[0]
lsb = data[1]
crc = data[2]
print("msb=", msb, " lsb=", lsb, " crc=", crc)

fdw.close()
fdr.close()

Page 187

import subprocess
import io
import fcntl
from time import sleep


def crcCheck(msb, lsb, check):
    data32 = (msb << 16) | (lsb << 8) | check
    divisor = 0x988000
    for i in range(16):
        if(data32 & 1 << (23 - i)):
            data32 ^= divisor
        divisor >>= 1
    return data32


def checkI2CBus():
    temp = subprocess.Popen(["sudo", "dtparam", "-l"],  stdout=subprocess.PIPE)
    output = str(temp.communicate())
    print(output)
    lasti2c = output.rfind("i2c_arm")
    if lasti2c != -1:
        lasti2c = output.find("i2c_arm=on", lasti2c)
    if lasti2c == -1:
        temp = subprocess.Popen(["sudo", "dtparam", "i2c_arm=on"],  stdout=subprocess.PIPE)
        output = str(temp.communicate())
    return


checkI2CBus()
I2C_SLAVE = 0x0703

fdr = io.open("/dev/i2c-1", "rb", buffering=0)
fdw = io.open("/dev/i2c-1", "wb", buffering=0)
fcntl.ioctl(fdr, I2C_SLAVE, 0x40)
fcntl.ioctl(fdw, I2C_SLAVE, 0x40)

fdw.write(bytearray([0xF3]))
while(True):
    try:
        data = fdr.read(3)
        break
    except:
        sleep(0.01)
msb = data[0]
lsb = data[1]
crc = data[2]

data16 = (msb << 8) | (lsb & 0xFC)
temp = -46.85 + (175.72 * data16 / 65536)
print("Temperature=", temp, "C")

fdw.write(bytearray([0xF5]))
while(True):
    try:
        data = fdr.read(3)
        break
    except:
        sleep(0.01)

msb = data[0]
lsb = data[1]
crc = data[2]
data16 = (msb << 8) | (lsb & 0xFC)
hum = -6 + 125.0 * data16 / 65536

print("humidity=", hum, "%")

print(crcCheck(msb, lsb, crc))
fdw.close()
fdr.close()
 

 

Page 197

import subprocess
import io
import fcntl
from time import sleep

def checkI2CBus():
    temp = subprocess.Popen(["sudo", "dtparam", "-l"], stdout = subprocess.PIPE)
    output = str(temp.communicate())
    lasti2c=output.rfind("i2c_arm")
    if lasti2c!=-1:
        lasti2c=output.find("i2c_arm=on",lasti2c)
    if lasti2c==-1:
        temp = subprocess.Popen(["sudo", "dtparam", "i2c_arm=on"],  stdout = subprocess.PIPE)
        output = str(temp.communicate())
    return

I2C_SLAVE=0x0703

fdr = io.open("/dev/i2c-1", "rb", buffering=0)
fdw = io.open("/dev/i2c-1", "wb", buffering=0)
fcntl.ioctl(fdr, I2C_SLAVE, 0x40)
fcntl.ioctl(fdw, I2C_SLAVE, 0x40)

fdw.write( bytearray([0xE3]))

data=fdr.read(3)
msb=data[0]
lsb=data[1]
crc=data[2]
print("msb=",msb," lsb=",lsb," crc=",crc)

fdw.close()
fdr.close()

Page 200

import subprocess
from ctypes import *
import os
import fcntl
import io


def checkI2CBus():
    temp = subprocess.Popen(["sudo", "dtparam", "-l"],  stdout=subprocess.PIPE)
    output = str(temp.communicate())
    lasti2c = output.rfind("i2c_arm")
    if lasti2c != -1:
        lasti2c = output.find("i2c_arm=on", lasti2c)
    if lasti2c == -1:
        temp = subprocess.Popen(["sudo", "dtparam", "i2c_arm=on"], stdout=subprocess.PIPE)
        output = str(temp.communicate())
    return


checkI2CBus()
I2C_SLAVE = 0x0703
I2C_FUNCS = 0x0705

I2C_FUNC_I2C = 0x00000001
I2C_FUNC_10BIT_ADDR = 0x00000002
I2C_FUNC_PROTOCOL_MANGLING = 0x00000004
I2C_FUNC_NOSTART = 0x00000010
I2C_FUNC_SLAVE = 0x00000020

i2cfd = os.open("/dev/i2c-1", os.O_RDWR | os.O_SYNC)
support = c_uint32(0)
fcntl.ioctl(i2cfd, I2C_FUNCS, support)
support = support.value
if support & I2C_FUNC_I2C:
    print("I2C Support")
if support & I2C_FUNC_10BIT_ADDR:
    print("10 bit address Support")
if support & I2C_FUNC_PROTOCOL_MANGLING:
    print("I2C Mangling Support")
if support & I2C_FUNC_NOSTART:
    print("I2C Nostart Support")
if support & I2C_FUNC_SLAVE:
    print("I2C Slave Support")

Page 204

import fcntl
import os
from ctypes import *


class Msgs(Structure):
    _fields_ = [("addr", c_uint16),
                ("flags", c_uint16),
                ("len", c_uint16),
                ("buf", POINTER(c_uint8))
                ]


class MsgSet(Structure):
    _fields_ = [("msgs", POINTER(Msgs)),
                ("nmsgs", c_uint32)
                ]


def i2cReadRegister(i2cfd, slaveaddr, reg, n):
    I2C_RDWR = 0x0707
    I2C_M_RD = 0x0001

    msgs = (Msgs*2)()

    msgs[0].addr = c_uint16(slaveaddr)
    msgs[0].flags = c_uint16(0)
    msgs[0].len = c_uint16(1)
    msgs[0].buf = POINTER(c_uint8)(c_uint8(reg))

    msgs[1].addr = c_uint16(slaveaddr)
    msgs[1].flags = c_uint16(I2C_M_RD)
    msgs[1].len = c_uint16(n)
    buf = (c_uint8*n)(0)
    msgs[1].buf = POINTER(c_uint8)(buf)

    msgset = MsgSet()
    msgset.msgs = POINTER(Msgs)(msgs)
    msgset.nmsgs = c_uint32(2)

    libc = CDLL("libc.so.6")
    libc.ioctl(i2cfd, I2C_RDWR, byref(msgset))

    return msgs[1].buf


def crcCheck(msb, lsb, check):
    data32 = (msb << 16) | (lsb << 8) | check
    divisor = 0x988000
    for i in range(16):
        if(data32 & 1 << (23 - i)):
            data32 ^= divisor
        divisor >>= 1
    return data32


i2cfd = os.open("/dev/i2c-1", os.O_RDWR | os.O_SYNC)
data = i2cReadRegister(i2cfd, 0x40, 0xE3, 3)
msb = data[0]
lsb = data[1]
crc = data[2]

data16 = (msb << 8) | (lsb & 0xFC)
temp = -46.85 + (175.72 * data16 / 65536)
print("Temperature=", temp, "C")
print(hex(msb), hex(lsb), hex(crc))
print(crcCheck(msb, lsb, crc))
 

 

Page 212

import subprocess
import io


def checkLM75():
    indicator1 = "i2c_arm=on"
    command1 = ["sudo", "dtparam", "i2c_arm=on"]
    indicator2 = "lm75"
    command2 = ["sudo", "dtoverlay", "i2c-sensor", "lm75", "addr=0x48"]
    temp = subprocess.Popen(["sudo", "dtparam", "-l"], stdout=subprocess.PIPE)
    output = str(temp.communicate())
    print(output, flush=True)
    if output.find(indicator1) == -1:
        temp = subprocess.Popen(command1, stdout=subprocess.PIPE)
        output = str(temp.communicate())
        print(output, flush=True)
    if output.find(indicator2) == -1:
        temp = subprocess.Popen(command2, stdout=subprocess.PIPE)
        output = str(temp.communicate())
        print(output, flush=True)


checkLM75()

fdr = io.open("/sys/class/hwmon/hwmon2/temp1_input", "r")
buf = fdr.read()
print(buf)
temp = int(buf) / 1000
print(temp)
fdr.close()

fdw = io.open("/sys/class/hwmon/hwmon2/temp1_max", "w")
fdw.write("19000")
fdw.close()

fdw = io.open("/sys/class/hwmon/hwmon2/temp1_max_hyst", "w")
fdw.write("18000")
fdw.close()

Page 215

import subprocess
import io

def loadHtu21():
    temp = subprocess.Popen(["sudo", "dtparam", "-l"], stdout=subprocess.PIPE)
    output = str(temp.communicate())
    print(output)
    if output.find("htu21") == -1:
        temp = subprocess.Popen( ["sudo", "dtoverlay", "i2c-sensor", "htu21"], stdout=subprocess.PIPE)
        output = str(temp.communicate())
        print(output)
    return

loadHtu21()

fdrt = io.open("/sys/bus/iio/devices/iio:device0/in_temp_input", "r")
print(int(fdrt.read())/1000)
fdrh = io.open( "/sys/bus/iio/devices/iio:device0/in_humidityrelative_input", "r")
print(int(fdrh.read())/1000)
 

 

Page 229

import subprocess
import io


def load1w(pin):
    indicator = "w1-gpio"
    command = ["sudo", "dtoverlay", "w1-gpio", "gpiopin="+str(pin)]
    temp = subprocess.Popen(["sudo", "dtparam", "-l"], stdout=subprocess.PIPE)
    output = str(temp.communicate())
    print(output, flush=True)
    if output.find(indicator) == -1:
        temp = subprocess.Popen(command, stdout=subprocess.PIPE)
        output = str(temp.communicate())
        print(output, flush=True)


def getDevices():
    fdr = io.open(
        "/sys/bus/w1/drivers/w1_master_driver/w1_bus_master1/w1_master_slaves", "r")
    buffer = fdr.read()
    fdr.close()
    return buffer.split()


def getData(dev, name):
    fdr = io.open("/sys/bus/w1/devices/"+dev+"/"+name, "r")
    data = fdr.read()
    fdr.close()
    return data


load1w(4)
devs = getDevices()
name = getData(devs[0], "name")
print("Name ", name)
resolution = getData(devs[0], "resolution")
print("Resolution ", resolution)
w1_slave = getData(devs[0], "w1_slave")
print("w1_slave ", w1_slave)
temperature = getData(devs[0], "temperature")
print("temperature ", temperature)
temperature = int(temperature) / 1000
print("temperature ", temperature, "C")
alarms = getData(devs[0], "alarms")
print("Alarms ", alarms)

Page 240

from ctypes import *
from socket import *
from struct import *
import os
import subprocess
import io
from time import sleep


NLMSG_DONE = 0x3

CN_W1_IDX = 0x3
CN_W1_VAL = 0x1

W1_SLAVE_ADD = 0
W1_SLAVE_REMOVE = 1
W1_MASTER_ADD = 2
W1_MASTER_REMOVE = 3
W1_MASTER_CMD = 4
W1_SLAVE_CMD = 5
W1_LIST_MASTERS = 6

W1_CMD_READ = 0
W1_CMD_WRITE = 1
W1_CMD_SEARCH = 2
W1_CMD_ALARM_SEARCH = 3
W1_CMD_TOUCH = 4
W1_CMD_RESET = 5
W1_CMD_SLAVE_ADD = 6
W1_CMD_SLAVE_REMOVE = 7
W1_CMD_LIST_SLAVES = 8
W1_CMD_MAX = 9

NETLINK_CONNECTOR = 11

nl_seq = 0


class nlmsghdr(Structure):
    _fields_ = [("nlmsg_len", c_uint32),
                ("nlmsg_type", c_uint16),
                ("nlmsg_flags", c_uint16),
                ("nlmsg_seq", c_uint32),
                ("nlmsg_pid", c_uint32)
                ]


cnh = nlmsghdr()
cnh.nlmsg_seq = c_uint32(nl_seq)
nl_seq += 1
cnh.nlmsg_pid = c_uint32(os.getpid())
cnh.nlmsg_type = c_uint16(NLMSG_DONE)
cnh.nlmsg_flags = c_uint16(0)


class cn_msg(Structure):
    _fields_ = [("idx", c_uint32),
                ("val", c_uint32),
                ("seq", c_uint32),
                ("ack", c_uint32),
                ("len", c_uint16),
                ("flags", c_uint16),
                ]


cmsg = cn_msg()
cmsg.idx = c_uint32(CN_W1_IDX)
cmsg.val = c_uint32(CN_W1_VAL)
cmsg.seq = c_uint32(cnh.nlmsg_seq)
cmsg.ack = c_uint32(0)


class w1_netlink_msg(Structure):
    _fields_ = [("type", c_uint8),
                ("status", c_uint8),
                ("len", c_uint16),
                ("id", c_uint8*8),
                ]


msg = w1_netlink_msg()
msg.type = c_uint8(W1_MASTER_CMD)
msg.id = (c_uint8*8).from_buffer_copy(c_uint64(1))


class w1_netlink_cmd(Structure):
    _fields_ = [("cmd", c_uint8),
                ("res", c_uint8),
                ("len", c_uint16),
                ]


w1_cmd = w1_netlink_cmd()
w1_cmd.cmd = c_uint8(W1_CMD_SEARCH)
w1_cmd.len = c_uint16(0)


msg.len = c_uint16(len(bytearray(w1_cmd)) + w1_cmd.len)
cmsg.len = c_uint16(len(bytearray(msg)) + msg.len)
cnh.nlmsg_len = c_uint32(len(bytearray(cnh))+len(bytearray(cmsg))+cmsg.len)


s = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR)
s.connect((0, AF_NETLINK))

buffer = bytearray(cnh)+bytearray(cmsg)+bytearray(msg)+bytearray(w1_cmd)
n = s.send(buffer)
print("Bytes sent", n, flush=True)
buffer2 = s.recv(65535)
print("Bytes received", len(buffer2), flush=True)

p = 0
cn_cnhr = nlmsghdr.from_buffer_copy(buffer2, p)
p = p+len(bytes(cn_cnhr))
cmsgr = cn_msg.from_buffer_copy(buffer2, p)
p = p+len(bytes(cmsgr))
msgr = w1_netlink_msg.from_buffer_copy(buffer2, p)
p = p+len(bytes(msgr))
w1_cmdr = w1_netlink_cmd.from_buffer_copy(buffer2, p)

num = int(w1_cmdr.len/8)
print("number of slaves", num)

p = p+len(bytes(w1_cmdr))
slaves = []
for i in range(num):
    slaves.append(c_uint64.from_buffer_copy(buffer2, p+i*8).value)
print([hex(slave) for slave in slaves])

# GET ACK
buffer2 = s.recv(65535)
print("length of ack received ", len(buffer2), flush=True)

# READ TEMPERATURE
# SET UP SLAVE COMMAND
print()
print("Read Temperature")

msg.type = W1_SLAVE_CMD

id = slaves[0].to_bytes(8, "little")
msg.id = (c_uint8*8).from_buffer_copy(id)


# SETUP AND SEND WRITE 0x44 = CONVERT
w1_cmd.cmd = c_uint8(W1_CMD_WRITE)
w1_cmd_data = c_uint8(0x44)


cnh.nlmsg_seq = c_uint32(nl_seq)
nl_seq += 1
cmsg.seq = c_uint32(cnh.nlmsg_seq)

w1_cmd.len = c_uint16(1)
msg.len = c_uint16(len(bytearray(w1_cmd)) + w1_cmd.len)
cmsg.len = c_uint16(len(bytearray(msg)) + msg.len)
cnh.nlmsg_len = c_uint32(len(bytearray(cnh))+len(bytearray(cmsg))+cmsg.len)

buffer = bytearray(cnh)+bytearray(cmsg)+bytearray(msg) + \
    bytearray(w1_cmd)+bytearray(w1_cmd_data)

n = s.send(buffer)
print("Bytes sent", n, flush=True)
buffer2 = s.recv(65535)
print("length of ack received ", len(buffer2), flush=True)
sleep(1)

# READ SCRATCH PAD
cnh.nlmsg_seq = nl_seq
nl_seq += 1
cmsg.seq = cnh.nlmsg_seq

w1_cmd.cmd = W1_CMD_WRITE
w1_cmd_data = c_uint8(0xBE)

w1_cmd2 = w1_netlink_cmd()
w1_cmd2.cmd = c_uint8(W1_CMD_READ)


w1_cmd.len = c_uint16(1)
w1_cmd2.len = c_uint16(9)
msg.len = c_uint16(len(bytearray(w1_cmd)) +
                   len(bytearray(w1_cmd2)) + w1_cmd.len+w1_cmd2.len)
cmsg.len = c_uint16(len(bytearray(msg)) + msg.len)
cnh.nlmsg_len = c_uint32(len(bytearray(cnh))+len(bytearray(cmsg))+cmsg.len)

w1_cmd2_data = (c_uint8*9)(0)
buffer = bytearray(cnh)+bytearray(cmsg)+bytearray(msg)+bytearray(w1_cmd) + \
    bytearray(w1_cmd_data)+bytearray(w1_cmd2)+bytearray(w1_cmd2_data)
n = s.send(buffer)
print("Bytes sent", n, flush=True)

buffer2 = s.recv(65535)
print("length of ack received ", len(buffer2), flush=True)

buffer2 = s.recv(65535)
print("length of data received ", len(buffer2), flush=True)
p = 0
cn_cnhr = nlmsghdr.from_buffer_copy(buffer2, p)
# print(cn_cnhr.nlmsg_len)
p = p+len(bytes(cn_cnhr))
cmsgr = cn_msg.from_buffer_copy(buffer2, p)
p = p+len(bytes(cmsgr))
msgr = w1_netlink_msg.from_buffer_copy(buffer2, p)
p = p+len(bytes(msgr))
w1_cmdr = w1_netlink_cmd.from_buffer_copy(buffer2, p)
p = p+len(bytes(w1_cmdr))

temp = c_uint16.from_buffer_copy(buffer2, p)

print("number of bytes found ", w1_cmdr.len, flush=True)
print(temp.value/16)
 
 

 

VSCODE TASKS

 

settings.json

which has to be customized to your IP, user name and folder:

{
    "sshUser": "pi",
    "sshEndpoint": "192.168.11.151",
    "remoteDirectory": "/home/pi/Documents/",
}

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": "makeRemoteWorkSpace",
            "type": "shell",
            "command": "ssh ${config:sshUser}@${config:sshEndpoint} 'mkdir  ${config:remoteDirectory}'",
            "problemMatcher": [],
            "presentation": {
                "showReuseMessage": false,
            }
        },
        {
            "label": "RunR",
            "type": "shell",
            "command": "ssh ${config:sshUser}@${config:sshEndpoint} 'python3 ${config:remoteDirectory}/${relativeFileDirname}/${fileBasename}'",
            "problemMatcher": [],
            "presentation": {
                "showReuseMessage": false,
            }
        },
        {
            "label": "RunRemote",
            "dependsOrder": "sequence",
            "dependsOn": [
                "copyToRemote",
                "RunR"
            ],
            "problemMatcher": [],
            "group": {
                "kind": "build",
                "isDefault": true
            },
        },
        {
            "label": "StopREmotePython",
            "type": "shell",
            "command": "ssh ${config:sshUser}@${config:sshEndpoint} 'pkill python3'",
            "problemMatcher": [],
            "presentation": {
                "showReuseMessage": true,
            }
        },
        {
            "label": "wait",
            "type": "shell",
            "command": "timeout 10"
        },
        {
            "label": "tunnel",
            "type": "shell",
            "command": "ssh -2 -L 5678:localhost:5678  ${config:sshUser}@${config:sshEndpoint}",
            "problemMatcher": [],
            "presentation": {
                "showReuseMessage": false,
            }
        },
        {
            "label": "startDebug",
            "type": "shell",
            "command": "ssh -2 ${config:sshUser}@${config:sshEndpoint} 'nohup python3 -m debugpy --listen 0.0.0.0:5678 --wait-for-client ${config:remoteDirectory}/${relativeFileDirname}/${fileBasename} > /dev/null 2>&1 &'",
            "problemMatcher": [],
            "presentation": {
                "showReuseMessage": false,
            }
        },
        {
            "label": "copyAndDebug",
            "dependsOrder": "sequence",
            "dependsOn": [
                "copyToRemote",
                "startDebug",
                "wait"
            ],
            "presentation": {
                "showReuseMessage": false,
            },
        },
    ]
}
launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Remote Attach",
            "type": "python",
            "request": "attach",
            "connect": {
                "host": "localhost",
                "port": 5678
            },
            "pathMappings": [
                {
                    "localRoot": "${workspaceFolder}/${relativeFileDirname}/",
                    "remoteRoot": "${config:remoteDirectory}/${relativeFileDirname}"
                }
            ],
            "preLaunchTask": "copyAndDebug",
            "postDebugTask": "StopREmotePython"
        }
    ]
}

Raspberry Pi IoT In C Using Linux Drivers

Second Edition

Programs

 

DriverC2E360

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. 

 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 26

#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 44

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char **argv)
{
    int fd = open("/sys/class/leds/ACT/trigger", O_WRONLY);
    write(fd, "none",4);
    close(fd);
    fd = open("/sys/class/leds/ACT/brightness", O_WRONLY);
    while (1)
    {
        write(fd, "0",1);
        sleep(2);
        write(fd, "1",1);
        sleep(2);
    }
}

Page 45

#include <stdio.h>
import io
from time import sleep

fd = io.open("/sys/class/leds/ACT/trigger","w")
fd.write("timer")
fd.close()

fd = io.open("/sys/class/leds/ACT/delay_on", "w")
fd.write("2000")
fd.close()

fd = io.open("/sys/class/leds/ACT/delay_off", "w")
fd.write("3000")
fd.close()

 


Page 54

#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);
         res = gpiod_ctxless_set_value("0", 4, 0, 1,  "output test", NULL, NULL);
    }
}
 

 Remember to change "0" to "4" if running on a Pi 5.

Page 55 

#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);
    }
}

 Remember to change "0" to "4" if running on a Pi 5.

Page 56 

#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, 17};
    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);
    }
}
 
 Remember to change "0" to "4" if running on a Pi 5.

Page 58

#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);

 Remember to change chip number 0 to 4 if running on a Pi 5.

Page 60 

#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);
    };

 Remember to change chip number 0 to 4 if running on a Pi 5.

 

Page 64

#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});
    };
}
 

 Remember to change chip number 0 to 4 if running on a Pi 5.

 

Page 66 

#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);
}  
 

 Remember to change chip number 0 to 4 if running on a Pi 5.


 

Page 70

#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;
}
 

If you run this on a Pi 5 change gpiochip0 to gpiochip4.

Page 73

#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;

Remember to change gpiochip0 to gpiochip4 if you are running on a Pi 5.

Page 74 

#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;
}

Remember to change gpiochip0 to gpiochip4 if you are running on a Pi 5.

Page 75 

#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;

Remember to change gpiochip0 to gpiochip4 if you are running on a Pi 5.


 

Page 83

#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 84

#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);
}

 

Remember to change gpiochip0 to gpiochip4 if you are running on a Pi 5.

Page 85

#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);
    }

Remember to change gpiochip0 to gpiochip4 if you are running on a Pi 5.

 

Page 86

#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");
    }
}

Remember to change gpiochip0 to gpiochip4 if you are running on a Pi 5.

Page 87

#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");
    }

Remember to change gpiochip0 to gpiochip4 if you are running on a Pi 5.

Page 88

#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;
}

 

Remember to change gpiochip0 to gpiochip4 if you are running on a Pi 5.

Page 92

#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);
    }
}

Remember to change gpiochip0 to gpiochip4 if you are running on a Pi 5.

Page 93

#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);
    }
}

Remember to change gpiochip0 to gpiochip4 if you are running on a Pi 5.

Page 97

#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);
    }

Remember to change gpiochip0 to gpiochip4 if you are running on a Pi 5.

Page 100

#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);
}

Remember to change gpiochip0 to gpiochip4 if you are running on a Pi 5.

 


Page 110 

#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 112

#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 133

#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);
    };
}
 

Remember to change "0" to "4" if you are running on a Pi 5.

Page  134

#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 (;;)
    {
    };
}
 

Remember to change "0" to "4" if you are running on a Pi 5.

Page 137

#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);
}

 

Remember to change "0" to "4" if you are running on a Pi 5.

Page 139

#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";
    char command[] = "sudo dtoverlay pwm-2chan, pin=18 func=2 pin2=12 func2=4" ;
    while (fgets(output, sizeof(output), fd) != NULL)
    {
        printf("%s\n\r", output);
        fflush(stdout);
        if (strstr(output, indicator) != NULL)
        {
            txfound = 1;
            printf("Overlay already loaded\n\r");
        }
    }
    if (txfound == 0)
    {
        fd = doCommand(command);
        sleep(2);
    }

    pclose(fd);
}

int main(int argc, char **argv)
{
    checkPWM();  
    int fd = open("/sys/class/pwm/pwmchip2/export", O_WRONLY);
    write(fd, "0", 1);
    close(fd);
    sleep(2);
    fd = open("/sys/class/pwm/pwmchip2/pwm0/period", O_WRONLY);
    write(fd, "10000001", 8);
    close(fd);
    fd = open("/sys/class/pwm/pwmchip2/pwm0/duty_cycle", O_WRONLY);
    write(fd, "4000000", 7);
    close(fd);
    fd = open("/sys/class/pwm/pwmchip2/pwm0/enable", O_WRONLY);
    write(fd, "1", 1);
    close(fd);
   
    fd = open("/sys/class/pwm/pwmchip2/export", O_WRONLY);
    write(fd, "2", 1);
    close(fd);
    sleep(2);
    fd = open("/sys/class/pwm/pwmchip2/pwm2/period", O_WRONLY);
    write(fd, "10000001", 8);
    close(fd);
    fd = open("/sys/class/pwm/pwmchip2/pwm2/duty_cycle", O_WRONLY);
    write(fd, "5000000", 7);
    close(fd);
    fd = open("/sys/class/pwm/pwmchip2/pwm2/enable", O_WRONLY);
    write(fd, "1", 1);
    close(fd);
}
 

Page 141 - full listing of finished program on Page 155

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

 #define Pi5

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 pin=12 func=4 pin2=13 func2=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)
    {
        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;
    char buf[150];
    char schan[6];
    va_list params;
    int param;

    if (chan != 0 && chan != 1)
        return -1;

#if defined(Pi5)
    char path[] = "/sys/class/pwm/pwmchip2/";
#else
    char path[] = "/sys/class/pwm/pwmchip0/";
#endif
    char chanNum[2];
    snprintf(schan, 6, "%s%d", "pwm", chan);
    snprintf(chanNum, 2, "%d", chan);

    int L;

    switch (action)
    {
    case OpenChan:
        checkPWM();
        snprintf(buf, 150, "%s%s", path, "export");
        fd = open(buf, O_WRONLY);
        write(fd, chanNum, 1);
        close(fd);
        sleep(2);
        snprintf(buf, 150, "%s%s%s", path, schan, "/period");
        fdf[chan] = open(buf, O_WRONLY);
        snprintf(buf, 150, "%s%s%s", path, schan, "/duty_cycle");
        fdd[chan] = open(buf, O_WRONLY);
        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;
    case EnableChan:
        snprintf(buf, 150, "%s%s%s", path, schan, "/enable");
        fd = open(buf, O_WRONLY);
        write(fd, "1", 1);
        close(fd);
        break;
    case DisableChan:
        snprintf(buf, 150, "%s%s%s", path, schan, "/enable");
        fd = open(buf, O_WRONLY);
        write(fd, "0", 1);
        close(fd);
        break;
    case CloseChan:
        close(fdf[chan]);
        close(fdd[chan]);
        snprintf(buf, 150, "%s%s%s", path, "/unexport");
        printf("%s\n", buf);
        fd = open(buf, O_WRONLY);
        write(fd, chanNum, 1);
        close(fd);
        break;

    case InvertChan:
        va_start(params, chan);
        param = va_arg(params, int);
        snprintf(buf, 150, "%s%s%s", path, 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, 0);
   

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

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

 


Page 167 

#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[] = {0xAA};
    uint8_t rx[] = {0};

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

    int fd = open("/dev/spidev0.0", O_RDWR);  
    int status = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
    if (status < 0)
        printf("can't send data");
    printf("%X,%X\n", tx[0],rx[0]);
    close(fd);
}

 

Page 177

#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 197

#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 206

#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 219

#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 main(int argc, char **argv)
{
    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 %d \n\rlsb %d \n\rchecksum %d \n\r", msb, lsb, check);
}

Page 222

#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 227

#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 234

#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 248

#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 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
  }