Preface ATT Io T Starter Kit (2nd Generation) Users Guide
User Manual:
Open the PDF directly: View PDF .
Page Count: 224
Download | |
Open PDF In Browser | View PDF |
Getting Started Guide AT&T IoT Starter Kit Getting Started Guide September 2016 AT&T IoT Starter Kit (2nd Generation) User’s Guide If you purchased an AT&T IoT Starter Kit (2nd Generation) and just want to get started with the QuickStart Demo, click here to jump right to that page in Chapter 1. Copyright © 2019 by AT&T Incorporated Revision 0.50 (Friday, February 8, 2019) Table of Contents Table of Contents AT&T IoT Starter Kit (2nd Generation) User’s Guide ................................................................................ 2 Table of Contents ...................................................................................................................................... 3 Table of Code Listings .............................................................................................................................. 6 License for Code Examples ...................................................................................................................... 8 Preface ...................................................................................................................................................... 9 Work in Progress ................................................................................................................................... 9 What this Book Covers ......................................................................................................................... 9 Downloads, Support and Tools .............................................................................................................. 11 Related Documentation ......................................................................................................................... 12 Document Locations........................................................................................................................... 13 1. Getting Started .............................................................................................................................. 15 1.1. What is IoT? ................................................................................................................................ 16 1.1.1. How Does IoT Work? ......................................................................................................... 17 1.1.2. The Case for Cellular IoT ................................................................................................... 18 1.1.3. The SK2: IoT Everywhere .................................................................................................. 18 1.2. IoT Starter Kit (SK2) ................................................................................................................... 19 1.2.1. What Comes In the Box..................................................................................................... 20 1.2.2. Hardware Overview ........................................................................................................... 21 1.2.3. Software Overview............................................................................................................. 24 1.2.4. Cloud Connectivity ............................................................................................................. 25 1.2.5. Description of QuickStart Demo ....................................................................................... 25 1.3. Running the QuickStart Demo .................................................................................................. 26 1.4. Resources .................................................................................................................................. 32 1.4.1. AT&T Resources ................................................................................................................ 32 1.4.2. Register with cloudconnectkits.org .................................................................................. 32 2. Embedded Linux............................................................................................................................ 33 2.1. Introduction to Linux .................................................................................................................. 34 2.1.1. Kernel Space vs User Space ............................................................................................ 35 2.2. Linux Distribution ....................................................................................................................... 36 2.2.1. Linux Kernel ....................................................................................................................... 36 2.2.2. Filesystem .......................................................................................................................... 37 2.2.3. Boot Loader ....................................................................................................................... 39 2.2.4. Toolchain ........................................................................................................................... 39 2.3. Linux Shell .................................................................................................................................. 40 2.3.1. Basic Linux Commands..................................................................................................... 40 2.3.2. Shell Scripting.................................................................................................................... 43 2.4. ADB – Connecting to the SK2 ................................................................................................... 45 2.4.1. Installing ADB .................................................................................................................... 46 2.4.2. Sidebar - What happens during “adb devices”................................................................ 49 2.4.3. ADB Commands ................................................................................................................ 49 2.5. Controlling Hardware Using the Linux Shell ............................................................................. 56 2.6. Linux Boot Sequence ................................................................................................................. 58 2.6.1. How Does the QuickStart Demo Run Automatically? ...................................................... 58 AT&T IoT Starter Kit (2nd Generation) User's Guide - Preface Page 3 Table of Contents 2.6.2. 3. Configuring Linux Application Bootstrap .......................................................................... 59 Installing and Using C/C++ ........................................................................................................... 63 3.1. Installing the C/C++ Tools and Software ................................................................................. 65 3.1.1. GIT (and ADB) .................................................................................................................... 65 3.1.2. Software Development Kit (SDK) ..................................................................................... 66 3.2. IoT_Monitor example ................................................................................................................. 68 3.2.1. Clone the IoT_Monitor Source Code ................................................................................ 68 3.2.2. Build the IoT Monitor Program ......................................................................................... 69 3.2.3. Push and Execute iot_monitor Application ...................................................................... 70 3.2.4. Avnet IoT Monitor GitHub and Videos .............................................................................. 71 3.3. Create Your First SK2 C/C++ Program ..................................................................................... 72 3.3.1. Hello World ........................................................................................................................ 72 3.3.2. GNU Automake Build System ........................................................................................... 72 3.3.3. Starting Project Files ......................................................................................................... 73 3.3.4. Install SK2 User Guide Examples ..................................................................................... 74 3.3.5. Building “Hello” ................................................................................................................. 74 3.4. Example: Blink LED (File I/O) .................................................................................................... 76 3.4.1. Blink LED with File I/O ...................................................................................................... 76 3.5. Using the SDK’s peripheral API ................................................................................................. 78 3.5.1. GPIO API Summary ............................................................................................................ 78 3.5.2. Example: Blink LED (GPIO API) ......................................................................................... 80 3.6. Writing C Programs for Linux .................................................................................................... 81 3.6.1. Multi-threading .................................................................................................................. 81 3.6.2. Event Handling .................................................................................................................. 86 4. 3.7. Example: myGpio.c .................................................................................................................... 94 3.8. Where to Go for More Information ............................................................................................ 98 Installing and Using Python ........................................................................................................... 99 4.1. Installing Python ...................................................................................................................... 101 4.1.1. Backup /CUSTAPP ........................................................................................................... 101 4.1.2. Setting up the Python IDE ............................................................................................... 103 4.2. Connect to Python IDE ............................................................................................................. 107 4.2.1. Overview .......................................................................................................................... 107 4.2.2. GPIO Control .................................................................................................................... 108 4.2.3. IDE .................................................................................................................................... 109 4.2.4. Links................................................................................................................................. 110 4.2.5. Terminal ........................................................................................................................... 111 4.3. Getting Started with Python .................................................................................................... 112 4.3.1. Running Python from the Command-Line ...................................................................... 113 4.3.2. Example: Hello World using Python ................................................................................ 116 4.3.3. Example: Cheer for Hello World ...................................................................................... 118 4.3.4. Example: Blinking the Red LED ...................................................................................... 119 4.3.5. Example: Reading the User Button ................................................................................ 120 4.3.6. Accessing Additional GPIO Pins ...................................................................................... 120 4.3.7. Killing a Running Python Program .................................................................................. 121 4.4. WWAN LED Class ..................................................................................................................... 122 4.4.1. Python Functions and Classes ....................................................................................... 122 4.4.2. Example: Using WWAN LED Class .................................................................................. 124 4.4.3. Importing & Using the WWAN LED Class ....................................................................... 125 AT&T IoT Starter Kit (2nd Generation) User's Guide - Preface Page 4 Table of Contents 4.4.4. WWAN Class Subprocessing ........................................................................................... 125 4.5. GPIO Interrupts in Python ........................................................................................................ 126 4.5.1. Fancier Button Interrupt Example .................................................................................. 127 5. 4.6. Running Python Scripts at Boot .............................................................................................. 129 4.7. Additional References ............................................................................................................. 130 Wireless Wide Area Networking with LTE ................................................................................... 131 5.1. Modem Abstraction Layer (MAL) ............................................................................................ 133 5.1.1. Connecting to the MAL Using the LTE API ...................................................................... 133 5.1.2. Using WWAN API to Get Network Time........................................................................... 138 5.1.3. Python MAL Example ...................................................................................................... 140 5.2. Communicating over HTTP/HTTPS ......................................................................................... 146 5.2.1. cURL ................................................................................................................................. 146 5.2.2. Hookbin.com ................................................................................................................... 147 5.2.3. Hookbin.com Examples .................................................................................................. 148 5.3. Connecting to the Cloud: M2X and Flow ................................................................................ 157 5.3.1. M2X QuickStart Demo .................................................................................................... 158 5.3.2. Using M2X ........................................................................................................................ 164 5.3.3. Flow .................................................................................................................................. 177 5.4. Sending SMS Messages .......................................................................................................... 195 5.4.1. Twilio ................................................................................................................................ 195 5.4.2. IFTTT ................................................................................................................................. 198 Appendix ............................................................................................................................................. 200 Topics..................................................................................................................................................... 200 A1. Glossary .......................................................................................................................................... 201 A2. What is, and how do you configure, the APN? .............................................................................. 203 What is “APN”? ................................................................................................................................. 203 Starter Kit APN value ........................................................................................................................ 203 Prerequisites ..................................................................................................................................... 203 View APN ........................................................................................................................................... 203 Modify APN ........................................................................................................................................ 205 A3. General Purpose Bit I/O (GPIO) ..................................................................................................... 207 What is GPIO? ................................................................................................................................... 207 SK2 GPIO Pins for LEDs and Pushbuttons ...................................................................................... 208 GPIO Pin Numbers – WNC vs Qualcomm ........................................................................................ 209 Linux GPIO Drivers ............................................................................................................................ 210 Deallocating GPIO Resources .......................................................................................................... 214 A4. More Details about the Linux Boot Sequence .............................................................................. 217 Getting to custapp-postinit.sh .......................................................................................................... 217 A5. Troubleshooting “adb devices” ...................................................................................................... 220 A5.1 Cannot find ADB command ..................................................................................................... 221 A5.2 Execute From ADB Directory ................................................................................................... 221 A5.3 WNC_ADB unauthorized .......................................................................................................... 223 AT&T IoT Starter Kit (2nd Generation) User's Guide - Preface Page 5 Table of Code Listings Table of Code Listings Listing 2.1: Chapter_02/list.sh................................................................................................................... 44 Listing 2.2 Chapter_02/list_dev.sh............................................................................................................ 44 Listing 2.3: Chapter_02/list_pipe_cat.sh .................................................................................................. 44 Listing 2.4: Turn Off the LED....................................................................................................................... 56 Listing 2.5: Turn On the LED ....................................................................................................................... 56 Listing 2.6: Chapter_02/blink.sh ............................................................................................................... 57 Listing 2.7: Appendix/GPIO/TurnOnRedLed.sh ......................................................................................... 57 Listing 2.8: Appendix/GPIO/TurnOffRedLed.sh ......................................................................................... 57 Listing 2.9: custapp-postinit.sh .................................................................................................................. 58 Listing 2.10: run_demo.sh .......................................................................................................................... 58 Listing 3.1: Chapter_03/hello/src/main.c ................................................................................................ 72 Listing 3.2: sample .gitignore ..................................................................................................................... 75 Listing 3.3: Blinking Red LED with File I/O (Chapter_03/fileio_red_led) ................................................. 77 Listing 3.4: Chapter_03/api_led_red_with_deinit/src/main.c................................................................. 80 Listing 3.5: Chapter_03/sigint/src/main.c................................................................................................ 88 Listing 3.6: Chapter_03/sigint2/src/main.c ............................................................................................. 89 Listing 3.7: Chapter_03/sigint2_with_pause/src/main.c ........................................................................ 90 Listing 3.8: sk2_users_guide/Chapter_03/sigaction/src/main.c ........................................................... 92 Listing 3.9: sk2_users_guide/src/api_button_interrupt .......................................................................... 93 Listing 3.10: sk2_users_guide/myGpio/src/main.c ................................................................................. 94 Listing 3.11: sk2_users_guide/myGpio/src/myGpio.c ............................................................................. 95 Listing 3.12: sk2_users_guide/myGpio/src/myGpio.h ............................................................................. 97 Listing 4.1: Chapter_04/hello_cheer.py ..................................................................................................118 Listing 4.2: Chapter_04/red_led_blink.py ...............................................................................................119 Listing 4.3 - Chapter_04/button_read.py ................................................................................................120 Listing 4.4: endless.py ..............................................................................................................................121 Listing 4.5: Chapter_04/wwan_class.py..................................................................................................124 Listing 4.6: Chapter_04/wwan_blink.py ..................................................................................................125 Listing 4.7: Chapter_04/button_interrupt.py ..........................................................................................126 Listing 4.8: Chapter_04/button_interrupt_fancy.py ...............................................................................128 AT&T IoT Starter Kit (2nd Generation) User's Guide - Preface Page 6 Table of Code Listings Listing 5.1: ex_01_mal_api_example.py (Python) ...................................................................................134 Listing 5.2: c_01_mal_api_example (C/C++) ..........................................................................................136 Listing 5.3: ex_02_get_network_time.py .................................................................................................138 Listing 5.4: c_02_get_network_time/src/mal.hpp .................................................................................139 Listing 5.5: c_02_get_network_time/src/mal.cpp ..................................................................................139 Listing 5.6: c_02_get_network_time/src/main.cpp................................................................................140 Listing 5.7: ex_03_get_system_info.py ....................................................................................................141 Listing 5.8: Chapter_05\c_03_system_info\src\main.cpp ....................................................................143 Listing 5.9: Chapter_05\c_03_system_info\src\wwan_status.hpp ......................................................144 Listing 5.10: Chapter_05\c_03_system_info\src\wwan_status.cpp ....................................................145 Listing 5.11: Chapter_05\sh_04_curl_to_hookbin.sh............................................................................148 Listing 5.12: ex_04_http_to_hookbin.py .................................................................................................150 Listing 5.13: c_04_http_to_hookbin/src/main.cpp ................................................................................152 Listing 5.14: c_04_http_to_hookbin/src/my_curl_post.cpp ..................................................................153 Listing 5.15: Chapter_05/c_05_http_put_post_get/src/main.cpp .......................................................155 Listing 5.16: sh_06_m2x_example.sh .....................................................................................................168 Listing 5.17: ex_08_m2x_print_values.sh ...............................................................................................170 Listing 5.18: Chapter_05/c_07_m2x_create_device_stream_value/src/main.cpp (lines 120-173) .172 Listing 5.19: Chapter_05/c_07_m2x_create_device_stream_value/src/main.cpp (lines 176-210) .173 Listing 5.20: Chapter_05/c_07_m2x_create_device_stream_value/src/main.cpp (lines 212-248) .174 Listing 5.21: Chapter_05/c_07_m2x_create_device_stream_value/src/main.cpp (lines 251-269) .175 Listing 5.22: ex_09_timestamp_debug_flow.json ..................................................................................184 Listing 5.23: ex_10_curl_to_flow.sh ........................................................................................................190 Listing 5.24: ex_10_http_to_flow.py ........................................................................................................191 Listing 5.25: c_10_http_to_flow/src/main.cpp ......................................................................................193 Listing 5.26: Chapter_05/ex_11_send_twilio_sms.py ...........................................................................197 AT&T IoT Starter Kit (2nd Generation) User's Guide - Preface Page 7 License for Code Examples License for Code Examples Copyright © 2019 AT&T Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. AT&T IoT Starter Kit (2nd Generation) User's Guide - Preface Page 8 Preface Preface Work in Progress As of January 2019, this User’s Guide is a work in progress. It currently includes the first five chapters. With the final three planned for 1Q2019. The next section highlights the chapters that are available, as well as the additional chapters planned for development What this Book Covers The 2nd generation IoT Starter Kit (SK2) development module runs a version of Linux and can be programmed with either the C language or with Python. It has quite a few peripherals that allow users to connect to various sensors and systems. What makes it an Internet of Things (IoT) module is its ability to connect to the world via an on-board LTE radio. These various capabilities and services are discussed in the following chapters. Chapter 1 - Getting Started The first chapter is all about getting started with the SK2. After a brief introduction to the kit itself, you’ll begin by registering your kit’s SIM card and then working through the QuickStart application that comes programmed into the SK2. Chapter 2 - Using Embedded Linux The SK2 runs a tiny distribution of Linux. If you’ve used Linux before then you already know most of what’s in this chapter. Along with showing you how to connect your personal computer to the kit, this chapter provide a quick primer for running Linux on the SK2. Chapter 3 - Programming with C The SK2 can be programmed using the C programming language. In essence, you can write a C Linux application to control the SK2 module. The SK2 is supported by two C callable libraries which let you access the on-board peripherals as well as the LTE communications. This chapter takes you through installing the C programming environment and writing your first C program. Once complete, you should be able to control the on-board LED and read the User Switch by programming the pins attached to those controls via the GPIO (General Purpose bit Input/Output) API (applications programming interface). Chapter 4 - Programming with Python The fourth chapter accomplishes the same goals as Chapter 3 but using Python. Therefore, in this chapter we will learn how to install a new Python-based image to the SK2 as well as use it to read the User Switch and toggle the LED. AT&T IoT Starter Kit (2nd Generation) User's Guide - Preface Page 9 Preface Chapter 5 - Connecting to the Cloud with LTE One of the unique capabilities of the SK2 is its ability to communicate over the AT&T LTE wireless network. This allows untethered, mobile access to the Internet. In this chapter you will learn how to connect to the Cloud to send and receive data. This chapter leverages cURL and the connectivity libraries to support both programming languages (Python and C). Note: As described earlier, the following chapters are currently in development Chapter 6 - Using the ADC with the Light Sensor The ADC (analogue to digital converter) is a useful peripheral interface found on the SK2’s Linux processor. This port converts real-world analog signals (i.e. voltages) into digital values (i.e. numbers) that we can use to observe our environment. In this case, the on-board light sensor is connected to our Linux processor through the ADC peripheral interface. As the light landing on the sensor gets brighter or dimmer, the light sensor outputs a greater or lesser voltage. Our Linux programs (either using C or Python) can read a numerical representation of the voltage via the ADC port. Chapter 7 - Using I2C with the Accelerometer I²C (pronounced I-squared-C) is a common serial communications port widely used on microcontrollers and processors. Alternatively, it’s also called an I2C port, as this is easier to write in simple text files. This serial port is widely used for communicating with lower-speed peripherals across short distances within a board. One of the main differences from other types of serial ports (SPI or UART) is that I2C ports support a simple addressing mechanism which allows them to connect multiple devices together across a single port. Conveniently, the SK2 contains an on-board sensor (the accelerometer) which is connected to our Linux processor by way of the I2C port. This makes it makes it easy to experiment with the I2C port as we learn about how it works. Chapter 8 - Getting the Location Using GPS GPS (global positioning system) is another popular sensor built into the SK2. In fact, this one is notable in that the GPS antenna is one of the three wires that need to be connected when first assembling the kit. If you have a phone, or a GPS unit in your car, then you already know that GPS systems provide location data by reading signals sent by orbiting satellites. We won’t get too deep into how GPS works but we’ll examine how your programs can retrieve location data from the GPS sensor to use locally or pass along to the Cloud for further processing or tracking. AT&T IoT Starter Kit (2nd Generation) User's Guide - Preface Page 10 Downloads, Support and Tools Downloads, Support and Tools Downloads Visit the following site to download the code for this User Guide: • https://github.com/att-iotstarterkits Support Please visit the the AT&T IoT Starter Kit Knowledge Base for support related to this book and/or your kit. https://att-iotservices.groovehq.com/help_center Tools Needed for Code Examples Hardware • Windows, Mac, or Ubuntu computer with an available USB 2.0/3.0 port. − Ubuntu Linux computer is required if you want to compile C/C++ code to run on the SK2. A virtual Linux computer – for example, using VMware – will allow you to build C/C++ programs if you do not have a Linux computer. (See note at the beginning of Chapter 3.) − • Windows or Mac computers will work fine if you are only planning on to connect to the SK2 to view files or execute pre-built examples. These operating systems also work well if you’re only planning to write Python code. AT&T IoT Starter Kit (2nd Generation) Software The following list summarizes the software required for building and running code on the SK2. • Chapter 2: Android Debug Bridge (ADB) is required to talk to the SK2 from your computer. Installation instructions are included in Chapter 2. • Chapter 3: The Avnet/WNC SDK must be installed to build C/C++ programs. Additionally, the M18QxIotMonitor program must be installed if you want to rebuild the QuickStart demo. Chapter 3 shows how to install both – along with instructors for their use. • Chapter 4: Python firmware image is required for Python coding in Chapter 4 (and later chapters): • All Chapters: Command line (i.e. shell) is needed to execute ADB commands and run scripts. Linux (BASH shell) and Mac (Terminal) command-line tools work fine. Some Windows users have experienced problems with their standard command-line tools and may want to install an improved command-line tool, such as: • WSL (Windows Subsystem for Linux) https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux • CMDER (http://cmder.net/) Note: The author used the standard command-line utilities for each platform in Chapter 1, then switched to CMDER (on Windows) for subsequent chapters. AT&T IoT Starter Kit (2nd Generation) User's Guide - Preface Page 11 Related Documentation Related Documentation Product Brief • AT&T IoT Starter Kit 2nd Generation Product Brief (PDF) • SK2 AT&T IoT Starter Kit Overview Slides (PDF) Hardware Documentation • SK2 Hardware User Guide (PDF) • SK2 SOM Schematic (PDF) • AES-M18QX LTE SOM Schematic Symbol (Orcad) (ZIP) • SK2 LTE SOM Bill of Materials (PDF) Software Guides • SK2 Quick Start Card (PDF) • IoT Starter Kit (2nd Generation) Quick Start Guide (PDF) • Avnet M18Qx LTE IoT API Guide (DOCX) • Avnet M18Qx Perpherial IoT Guide (DOCX) • Python M18Qx LTE IoT API Guide (PDF) • Python M18Qx Peripheral IoT API Guide (PDF) Software / Repositories Note that installation & usage instructions are provided in their associated chapters of this user guide. • Avnet WNC SDK: This repository contains the software development kit (SDK) libraries and documentation for use with the the IoT Starter Kit (2nd generation) (also known as ‘SK2’). https://github.com/Avnet/AvnetWNCSDK • Avnet IoT Monitor Example: The monitor source code for the (SK2). This is the source code for the Out-of-Box program that is loaded on the SK2 board when delivered from the factory. https://github.com/Avnet/M18QxIotMonitor • AT&T IoT Starter Kit (2nd Generation) Python Firmware Image https://s3-us-west-1.amazonaws.com/td-marketplace-assets/SDK01/M18Q2_v12.09.182151_APSS_OE_v01.07.183121.zip Warning: Do not install the Python firmware without reading the instructions in Chapter 4. • AT&T GitHub Repository https://github.com/att-iotstarterkits AT&T IoT Starter Kit (2nd Generation) User's Guide - Preface Page 12 AT&T IoT Starter Kit (2nd Generation) Videos • Device Fundamental Tutorial 1: Install the SDK, ADB plus other Tools (MP4) • Device Fundamental Tutorial 2: Install and Build the IoT_Monitor Reference Design (MP4) • Device Fundamental Tutorial 3: Running IoT_Monitor and Other Applications (MP4) • Device Fundamental Tutorial 4: Exploring the IoT_Monitor Application Source Code (MP4) Certifications Please refer to Avnet’s Cloud Connect Kits page and scroll to review and download the certification documents. http://cloudconnectkits.org/product/lte-starter-kit-2 Document Locations AT&T Marketplace • https://marketplace.att.com/products/att-iot-starter-kit-2nd-gen • https://marketplace.att.com/quickstart#starterkit-2nd-gen Avnet Cloud Connect Kits • http://cloudconnectkits.org/product/lte-starter-kit-2 • http://cloudconnectkits.org/product/global-lte-starter-kit AT&T IoT Starter Kit (2nd Generation) User's Guide - Preface Page 13 Page left intentionally blank. AT&T IoT Starter Kit (2nd Generation) User's Guide - Preface Page 14 1. Getting Started The chapter introduces IoT (Internet of Things) and the AT&T IoT Starter Kit (2nd Generation) – nicknamed the “SK2” – and then quickly gets you playing with the QuickStart demonstration program that comes pre-programmed into the kit. After a brief review of IoT and the kit’s hardware, you will need to register the SIM (Subscriber Identity Module) card that comes with the SK2 so that your kit can be recognized by AT&T’s LTE cellular network. Once registered, we’ll take you through assembling your kit and kicking off the QuickStart demo, by pushing the board’s User Button, whereupon the on-board LEDs indicate the various stages of the demo’s execution. Finally, we’ll introduce the support and development resources available for the SK2. Topics 1. Getting Started .............................................................................................................................. 15 1.1. What is IoT? ................................................................................................................................ 16 1.1.1. How Does IoT Work? ......................................................................................................... 17 1.1.2. The Case for Cellular IoT ................................................................................................... 18 1.1.3. The SK2: IoT Everywhere .................................................................................................. 18 1.2. IoT Starter Kit (SK2) ................................................................................................................... 19 1.2.1. What Comes In the Box..................................................................................................... 20 1.2.2. Hardware Overview ........................................................................................................... 21 1.2.3. Software Overview............................................................................................................. 24 1.2.4. Cloud Connectivity ............................................................................................................. 25 1.2.5. Description of QuickStart Demo ....................................................................................... 25 1.3. Running the QuickStart Demo .................................................................................................. 26 1.4. Resources .................................................................................................................................. 32 1.4.1. AT&T Resources ................................................................................................................ 32 1.4.2. Register with cloudconnectkits.org .................................................................................. 32 AT&T IoT Starter Kit (2nd Generation) User's Guide - Getting Started pg. 15 What is IoT? 1.1. What is IoT? Who hasn’t heard of IoT (Internet of Things) these days? Well, maybe my mother doesn’t realize that her thermostat, which can be controlled by her iPhone, is an IoT device. But engineers, programmers and makers are all trying to figure out how to leverage the Internet to make their projects more exciting and useful. There are just too many applications where IoT might be useful to cover them all, but here are three examples where you might see it in your daily life: 1. Tracking buses, trains and other transportation: While it’s handy to inform riders when to expect the next bus, it also provides useful data for managing operations and expenses. Figure 1.1 2. Parking: Becoming more popular at airports and cities, tracking empty parking spaces allows cloud and mobile apps to direct citizens and clients to available spaces. Once again, though, the aggregate data from these operations also help communities and business better plan for, and utilize, their infrastructure. Figure 1.2 3. Asset Tracking: This is the most widely used application for IoT today. Keeping track of trucks, containers, pallets - or just about anything - is an essential requirement for our just-in-time world. Figure 1.3 AT&T IoT Starter Kit (2nd Generation) User's Guide - Getting Started pg. 16 What is IoT? 1.1.1. How Does IoT Work? In each of above use cases, the device (i.e. “thing”) is capturing data (location, temperature, etc.) and sending it to the cloud (i.e. “Internet”). Figure 1.4 – How Does IoT Work? Breaking it down, we can describe IoT in four parts: 1. IoT Device: The device captures sensor data and sends it to the Internet. For decades we have built devices that can read sensors, but only in the past few years have we begun to add the hardware which allows them to talk to networks and the cloud. 2. Connection: There are several methods for sending data to the Cloud. For example, until recently, WiFi is a popular method for many home or business applications. But a growing number of applications require connectivity over longer distances and with fewer configuration headaches. Cellular connections, as provided in the SK2, makes IoT easier and cheaper for most use cases. 3. Cloud: That is, the “Internet”, receives and processes the data sent from the device. 4. Action: While it’s true that the Action is generally handled by the Cloud, we’re explicitly noting it because this represents the reason for using IoT in the first place. Why capture and send data to the Cloud if you don’t need to trigger alarms, notifications, or analyze the data in the first place? AT&T IoT Starter Kit (2nd Generation) User's Guide - Getting Started pg. 17 What is IoT? 1.1.2. The Case for Cellular IoT As stated in the previous section, WiFi has been a popular ingredient for early IoT projects, but it runs into several roadblocks for a growing list of applications. In our earlier examples, WiFi might only be able to send data from truck or container residing in a terminal, but not while in transit. Similarly, trying to provide WiFi across an entire city, or even just a parking garage, is difficult and expensive. Finally, WiFi configuration is tedious and difficult. Many early IoT adopters have struggled with the cost of setting up and maintaining WiFi configuration. It’s not hard to imagine the value of outfitting every vending machine with an IoT device. Just think of how useful that data might be in managing a vending operation. Then consider how much time you would need to pay your technicians to configure the WiFi settings for each vending machine. Even worse, how about paying them to do this again each time the building or business hosting the machines updates their WiFi passwords? 1.1.3. The SK2: IoT Everywhere With the AT&T IoT Starter Kit (2nd Generation), developers get the power of AT&Ts LTE network in a small, easy-to-develop module. A one-time configuration with the AT&T certified SIM (subscriber identity module) will ensure your device stays secure and ready to connect anywhere. Figure 1.5 This is where the AT&T IoT Starter Kits fit into the picture. They give developers access to low-cost, fully certified, small footprint modules that can be used to build LTE connected IoT devices. Use them to host your embedded applications, or to just provide the LTE connectivity to an embedded system you have already developed. Either way, these kits make LTE a reality for IoT applications. AT&T IoT Starter Kit (2nd Generation) User's Guide - Getting Started pg. 18 IoT Starter Kit (SK2) 1.2. IoT Starter Kit (SK2) Figure 1.6 AT&T IoT Starter Kit (2nd Generation) - also known as “SK2” - provides an innovative new System-onModule IoT solution, enabling the design of cellular connected edge devices, certified for operation in the United States. (An alternative version of the kit “Global LTE IoT Starter Kit” is also available from Avnet to support markets outside of the United States.) Designed to be used for both prototyping and production, the slim form-factor LTE SK2 board is fully compliant with FCC, PTCRB, and AT&T network certifications, thereby reducing development risk and speeding IoT deployments. AT&T IoT Starter Kit (2nd Generation) User's Guide - Getting Started pg. 19 IoT Starter Kit (SK2) 1.2.1. What Comes In the Box Figure 1.7 1. LTE IoT SOM - LTE System Board (p/n: AES-ATT-M18Q2FG-M1-G). 2. LTE Primary + GPS Antennas - Pulse FPC LTE combo antenna. 3. LTE Secondary Antenna - Pulse FPC LTE antenna. 4. AT&T IoT Starter SIM Card - 3FF Micro-SIM card. 5. AC/DC Power Supply - AC/DC power supply (5V @ 2.5A) plus country/region outlet adapter. 6. USB Cable - for programming and debug. AT&T IoT Starter Kit (2nd Generation) User's Guide - Getting Started pg. 20 IoT Starter Kit (SK2) 1.2.2. Hardware Overview The Starter Kit features a small (79.5 mm x 30 mm) development board built around Wistron NeWeb Corporation (WNC) M18Q2FG-1 LTE Cat-4 modem module. The M18Q2FG-1 module provides cellular modem functionality plus user application code support via a dedicated Arm® Cortex™-A7 processor, thus eliminating the need for an external host processor. The following discussion briefly introduces the top and bottom of the board. For additional technical details regarding the kit’s hardware, please refer to Avnet’s SK2 Hardware User Guide (PDF). 1.2.2.1. Top Figure 1.8 – Top of SK2 Module The WNC modem/processor module sits on the left side of the board; this includes the Linux processor that will be programmed in later chapters. Starting at the left side of Figure 1.8, other features include: • ADC Input Select: The ADC (analog to digital convertor) jumper lets you select how the ADC pins from the WNC module are connected within the SK2 board: either to the light sensor or the 60-pin jumper. • Antenna Mounts (x3): Three antenna connections are found on the left side of the module. This support both the LTE radio (which requires two antennas) as well as the GPS sensor. • Three Push Button Switches: There are three push-button switches on the board. − Reset: Initiate a reset by pressing and holding the button for greater than 3 seconds. − User: The USER BUTTON can be accessed by user programs. Programming this button via GPIO (general purpose input/output) is discussed in Chapters 3 and 4. − Boot: Forces USB boot for reprogramming the firmware. (This is an advanced function that is not covered in this book.) • Light Sensor: The ADC (analog to digital convertor) in the WNC module measures the amount of light hitting this sensor. • RGB LED: The User RGB (red, green, blue) LED can also be controlled via user software (also discussed in Chapters 3 and 4). AT&T IoT Starter Kit (2nd Generation) User's Guide - Getting Started pg. 21 IoT Starter Kit (SK2) • WWAN LED: The WWAN (wireless wide-area network) LED is controlled by the LTE modem and provides status regarding the cellular connection. This can also be user programmed using SYSFS, which is discussed in Chapters 2-4. • PMOD connector: This allows you to attach PMOD peripheral boards, making it easy attach sensors or other resources to your kit. There are a wide number of PMOD capable modules that can be purchased separately. (Digilent provides a handy PMOD reference.) • Power LED: This LED illuminates green when the circuit is correctly powered. It is not user programmable. • Debug UART: This port is dedicated for system debug output (i.e. Linux kernel debug log output) and is currently not programmable. • Two Micro USB connectors: − DC Power Supply: USB connector requires 5V 2.5A DC power. (The kit includes the correct AC/DC power adaptor). − Host USB: The “Host Interface” USB connector can be connected to your computer, allowing you to modify and control the module via the ADB (Android Debug Bus) protocol. (This is discussed Chapter 2.) 1.2.2.2. Bottom Figure 1.9 – Bottom of SK2 module Starting from the left and working around the board: • • • • • 3FF Micro SIM Card Cage: Holds the micro SIM (Subscriber Identification Module) card that comes with the kit. Once registered, the SIM allows communication through AT&T’s IoT cellular network. (See the SIM registration steps later in this chapter.) 3.8V Current Measurement Testpoint: Can be used to test the output of the on-board voltage converter. After applying an unregulated 5V supply thru, say, the micro-USB power connector, the on-board converter adapts and regulates the power supply to the board. With a small hardware modification, this unpopulated header can be used to measure the current flowing through this regulated supply. 1.8V to 3.3V Level Shifter: Handles the voltage differences between the modem processor module pins and the sensor and expansion devices. 3D Accelerometer & Temperature Sensor: Provides movement and temperature data to the system. (These will be discussed later during the I2C chapter.) 60-pin I/O Expansion connector: Provides access to many of the processor’s pins and ports. Use this to add your own hardware to the SK2 system. Alternatively, you can attach the AT&T IoT Starter Kit (2nd Generation) User's Guide - Getting Started pg. 22 IoT Starter Kit (SK2) Avnet’s LTE IoT Breakout Carrier as shown below. The breakout makes it easier to access the expansion pins - or allows easy connection of Click modules (as shown below). Figure 1.10 Avnet’s LTE IoT Breakout Carrier 1.2.2.3. Block Diagram Figure 1.11 Please refer to the SK2 Hardware User’s Guide for further details and explanation regarding this board. AT&T IoT Starter Kit (2nd Generation) User's Guide - Getting Started pg. 23 IoT Starter Kit (SK2) 1.2.3. Software Overview The SK2 uses the WNC M18Q2FG-1 module, whose ARM Cortex-A7 processor is pre-loaded with an OpenEmbedded version of Linux. User application code (scripts, C language, and Python) can run within this Linux environment. You can program the Linux processor using one or more of three different languages: 1. Linux shell scripts: Useful for simple demos and examples. 2. Python: The optional AT&T Python environment lets you access the hardware using the popular scripting language. The Python environment is covered in Chapter 4. 3. C/C++: You build C applications that run within the Linux environment. In fact, the QuickStart demo - which comes pre-loaded on the SK2 - was written using C/C++. Chapter 3 describes how to setup the tools and build C/C++ programs. The M18Q2FG-1 Software Development Kit (SDK) provides APIs that simplify access to system resources when programming with C/C++. The SDK consists of two main APIs (Application Programming Interfaces): • Cellular Network Control API: Provides access to the communications services over the LTE cellular radio. This is described in the Avnet M18Qx LTE IoT API Guide and Python M18Qx LTE IoT API Guide. • Hardware Related Control API: Provides access to the peripheral ports and pins on the M18Q2FG1 processor module. In other words, using this API you can access the ports, as well as the sensors that are connected to these ports (e.g. temperature, accelerometer). This is documented in the Avnet M18Qx Peripheral IoT API Guide and Python M18Qx Peripheral IoT API Guide. The Python firmware image for the SK2 includes these API by porting them into Python callable functions. Coding with Python is discussed in Chapter 4. (Please refer to the Python versions of the two API guides for specific details.) AT&T IoT Starter Kit (2nd Generation) User's Guide - Getting Started pg. 24 IoT Starter Kit (SK2) 1.2.4. Cloud Connectivity AT&T services facilitate Cloud based application development and deployment: • M2X - a cloud-based, fully managed IoT device management and time-series data storage service for network connected devices. • Flow Designer - a visual IoT application development and data orchestration environment, with run-time support for complex nonstandard protocol translation, data processing and integrations, to help developers create IoT applications fast. The SK2’s QuickStart demo (i.e. IoT Monitor program) utilizes these services and provides an example for how to get started with them. 1.2.5. Description of QuickStart Demo When the IoT Starter Kit (2nd Generation) is initially powered-on, a basic user interface will allow you to perform complete Transmit/Receive operations. This initial program will post readings from the sensors located on the IoT Starter Kit module to a pre-configured AT&T Dashboard each time you push the “User” button. You can see this operation progress by following the LED sequence on the board. Sensor data from the module includes: • Motion sensor data provides 3-axis accelerometer data indicating board position • Temperature sensor • Ambient light sensor Note that GPS location data is not enabled in the startup application. The demonstration runs the “IoT Monitor” application. The code for this can be found on Avnet’s GitHub site: https://github.com/Avnet/M18QxIotMonitor As this software is pre-loaded onto the module at production, there is no need for you to download or modify it before running the QuickStart out-of-box demo. You can find further explanation, and directions, for this demo in the next section. (Instructions for running the demo can be found in the next section.) This initial program, called “IoT Monitor”, will post readings from the SK2 sensors to the cloud. Linux has been configured to run it automatically upon powering up the SK2. In other words. the QuickStart demo is implemented as a C/C++ program called iot_monitor. Further examination of the QuickStart demo includes: • Chapter 1 (this chapter) examines the QuickStart demo from a user perspective; that is, “how do I run the demo?” • Chapter 2 describes how the iot_monitor runs automatically by Linux when the SK2 boots up – and how you can stop it from running automatically, if you want. • Chapter 3 examines the demo’s the source code (i.e. the C/C++ iot_monitor program). It includes instructions for downloading and rebuilding it, after you have installed the Linux C/C++ tools. • Chapter 5 explores the ‘cloud’ side of the QuickStart demo by examining the AT&T’s M2X service. This includes a description for creating – and then sending – the QuickStart demo’s data to your own M2X account. AT&T IoT Starter Kit (2nd Generation) User's Guide - Getting Started pg. 25 Running the QuickStart Demo 1.3. Running the QuickStart Demo 1.3.1.1. Register the AT&T SIM Card Before we get started with the QuickStart demo, we need to register your kit and its SIM card with the AT&T Marketplace. This provisioning will allow AT&T’s network to recognize your kit. 1. Log onto AT&T’s IoT Marketplace: https://marketplace.att.com You have choice of login methods - either using an account that you have previously setup, an AT&T Developer account, or a GitHub account. If you would like to create a new account, click the “Create an account” link near the bottom of the screen. 2. After you are logged in, navigate to the Register SIMs screen by clicking: Management > Register SIMs 3. Enter the SIM ICCID number located on the SIM card carrier (and the SIM card itself). Then click the “Register SIMs” button. We recommend giving it a nickname, just in case you end up with more than one kit or SIM card and want to tell them apart. 4. View data about your SIM in the “Dashboard”. If you are not taken to the Dashboard, click the “Dashboard” button and you should see your SIM card listed. Click the + button next to your SIM card to view more data about your SIM card. AT&T IoT Starter Kit (2nd Generation) User's Guide - Getting Started pg. 26 Running the QuickStart Demo 1.3.1.2. Assembling the SK2 To assemble IoT Starter Kit (2nd Generation) components, there are just a few connection steps required to connect the three main items needed for basic operation. • Antenna • SIM card • Power adapter cable Directions to assemble the kit include: 1. Connect the antennas. The flexible antenna arrays should be gently connected to the module antenna terminals as shown by matching each of the labeled antenna cables to the corresponding connector: Figure 1.13 2. Install the SIM into the SK2 holder. Carefully pop the AT&T micro-SIM card out from its carrier and install it into SIM card holder: Note: Note that you must register the SIM card before it will be recognized by the AT&T network. (These instructions were provided in Section 1.3.1.1.) Figure 1.15 3. Connect the micro-USB power cable. The included power adapter cable should be connected to the micro-USB connector labeled “PWR IN” and the wall adapter plugged into an AC power outlet. This will power on the module: AT&T IoT Starter Kit (2nd Generation) User's Guide - Getting Started Figure 1.16 pg. 27 Running the QuickStart Demo 1.3.1.3. Running the QuickStart Demo As stated earlier, the QuickStart demo comes pre-programmed into your kit and should run automatically after power-up. Note: The next chapter (Chapter 2 – Embedded Linux) will show how to stop this program from running automatically – or how to set your own program or script to run at power-on. 4. Confirm successful power up. When power is provided to the IoT module it automatically begins basic operations. The presence of power is indicated by the Power-On LED (LED1) illumination: Hint: If the power is already on, power-cycle the board by disconnecting and then reconnecting the USB power supply cable. Figure 1.17 5. Confirm network connectivity. After the module is powered on, the Network Service LED (LED2) will begin flashing. This indicates that the module is attempting to register with the AT&T network and establish a connection. Once connected to the AT&T network, the yellow (WWAN) Network Service LED will quit flashing and become steady. Note: If the Network Service LED does not become steady (i.e. it keeps flashing), then it’s possible that the APN has been incorrectly configured for your kit. Please refer to the Appendix for more information about the APN setting and how to configure it. AT&T IoT Starter Kit (2nd Generation) User's Guide - Getting Started pg. 28 Running the QuickStart Demo Use the following QuickStart demo description for completing the next step. Quick Start Demo Sequence of Events 1. The QuickStart demo starts up with the Red LED lit, indicating that communication has not yet been established with the AT&T service. It becomes green when the service is ready. 2. While the tri-color LED is GREEN, the user may press the USER button to initiate a data transmission. 3. While the push button is being pressed, the tri-color LED will illuminate white, while the tri-color LED is WHITE no transmission takes place. The WHITE LED only indicates that the module detects that the USER button is being depressed. 4. Once the USER push button is released, the tri-color LED will illuminate BLUE and the sensor data will be collected and sent to AT&T’s IoT Platform (i.e. the AT&T M2X service). It will stay BLUE until all the data has been sent and acknowledged by M2X. (Note that the Marketplace Dashboard, described later, pulls the information from M2X. M2X will be described in Chapter 5.) 5. After the data transmission has completed, the tri-color LED will go back to GREEN. This process can be repeated, and the Quick Start demonstration application will continue to follow this execution logic as indicated in the following diagram: Figure 1.18 – QuickStart Demo Sequence – Tri-Color LED Chart Stopping the Demo: If the USER push button is depressed for greater than 3 seconds, it signals that the demonstration program should be terminated, and no further operations are performed. At this point to restart the Quick Start demonstration application, you will need to depress the RESET button for longer than 3 seconds (or power-cycle the board) to reset the module. (To permanently stop the demo, please refer to the Linux Boot section in Chapter 2.) AT&T IoT Starter Kit (2nd Generation) User's Guide - Getting Started pg. 29 Running the QuickStart Demo 6. When the Tri-color LED turns Green, push the user button once. After network service is obtained, the module’s demo will connect to the AT&T M2X service. Once established, the tri-color LED becomes GREEN. After network service is established and the module is ready to receive user input, you can press the USER Push Button (SW2) to initiate collecting sensor data from the SK2 and sending it to the M2X service. Each step in the sequence of events kicked off by pressing the USER button can been seen in the Tri-color LED (LED3). Figure 1.19 Hint: The QuickStart demo’s sequence of events are described on the previous page. AT&T IoT Starter Kit (2nd Generation) User's Guide - Getting Started pg. 30 Running the QuickStart Demo 1.3.1.3.1. Sidebar – QuickStart Data Sent to the Cloud The following sensor data is sent to AT&T M2X each time the user presses the USER key: 3-Axis Acceleration Sensor Data: • XVALUE = X data point from the onboard LIS2DW12 sensor chip • YVALUE = Y data point from the onboard LIS2DW12 sensor chip • ZVALUE = Z data point from the onboard LIS2DW12 sensor chip Temperature Sensor Data: • TEMP = Temperature data from the onboard LIS2DW12 sensor Ambient Light Sensor Data: • ADC = Light intensity measurement from the integrated ADC and onboard light sensor The data is stored at the AT&T M2X service and sends an HTTP response allowing the QuickStart demo to return to the green Ready state. AT&T IoT Starter Kit (2nd Generation) User's Guide - Getting Started pg. 31 Resources 1.4. Resources 1.4.1. AT&T Resources AT&T provides several resources, many of them are listed in the preface of this book. Here are four sites to find support from AT&T for the SK2: • https://marketplace.att.com/products/att-iot-starter-kit-2nd-gen • https://marketplace.att.com/quickstart#starterkit-2nd-gen • https://github.com/att-iotstarterkits • https://att-iotservices.groovehq.com/help_center 1.4.2. Register with cloudconnectkits.org Along with AT&T’s information website, you can also find resources at Avnet’s Cloudconnectkits.org. We recommend creating an account at: http://cloudconnectkits.org/ During account creating, you will be able to register your kit. Figure 1.20 AT&T IoT Starter Kit (2nd Generation) User's Guide - Getting Started pg. 32 2. Embedded Linux Most of today’s embedded systems run some form of operating system (OS). The OS provides a broad set of services that simplifies programming the device, making it easier – and faster – to deploy new products. Linux is fast becoming a favorite operating system for embedded devices. Not only does it provide a rich set of services, but it has wide community support and is a favorite among developers. The AT&T IoT Starter Kit (2nd Generation) (i.e. SK2) is based on an OpenEmbedded distribution of Linux. This environment provides the foundational basis for all interaction and development with this kit. If you are already a Linux master, then you’ll have a big head start with your development. If not, we think you will find this OS, and the kit itself, easy to use and fun to program. Using the SK2 is somewhat akin to using a Raspberry Pi in that they are both small, Linux-based, software-programmable kits. While the IoT Starter Kit doesn’t provide quite the wide-range of functionality found in the Raspberry Pi, it does have a built-in LTE cellular modem which gives it wide ranging IoT connectivity. Topics 2. Embedded Linux............................................................................................................................ 33 2.1. Introduction to Linux .................................................................................................................. 34 2.1.1. Kernel Space vs User Space ............................................................................................ 35 2.2. Linux Distribution ....................................................................................................................... 36 2.2.1. Linux Kernel ....................................................................................................................... 36 2.2.2. Filesystem .......................................................................................................................... 37 2.2.3. Boot Loader ....................................................................................................................... 39 2.2.4. Toolchain ........................................................................................................................... 39 2.3. Linux Shell .................................................................................................................................. 40 2.3.1. Basic Linux Commands..................................................................................................... 40 2.3.2. Shell Scripting.................................................................................................................... 43 2.4. ADB – Connecting to the SK2 ................................................................................................... 45 2.4.1. Installing ADB .................................................................................................................... 46 2.4.2. Sidebar - What happens during “adb devices”................................................................ 49 2.4.3. ADB Commands ................................................................................................................ 49 2.5. Controlling Hardware Using the Linux Shell ............................................................................. 56 2.6. Linux Boot Sequence ................................................................................................................. 58 2.6.1. How Does the QuickStart Demo Run Automatically? ...................................................... 58 2.6.2. Configuring Linux Application Bootstrap .......................................................................... 59 AT&T IoT Starter Kit (2nd Generation) User's Guide - Embedded Linux pg. 33 Introduction to Linux 2.1. Introduction to Linux Linux, like all operating systems, provides a set of services to the user. If you have ever used a Linux computer – or another other computer (e.g. Windows, Mac) – you are familiar with many of these user-oriented services. For example, you may have used word processor program to create and edit files, which are stored in the OS’s filesystem. Or, you may have used a web browser, which relies on the networking services provided by the operating system. While many Linux-based “embedded systems” do not generally run big word processor programs, they still rely on the Linux filesystem to manage files – allowing programs to create, edit and delete files as needed. And like most other operating systems, Linux provides a command-line interface that can be used to view files, execute programs or otherwise interrogate the system. While a command-line is rarely used during the execution of an embedded system’s target application (i.e. we don’t use a command-line to run our microwave), it is quite handy when developing and debugging software running user software. While the following diagram is only a generic description, it gives us a summary of the types of services we can expect to find in Linux, such as: memory management, file systems, networking, and device drivers (e.g. serial ports, analog to digital converters). Together, this core group of services is often called the ‘kernel’ of an operating system, hence the name Linux Kernel. Figure 2.1 - Linux Kernel During this chapter we hope to provide a brief introduction to embedded Linux, some details about the Linux distribution provided with the SK2, and how to interact with it. In subsequent chapters, we’ll dig even further, learning how to write programs that run within the SK2’s Linux environment. AT&T IoT Starter Kit (2nd Generation) User's Guide - Embedded Linux pg. 34 Introduction to Linux 2.1.1. Kernel Space vs User Space Digging a little deeper into Linux, we need to delineate between “kernel” space and “user” space. Figure 2.2 User Space vs Kernel Space 2.1.1.1. Kernel Space In the previous section we described the Linux kernel as all the drivers and networking services provided by the OS. This code typically runs with permissions that allow it to directly interact with the hardware. With the SK2, the hardware manufacturer created the Linux kernel for us to work with their hardware. In other words, WNC adapted generic Linux code to work with the CPU, memory and peripherals found on their M18Q2FG-1 modem module. 2.1.1.2. User Space In a similar way, we might describe ‘user’ space as all the programs and code that are isolated from the hardware. These programs access standard driver and socket interfaces that are portable across devices. In fact, if you’ve used an Ubuntu Linux computer before, you might only recognize user space, as this is the area where we interact with Linux to run programs and configure our preferences. In an embedded system, we might think of user space as the area where we create and run software applications. 2.1.1.3. Protecting the Environment Notice how Kernel space comes between User space and the hardware? Linux systems are layered in this fashion to create a secure and stable system. User applications are not allowed to talk directly to hardware, rather, they must call upon the services of the Linux kernel to interact with memory and peripherals. Therefore, when writing programs for Linux, we will need to learn how to interact with the Linux kernel – that is, we will need to learn how to call the functions provided by Linux and WNC that will let us access OS resources, such as the peripherals which talk to the sensors on the SK2, as well as the cellular LTE modem. AT&T IoT Starter Kit (2nd Generation) User's Guide - Embedded Linux pg. 35 Linux Distribution 2.1.1.4. Protecting Users From Each Other One last note, while we are talking about protection and User space. Another advantage to enforcing that all resources are accessed via the kernel is that it helps to protect one user from another. We might redraw our previous diagram to look like this: Figure 2.3 Separation of User Space Linux allows programmers to create application programs which run independently of each other, as shown above. Alternatively, applications can be programmed to run in the same ‘space’ as each other (like on the previous page). While the choice is yours, as a programmer, how to implement your application(s) code, but we can thank the separation of Kernel space for helping to provide us with these options. 2.2. Linux Distribution Linux is delivered as a ‘distribution’. Generally, a distribution includes: • Linux kernel – set of core services (as we discussed earlier) • Filesystem – collection of user space libraries and utilities/applications • Boot loader – an orderly, sequential means for low level hardware configuration and loading the kernel • Toolchain – common collection of compiler, linker, libraries, etc. Our board comes pre-loaded with the Linux distribution. When writing code for the SK2, you will need to download the appropriate toolset – choosing whether you want to write your programs in Python or the C language. (Chapters 3 & 4 will describe each of these toolsets – how to download, install, and build programs with them.) 2.2.1. Linux Kernel We access resources using a combination of common Linux commands (e.g. reading and writing a file or memory) or using a set of device driver libraries provided by WNC (the module vendor). These will be covered in greater detail throughout the rest of this user’s guide. AT&T IoT Starter Kit (2nd Generation) User's Guide - Embedded Linux pg. 36 Linux Distribution 2.2.2. Filesystem The Linux filesystem provides a hierarchical organization for storing and retrieving files. Like most operating systems, the Linux community has defined a common set of directories for storage. As an example, the description below highlights a few key directories found on the SK2 filesystem (found on the right side of the page): Filesystem - Unlike Microsoft Windows, Linux only has a single filesystem. In other words, Linux doesn’t have a filesystem for each drive or entity. Where Windows users might be used to “C” and “D” drives, Linux only has a single filesystem. In Linux, the topmost location – that is, the root of the filesystem – is denoted by “/”. We won’t describe each folder in the SK2 filesystem, but here’s a description for a few of them: CUSTAPP • For ‘your’ application (i.e. customer applications) • It’s the only folder in the filesystem that can be written to; all other folders are read only • Contains the QuickStart demo that runs on powerup; this will be discussed further later in this guide data • This ‘directory’ is just a link to ‘/CUSTAPP’. • Like a shortcut in Windows or Mac /data -> /CUSTAPP dev • Common location for listing Linux device drivers mnt • Common location to mount other file systems • Additional drives, memory cards, or network locations become part of the one filesystem whenever they are added (i.e. “mounted”) to the Linux device. “mnt” is a generic place to place them. media • Rather than using mnt for USB drives and CDROM media, some Linux distributions create a “media” where these items are mounted sdcard • This ‘directory’ is just a link to ‘/media/card’. • Like a shortcut in Windows or Mac /sdcard -> /media/card proc • “/proc” is not a real directory, but rather, it’s a virtual directory and does not hold physical files. Contained within proc are information about processes and other system information. This information is mapped to /proc and mounted at boot time. Here’s a good reference, if you are looking to learn more about the standard Linux Filesystem Hierarchy: https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard Figure 2.4 Filesystem AT&T IoT Starter Kit (2nd Generation) User's Guide - Embedded Linux pg. 37 Linux Distribution 2.2.2.1. Virtual Files, Status Info, and Configuration Extending the concept of the filesystem, Linuxs uses it for more than just text or binary files. Linux also uses the file reading/writing paradigm to write to peripheral device-drivers. For example, you can write to the user-LED on the SK2 by writing to a virtual file, as we will see later in the chapter. In a similar fashion, Linux lets users read status information and/or write configuration preferences through its filesystem. (As discussed earlier in the description of the /proc filesystem directory.) 2.2.2.2. Permissions and Owners The Linux filesystem provides a robust set of file permissions and owners. To access a file, you must have the required permission to read, write, and/or execute it. Here is another view of the SK2 filesystem. This one was generated using the “ls” (small LS) Linux list command with the “-ls” (small LS) option. That is, the specific was: ls -ls File permissions Links to file File Owner File Group Size (bytes) Modification Date File/Directory name Figure 2.5 Filesystem Listing ("ls -ls") Note that if the “File Permissions” begins with a “d” then that line represents a directory. The remaining characters indicate if the “owner”, “group”, and “all users” have permission to read, write, and/or execute. Figure 2.6 - File Permissions Explained In this example, User can read, write and execute; the Group cannot write; and Others cannot execute. AT&T IoT Starter Kit (2nd Generation) User's Guide - Embedded Linux pg. 38 Linux Distribution Here’s a handy reference to learn more about file permissions: https://nitstorm.github.io/blog/understanding-linux-file-permissions The “Linux Commands” section lists several commands useful for listing (e.g. “ls”), reading and modifying the ownership of files, (“chown”) as well as viewing and changing the permissions on files (“chmod”). In fact, the procedures in Section 2.52.4.3.3 will require executing chmod to enable execute permissions. 2.2.3. Boot Loader The SK2 Linux kernel has a pre-defined sequence for getting the module up-and-running. As part of this sequence, you can hook your programs to “auto-execute”. That is, you make your own programs begin running at power-up, just like the Out-of-Box example that ships with the SK2. This will be discussed in further detail during a later part of this Users Guide. 2.2.4. Toolchain The set of tools used to write software programs to run in a specific version of Linux. In later chapters, we will introduce two toolchains for the SK2. One will focus on writing C programs, while the other will utilize Python. AT&T IoT Starter Kit (2nd Generation) User's Guide - Embedded Linux pg. 39 Linux Shell 2.3. Linux Shell The Linux shell – also known as the Linux command-line – provides a textual interface for issuing commands to Linux and then viewing the results. While most operating systems provide this capability, Linux (and Unix) users, seem to rely on it more than users of other operating systems. With Embedded Linux – where limited memory may not be able to support graphical interfaces – the command-line shell becomes even more important. The next section highlights several key commands that can be invoked from the Linux shell. Experienced Linux users will likely know these already. For those new to Linux, we provide a short explanation of each. With a little practice – and some Googling – all users should become comfortable with them. Note: If you are familiar with using the Windows command line, then you should be familiar with the Linux shell. In some cases, both use the same command – for example both use the command “cd” for “changing the active directory”. In other cases, they use different commands (e.g. Windows uses “dir” to list a directory, while Linux uses “ls”). Check out the ComputerHope site, which provides a brief comparison of both DOS and Linux command-line shells. 2.3.1. Basic Linux Commands Linux distributions a common set of programs that can invoke from the Linux shell. For example, if you have ever used Linux – whether Ubuntu or embedded Linux – you will likely have made use of these various command-line programs. From listing the files in a directory (“ls”), to editing files (“vi”), or pinging a network (“ping”). Note: It’s OK if you’re not familiar with the tools we just mentioned. Those, and many more, will be discussed as needed throughout the rest of this user’s guide. In other words, the commands we run from the Linux shell command are just executable applications that reside within the Linux filesystem. To minimize the size of the Linux on the SK2, its distribution packs all of these little command-line utility programs into a single executable called BusyBox. This is a common way for embedded Linux systems to include a large set of tools with a very small memory footprint, albeit with some minor tradeoffs in functionality. AT&T IoT Starter Kit (2nd Generation) User's Guide - Embedded Linux pg. 40 Linux Shell 2.3.1.1. BusyBox Commands The SK2 relies on BusyBox to provide many of the command line utilities that we use every day. busybox Entering the ‘busybox’ at the command line will return the version of BusyBox along with the command-line functions supported with this distribution. Figure 2.7 BusyBox 2.3.1.2. File Management • pwd: print working directory – simply returns the directory where your command line is currently located; good for answering “where am I” in the filesystem? AT&T IoT Starter Kit (2nd Generation) User's Guide - Embedded Linux pg. 41 Linux Shell • ls (small LS): listing – creates a simple listing of the files and subdirectories in the current working directory Make this more useful by adding an option, such as, “ls -ls” or “ls -la”. This will list the files vertically and provide the additional information shown in the graphic in Section 2.2.2.2 • alias: tells the shell to replace one string with another This lets you create a new command from one (or more) other commands; for example: alias ll=’ls -la’ After entering this command, entering ll (small LL) will execute the “ls -la” command for you. • cd: change directory – changes the current working directory to a new location Examples: • • • • • • • • • • • • “cd /CUSTAPP” makes CUSTAPP your current working directory cp: copy – copies a file (or files) from one location to another mv: move – moves a file (or files) from one location to another Note that this is how you rename a file in Linux rm: remove – is how you delete a file or files ln (small LN): link – link files which is like shortcuts in Windows Also popular to create symbolic links, which adds an s option: “ln –s”. chmod: change mode – allows you to change the permissions of files and directories chown: change ownership of files and directories mkdir: make a new directory • • “cd /” sets your command-line session to the root of the filesystem rmdir: remove directory – note that the directory must be empty before it can be deleted mount: mount a filesystem to your root (for example, attaching a USB or network drive) • Generally, you must create a new empty directory – for example, in the /mnt folder – and then mount the new filesystem into the root filesystem • umount: unmount – unmounting a filesystem from the root find: find a file or group of files grep: global regular expression print – search one or more files for lines that match a regular expression pattern tar: tape archive - combine a group of files into the tar archive format with - or without compression; the tar command can also be used to modify, extract and manage tar files AT&T IoT Starter Kit (2nd Generation) User's Guide - Embedded Linux pg. 42 Linux Shell 2.3.1.3. Viewing, Creating and Editing Text Files • touch – Either creates a new empty file with the specified name or updates the files modification timestamp if the file already exists • cat: catenate – reads data from the specified file(s) and outputs the contents to the commandline • vi: visual editor – a small, simple text editor included with most Linux distributions It’s not visual (or anything) like Microsoft Word, but it lets us view and modify text files while taking up very little of our valuable memory 2.3.1.4. Program Control ps: process listing – produces a list of processes running on the Linux system top: produces a listing of processes sorted by % CPU usage kill: tell Linux to kill a process using it PID (process ID) number; a PID can be viewed using the ps or top command -c: stops a process by sending it the SIGINT interrupt signal clear: clears the Linux shell 2.3.2. Shell Scripting As discussed earlier, the command-line shell provides a handy and powerful way to work with Linux, such as managing files or executing programs. Behind the scenes, this shell itself is a Linux program that provides the command-line interface and command interpreter. There are a variety of shell programs found in Linux (and Unix) distributions – the most common being one called Bash. Alternatively, the SK2 comes with a similar, smaller shell program called Ash, which is part of the BusyBox toolset. (In fact, you can see this listed in Figure 2.7 BusyBox.) Shell scripting is nothing more than a sequence of command-line (i.e. shell) calls. These sequences can be a simple grouping of one or two commands or complicated sequences that contain logical control statements. We use the term “scripting”, rather than “programming”, as these sequences do not need to be explicitly compiled before they are executed. When grouped together into a single text file, the “.sh” file extension is used to signify a shell script. Linux doesn’t require that we use the .sh extension, but this is common practice in Linux since this makes it easier for us to identify which files are shell scripts. AT&T IoT Starter Kit (2nd Generation) User's Guide - Embedded Linux pg. 43 Linux Shell Listing 2.1 is an example of a very simple shell script that was used to create Figure 2.5 Filesystem Listing ("ls -ls"): Listing 2.1: Chapter_02/list.sh # list.sh # # list the files in the current directory to the command-line # note that the -ls option creates a vertical listing with more info ls -ls A second example lists the files in the dev directory: Listing 2.2 Chapter_02/list_dev.sh # list_dev.sh # # change to the /dev directory # and then print a listing the command line cd /dev ls -ls Let’s look at one final example: Listing 2.3: Chapter_02/list_pipe_cat.sh # list_pipe_cat.sh # # - This script writes a listing of /dev directory into # a file named "mylisting.txt" in /CUSTAPP # - The ">" pipe symbole tells the shell to pipe the output # from the "ls -ls /dev" command into the txt file rather # than printing it to the standard output # - It then prints out the contents of mylisting.txt # using the Linux "cat" command # ls -ls /dev > /CUSTAPP/mylisting.txt cat /CUSTAPP/mylisting.txt Later, in Section 2.4.3.3 on page 52, we walk you through using shell scripts on your SK2. Note: Linux Line Endings Be careful when creating shell scripts in Windows for use in Linux on your SK2. Windows uses different characters to signify line-endings than Linux. In some cases, the different characters can return unexpected results. A couple of guidelines to help you get better results: – Do not use Windows Notepad to create shell scripts. It does not handle Linux line endings. – Find and use a good Windows text editor. There are many good ones available. A popular, free editor is Notepad++ (https://notepad-plus-plus.org). AT&T IoT Starter Kit (2nd Generation) User's Guide - Embedded Linux pg. 44 ADB – Connecting to the SK2 2.4. ADB – Connecting to the SK2 The SK2 was developed using ADB (Android Debug Bridge) to communicate between your computer and the kit. ADB is a versatile command-line tool that facilitates a variety of device actions, such as pushing and pulling files, as well as providing access to a Unix shell that you can use to run a variety of commands on your device. It is a client-server program that includes three components: 1. ADB Daemon (SK2): Resident on your SK2, running in the background, providing development and debug access to authorized users through the COMmunications USB port. 2. ADB Client (Computer): The client runs on your development machine, letting you send commands. You can invoke a client from a command-line terminal by issuing ADB commands. 3. ADB Server (Computer): The server manages communication between the client and the daemon. The server runs as a background process on your development machine. Once the server has set up connections to all devices, you can use ADB commands to access those devices. Since the ADB daemon is already installed on your SK2, we only need to install ADB onto our development computers. This is addressed in the next section. AT&T IoT Starter Kit (2nd Generation) User's Guide - Embedded Linux pg. 45 ADB – Connecting to the SK2 2.4.1. Installing ADB Since ADB is already installed on your SK2, we only need to install the remaining two components on your development computer; these are both installed with a single installation program. Installing ADB on your Windows, Mac or Linux computer follows a similar set of steps. After downloading and extracting the ADB executables, you will also need to set up an authorization key file to gainaccess to your SK2. 2.4.1.1. Install ADB Executables 1. Download the ADB ZIP file for your computer from the Android developers’ site. There are separate download links for each OS (Windows, Mac, Linux). Pick the one that matches your development computer. https://developer.android.com/studio/releases/platform-tools Hint: If you are using a Debian-based Linux, such as Ubuntu, you can type the following command to download and install ADB (and skip the next step): sudo apt-get install adb 2. Extract the contents of this ZIP file into an easily accessible folder. Some suggestions include: Windows: C:\adb Mac: /Users/MY_USER_NAME/Desktop/adb (replacing MY_USER_NAME with your login id) Linux: /home/MY_USER_NAME/Desktop/adb (replacing MY_USER_NAME with your login id) Note: Linux users can skip this step if ADB was installed with apt-get. AT&T IoT Starter Kit (2nd Generation) User's Guide - Embedded Linux pg. 46 ADB – Connecting to the SK2 2.4.1.2. Set up Credentials (i.e. access key) 3. Create a new folder called “.android” in your user directory. Using your computer’s file browser (or command-line), create the new folder as shown: Windows: C:\Users\MY_USER_NAME\.android (replacing MY_USER_NAME with your login id) (replacing MY_USER_NAME with your login id) Mac: /Users/MY_USER_NAME/.android Linux: /home/MY_USER_NAME/.android (replacing MY_USER_NAME with your login id) 4. Add “adbkey.pub to your new “.android” folder. For the SK2, this is simply a text file named “adbkey.pub” which contains a single word: wnc000000 Hint: This file should contain only this word. It should not contain a carriage return or line-feed. You can create this file yourself or download it from github.com: https://github.com/Avnet/AvnetWNCSDK/blob/master/adbkey.pub If downloading from github, we recommend right-clicking on the “Raw” button and select “Save Link As…” With this step complete, as an example, a Windows user named “doug” should have the following file on their computer: C:\Users\doug\.android\adbkey.pub AT&T IoT Starter Kit (2nd Generation) User's Guide - Embedded Linux pg. 47 ADB – Connecting to the SK2 2.4.1.3. Connect to Your SK2 5. Open a command window in the same directory where you installed the ADB binary. In Windows, this can be done by holding Shift and Right-clicking within the ADB folder, then choosing the “open command prompt here” option. (Some Windows 10 users may see “PowerShell” instead of “command prompt”.) Mac users can open “Terminal” from their Applications folder and navigate to where you installed ADB (in step 2). For example: cd /Users/MY_USER_NAME/Desktop/adb Linux users should open their command-line shell and navigate to where you installed ADB (in step 2). For example: cd /home/MY_USER_NAME/Desktop/adb Note: Linux users who installed ADB via apt-get may run ADB commands from any location. You do not need to navigate to the adb folder in order to run it. 6. Connect your SK2 to your computer with a USB cable. Make sure the USB power cable is also connected. It won’t work without both USB cables being connected. 7. In the Command Prompt window, enter the following command to launch the ADB daemon: adb devices Windows: Mac and PowerShell: (Precede commands with “./”) Ubuntu Linux: ./adb devices sudo adb devices In response, you should see: WNC_ADB device as shown below: Figure 2.8 adb devices You can now run ADB commands (discussed in Section 2.4.3 on page 49) on your device. Note: Refer to Appendix A5 for ADB Troubleshooting Tips. AT&T IoT Starter Kit (2nd Generation) User's Guide - Embedded Linux pg. 48 ADB – Connecting to the SK2 2.4.2. Sidebar - What happens during “adb devices” When you run “adb devices” a few things happen: 1. ADB Server is started. (This was briefly described in Section 2.4 on page 45.) Note that you can explicitly start the ADB server with the command: adb start-server 2. The ADB Server scans your computer for connected ADB devices. 3. It then verifies if you have the credentials to access the connected ADB devices. a) Looks for the required ‘key’ in your .android folder. b) Creates the .android folder, if it doesn’t exist. c) If a key doesn’t exist, but it finds “adbkey.pub”, is uses that to create the actual authorization key “adbkey”. 4. Finally, it prints the list of devices to the command line (as seen in Figure 2.8). 2.4.3. ADB Commands This section assumes that you were able to install ADB on your computer and successfully list your kit using the “adb devices” command. If not, please refer to Installing ADB (Section 2.4.1). 2.4.3.1. ADB Commands found in this User Guide ADB Debugging • adb devices – lists available adb targets • adb kill-server – stop the adb server • adb reboot – reboots the SK2 File Management • adb pull – pull a file from the SK2 • adb push – push a file to the SK2 Execute on Device • adb shell - Starts a remote shell on the SK2 • exit – exits the remote shell and returns to your computers command-line Of course, you can find a listing of all the commands from many places on the Internet, such as: adbshell.com, https://developer.android.com/studio/command-line/adb, droidviews. AT&T IoT Starter Kit (2nd Generation) User's Guide - Embedded Linux pg. 49 ADB – Connecting to the SK2 2.4.3.2. Exploring the SK2 Filesystem using “adb shell” Here are the results after executing the following instructions. (Note that this screen-capture was taken from a Windows computer running the CMDR shell.) Figure 2.9 Using "adb shell" 1. Open a command-line shell on your computer in the ADB folder. This was discussed in Step 5 (Section 2.4.1.3) on page 48. 2. Verify you can connect to your board using ADB. Running this command from the shell you just opened: adb devices or ./adb devices Should return: WNC_ADB device If it doesn’t, then you need to verify your ADB installation (Section 2.4.1) and/or view ADB troubleshooting (Appendix A5). AT&T IoT Starter Kit (2nd Generation) User's Guide - Embedded Linux pg. 50 ADB – Connecting to the SK2 3. Start a remote session on your SK2 using “adb shell”. You can start a remote shell session running on your SK2 using the adb shell command. adb shell or ./adb shell Notice, in Using "adb shell (Figure 2.9 Using "adb shell"), that the command prompt changes to “#” after starting the “adb shell” command. The commands executed from the # shell are running on the SK2 (and not on your computer). 4. List the SK2 filesystem “ls”. 5. List the SK2 filesystem again using “ls -ls”. 6. Exit the SK2 remote shell. Exit the remote shell using the exit command. exit Notice how the command prompt returns to its original value. This indicates that our commandline is running on our computer again. AT&T IoT Starter Kit (2nd Generation) User's Guide - Embedded Linux pg. 51 ADB – Connecting to the SK2 2.4.3.3. Running Shell Scripts (.sh) on the SK2 To demonstrate running shell scripts on your SK2, we will use the list_dev.sh script (Listing 2.2) from earlier in the chapter that listed the contents of the /dev directory. We will create (or download) the shell script on our computer and then push it to the SK2 and execute it. Note: See a screen capture of this procedure’s results at the end of the instructions. 1. Create (or download) the list_dev.sh file to your adb folder. Since this is such a small file, you may prefer to create it using your text editor. If so, create a file called “list_dev.sh” and add the following two lines of code. cd /dev ls -ls Note: If using Windows, save the file using Linux (or Unix) line endings. (See note on page 44). Alternatively, you may want to download this file from the AT&T Starter Kit GitHub site: https://github.com/att-iotstarterkits/sk2-Users-Guide Hint You can place your shell file in any folder; we only chose the adb folder for convenience. 2. Open a command-line shell on your computer, if it isn’t already open. This was discussed in Step 5 (Section 2.4.1.3) on page 48. 3. Verify your SK2 connection using “adb devices”. It should return: WNC_ADB device If not, you will need to verify your ADB installation (Section 2.4.1) and/or do some ADB troubleshooting (Appendix A5). 4. Push the shell script to the /CUSTAPP folder. The ADB push command takes two arguments, the from and to locations: adb push "C:/adb/list_dev.sh" /CUSTAPP or ./adb push "C:/adb/list_dev.sh" /CUSTAPP Modify the path to your list_dev.sh file as necessary. 5. Open a shell session on your SK2. adb shell or ./adb shell 6. Change directories, opening /CUSTAPP. cd /CUSTAPP AT&T IoT Starter Kit (2nd Generation) User's Guide - Embedded Linux pg. 52 ADB – Connecting to the SK2 7. List the /CUSTAPP directory and look at the permissions for your list_dev.sh file. ls -ls You will see the shell file has the following permissions. 4 -rw-rw-rw- 1 root root 15 Oct 19 04:15 list_dev.sh Unfortunately, since the permissions do not include an ‘x’, you won’t be able to execute the script. To prove this to yourself, you can try to run it, if you’d like. 8. Modify permissions so that you can execute your shell script. There are several permutations for setting file permissions. By using the “+x” argument with the chmod command we simply enable execute permission for our script file. (We recommend that you explore file permission options further on your own.) chmod +x list_dev.sh Hint Handily, Linux will autofill filenames when possible. For example, in this step, typing “chmod +x lis” and hitting the tab key should autofill the complete filename. 9. Check the permissions on the file after chmod. ls -ls list_dev.sh Notice that the executable flags are set: -rwxrwxrwx 10. Run the list_dev.sh. Since we are using the SK2 Linux shell, we must append “./” when running executables. ./list_dev.sh The contents of the /dev directory (the SK2 Linux drivers) should be printed to your terminal. 11. Notice that you remained in the /CUSTAPP directory. Even though the shell script changed to the working directory to /dev, the script returned to the /CUSTAPP directory when it finished running. This happens because shell scripts are run in their own “sub-shell”. This is often handy, especially when running multiple sequential scripts. You can use the source command (see next step) if you want to affect the working directory. 12. Run your script with the “source” command to have the script affect the working directory. source ./list_dev.sh This time, your working directory should be /dev when the script completes. (Notice the “/dev” to the left of the “#” prompt.) 13. Exit the ADB shell. exit AT&T IoT Starter Kit (2nd Generation) User's Guide - Embedded Linux pg. 53 ADB – Connecting to the SK2 Here is a recording of our running the list_dev.sh shell script. Figure 2.10 Running the list_dev.sh script AT&T IoT Starter Kit (2nd Generation) User's Guide - Embedded Linux pg. 54 ADB – Connecting to the SK2 2.4.3.4. Modifying shell script with vi You can use the “vi” text editor to create and modify text files with your SK2. This can be handy if you need to make a change to a file already resident on the board. This section assumes you have created the shell script (list_dev.sh) in the previous section. Additionally, please refer back to previous sections if you need with the early instructions in this sequence. 1. Open a command-line shell on your computer, if it isn’t already open. 2. Verify your SK2 connection using “adb devices”. 3. Open a shell session on your SK2. 4. Change directories, opening /CUSTAPP. cd /CUSTAPP 5. Copy “list_dev.sh” to “list_lib.sh”. cp list_dev.sh list_lib.sh 6. Edit the list_dev.sh file. vi list_lib.sh a) Enter Insert/Edit mode. type the “i” character b) Change the cd command from “cd /dev” to “cd /lib”. Using the arrow keys, move the cursor to the “d” in “/dev”. Press the “x” (or Delete) key three times (to erase the “dev”). Press the right arrow key once (to move the cursor to the right of the “/”). Type “lib”. c) Exit Insert/Edit mode. (i.e., press the Escape key) d) Write the changed file and quit. :wq (and press the Enter key) 7. Run the newly edited script. ./list_lib.sh If you are used to editing with Microsoft Word, the “vi” editor may take some time to get used to. But it’s a convenient – and very powerful – text editor that resides inside your SK2. Please search the web for numerous pages describing how to use vi’s many options. Here are two to get you started: • • https://www.howtogeek.com/102468/a-beginners-guide-to-editing-text-files-with-vi/ https://www.cs.colostate.edu/helpdocs/vi.html AT&T IoT Starter Kit (2nd Generation) User's Guide - Embedded Linux pg. 55 Controlling Hardware Using the Linux Shell 2.5. Controlling Hardware Using the Linux Shell The SK2 hardware can be controlled from the Linux shell. While it isn’t very effective to try and control an I2C serial port from the command-line, the LED makes a convenient example. The following examples demonstrate how to turn the WWAN LED on/off. (Refer to the Hardware Overview in Chapter 1 if you cannot find the WWAN LED.) If the QuickStart demo is running, you’ll need to (temporarily) turn it off by holding the USER Button down for longer than 3 seconds. After doing so, you will see the RGB LED turn off. (Ref: Section 2.6.2) 2.5.1.1. Writing the WWAN LED In the filesystem, the WWAN LED is found under the /sys directory. This is one of the directories, along with /dev, that maps hardware to the Linux filesystem. Figure 2.11 Turning the WWAN LED off/on To turn off the LED, we simply write a “0” to its associated (virtual) file. Listing 2.4: Turn Off the LED echo 0 > /sys/class/leds/wwan/brightness Similarly, we can turn the LED on by writing a “1” to the same location. Listing 2.5: Turn On the LED echo 1 > /sys/class/leds/wwan/brightness AT&T IoT Starter Kit (2nd Generation) User's Guide - Embedded Linux pg. 56 Controlling Hardware Using the Linux Shell 2.5.1.2. Simple Blink LED Script Here’s a very simple script which blinks the WWAN LED. Listing 2.6: Chapter_02/blink.sh # blink.sh # # This is a simple example for blinking the WWAN LED five times # - The For loop executes once per character (a thru e) # - 'sleep 1' causes the cpu to wait 1 second # - At the end of the script, the LED is turned off # for var in a b c d e; do echo 0 > /sys/class/leds/wwan/brightness sleep 1 echo 1 > /sys/class/leds/wwan/brightness sleep 1 done echo 0 > /sys/class/leds/wwan/brightness 2.5.1.3. Using the RGB LED or USER Button While the WWAN LED is controlled directly by the WWAN pin on the WNC module, the RGB LED and USER button are controlled by GPIO pins. Here’s a simple example for lighting the Red LED (in the RGB LED). Listing 2.7: Appendix/GPIO/TurnOnRedLed.sh # TurnOnRedLed.sh # # This simple example turns on the Red RGB LED # cd /sys/class/gpio echo 38 > export echo out > gpio38/direction echo 1 > gpio38/value Listing 2.8: Appendix/GPIO/TurnOffRedLed.sh # TurnOffRedLed.sh # # This simple example turns off the Red RGB LED # cd /sys/class/gpio echo 38 > export echo out > gpio38/direction echo 0 > gpio38/value Refer to the Appendix on GPIO for more details concerning: • What is GPIO? • How do I use the Linux GPIO driver to access the RGB LED and Button? • Additional GPIO shell examples AT&T IoT Starter Kit (2nd Generation) User's Guide - Embedded Linux pg. 57 Linux Boot Sequence 2.6. Linux Boot Sequence Linux follows an orderly boot sequence from power-up to user shell access. This sequence of scripts, functions, and tasks prepares the operating system to host users or run programs. While most of these details are not generally of interest – especially on the SK2 since we cannot affect them – the final steps may be useful for us to understand. In our case, the questions of interest may include: • How does the SK2 QuickStart demo start running automatically? • Can I stop the demo from running automatically? • Once I have written a program of my own, can I start it running automatically? These are the questions we’ll address in this section. 2.6.1. How Does the QuickStart Demo Run Automatically? The QuickStart demo consists of a C/C++ program called iot_monitor. Its name derived from the fact that it monitors several sensors and then communicates that information over the Internet. (Throughout many chapters in this book we’ll explore many facets of the iot_monitor program – starting with the C/C++ build tools in the next chapter.) So how exactly does “iot_monitor” getting started? 1. The simple answer is that Linux always calls the following script file after at then end of its boot sequence: /CUSTAPP/custapp-postinit.sh 2. Examining the script file, we find it calls another script called run_demo.sh: Listing 2.9: custapp-postinit.sh start-stop-daemon -S -b -x /CUSTAPP/iot/run_demo.sh The start-stop-daemon is used to start system-level processes as described by: http://www.man.he.net/man8/start-stop-daemon 3. Finally, when examining the /CUSTAPP/iot/run_demo.sh, script we see that it calls the actual iot_monitor program (along with a few arguments). Listing 2.10: run_demo.sh iot_monitor -q5 -a a2e26b03f4e77aab23dbc5294b277d69 Note that the iot_monitor command-line arguments are described further in Section 5.3.1.2. Bottom line, you can control what programs autostart on your SK2 by editing (or deleting) the custapp-postinit.sh script. Note: This is the simple, short answer. The longer, more involved answer is found in the Appendix Linux Boot Sequence discussion. AT&T IoT Starter Kit (2nd Generation) User's Guide - Embedded Linux pg. 58 Linux Boot Sequence 2.6.2. Configuring Linux Application Bootstrap The QuickStart demo can be turned off by holding the USER Button down for longer than 3 seconds. After doing so, you will see the RGB LED turn off. Since the iot_monitor program autostarts after power-cycling the SK2, turning off the program using the USER Button is only temporary. To stop the program altogether we need to edit, delete, or rename the custapp-postinit.sh script. In this case, let’s rename the script and then verify that the QuickStart program doesn’t run. 2.6.2.1. Stop the QuickStart Demo (from running automatically) 1. Power-cycle your SK2 and verify the QuickStart demo runs. Unplug, then plug back in the USB power to your SK2. The QuickStart demo should begin running within a minute. You can refer back to Chapter 1 (Running the QuickStart Demo) for more information about the demo. 2. Open a command-line shell on your computer in the ADB folder. This was discussed in Step 5 (Section 2.4.1.3) on page 48. 3. Verify you can connect to your board using ADB. Running this command from the shell you just opened: adb devices or ./adb devices Should return: WNC_ADB device If it doesn’t, then you need to verify your ADB installation (Section 2.4.1) and/or view ADB troubleshooting (Ref: Appendix A5). 4. Start a remote session on your SK2 using “adb shell”. You can start a remote shell session running on your SK2 using the adb shell command. adb shell or ./adb shell Notice that the command prompt changes to “#” after running the “adb shell” command. (Ref: Figure 2.9 Using "adb shell"), The commands executed from the # shell are running on the SK2 (and not on your computer). 5. Navigate to the /CUSTAPP folder. cd /CUSTAPP 6. Rename the custapp-postinit.sh script to something else. In Linux we can use the “mv” (move) command to rename a file. In this case, let’s just append “.txt” to the end of the filename. mv custapp-postinit.sh custapp-postinit.sh.txt 7. List the directory to verify the name was changed. ls -l 8. Exit the ADB remote shell. exit AT&T IoT Starter Kit (2nd Generation) User's Guide - Embedded Linux pg. 59 Linux Boot Sequence 9. Power-cycle your SK2 and watch the LEDs to verify the QuickStart demo doesn’t start. If the WWAN and RGB LEDs do not light up within a minute or two, it’s a safe bet that the QuickStart demo is not running. 2.6.2.2. Autostart the Blink Script If you created and ran the /CUSTAPP/blink.sh script in Section 2.5.1.2, let’s try running that script automatically. If not, we suggest that you return to that section and create the script and put it into the /CUSTAPP directory before doing the following steps in this section. 1. Reconnect to the ADB shell. adb shell 2. Change to the /CUSTAPP directory. cd /CUSTAPP 3. Verify that blink.sh exists and is working. ./blink.sh The WWAN LED should blink 5 times. 4. Create a new copy of the original custapp-postinit.sh file (which we renamed in the previous section). cp custapp-postinit.sh.txt custapp-postinit.sh 5. Edit the custapp-postinit.sh file. vi custapp-postinit.sh a) Enter Insert/Edit mode. i b) Modify the script to be executed: The original script runs /CUSTAPP/iot/rundemo.sh. Change this to run our blink.sh script. After editing it should read: start-stop-daemon -S -b -x /CUSTAPP/blink.sh c) Exit Insert/Edit mode. d) Write the changed file and quit. :wq 6. Verify the file is correct. cat custapp-postinit.sh Which should print out the contents: start-stop-daemon -S -b -x /CUSTAPP/blink.sh AT&T IoT Starter Kit (2nd Generation) User's Guide - Embedded Linux pg. 60 Linux Boot Sequence 7. Exit the ADB remote shell. exit 8. Reboot/power-cycle the board to view blink running. Run the following to reboot the board: sudo adb reboot And, it never hurts to power-cycle the board, too. Once the board reboots, the blink.sh script should start running after 10-15 seconds. When it runs, the WWAN LED will blink five times. 2.6.2.3. Autostart the QuickStart Demo Assuming that you have completed the previous two sections (2.6.2.1 and 2.6.2.2) we can return the SK2 to its original state of running the QuickStart demo by renaming (or deleting) our new custapppostinit.sh file and restoring the original file. 1. Enter the ADB shell and change to the /CUSTAPP directory. adb shell cd /CUSTAPP 2. Rename your new custapp-postinit.sh file by adding appending blink to the name. mv custapp-postinit.sh custapp-postinit.sh.blink 3. Restore the original custapp-postinit.sh file. mv custapp-postinit.sh.txt custapp-postinit.sh 4. Verify the original file was restored by listing the directory and cat’ing the file. ls -l cat custapp-postinit.sh 5. Exit the shell. exit 6. Power-cycle your SK2 to verify the original QuickStart demo runs again. As an alternative to power-cycling the board, you could restart the SK2 by using this command: adb reboot How ever you restart the SK2, you should see the QuickStart demo begin running within 45-60 seconds, as it did in Chapter 1 (and at the beginning of this Section 2.6.2). AT&T IoT Starter Kit (2nd Generation) User's Guide - Embedded Linux pg. 61 Page left intentionally blank AT&T IoT Starter Kit (2nd Generation) User's Guide - Embedded Linux pg. 62 3. Installing and Using C/C++ The SK2 (AT&T IoT Starter Kit - 2nd generation) is supported by a variety of programming tools and languages. As demonstrated in the previous chapter, simply by the fact it’s running Linux, the board can be programmed using simple shell scripts. In the next chapter, we explore how you can use the simple, yet powerful Python language to build and run applications. For more demanding applications, though, this chapter discusses how to utilize the C or C++ languages to build and run Linux programs for the SK2. The chapter begins with an introduction to the WNC Software Development Kit (SDK) and its installation. With the tools installed you can download the source and rebuild the IoT Monitor application that comes pre-installed on your SK2. After building and running the large, production-level IoT application, we pivot to building our own applications. Starting small with Hello World provides us an opportunity to examine how to use the GNU Automake toolset to build a simple application. Next, we examine how to program the same GPIO resources – discussed in the previous chapter – using the C language. The chapter ends with a higherlevel discussion of building Linux C programs, multi-tasking, and using signals & interrupts. Prerequisite Knowledge and Tools This guide assumes that you are generally familiar with the C or C++ language. Language constructs are not explained or taught in this book, although we do cover those topics that deal specifically with using C/C++ on the SK2 running under Linux. Please refer to the “Additional Resources” section at the end of the chapter for more information about building C or C++ programs – or writing such programs running under the Linux operating system. Additionally, you will need to have Internet access when installing the tools and software during the first few sections of this chapter. Note: Developing applications for the SK2 using C/C++ is only supported on Linux platforms. Neither Windows or Mac platforms are supported. Unfortunately, it is not an uncommon for development tools supporting Linux-based embedded controllers to require development on a Linux host platform. As such, if you do not have access to a Ubuntu Linux computer your options include: • Create a virtual Ubuntu computer using software such as VMware Workstation (Windows), VMware Fusion (Mac), Parallels (Mac), or Virtual Box (Windows and Mac). This essentially allows you to run a Linux computer inside the virtual computer application on your Windows (or Mac) computer. The examples provided with this user guide were built and tested using Ubuntu 16.04 LTS running within VMware Workstation 15 virtual machine on a Windows laptop. • Create a second boot partition on your computer and install Ubuntu to host and run the WNC SDK development tools. • Program the SK2 using shell scripts (Chapter 2) or Python (Chapter 4). AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 63 Installing the C/C++ Tools and Software Topics 3. Installing and Using C/C++ ........................................................................................................... 63 3.1. Installing the C/C++ Tools and Software ................................................................................. 65 3.1.1. GIT (and ADB) .................................................................................................................... 65 3.1.2. Software Development Kit (SDK) ..................................................................................... 66 3.2. IoT_Monitor example ................................................................................................................. 68 3.2.1. Clone the IoT_Monitor Source Code ................................................................................ 68 3.2.2. Build the IoT Monitor Program ......................................................................................... 69 3.2.3. Push and Execute iot_monitor Application ...................................................................... 70 3.2.4. Avnet IoT Monitor GitHub and Videos .............................................................................. 71 3.3. Create Your First SK2 C/C++ Program ..................................................................................... 72 3.3.1. Hello World ........................................................................................................................ 72 3.3.2. GNU Automake Build System ........................................................................................... 72 3.3.3. Starting Project Files ......................................................................................................... 73 3.3.4. Install SK2 User Guide Examples ..................................................................................... 74 3.3.5. Building “Hello” ................................................................................................................. 74 3.4. Example: Blink LED (File I/O) .................................................................................................... 76 3.4.1. Blink LED with File I/O ...................................................................................................... 76 3.5. Using the SDK’s peripheral API ................................................................................................. 78 3.5.1. GPIO API Summary ............................................................................................................ 78 3.5.2. Example: Blink LED (GPIO API) ......................................................................................... 80 3.6. Writing C Programs for Linux .................................................................................................... 81 3.6.1. Multi-threading .................................................................................................................. 81 3.6.2. Event Handling .................................................................................................................. 86 3.7. Example: myGpio.c .................................................................................................................... 94 3.8. Where to Go for More Information ............................................................................................ 98 AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 64 Installing the C/C++ Tools and Software 3.1. Installing the C/C++ Tools and Software Note: Once again, the C/C++ toolchain has been developed and tested for the Linux platform. The examples and procedures in this book have been created and tested while running Ubuntu 16.04 LTS. If you only have a Windows computer, you may find it necessary to create a second boot partition with Ubuntu or create a virtual Ubuntu computer using software such as VMware or Virtual Box. Creating such an environment is outside the scope of this document, but the procedures and examples described in this book have been tested on Ubuntu 16.04 running under VMware Workstation 14 and 15. As described in Chapter 1, the WNC module on the SK2 contains a single, user-programmable CortexA7 processor that runs Linux. This is the processor that runs your software applications. The tools and libraries needed to create your applications programs are found in the WNC Software Development Kit (SDK), as well as natively within your Ubuntu Linux computer. After installing the SDK, your Ubuntu development computer will be able to create ARM programs that will run under Linux on the SK2. 3.1.1. GIT (and ADB) Before installing the SK2’s software development kit (SDK), we need to make sure two other necessary tools are available on your computer: GIT and ADB. GIT is a popular version control system used to manage software development and deployment. In fact, we will use GIT to download and install the SDK in the next section of this document. Your Ubuntu computer needs to have the GIT tools installed for you to clone and download the tools, as well as Avnet’s example IoT application. If you are working sequentially through this User’s Guide, your system should already have ADB installed, which was needed to explore Linux in Chapter 2. We include the installation of ADB here just in case you are skipping around and have not installed it already – and the following won’t hurt anything even if it’s already been installed. 3.1.1.1. GIT (and ADB) Installation Procedure The following steps will install both GIT and ADB onto your computer. 1. Open a command-line terminal window on your Ubuntu computer. This was covered in Section 2.4.1.3. “Connect to Your SK2”. 2. Use apt-get to install GIT and ADB. APT-GET is a tool used for downloading and installing packages from the Internet. The following command will install the tools if they haven’t already been installed. sudo apt-get install git adb Prefixing commands with SUDO (superuser do) tells Linux to treat the command as if it’s coming from a superuser, who has advanced privileges. Just as with Windows or Mac, Ubuntu Linux requires superuser privileges to install programs. When executing SUDO commands, you may be asked to enter your logon password for your Ubuntu computer, after which you should see the tools being installed (if they weren’t previously installed). AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 65 Installing the C/C++ Tools and Software 3.1.2. Software Development Kit (SDK) The WNC SDK will be installed next. It contains the additional tools and libraries required to build programs for the SK2. As mentioned in the previous section, we’ll use GIT to download and install the SDK onto our Linux computer. 3.1.2.1. SDK Installation Procedure The following steps will download and install the WNC SDK. 1. Open a command-line terminal window on your Ubuntu computer. 2. Navigate to your home directory. cd ~ The “cd” stands for “change directory. The tilde “~” is Linux shorthand for the path to your user’s home directory. 3. Make a new directory “AvNet2” for the SDK. While you can do this with the Ubuntu file manager, it’s just as easy to do it from the command line. mkdir AvNet2 where mkdir stands for “make directory”. 4. Change to the new AvNet2 subdirectory. cd AvNet2 5. Clone the WNC SDK from Avnet’s GitHub site. On your command line enter: git clone https://github.com/Avnet/AvnetWNCSDK which tells our computer to create a clone of the git repository found at the given URL. 6. Change to the cloned AvnetWNCSDK directory and view its contents. The clone of the WNCSDK created a new directory inside of AvNet2. Change to that directory and view its contents. cd AvnetWNCSDK ls -l (list command “ls” with the small -L option) You should see the following files in the directory: − − − − − − adbkey.pub adb_usb.ini Avnet M18Qx LTE IoT API Guide.docx Avnet M18Qx Peripheral IoT Guide.docx oecore-x86_64-cortexa7-neon-vfpv4-toolchain-nodistro.0.sh README.md AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 66 Installing the C/C++ Tools and Software 7. (Optional) Copy DOCX files and convert to PDF. The API guides are useful references when writing programs. One guide describes the LTE communication library API, while the other describes the Peripheral API. Hint: If you find it difficult to open and use Word DOCX files for quick reference books, you may want to create PDF versions of these two guides and place them in a more convenient location on your computer. Alternatively, you may prefer to print them out, if that makes referencing them easier for you. 8. Install the SDK using the provided shell script. Make sure your command-line cursor is still in the AvnetWNCSDK directory and execute the cloned shell script: sudo ./oecore-x86_64-cortexa7-neon-vfpv4-toolchain-nodistro.0.sh Respond with “y” (for yes) when asked if you want to install the SDK. Note: After successful installation, the SDK script tells us that we need to enter the following configuration command each time we open a new shell session where we plan to build code for the SK2. Please make note of this command: . /usr/local/oecore-x86_64/environment-setup-cortexa7-neon-vfpv4-oe-linux-gnueabi 9. Run the shell configuration command indicated by the SDK installation script. . /usr/local/oecore-x86_64/environment-setup-cortexa7-neon-vfpv4-oe-linux-gnueabi This script must be run each time you open a new command-line terminal and want to build code for the SK2. (And, don’t miss the “.” at the beginning of the command.) AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 67 IoT_Monitor example 3.2. IoT_Monitor example With the development tools and software installed, let’s download the code for the QuickStart demo, rebuild it from source, and download it to the SK2. This allows us to verify that the tools and software were correctly installed. 3.2.1. Clone the IoT_Monitor Source Code As we learned in the first two chapters, the QuickStart demo – which runs on the SK2 directly after opening the box and powering up the board – is actually a C++ program called “iot_monitor”. Like the WNC SDK, we recommend downloading the program source code using GIT. 1. Open a command-line terminal window on your Ubuntu computer. 2. Navigate to your “AvNet2” directory. If you followed the previous procedures in this chapter, you can get there using the following command: cd ~/AvNet2 3. Clone the IoT Monitor program from Avnet’s GitHub site. git clone https://github.com/Avnet/M18QxIotMonitor This command will create a new subdirectory “M18QxIotMonitor” and download the contents of the GitHub project into it. 4. View the contents of the new IoT Monitor program directory. ls M18QxIotMonitor Figure 3.1 - Listing of M18QxIotMonitor You will learn about many of these files as you work through this User Guide. You can also watch a video tutorial that briefly describes many of the files in this program directory. Device Fundamental Tutorial 4 can be found here: https://vimeo.com/247415717 AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 68 IoT_Monitor example 3.2.2. Build the IoT Monitor Program With the tools, libraries and QuickStart IoT Monitor program source code installed, let’s try building the application for ourselves. In all, there are four commands needed to build programs for the SK2: • Configure your shell environment (the command provided by SDK installation) • Run the GNU automake tools • − Autogen − Configure Run the makefile After making sure we’re in the correct directory, let’s walk through the procedure to see each of these commands in action. 5. Execute the environment configuration command, if you haven’t already done so after opening your terminal command-line window. . /usr/local/oecore-x86_64/environment-setup-cortexa7-neon-vfpv4-oe-linux-gnueabi 6. Navigate to the “M18QxIotMonitor” project directory. cd ~/AvNet2/M18QxIotMonitor 7. Run the GNU automake tools to create a makefile for our project. The GNU automake system automatically builds makefiles for your project. This requires running two programs which are found in the project’s directory. (These files will be discussed further in the next section.) a) Run the “autogen.sh” shell script that’s found in the project directory ./autogen.sh b) Run the “configure” automake utility. configure ${CONFIGURE_FLAGS} Once complete, these two commands will have automatically created a makefile for your program. 8. Run the makefile to build the IoT Monitor application. make Hint: While writing and debugging code, you only need to run the “make” command to rebuild the program. The first three commands must be run under these conditions: Environment configuration needs to be run each time you start a new shell session. The autogen.sh and configure commands only needs to be run if you add, modify, or delete any files associated with your project. 9. List the directory and verify the application was built. List the directory with the -l (small L) option and check for the “iot_monitor” application. You should see this file in your project directory. Verify that it exists with a time-stamp consistent with your running the “make” command. ls -l AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 69 IoT_Monitor example 3.2.3. Push and Execute iot_monitor Application After building the IoT Monitor application, we need to push it onto the SK2 before we can run it. Even though both environments are running Linux, the IoT Monitor was built to run on the ARM Cortex-A7 and therefore cannot be tested by running it on your Ubuntu Linux PC. You use ADB to push the executable program to the SK2 and place it in the correct location. (This was discussed previously in Chapter 2.) 1. Make sure you’re in the M18QxIotMonitor directory (i.e. where your program file is). cd ~/AvNet2/M18QxIotMonitor 2. Verify that your SK2 is powered on; plugged into your computer; and that your Ubuntu computer recognizes the device. Type this → adb devices Response should be → List of devices attached WNC_ADB device (Please refer to Appendix A5 for ADB troubleshooting.) 3. If required, stop the IoT Monitor program that automatically runs when powering up your SK2. Chapter 2 discussed how the IoT Monitor program begins running automatically – and how you can prevent this from happening. Most users want to stop the program from automatically running before starting to write and debug their own programs. If your SK2 is running the out-of-box IoT Monitor program (i.e. QuickStart demo), you can temporarily stop it by pressing and holding the USER BUTTON (middle button) on the SK2 for 10 seconds. This will quit the application, but it will auto-start again the next time you power up the board without completing the steps in Section 2.6). 4. Use the ADB push command to send your program file to the SK2 “/CUSTAPP” directory. adb push iot_monitor /CUSTAPP If successful, you will see a response that specifies the size, speed, and time for the transfer. (Note that your results make differ from those shown here.) 93 KB/s (99080 bytes in 1.071s) If you prefer, you can place your program into a subdirectory of CUSTAPP (Customer Applications). Note: You do need to store your programs in CUSTAPP (or its subdirectories) because CUSTAPP is the only “writeable” directory on the SK2. 5. Open a remote shell to your SK2 board. adb shell When running the remote shell on the SK2, you should see your command-line prompt change to “#” character. 6. Change to the CUSTAPP directory # cd /CUSTAPP AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 70 IoT_Monitor example 7. Run the program you pushed to the CUSTAPP directory. # ./iot_monitor Not only will the program behave as when it was auto-started, if you are remotely connected via an ADB terminal session, you can see the textual output from the program as well as control it using the program’s terminal commands. 3.2.4. Avnet IoT Monitor GitHub and Videos The IoT Monitor Avnet GitHub page provides a summary of these instructions along with a link to Avnet’s Device Foundation videos, which walk through many of the steps listed towards the beginning of this chapter. GitHub site: https://github.com/Avnet/M18QxIotMonitor Video Tutorial 1: Setting up the Development Environment (roughly covers Users Guide 3.1) Video Tutorial 2: Downloading and building the IoT Monitor program (User’s Guide 3.2) Video Tutorial 3: Running the IoT Monitor program Video Tutorial 4: Brief explanation of IoT Monitor program files AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 71 Create Your First SK2 C/C++ Program 3.3. Create Your First SK2 C/C++ Program We begin with the simple “Hello World” program so that we can focus on the steps to build and run a Linux application on the SK2. Note: The directions in the rest of this chapter assume that the QuickStart demo has been temporarily or permanently disabled – was discussed in Section 3.2.3, Step 3 (on page 70). 3.3.1. Hello World This program simply uses the Standard I/O runtime library to print “Hello World” to the terminal. Listing 3.1: Chapter_03/hello/src/main.c #include int main(void) { printf("Hello World\n"); return 0; } 3.3.2. GNU Automake Build System As described earlier in the chapter, the WNC SDK uses the GNU Automake tools. These tools simplify the process of building application programs because they automatically build the makefile(s) required to for creating applications. What are makefiles? They are the instructions that tell the toolchain (e.g. compilers, linkers, etc.) how to compile and construct your application programs. This guide focuses on using the tools as provided by the WNC SDK. When building your own application programs, we suggest that you copy and modify the “hello” example, tweaking it to meet your requirements. (This is what we have done to create the examples provided for the user guide.) AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 72 Create Your First SK2 C/C++ Program 3.3.3. Starting Project Files Here is an inventory of the starter files needed to build our “hello” project. There will be many more files created after building the application, but these are the only required files when using the build system for the WNC SDK toolchain. (Actually, the two shell script files highlighted in blue are not required, but we added them for user convenience.) Chapter_03/hello | autogen.sh | configure.ac | Makefile.am | _1_autoname.sh | _2_build.sh | /---src main.c Makefile.am Figure 3.2 - Starter files in C/C++ The make system does not require users to put source code into a folder called “src”. This is common practice by many GNU automake users, but not a requirement. In fact, the IoT Monitor example discussed earlier in this chapter used a single, flat folder. For the User Guide examples, though, we chose to place our source code into the “src” subdirectory. Here’s a summary of the project files, a brief description, and what you will need to modify when reusing this example to build your own applications. File Name Need to Edit? autogen.sh No Shell script that runs the automake tools. (Later versions of _1_autoname.sh build this file for you.) configure.ac No Configuration script for the ‘configure’ automake tool. Only need to edit this file if you change the subdirectory structure of your project. (Later versions of _1_autoname.sh build this file for you.) Makefile.am No Specifies project subdirectories – again, you only change this file if you rename/modify the project’s subdirectories. (Later versions of _1_autoname.sh build this file for you.) _1_autoname.sh No This shell script builds a new src/Makefile.am (backing up any current version). It renames the executable program app from the name of the project folder. Additionally, it adds all .c and .cpp files found in the ‘src’ folder. _2_build.sh No Runs the commands required to build the application and push it to the SK2. Description This is your programs source code. You may also add additional c/c++ files to the ‘src’ directory. src/main.c Yes src/Makefile.am Maybe • Your program must contain a “main.c” or “main.cpp” • The main() function must return an ‘int’. You app does not require main() to have any arguments. The _1_autoname.sh script builds this file for you. For complex programs, though, you may have to manually edit Makefile.am. (While GNU Automake power-users may want to edit all these files and more, most users can get by with these recommendations.) Note that even a successful execution of the _1_autoname.sh script may generate the following errors: ls: cannot access '*.c': No such file or directory ls: cannot access '*.cpp': No such file or directory mv: cannot stat 'src/Makefile.am': No such file or directory AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 73 Create Your First SK2 C/C++ Program 3.3.4. Install SK2 User Guide Examples Hint: We recommend using git, but alternatively, you can download them in zip format from: https://github.com/att-iotstarterkits/sk2-Users-Guide/archive/master.zip 1. Open a command-line terminal window on your Ubuntu computer. 2. Navigate to your “AvNet2” directory. If you followed the previous procedures in this chapter, you can get there using the following command: cd ~/AvNet2 3. Clone the User Guide examples from GitHub. git clone https://github.com/att-iotstarterkits/sk2-Users-Guide.git This command creates a new subdirectory and downloads the GitHub project to it. 4. View the contents of the new sk2-Users_Guide directory. ls -ls sk2-Users-Guide 3.3.5. Building “Hello” Here are the steps required to build the “hello” project. (Assuming you downloaded the examples as described in the previous section.) 1. Open a command-line terminal window on your Ubuntu computer. 2. Navigate to the “hello” directory. For example: cd ~/AvNet2/sk2-Users-Guide/Chapter_03/hello 3. Run the build shell script. ./_2_build.sh This will follow the build steps outlined in Section 3.2.2. Then the script will push the executable application program, residing in the “src” (src/hello), via ADB to the /CUSTAPP folder, if your SK2 is connected. Hint: Running the _2_build.sh script is convenient, but it always executes each step in the procedure. If you are repeatedly building over-and-over again while debugging code, you can speed up your build time by running “make” and manually pushing your application to the SK2. AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 74 Create Your First SK2 C/C++ Program 3.3.5.1. .gitignore If you are using GIT for your own development, you likely know that a “.gitignore” file tells GIT which files you do not want to save into your repository. For example, even though running the build tools creates many files, we relied on .gitignore to only retain the absolute minimum files, as presented in Section 3.3.3. We created our .gitignore file by starting with the recommendation from gitignore.io and adding the files we wanted to ignore that were generated by the GNU automake tools. Listing 3.2: sample .gitignore # Created by https://www.gitignore.io/api/c++ # Edit at https://www.gitignore.io/?templates=c++ ### Backup Files ### *.bak ### C++ ### # Prerequisites *.d .deps/ # Compiled Object files *.slo *.lo *.o *.obj # Precompiled Headers *.gch *.pch # Autogenerated Automake Config Files autom4te.cache/ m4/ *.m4 arm-oe-linux-gnueabi-libtool compile *.guess config.h *.in config.log config.status config.sub configure depcomp install-sh ltmain.sh Makefile missing stamp-h1 ## Compiled Static libraries #*.lai #*.la #*.a #*.lib # End of https://www.gitignore.io/api/c++ AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 75 Example: Blink LED (File I/O) 3.4. Example: Blink LED (File I/O) Often called the embedded processing version of “Hello World”, blinking an LED is one of the fundamental starting points for embedded systems. Once you can blink and LED, you’ve learned how to build a simple program that can talk to real hardware. In Chapter 2, we were able to use shell scripts to control pins (connected to LEDs) by writing to Linux GPIO device drivers via virtual files. Since C can read/write files, we can do the same using the C language. (In a later section, we’ll explore using the WNC SDK API to interface to write code for the Linux device drivers.) 3.4.1. Blink LED with File I/O As described in Chapter 2 – as well as the GPIO section of the Appendix – we can observe and control GPIO pins using the virtual file system provided by the Linux device drivers. The resulting code is very similar to the shell scripts in Chapter 2, only it uses the C standard I/O routines to make it so. To quickly summarize working with GPIO, your program needs to: • Export the driver – which allows user space access to the driver • Set the drivers direction (in/out) • Write the value (0/1) based on whether you want the LED off/on The Red LED is connected to GPIO pin 38 on the WNC module. You can find a listing of the LED and USER SWITCH pin numbers in the Appendix section titled “GPIO Pin Numbers – WNC vs Qualcomm”. Note: When accessing GPIO using file I/O we need to use the Qualcomm Pin Number (#38 as shown in the following fileio_red_led example). Conversely, when using the WNC SDK API you will need to use the WNC Pin Number (#98 as shown later in the api_red_led example). To blink an LED, you must turn it on, then off, while waiting for some time period between the on and off states. We chose to use a 1-second time interval which was accomplished using the usleep(X) function – which sleeps the processor for X microseconds. To fit the code onto a single page (i.e. the next page), we removed some of the error checking, as well as some printf’s to the terminal we used for debugging the code. You can find the full source code in the project: Chapter_03/fileio_red_led_with_deinit. AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 76 Example: Blink LED (File I/O) Listing 3.3: Blinking Red LED with File I/O (Chapter_03/fileio_red_led) #include #include // Needed for fileio calls #include // Needed for usleep() calls #define GPIO_EXPORT "/sys/class/gpio/export" #define GPIO_RED #define GPIO_RED_DIR #define GPIO_RED_LED 38 "/sys/class/gpio/gpio38/direction" "/sys/class/gpio/gpio38/value" #define OFF #define ON 0 1 #define SECOND 1000000 int main(void) { int count; int max = 4; FILE *fptr; // Loop counter for blinking // Number of blinks before exiting program // File pointer // One second = 1000000 microseconds // Open GPIO #38 (red) for use by exporting to user space fptr = fopen(GPIO_EXPORT,"w"); fclose(fptr); // Set direction for GPIO #38 (red) fptr = fopen(GPIO_RED_DIR,"w"); fclose(fptr); // Turn off Red LED fptr = fopen(GPIO_RED_LED,"w"); fclose(fptr); // Blink Red LED 'count' times for(count = 1; count <= max; ++count) { fptr = fopen(GPIO_RED_LED,"w"); fprintf(fptr,"%d", ON); fclose(fptr); usleep(1 * SECOND); } } fptr = fopen(GPIO_RED_LED,"w"); printf(fptr,"%d", OFF); fclose(fptr); usleep(1 * SECOND); return 0; AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 77 Using the SDK’s peripheral API 3.5. Using the SDK’s peripheral API The WNC SDK provides a Peripheral Application Programming Interface (API) library which supports the various peripherals found on the WNC M18Qx module used in the SK2. We can utilize this peripheral interface to initialize and control the peripherals within our C/C++ programs. The WNC Peripheral API supports the following peripherals: • I2C • SPI • GPIO • ADC The GPIO peripheral interface is discussed in this chapter of the User’s Guide. The remaining peripherals will be explored in future chapters. 3.5.1. GPIO API Summary Application programming interfaces (APIs) consist of “data types” and “methods” (i.e. functions). Such is the case with the Peripheral API. The Avnet M18Qx Peripheral IoT Guide.docx file, found in the WNC SDK details the typedefs and functions for each peripheral. Turning to the GPIO Interface chapter we find the following elements defined: Datatype Example Description gpio_pin_t GPIO_PIN_98 Specifies which GPIO pin should be initialized or deinitialized. Enumeration only supports the GPIO specific pins – and uses the WNC Pin Numbers. gpio_direction_t GPIO_DIR_OUTPUT Specifies the direction of data transfer used by the gpio_dir() function. gpio_level_t GPIO_LEVEL_LOW Is the pin value 0 (low) or 1 (high). gpio_handle_t hMyGpio This value is returned by the gpio_init() function and is an argument to many other gpio_ functions. You can choose any valid C variable name. gpio_irq_trig_t GPIO_IRQ_TRIG_RISING Passed to the gpio_irq_request() function, this argument indicates when an interrupt should be generated: when the signal goes from low→high, high→low, or in both cases. gpio_irq_callback_fn_t Any valid C function This datatype is passed to the gpio_irq_request() function. It indicates which C function should be run in response to a triggered interrupt. Notes: • • • • Commonly, definitions using the suffix “_t” are used to indicate data type. In many cases, the API guide specifies the valid enumerations (i.e. values) supported by the API. For example, gpio_direction_t allows for GPIO_DIR_OUTPUT and GPIO_DIR_INPUT. The API’s datatypes support specific requirements needed by the API’s function arguments and return values – that is, in those cases where a standard C datatype does not meet the need or may be unclear. For those used to programming low-level microcontrollers, you might think of the callback function (e.g. gpio_irq_callback_fn_t) being like an Interrupt Service Routine “ISR”. AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 78 Using the SDK’s peripheral API GPIO API Functions: Allocating GPIO pin resources – the first three functions are used to allocate and de-allocate the hardware resources to be used by your program. • gpio_init() • gpio_deinit() • gpio_is_inited() The next three functions are used to configure the GPIO resources once they have been allocated. You always need to indicate the direction (in or out) that you plan to transfer data through the pin. But, you only need to use the two IRQ (interrupt request) functions when the pin is used as an “input” and your program needs the input pin to create an interrupt event when its value changes. • gpio_dir() • gpio_irq_request() • gpio_irq_free() The final two functions specify the data value of the pin to be transferred externally (when writing) or internally (when reading). • gpio_write() -- when pin is configured as an OUTPUT • gpio_read() – when pin is configured as an INPUT Hint: To review all the details for the GPIO API functions and datatypes, please refer to the “Avnet M18Qx Peripheral IoT Guide.pdf” found in your WNC SDK installation or on the Avnet SDK GitHub page. Note: We won’t summarize the other peripheral API in this User’s Guide, rather, we’ll let you read through the API Guide on your own. We wanted, though, to discuss one of the peripheral’s functions and datatypes for users who might not have experienced working with hardware API before the SK2. AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 79 Using the SDK’s peripheral API 3.5.2. Example: Blink LED (GPIO API) In section 3.4.1, we detailed using the GPIO pin connected to the red LED using the File I/O driver interface. This section looks at the same example but uses the Peripheral API to configure and control the pin. In fact, while the syntax may differ, you’ll likely find the general steps in this example are very much like those found in the File I/O example. 3.5.2.1. api_led_red_with_deinit Example Listing 3.4: Chapter_03/api_led_red_with_deinit/src/main.c Notice the lines of code (#include and three key API functions) that are used to allocate, initialize and control the GPIO pin which is connected to the red LED. Line 5 – you must #include the library when using the WNC SDK hardware API. Line 23 – gpio_init() allocates the red GPIO_PIN_98 and assigns the resources to the myGPIO handle. Line 28 – the pin resource pointed to by the myGPIO handle is configured as an output. Line 33 and 36 – gpio_write() is used to send a high, then low, level to the pin specified by myGPIO. Line 40 – deallocates red LED resource (i.e. GPIO_PIN_98). Hint: It’s important to deallocate hardware resources at the end of a program, such as releasing the LED GPIO pin on line 40 of this program. This topic is discussed further in Appendix A3, under Deallocating GPIO Resources. AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 80 Writing C Programs for Linux 3.6. Writing C Programs for Linux Writing C programs for the Linux platform often involves more than just plain C code. While this is the case when writing code for any operating system, Linux provides a rich assortment of capabilities that your programs can leverage. For the most part, covering the use of Linux services falls outside the goals of this user guide, but we wanted to introduce two main concepts that may be useful when writing programs for the Linux platform: Multi-threading and Events. The latter topic – Events – includes a few example programs since Events are often triggered by hardware peripherals, such as GPIO inputs. 3.6.1. Multi-threading The terms multi-processing, multi-tasking, and multi-threading are often discussed when using an operating system – especially a high-level O/S such as Linux. There are subtle differences between their definitions, but they all describe multiple things (e.g. programs) executing in parallel. Application programs, as well as users themselves, can start multiple program threads running at the same time by using the operating system’s API and commands. Let us introduce a few topics that you may find useful during your code development. 3.6.1.1. Multiple Processors If your system has multiple processors, it’s easy to imagine running more than one program at a time. Figure 3.3 - Multi-processing For example, if you have three processors, each with their own memory, you can execute three different programs concurrently as shown below: Figure 3.4 - Multi-processing Graph This type of capability exists within the WNC M18Qx module. It has different processors which handle various tasks, such as LTE communications, or running the Linux platform. We are only allowed to program the single ARM Cortex-A7 apps processor, running Linux, with C/C++ or Python. While the system gains from having multiple processors, your Linux programs can only use the one. AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 81 Writing C Programs for Linux 3.6.1.2. Multiple Processes When you only have one processor, as in Figure 3.5 below, your programs must share the resource. Linux enables this by letting you create multiple processes. A “process” is defined by its memory and file descriptors. Returning to Figure 3.5, notice how each process has its own memory (which also includes any file descriptors that have been allocated). The memory management hardware in modern application processors, such as the ARM Cortex-A7, firewalls the memory for each process. In other words, the code in “Process A” cannot access the memory from “Process B” or “Process C” and vice-versa. This allows us to robustly run three different programs at the same time. Figure 3.5 - Multiple Processes Well, let’s clarify that last statement. While three different programs can be configured to run simultaneously, with only a single processor, only one program can run at a time. This can be seen in Figure 3.6 where the processes take turns using the processor. The two waiting to run are effectively paused (sometimes called “blocked”) waiting for their turn – but at least their memory is protected from the running process. Figure 3.6 - Multiple Processes Graph 3.6.1.2.1. Why create multiple processes? Why multiple processes? Because it’s easier using different programs to solve different problems. For example, think about the host computer you use. Whether it runs Windows or Linux, you likely have more than one program running at the same time. Think how much easier it is to build a robust spreadsheet program if it doesn’t have to include all the features of a word processor. When you start each program, it runs in its own process, sharing your systems resources. This may also simplify your programming for the SK2. If you have independent activities that need to operate at the same time, it may be easier to write two programs and set them both running when your SK2 boots up. AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 82 Writing C Programs for Linux 3.6.1.2.2. How to Create a New Process using Fork When Linux boots up, it’s executing a single process. When a second process is needed, this is usually done by issuing a Linux “fork” command. When a fork is executed, Linux makes a duplicate copy of the current process – including all its memory and file descriptors. At this point, the new, duplicate process can begin running a new program, changing anything or everything in the process without affecting the original process. Figure 3.7 - Fork Forking isn’t restricted to C/C++ programming, it can also be done from the Linux command-line. For example, when you invoke a program from the terminal, such as: ./blink_led you may have noticed that the terminal session is paused, waiting for the new program to complete. In other words, the blink_led program is running in the same process as the terminal. But, Linux actually let’s us force the new program to run in its own process. This is done using the “&” symbol: ./blink_led & Including the ampersand at the end of the command-line tells Linux to fork the current process and begin running the new program in the new process. In this case, you’ll notice that the commandprompt returns immediately, even though the blink program may still be running. You can implement the same action using fork() in your C/C++ programs – letting one program spawn many different processes. However you invoke fork, it’s a handy way to run multiple programs at the same time. One of the nice things about using Linux for your embedded system is the wide availability of example code. We pulled a fork.c example from Beginning Linux Programming (see reference at the end of this chapter) and tested it on the SK2. You can find a copy of this generic fork example in the User Guide’s code examples: sk2_users_guide/Chapter_03/fork/src/main.c AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 83 Writing C Programs for Linux 3.6.1.2.3. Useful Commands for Managing Processes There’s a great deal of information available across the internet for learning about and managing Linux processes. We’re only introducing a few of the most basic commands that may come in handy. Command Description ps Lists currently running user processes ps -e ps ax Lists all processes top Ranks processes in order of CPU usage Ends a running process kill kill • PID is returned by fork() • Get PID using “ps” or “top” Pass a specific signal to a process (Signals are discussed in Section 3.6.2.2) AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 84 Writing C Programs for Linux 3.6.1.3. Multi-threading Linux also includes the ability to create multiple threads of execution within a single process. Since multiple program threads share a processes memory, it lowers the overhead of time and memory versus creating multiple processes. But this is done at the expense of robustness, since one errant thread could wipe out all of the shared memory in the process – in other words, no ‘firewall’ exists between multiple threads (in a single process) as it does between processes. Here’s a simple diagram showing Process A consisting of three threads of independent execution, while Process B only contains one. (By default, a process always has at least one thread of execution.) Figure 3.8 - Multiple Threads in a Process You may have noticed the additional threads in Figure 3.8 are labeled “pThread”. This comes from the name of the function (and library) used to create additional threads within a process. Linux generally includes the standard POSIX library (Portable Operating System Interface) which includes routines for creating, managing, and deleting new threads of execution. The pthread_create() function can be used to spawn new program threads within in a process. From a scheduling perspective, Linux sees each thread as an independent unit to schedule when time-slicing between them. In words, the single thread in Process B may only get 25% of the processor time while those in Process A will likely get 25% each. That said, Linux provides multiple ways to tweak and override the scheduling and priority of threads – and that discussion falls outside of what we will address here. 3.6.1.4. Why Should I Use Multiple Threads? Back in Section 3.6.1.2.1 we suggested that using multiple processes can be useful to simplify programming – creating smaller, simple programs for each independent task is often easier and more robust than creating a single, more complex program. But, there’s another big advantage to using multiple threads and/or processes. When one thread blocks (i.e. is paused) waiting for a resource, such as a serial port or new sensor data, other threads can use that time to execute their code. In fact, embedded systems make great use of this feature. For example, the main program may spin in a while{} loop – or in a low-power mode – while waiting for Linux Events to announce that new data is available or that a timer has signaled its time to sample a sensor and post the data to the cloud. This leads us to the next section: Linux Events. AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 85 Writing C Programs for Linux 3.6.2. Event Handling Traditional embedded systems are often built around handling various “events”; for example, when data becomes available, a user presses a button, or a specified time interval has expired. When these systems are built with Linux, there are even more events to choose from, such as signals from the operating system. Unique to the SK2 are the hardware peripherals and their associated API provided by the WNC SDK. In this chapter we introduce the functions and procedures for handling hardware interrupt events generated by the GPIO pins. Before we deal with the GPIO functions, though, let’s explore a few other common Linux events that are used throughout the user’s guide examples. 3.6.2.1. Sleep Sleep is one of the many time-based events that can be generated by the Linux O/S. It’s also one of the easiest to use – so easy, in fact, that we’ve already used it in many code examples. There are a number of “sleep” functions, the most obvious being sleep() – which tells the process calling the function to sleep (i.e. suspend execution) for a given number of seconds. #include unsigned int sleep (unsigned int seconds); If the sleep() function is interrupted by some other event, it returns the number of seconds not slept. Most users ignore the return value, but you can use it to recall the function in order to force the process to sleep for the specified time. Two other similar functions are: • • usleep() – sleeps for a given number of microseconds nanosleep() – sleeps the process for a given number of nanoseconds Besides increasing orders of precision, these two functions are slightly different from each other. While the usleep() function works the same as sleep(), the nanosleep function is found in the library and requires a Linux timespec structure as its argument. While our examples wait for seconds, we’ve chosen to use usleep() in most cases. AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 86 Writing C Programs for Linux 3.6.2.2. Signals Signals (i.e. software interrupts) are events generated by Linux in response to an internal or external event. Signals occur asynchronously to our software programs – meaning that they could happen at any time, and won’t necessarily happen at any specific point in our program code. A signal can be raised (i.e. generated) by a variety of events. For example, when a user generates an interrupt character (e.g. Ctrl-C); an error condition occurs – such as when a process divides by zero; or when one process sends a signal to another. Applications can be programmed to catch and respond to signals. This is done by passing an event handler function to Linux, essentially telling it what code we wish to run in response to a given event… if it occurs. The event handler function is often called a callback function because our program is telling Linux to “call back” to our program using a specific function name. Here’s a listing of Signals that Linux supports: Signal Description Signal Description SIGABORT *Process abort SIGTERM Termination SIGALRM Alarm clock SIGUSR1 User-defined signal 1 SIGFPE *Floating-point exception SIGUSR2 User-defined signal 2 SIGHUP Hangup SIGCHLD Child process has stopped or exited SIGILL *Illegal instruction SIGCONT Continue executing, if stopped. SIGINT Terminal interrupt SIGSTOP Stop executing (Can’t be caught or ignored) SIGKILL Kill (can’t be caught or ignored) SIGTSTP Terminal stop signal SIGPIPE Write on a pipe with no reader SIGTTIN Background process trying to read SIGQUIT Terminal quit SIGTTOU Background process trying to write SIGSEGV *Invalid memory segment access We’ll explore one of the most common signals, SIGINT, the terminal interrupt that’s generated when we press the Control-C keys while running a program from our terminal command-line. AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 87 Writing C Programs for Linux 3.6.2.2.1. Control-C (SIGINT) SIGINT is a handy, common signal to use when debugging your programs. It makes it easy for you to send a signal to your program from the command line. One simple example, shown here, is to catch this signal and terminate your program. Listing 3.5: Chapter_03/sigint/src/main.c Except for one line of code in main() that deals with the SIGINT signal, this program will loop forever due to the while(1) loop on line 15. To handle the SIGINT signal event, two lines of code – and the my_handler() function – were added to the program. Looking at main(), let’s examine the code required: Line 1 When using the Linux to handle the SIGINT event generated by Control-C, you must include the header file. Line 13 The signal() function tells Linux what to do when the SIGINT event occurs. More specifically, this function registers the callback function “my_handler” to the SIGINT signal event. Note: • Whenever SIGINT occurs while this program is running, Linux will pre-empt your program and run the registered call-back function. • When my_handler() is called by Linux (after Ctrl-C is pressed), it will print “Caught signal” to the terminal and exit the function. • If you don’t want the program to exit after a signal occurs, don’t call exit() inside the signal handler. (We provide an example of this in the GPIO pin Interrupt section.) Even though our example’s signal handler uses printf(), it is not recommended to use printf() in signal handlers. That said, printf() makes it easy to visualize what is happening during program execution. In fact, you can refer to the signal documentation (or the Beginning Linux Programming book listed at the end of the chapter) for a list of functions that are safe to use within a signal handler. Hint: One recommended technique, if you need to use an unsafe function, is to set a flag during the signal handler and then print the message – or call the appropriate unsafe function – from inside the main program. AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 88 Writing C Programs for Linux 3.6.2.2.2. Pause The pause() function is a useful debugging function that puts a process to sleep while waiting for any signal. Upon receiving a signal, it wakes and responds as if the routine as if it had been awake, running the signal handler registered by the program. We provide two examples to demonstrate this function. The sigint2 does not use pause() while the sigint2_with_pause does. Both functions provide another example for handling the SIGINT. Listing 3.6: Chapter_03/sigint2/src/main.c // Example taken from “Beginning Linux Programming” 4th Edition // by Neil Matthew and Richard Stones; Wiley Publishing © 2008 #include #include #include void ouch(int sig) { printf("\nOUCH! - I got signal %d\n", sig); (void) signal(SIGINT, SIG_DFL); } int main() { (void) signal(SIGINT, ouch); } while(1) { printf("Hello World!\n"); sleep(1); } When running the program, “Hello World!” prints out repeatedly until the user has entered Ctrl-C twice. Notice that the signal handler ouch() redefines the signal’s handler, changing it back to the signal’s default (SIG_DFL) action for Linux (causing the program to exit). Here’s what it looks like in the terminal: Figure 3.9 - Running sigint2 AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 89 Writing C Programs for Linux Modifying the program slightly, we replaced the sleep() command with pause(). Listing 3.7: Chapter_03/sigint2_with_pause/src/main.c #include #include #include void ouch(int sig) { printf("\nOUCH! - I got signal %d\n", sig); (void) signal(SIGINT, SIG_DFL); } int main() { (void) signal(SIGINT, ouch); } while(1) { printf("Hello World!\n"); pause(); } Notice that after swapping out sleep() with pause(), “Hello World!” only prints out once before and after the first Cntrl-C: Figure 3.10 - Running sigint2_with_pause AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 90 Writing C Programs for Linux 3.6.2.2.3. Sending Signals from the Terminal In the following figure, we are once again running the program sigint2_with_pause, but this time we added “&” to run it in a separate process. Notice that after starting the program in Figure 3.11, our terminal returns to allow us to enter new commands – where we then executed the ps command to see our program running in a new process (with pid = 3349). Figure 3.11 - Running sigint2_with_pause in separate process But now that the program is running in a separate process, it doesn’t receive our Control-C commands anymore. How can we send it a signal? As was mentioned back in Section 3.6.1.2.3, the Linux kill command can be used to send a signal to a running process. If we just typed: kill 3349 our program would simply terminate. But rather, we used kill to send the SIGINT (i.e. Control-C) signal kill -SIGNINT 3349 to the process using kill. Notice how sending it twice caused the same results as was seen in Section 3.6.2.2.2. AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 91 Writing C Programs for Linux 3.6.2.2.4. Upgrading to sigaction() While the signal() functionality is long-standing and well adopted by Linux and Unix, sigaction() has become the preferred method of handling signals due to its robust flexibility. It takes a little more code to implement, though, which is why we consider this an ‘upgrade’ to the previous example. Additionally, we followed the earlier advice for moving the printf() functions out of the signal handlers. Listing 3.8: sk2_users_guide/Chapter_03/sigaction/src/main.c #include // Needed #include // Needed #include // Needed #include // Needed for for for for sigaction() printf() sleep() exit() int flag = 0; int lastSig = 0; void ouch(int sig) { flag = 1; lastSig = sig; } // First pass SIGINT handler void quit(int sig) { flag = 3; } // Second pass SIGINT handler int main() { struct sigaction act; } // ‘action’ struct for signal act.sa_handler = ouch; sigemptyset(&act.sa_mask); act.sa_flags = 0; // Callback function is 'ouch' // Don’t block any signals // No signal action modifiers sigaction(SIGINT, &act, 0); // Set action for SIGINT signal while(1) { // Respond to value of ‘flag’ switch(flag) { case 0: case 2: printf("Hello World!\n"); sleep(1); break; case 1: printf("\nOUCH! - I got signal %d\n", lastSig); act.sa_handler = quit; //Could have set to SIG_DFL sigaction(SIGINT, &act, 0); //Set new action for SIGINT flag = 2; break; case 3: printf("\nOUCH again. This time it's Goodbye!\n"); exit(0); break; default: printf("Don't know how I got here... exiting\n"); exit(1); } } Figure 3.12 - Running sigaction AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 92 Writing C Programs for Linux 3.6.2.3. GPIO pin Interrupt The Linux GPIO pin driver provides an interrupt event whenever an input pin is changed. Your program needs to initialize and configure the GPIO input pin, as well as register the interrupt (“irq”) callback function before it can catch the event. The following code example enables interrupts from the SK2’s User Button. Notice the three additional items required to convert an input GPIO pin to an interrupt triggered GPIO pin. 1. Callback function 2. Call IRQ request to initialize the interrupt event 3. Wait for the interrupt request to complete! 4. Free the IRQ resource when it’s not needed anymore Listing 3.9: sk2_users_guide/src/api_button_interrupt #include #include #include #include #include #define USER_BUTTON Generating an interrupt before the IRQ request completes triggers a user signal that aborts the program. Needed Needed Needed Needed for for for for printf() exit() pause() WNCSDK GPIO API GPIO_PIN_98 int ret = 0; gpio_handle_t myBtn = 0; gpio_handle_t myLed = 0; Warning // // // // // Return value // Handle for button's GPIO pin //***** GPIO callback routine **************************************** int myBtn_irq_callback(gpio_pin_t pin_name, gpio_irq_trig_t direction) { if (pin_name == USER_BUTTON) { printf("Button interrupt received\n”); } } //***** Main ********************************************************* int main(void) { printf("\nStarting GPIO Callback Example!\n"); printf("Please wait while we configure your device...\n"); // Allocate and configure GPIO pin for User Pushbutton switch input ret = gpio_init(USER_BUTTON, &myBtn); gpio_dir(myBtn, GPIO_DIR_INPUT); Prove this to yourself by pressing the User Button before getting the “Device config complete” message”. // Register callback function for GPIO pin interrupt to trigger on up/down gpio_irq_request(myBtn, GPIO_IRQ_TRIG_BOTH, myBtn_irq_callback); // Now waiting for interrupt to occur printf("Device configuration complete.\n"); printf("Press and release User Button to trigger interrupt.\n"); pause(); // Wait for signal from user button // Release resources and exit printf("Releasing GPIO resources...\n"); gpio_irq_free(myBtn); // Free the IRQ push button callback gpio_deinit( &myBtn ); // Release the button's GPIO resource } return 0; The user guide examples archive (or git) contains an additional example that turns on the blue LED when the button is pressed. Look for: sk2_users_guide/Chapter_03/api_button_irq_led AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 93 Example: myGpio.c 3.7. Example: myGpio.c As the final example for the chapter, we’ve created a reusable GPIO example. This example contains a generic initialization function that can allocate all the requested GPIO resources. Using the routine requires a few instructions: • myGpio.c • − Modify the myGpio structure in myGpio.c for the GPIO pins your application will use. − Create or modify the sample myGpio_irq_callback function if you plan to use GPIO interrupts. main.c (or where ever you wish to initialize and use GPIO) − − − #include “myGpio.h” Call the myGpio_init() function Call the myGpio_close() function when finished with the GPIO resources If this doesn’t meet everyone’s needs, we hope it provides a good example that users can work from. Listing 3.10: sk2_users_guide/myGpio/src/main.c AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 94 Example: myGpio.c Listing 3.11: sk2_users_guide/myGpio/src/myGpio.c AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 95 Example: myGpio.c Listing – sk2_users_guide/myGpio/src/myGpio.c (continued) AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 96 Example: myGpio.c Listing 3.12: sk2_users_guide/myGpio/src/myGpio.h AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 97 Where to Go for More Information 3.8. Where to Go for More Information Recommended materials for learning more about C/C++ programming for Linux and the SK2. • Avnet M18Qx Peripheral IoT Guide (DOCX) • Matthew, Neil, and Richard Stones. Beginning Linux Programming (4th Edition). Wiley, 2011. • Robert Love. Linux System Programming: Talking Directly to the Kernel and C Library (2nd Edition). O'Reilly Media, 2013 • Michael Kerrisk. The Linux Programming Interface: A Linux and UNIX System Programming Handbook (1st Edition). No Starch Press, 2010. AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using C/C++ pg. 98 4. Installing and Using Python Python 2.7 has been ported to the SK2 to aid in rapid-prototyping – or full-scale development – of applications for the SK2 (AT&T IoT Starter Kit 2nd Generation). After upgrading your SK2 firmware, you will be able to run Python scripts from the Linux command-line. Additionally, the SK2 Python firmware includes a cloud-based IDE for editing, running, and managing python scripts and applications. This chapter focuses on installing and using the SK2’s Python platform. Look back to Chapter 2 for details about the Linux environment and writing shell-scripts. Or Chapter 3 for details about C/C++ environment. Also note that Warning! Installing the Python SK2 Linux firmware will replace the filesystem on your SK2. Please follow the directions carefully – including Section 4.1.1 “Backup /CUSTAPP” – to make sure any files you have added to your kit are backed up before installing the Python firmware. Prerequisite Knowledge and Tools This guide assumes that you are generally familiar with the Python language. Language constructs are not explained or taught in this book, although it covers a few topics that are part of the Python code examples for the SK2. Please refer to the Additional Resources section at the end of the chapter for more information about Python coding. AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 99 Installing Python Topics 4. Installing and Using Python ........................................................................................................... 99 4.1. Installing Python ...................................................................................................................... 101 4.1.1. Backup /CUSTAPP ........................................................................................................... 101 4.1.2. Setting up the Python IDE ............................................................................................... 103 4.2. Connect to Python IDE ............................................................................................................. 107 4.2.1. Overview .......................................................................................................................... 107 4.2.2. GPIO Control .................................................................................................................... 108 4.2.3. IDE .................................................................................................................................... 109 4.2.4. Links................................................................................................................................. 110 4.2.5. Terminal ........................................................................................................................... 111 4.3. Getting Started with Python .................................................................................................... 112 4.3.1. Running Python from the Command-Line ...................................................................... 113 4.3.2. Example: Hello World using Python ................................................................................ 116 4.3.3. Example: Cheer for Hello World ...................................................................................... 118 4.3.4. Example: Blinking the Red LED ...................................................................................... 119 4.3.5. Example: Reading the User Button ................................................................................ 120 4.3.6. Accessing Additional GPIO Pins ...................................................................................... 120 4.3.7. Killing a Running Python Program .................................................................................. 121 4.4. WWAN LED Class ..................................................................................................................... 122 4.4.1. Python Functions and Classes ....................................................................................... 122 4.4.2. Example: Using WWAN LED Class .................................................................................. 124 4.4.3. Importing & Using the WWAN LED Class ....................................................................... 125 4.4.4. WWAN Class Subprocessing ........................................................................................... 125 4.5. GPIO Interrupts in Python ........................................................................................................ 126 4.5.1. Fancier Button Interrupt Example .................................................................................. 127 4.6. Running Python Scripts at Boot .............................................................................................. 129 4.7. Additional References ............................................................................................................. 130 AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 100 Installing Python 4.1. Installing Python Installing Python onto your SK2 involves updating the entire firmware image for the development board. Python, and the cloud-based IDE have been baked into the Linux image. While this increases the steps required to install Python – versus installing only a simple Python executable – the result is a complete platform that has been pre-verified to run on the SK2 board. The SK2 Python firmware downloads as a large ZIP file. After downloading the ZIP file, you will unzip the firmware image and run a series of ADB commands in order to update the various elements of the Linux firmware on your kit. When complete, your SK2 will include the Python executable and IDE. WARNING - The following Python installation will replace your current SK2 Linux firmware. Any files that have been created or written to the /CUSTAPP directory on your kit will be erased during installation of the new Linux firmware. Please backup any files that you have added to the kit before installing the new firmware – backup instructions are found in the next section. 4.1.1. Backup /CUSTAPP The following sections step you through the procedure to update your SK2 with the new Python firmware. These steps entirely replace your Linux firmware – including the /CUSTAPP directory where you have likely created, modified, or uploaded files. Follow the steps in this section to backup – and then verify – that your files have been saved from the SK2 before continuing with installation in the next section. 1. Open a command-line shell on your computer in your ADB folder and verify that you can connect to your board using “adb devices”. This was covered in detail in chapter 2. 2. Start a remote session on your SK2 using “adb shell”. You can start a remote shell session running on your SK2 using the adb shell command. adb shell or ./adb shell 3. Test if Python is already installed. Python should not be installed, but by trying this step now, we can tell later if our installation was successful. python --version If Python was installed, it would return the version of Python currently available. 4. Change to the /CUSTAPP directory. cd /CUSTAPP 5. List the read/write directory of the SK2 filesystem. ls -ls Make a note of any files or directories that you’ve added to /CUSTAPP. AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 101 Installing Python 6. Backup any files that need to be saved from the SK2. You can individually pull files from the SK2 using the “adb pull” command. Although, the easiest solution may be to TAR (i.e. zip) the files and then pull them all with one command. This is the method we’ll demonstrate. a) TAR the files in /CUSTAPP. Use the TAR (tape archive) command to create a compressed, archive of all the files within /CUSTAPP. tar -czvf myCustapp.tar.gz . tar: -c: -z: -v: -f: tape archive command Create and archive Compress files when added to archive Verbose - display progress in the terminal while creating the archive Specify the filename of the archive You can use any name you want for your archive, although it should end with “.tar.gz”. We chose the name “myCustapp.tar.gz”. Finally, the “.” at the end of the command specifies all the files in the current directory. The TAR command will recurse any subdirectories and include their files. Hint: If you didn’t want to include a specific directory in your TAR files – for example, let’s say we had a directory named “temp”, it could be excluded by adding the following to our example: tar exclude=’temp’ -czvf myCustapp.tar.gz . b) List the /CUSTAPP directory again. The listing should now include your TAR file, for example: myCustapp.tar.gz If it doesn’t, debug the problem with your TAR command and keep trying until you succeed. c) Exit the SK2 remote session. exit Your command-line terminal should be back in your “adb” folder on your host computer. d) Pull the TAR file from the SK2. adb pull /CUSTAPP/myCustapp.tar.gz Make sure you include /CUSTAPP in your file’s path. 7. Verify saved files. Open the TAR file on your host computer and verify it contains all the files you wanted to save from step #5. Hint: Many utilities allow you to view and extract TAR files. Popular utilities include: WinZip, WinRAR, and 7-zip. Make sure that you have saved all the files from your /CUSTAPP directory before proceeding with the next section. AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 102 Installing Python 4.1.2. Setting up the Python IDE The SK2 Python firmware image is provided in a large ZIP file. You need to download the ZIP file and extract it to a folder on your host computer. 8. Download the SK2 Python Image ZIP file. M18Q2_v12.09.182151_APSS_OE_v01.07.183121.zip 9. Unzip this file onto your computer. After unzipping this file, your computer should contain a new folder named: M18Q2_v12.09.182151_APSS_OE_v01.07.183121 View the files in the archive: Files we will use for Python: • Blue files support ADB and Fastboot installation • Remaining files make up the Python firmware image • • • • • • • • • Files that are not needed from the Python image ZIP file: • • • • • • • • • • • • • • • • • • • • • • • • adb.exe AdbWinApi.dll AdbWinUsbApi.dll fastboot.exe firmware.ubi.4k fw.bin.full.4k mdm9607-boot.img.4k mdm9607-datafs.ubi.4k mdm9607-sysfs.ubi.4k README - Usage of WNC_Dloader_SB3.0_Support_MDM9x07.txt appsboot.mbn cmd.bat rpm.mbn sbl1.mbn tz.mbn tzbsp_no_xpu.mbn WNC_Dloader_SB3.0_Support_MDM9x07.exe ENPRG9x07.mbn factory.yaffs2.2k.ESMT factory.yaffs2.2k.ETRON factory.yaffs2.4k firmware.ubi.2k fw.bin.full.2k M18_wnccm_fastboot_2k.txt M18_wnccm_fastboot_2k_ESMT.txt M18_wnccm_fastboot_4k.txt mdm9607-boot.img.2k M18_download_4k.bat mdm9607-datafs.ubi.2k mdm9607-sysfs.ubi.2k NPRG9x07.mbn partition.mbn.2k partition.mbn.4k Note that you do not need to delete any of the “unnecessary” files listed above. We just wanted to state that these files would not be needed in case you wondered why they weren’t used in the following procedure. AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 103 Installing Python 10. Open a command-line shell on your computer, if it isn’t already running. 11. Change to the directory where you extracted the SK2 Python firmware image files. To install the new firmware image, you will need to switch to the new directory created by unzipping the SK2 Python Image ZIP – that is, the directory containing the files we just examined. For example: cd C:\M18Q2_v12.09.182151_APSS_OE_v01.07.183121 12. Verify that you can connect via ADB using the ADB in the Python image directory. adb devices You will likely see a notice stating that the ADB daemon is not running and that it has been started. Since we are running a new version of ADB from the Python image directory, ADB will stop the currently running server and restart it using the version of ADB in our new directory. Figure 4.1 - Restarting ADB with "adb devices" 13. Execute the following series of commands to write (i.e. ‘flash’) the Python image files to your SK2. The following steps reboot the device into bootloader mode and then use ‘fastboot’ to write the images to their respective locations on the SK2. adb reboot bootloader fastboot flash boot_b mdm9607-boot.img.4k fastboot flash system_b mdm9607-sysfs.ubi.4k fastboot flash boot_a mdm9607-boot.img.4k fastboot flash system_a mdm9607-sysfs.ubi.4k fastboot flash data mdm9607-datafs.ubi.4k fastboot flash firmware_a firmware.ubi.4k fastboot flash firmware_b firmware.ubi.4k fastboot reboot Hint: Copy/Paste the commands from this page. Or, you can copy/paste them from the git file: Chapter_04\py_install_cmds.txt View a successful execution of these commands on the next page. 14. When complete, open an ADB shell and check what version of Python is now installed. adb shell python --version Not only will your python version command return a version – rather than an error – you can also see quite a few new files and directories by listing the /CUSTAPP directory. AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 104 Installing Python A successful execution of the Python installation looks like → It only took a few minutes to complete the entire sequence Figure 4.2 - Successful Flashing of Python Firmware AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 105 Installing Python 15. Exit the ADB remote session. exit 16. Examine your Network settings ipconfig Figure 4.3 - ipconfig Notice that along with our wireless LAN adapter, we now have an additional Ethernet connection with an IPv4 address of 192.168.8.100. (This is important for the next section.) 17. Change back to your original ADB folder. Leaving the Python image installation folder, return to your normal ADB folder. For example: cd C:\adb 18. Run the ‘adb devices’ command to restart the original ADB server. adb devices Figure 4.4 - Restarting Original ADB Server 19. Open an ADB shell and try verifying Python again. adb shell # python --version Figure 4.5 - Verifying Python AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 106 Connect to Python IDE 4.2. Connect to Python IDE After the Python firmware has been installed on your SK2, you should be able to run Python scripts from the SK2 command-line (from within an ADB remote session). Additionally, you can open and use the Python IDE that was installed to your SK2 – which is what we will experiment with first. 4.2.1. Overview From an Internet browser, connect to the following address: 192.168.8.1 Upon a successful connection, you should see the Python IDE overview. Figure 4.6 - Python IDE (Overview) The overview provides a short introduction to the SK2 and its advantages. Next, let’s explore the main facets of the Python IDE. AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 107 Connect to Python IDE 4.2.2. GPIO Control Click the “GPIO Control” button towards the top of the Python IDE. GPIO Control opens a screen that allows you to control the RGB LED on your connected SK2 as well as reading the ADC value. Figure 4.7 - Python IDE (GPIO Control) You can turn the various LED colors on/off. For example, we turned on the Red LED. Clicking ‘Refresh’ to read the ADC (analog to digital convertor) causes the IDE to read the ADC peripheral on the WNC module. Since it’s connected to a light sensor on the SK2, reading the ADC gives us a number that represents the amount of light hitting your board. You can see a difference in light intensity using the SK2. First read the ADC by clicking ‘Refresh’. Then change the amount of light hitting the board – say, by shining a flashlight on it – and clicking ‘Refresh’ again. Here’s an example of our readings: Room lighting Flashlight 27 3521 AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 108 Connect to Python IDE 4.2.3. IDE Clicking the “IDE” button towards the top right of the Python IDE: IDE opens the main Python IDE screen where you can create, edit, and run Python scripts. Figure 4.8 Python IDE (IDE) You can open the iot_blink_led_example.py that comes preinstalled with the Python image by double-clicking on it. This opens the script in the editor, allowing you to modify or run the Python script. Figure 4.9 - Python IDE (IDE) showing code Run the script open in the editor by clicking the “Run” button in the lower left-hand corner. The IDE asks you to verify the script you want to run before executing it. AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 109 Connect to Python IDE Note that if you modify the files in the Python IDE directory while it is open, the IDE may not see the new files or folders. You can refresh the file listing by clicking the “Refresh” button or using Ctrl-R. Figure 4.10 - Refresh File Listing 4.2.4. Links Click “Links” to open the IDE’s links page. This page provides a few links connecting you to SK2 resources, such as the product page. Figure 4.11 - Python IDE (Links) Note: Some of these links may not be active. AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 110 Connect to Python IDE 4.2.5. Terminal Click “Terminal” to open a BASH command-line terminal. This page allows you to connect to your SK2 and run command-line functions. It provides an alternate to the ADB connection that we have used in other parts of this user guide. For example, we executed the Python version command that was used earlier in this chapter. Figure 4.12 - Python IDE (Terminal) AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 111 Getting Started with Python 4.3. Getting Started with Python Python is high-level, general purpose programming language that’s easy and fun to program. In fact, it was named after the British television comedy “Monty Python’s Flying Circus”, so how much more fun does it get than this? Here are some key distinguishing features from “Python in Easy Steps” (Mike McGrath) that do well in describing the Python language. (See “Additional References” at the end of the chapter for a reference to his book.) • Python is free – is open source distributable software. • Python is easy to learn – has a simple language syntax. • Python is easy to read – is uncluttered by punctuation. • Python is easy to maintain – is modular for simplicity. • Python is “batteries included” – provides a large standard library for easy integration into your own programs. • Python is interactive – has a terminal for debugging and testing snippets of code. • Python is portable – runs on a wide variety of hardware platforms and has the same interface on all platforms. • Python is interpreted – there is no compilation required. • Python is high-level – has automatic memory management. Like with shell-scripts and C, we’ll begin using Python with the simple “Hello World” program, after which we’ll quickly focus on how to access the SK2 hardware using the Python language. AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 112 Getting Started with Python 4.3.1. Running Python from the Command-Line Running Python from the command-line is different than you might have seen with other languages, such as C/C++ which was covered in the previous chapter. While there are utilities that can convert Python scripts into executable files, generally Python scripts (i.e. Python .py files) are executed by the Python interpreter. But before we explore executing Python files, let’s examine the Python command interpreter. 4.3.1.1. Using the Python Interactive Interpreter While you are not likely to use the Python interpreter in your normal SK2 applications, it can be handy if you’re starting out with Python and want to execute commands one-by-one. 1. Open a SK2 remote command-line session. There are now two easy ways to do this. With the SK2 powered-on and connected to your computer: • You can execute “adb shell” from your host computers terminal, as we’ve been doing since Chapter 2. • Open the Python IDE’s “Terminal” window, as was discussed in the previous section of this guide. It doesn’t matter which method you choose, either will let you run Python. 2. Start the Python interpreter. Typing the command “python” without any arguments starts the python interpreter. python Hint: Note that you can see an example invocation of the commands from section 4.3.1.1 in Figure 4.13 - Interactive Python interpreter session. 3. Enter the Python syntax to print ‘Hello World’ to the terminal output. print(‘Hello World!’) Python doesn’t care if you use single or double quotes, as long as they’re a matched pair. Also, while Python 2 doesn’t require parenthesis for print statements, Python 3 does, so we recommend getting used to it right from the beginning. 4. Execute a Python expression with the interpreter. Enter the following expression: 10 * (20 + 12) and see it return the result. 5. You can even use variables. Try entering the following three lines, hitting return after entering each one: a = 20 b = 12 10 * (a + b) Should return the same number we saw earlier. AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 113 Getting Started with Python 6. How about getting information from the command-line user (i.e. yourself). Try the following two lines: c = input(“Enter a number: “) 10 print( int(c) * (a + b) ) The input function reads characters from the command line, in this case, assigning the value to the variable ‘c’. We then printed the result of an expression – though we needed to cast the character value in ‘c’ as an integer before we could mathematically combine it with ‘a’ and ‘b’. Here are the commands from this section while using the Python IDE Terminal. Figure 4.13 - Interactive Python interpreter session 7. Exit the Python interpreter. exit() AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 114 Getting Started with Python 4.3.1.2. Running Python scripts More likely you will want to write your Python code into a file and run it. Before we write and execute our own code, let’s simply try running one of the examples that’s included within the Python image. 1. Open a SK2 remote command-line session. Use either of the methods discussed in Section 4.3.1.1, Step 1 (on page 113). 2. Open the /CUSTAPP/iot_files directory on your SK2. If you are using the Python IDE Terminal, you should already be at this location. If using the “adb shell” method, you’ll need to change directories to reach this location. Figure 4.14 - Navigating to 'iot_files' 3. Run the iot_blink_led_example.py python script. This is the same file we executed earlier, back in Section 4.2.3. To execute it from the command line, you need to include “python” along with the file name. python iot_blink_led_example.py As the script it running, you should see the RGB LED blink a variety of colors. AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 115 Getting Started with Python 4.3.2. Example: Hello World using Python Writing Python can be accomplished with any text editor, then executing the code as was examined in the previous section. The SK2 makes the task easier, though, by providing a Python aware text editor in the IDE view. Let’s create our first Python file using the IDE. 1. Open the Python IDE to the ‘IDE’ pane. 2. Create a new Python file named “hello.py”. There are two ways to create a new file in the IDE: a) Select the “New File” button. b) Right-click in the editor, then choose: New → File. In either case, enter the name “hello.py” and hit OK. Figure 4.15 - Creating a New Python File Hint: Notice that the Right-click menu also allows you to create a new “Directory”. Both tasks – creating a new file or directory – can be done from the command-line. There isn’t anything fancy being done by the IDE, it just provides a simple way to create these objects without having to leave the IDE. 3. Open “hello.py” in the IDE’s editor. This can also be done two different ways: a) Double-click on the ‘hello.py’ filename. b) Right-click on the filename and choose “Edit”. 4. Enter the code for Hello World! Simply add the following code which we saw earlier in the chapter: print(“Hello World!”) AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 116 Getting Started with Python 5. Save and run your hello.py script. Clicking the two buttons in the lower-left corner will save and execute your script. Save Run Upon clicking run, you’ll be asked to confirm the command that will be executed. While we could modify it before clicking OK, we don’t need to do that for this example. Click OK Hopefully your program ran fine. Ours didn’t. Figure 4.16 shows the error we received. Figure 4.16 - Running 'hello.py' (with error) It’s difficult to see the error. It’s the same code we used before with the interactive interpreter, so why is it failing now? Well, we were lazy and copied the code from the user’s guide. Unfortunately, Microsoft Word has a habit of replacing quotes with fancy curly versions… which apparently the Python interpreter doesn’t like. Replacing the quotes in our file fixed the problem. Figure 4.17 - hello.py Success AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 117 Getting Started with Python 6. Close the file. Right-click and select ‘Close’ Note that while the Right-click menu indicates that hitting the ‘Esc’ key will close the file, it didn’t work for us. Hint: Right-clicking too close to the bottom of the editor hides part of the context menu and you might therefore be unable to see the lower options, such as ‘Close’. Make sure you Right-click high enough on the screen to see the entire list. 4.3.3. Example: Cheer for Hello World To demonstrate another relatively simple program, we expanded on the Hello World script by adding a for loop. The code is in Listing X (and can be downloaded from the User’s Guide Git). Listing 4.1: Chapter_04/hello_cheer.py # hello_cheer.py msg = 'Hello World' for c in msg: print("Give me a '" + c + "'") print("\nWhat does it spell? \n " + msg) For those that are new to Python, note that the language is easy to read. Also note that white space is important. The “contents’ of the for loop are defined by white space; notice that the print() statement in the loop is indented and will be repeated, while the second print() only executes once. (By the way, the “\n” characters tell Python to insert a line-feed, similar to how they work in C/C++.) Figure 4.18 - Running hello_cheer.py AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 118 Getting Started with Python 4.3.4. Example: Blinking the Red LED Like shell-scripts and C/C++, blinking an LED is a good way to begin working with hardware. It’s easy to see the results by verifying if the LED turns on or not. The red_led_blink.py example (Listing 4.2) was easy to create because we could borrow directly from the iot_blink_led_example.py that came with the Python firmware image. Listing 4.2: Chapter_04/red_led_blink.py import time import iot_hw # Needed for time.sleep() function # Allows access to SK2 hardware resources # Define 'ON' and 'OFF' ON = iot_hw.gpio_level.GPIO_LEVEL_HIGH OFF = iot_hw.gpio_level.GPIO_LEVEL_LOW # Allocate and configure GPIO as output for Red LED red_led = iot_hw.gpio(iot_hw.gpio_pin.GPIO_LED_RED) red_led.set_dir(iot_hw.gpio_direction.GPIO_DIR_OUTPUT) # Red on red_led.write(ON) time.sleep(1) # Red off red_led.write(OFF) # Release Red LED resource red_led.close() Executing the Python script will blink the Red LED once. Here are some notes about this example: import time Like C, ‘time’ is a standard library which provides a simple sleep() function import iot_hw Again, like C/C++, this imports the library API which allows us to use the SK2 hardware resources ON, OFF These variables were not required; alternatively, the code could have used the longer values (i.e. iot_hw.gpio_level.GPIO_LEVEL_LOW) in the write() function iot_hw.gpio() Allows the program to allocate GPIO resources; you must import iot_hw in order to use this function; setting the variable with iot_hw.gpio_pin.GPIO_LED_RED selects the color red – i.e. it tells the library which pin needs to be used iot_hw.set_dir() Configures the red_led object’s direction, which was allocated by iot_hw.gpio() red_led.write() The write() function, provided by the iot_hw module sets the value of the GPIO pin Please examine the iot_blink_led_example.py to see another example utilizing the RGB LEDs. AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 119 Getting Started with Python 4.3.5. Example: Reading the User Button Reading the User Button on the SK2 is similar to using the LEDs except for two items: • The Button needs to be set as an input (iot_hw.gpio_direction.GPIO_DIR_INPUT) • You read() the button rather than write() to it. The following example simply reads from the button and prints out its value with a string. Listing 4.3 - Chapter_04/button_read.py # button_read.py # # This script reads the button and prints whether # the button is up or down import iot_hw ON = iot_hw.gpio_level.GPIO_LEVEL_HIGH OFF = iot_hw.gpio_level.GPIO_LEVEL_LOW # Initialize the GPIO connected to the SK2 User Button button = iot_hw.gpio(iot_hw.gpio_pin.GPIO_USER_BUTTON) button.set_dir(iot_hw.gpio_direction.GPIO_DIR_INPUT) val = button.read() if val: print("The button is up (" + str(val) + ")") else: print("The button is down (" + str(val) + ")") Running the example twice – first with the button up, and then down – gives the following output. Figure 4.19 - Running the button_read.py script twice Note: Configuring the button as an interrupt is explored in Section 4.5. 4.3.6. Accessing Additional GPIO Pins The Python Peripheral IoT API Guide provides details of all the peripheral API functionality provided by the iot_hw Python module. The API guide also includes details for setting up all the GPIO pins including the RGB LEDs and the User Button. AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 120 Getting Started with Python 4.3.7. Killing a Running Python Program If you accidentally write a program that won’t exit (e.g. an endless loop) you a second terminal and Linux to kill it. This is done by getting the PID (process ID number) assigned to your program by Linux, then using the Kill command as discussed in Chapters 2 and 3. ps -e | grep python kill Here’s a simple code example for an endless loop: Listing 4.4: endless.py import time print("Starting up...") while 1: time.sleep(5) print("Five more seconds have gone by...") Running the endless.py example in the Terminal (below left), the program will run forever. By starting a second remote terminal session on the SK2 (below right) • Run the “ps” command to list the active Linux processes and pipe the results into grep to only show those named ‘python’ • Using the PID (process ID), which in this case was 4376, you can tell Linux to kill the process Figure 4.20 - Running and killing endless.py AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 121 WWAN LED Class 4.4. WWAN LED Class The Python peripheral API (iot_hw module) does not include support for the WWAN LED. The User Guide software examples include a Python class which allows easy use of the WWAN LED. The class includes the following methods: on(), off(), toggle(), value(), read(). 4.4.1. Python Functions and Classes 4.4.1.1. Python Functions You can create functions in Python using the “def” (define) keyword. The following example defines and then uses a function called my_func(). # my_func example def my_func(a): print(a) # Using the function my_func() my_func(‘Print me!’) Which outputs: Print me! Notice that, like the for loop examined earlier, the body of the function is defined by the white space, either using tabs or spaces. Just like using C, or other extensible languages, you can “import” functions from other .py files. For example, as long as we had added the proper import statement, we could have defined my_func() in a separate .py file, away from where it was used. AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 122 WWAN LED Class 4.4.1.2. Python Classes Like other high-level languages, such as C++, Python classes can contain data and methods (i.e. functions). The data and functions are coded like they are outside of classes with two distinct differences: • Class elements must follow a “class” statement. • Class elements must be indented using white-space. For example, a class called “my_class” might look like: class my_class: my_class_variable = 0 def __init__(self): # add code here to instantiate the class object def print_me(self, a): print(a) You could then use the class in your code by: x = my_class() x.print_me(“Hello”) We don’t include this example in our code listings since the next section examines a real-world example class. The goal here was to provide a simple description for Python classes. AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 123 WWAN LED Class 4.4.2. Example: Using WWAN LED Class The following code makes it easy to access and control the WWAN LED from your Python scripts, whether you want to turn the LED on or off. You can also toggle the LED and read its value. Listing 4.5: Chapter_04/wwan_class.py The WWAN LED is turned on/off using file I/O as was described in the Linux chapter. Using the value() method returns the value tracked in the class itself. Whereas, the read() method actually goes out and reads the value from filesys. AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 124 WWAN LED Class 4.4.3. Importing & Using the WWAN LED Class Using the WWAN class by following the steps required for most object-oriented languages. You must follow two steps before you can use it: • Import the class • Instantiate the class object At which point you are free to use it in your code. Listing 4.6: Chapter_04/wwan_blink.py In this example, after we imported the “wwan” class from the wwan_class python file, we were able to instantiate our local class object by setting our variable “w” equal to the wwan() class. From that point on we used the off() and toggle() methods in order to blink the WWAN LED 4 times. 4.4.4. WWAN Class Subprocessing We planned to write a simple example that showed accessing WWAN and the RGB LEDs using simple File I/O function calls like the examples in the C/C++ chapter. This proved to be more difficult in Python than expected. While performing file reads/writes in Python is pretty easy, there were timing issues when talking to the virtual GPIO and WWAN drivers. With GPIO resources being well handled by the Python Peripheral Driver API (i.e. iot_hw module), the File I/O examples for the LEDs and User Button were skipped. Unfortunately, since the API does not provide support for the WWAN LED, this needed to be handled with a File I/O solution. Sending commands (i.e. sending 0 or 1) to the WWAN LED is less problematic than GPIO since this resource does not need to be exported before use. That said, timing issues still arose, especially when trying to blink the WWAN LED quickly. The simple answer was to call shell commands from Python using the “os.system()” call. Examples for this can be seen in the following WWAN class methods: on(), off(), and toggle(). Reading the WWAN LED value was tricky. The Linux ‘cat’ function would read the WWAN virtual file from sysfs, but subprocessing was needed to return the value from ‘cat’ back to Python. Subprocessing let your Python program spawn new applications. It also has a mechanism for returning results back to your program. You can see an example of this in the WWAN read() method. AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 125 GPIO Interrupts in Python 4.5. GPIO Interrupts in Python Along with simply reading a GPIO input value, the Python Peripheral API also supports interrupts. This support is similar to the C/C++ Peripheral API support which was discussed in Chapter 3. Using GPIO pins to generate interrupts requires three steps: 1. Allocate the GPIO pin. 2. Configure the GPIO pin as an input. 3. Set the GPIO input as an interrupt (i.e. irq) specifying: a) Whether interrupts should be triggered when the pin’s value rises, falls, or in both cases. b) What callback function should run when a configured interrupt occurs. The first two steps were explored in Section 4.3.5 Example: Reading the User Button. Interrupts require one more function call to register the trigger and callback values. Examine the following example which uses the SK2 User Button to trigger an interrupt. Listing 4.7: Chapter_04/button_interrupt.py AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 126 GPIO Interrupts in Python Running the button_interrupt.py function results in the following: Figure 4.21 - Running button_interrupt.py Note that if the User Button was not pushed within the 30 second sleep time, the resulting output would not include “Interrupt occurred…”. 4.5.1. Fancier Button Interrupt Example The following example (Here’s the fancy code example. Notice below how the interrupt’s callback function ‘trigger’ argument can be used to determine whether the button was pushed or released. Listing 4.8) combines several elements discussed in this chapter: • RGB LED using the Python Peripheral API • User Button configured as an interrupt • Interrupt callback function detecting which edge (rising, falling) and acting accordingly • Using Python time.time() to get the current time – which was used to determine if the button had been held for longer than 3 seconds • WWAN LED class used to signify script is running • ‘global’ keyword allows use of global variables within a function Running the example produces the following output: Figure 4.22 - Running button_interrupt_fancy.py AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 127 GPIO Interrupts in Python Here’s the fancy code example. Notice below how the interrupt’s callback function ‘trigger’ argument can be used to determine whether the button was pushed or released. Listing 4.8: Chapter_04/button_interrupt_fancy.py AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 128 Running Python Scripts at Boot 4.6. Running Python Scripts at Boot The Linux boot sequence was discussed towards the end of Chapter 2. But here’s the gist of that discussion: In order to autostart an application when powering on the SK2, you need to add an entry into the following script: /CUSTAPP/custapp-postinit.sh In the following example, we added a shell script to custapp-postinit.sh. We viewed this file by executing the Linux ‘cat’ command. Using cat to view myCode.sh, we see that it runs a simple blink example for the Green LED and then executes the fancy interrupt example discussed in the previous section of this chapter. Figure 4.23 - Viewing custapp-postinit.sh and myCode.sh AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 129 Additional References 4.7. Additional References There are a great many Python tutorials available on the Internet. Additionally, there are a great number of Python books. Here are a couple that we found useful: • Mike McGrath. Python In easy steps (2nd Edition). In Easy Steps Limited, 2018. • Magnus Lie Hetland. Beginning Python: From Novice to Professional (3rd Edition). Apress, 2017. Please note that two generations are in active use and both supported by the community: Python 2 and Python 3. The SK2 supports Python 2, so keep this in mind as you reference the books or Internet. There aren’t a lot of differences between the two, but it good to keep this in mind when researching and referencing Python information. Along with the Python documentation, you may need to reference the API document: • SK2 Python Peripheral API Guide (link not available at the time of publishing) AT&T IoT Starter Kit (2nd Generation) User's Guide - Installing and Using Python pg. 130 5. Wireless Wide Area Networking with LTE AT&T’s 2nd Generation IoT Starter Kit (SK2) provides hardware that allows connecting the module to the Wireless Wide Area Network (WWAN). For the SK2, this puts the “I” into IoT (Internet of Things). Using both Python and C/C++, this chapter discusses connecting to the Modem Abstraction Layer (MAL) to access the WWAN, as well as status information about the module’s radio hardware. A WWAN connection to the Internet allows connection to AT&T’s IoT Cloud Platform services, such as M2X (for managing devices and storing data) and Flow (building custom IoT Cloud applications). Before venturing into these services, though, a simple HTTP example connecting the SK2 to Hookbin.com provides an easy way to confirm our ability to make HTTP connections. Finally, this chapter also examines sending SMS messages. Since the module does not presently support direct SMS communications, connections via two different 3rd party services – Twilio and IFTTT – are demonstrated. Topics 5. Wireless Wide Area Networking with LTE ................................................................................... 131 5.1. Modem Abstraction Layer (MAL) ............................................................................................ 133 5.1.1. Connecting to the MAL Using the LTE API ...................................................................... 133 5.1.2. Using WWAN API to Get Network Time........................................................................... 138 5.1.3. Python MAL Example ...................................................................................................... 140 5.2. Communicating over HTTP/HTTPS ......................................................................................... 146 5.2.1. cURL ................................................................................................................................. 146 5.2.2. Hookbin.com ................................................................................................................... 147 5.2.3. Hookbin.com Examples .................................................................................................. 148 5.3. Connecting to the Cloud: M2X and Flow ................................................................................ 157 5.3.1. M2X QuickStart Demo .................................................................................................... 158 5.3.2. Using M2X ........................................................................................................................ 164 5.3.3. Flow .................................................................................................................................. 177 5.4. Sending SMS Messages .......................................................................................................... 195 5.4.1. Twilio ................................................................................................................................ 195 5.4.2. IFTTT ................................................................................................................................. 198 AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 131 Modem Abstraction Layer (MAL) Detailed Outline 5. Wireless Wide Area Networking with LTE ................................................................................... 131 5.1. Modem Abstraction Layer (MAL) ............................................................................................ 133 5.1.1. Connecting to the MAL Using the LTE API ...................................................................... 133 5.1.1.1. Python Example (ex_01_mal_api_example.py) ............................................................ 134 5.1.1.2. C/C++ Example (c_01_mal_api_example) ................................................................... 135 5.1.2. Using WWAN API to Get Network Time........................................................................... 138 5.1.2.1. Python Example (ex_02_get_network_time) ................................................................ 138 5.1.2.2. C/C++ Example (c_02_get_network_time) .................................................................. 139 5.1.3. Python MAL Example ...................................................................................................... 140 5.1.3.1. Python Example (ex_03_get_system_info.py) .............................................................. 140 5.1.3.2. C/C++ Example (c_03_get_system_info) ..................................................................... 143 5.2. Communicating over HTTP/HTTPS ......................................................................................... 146 5.2.1. cURL ................................................................................................................................. 146 5.2.2. Hookbin.com ................................................................................................................... 147 5.2.2.1. Getting Started with Hookbin.com ................................................................................ 147 5.2.3. Hookbin.com Examples .................................................................................................. 148 5.2.3.1. Shell-Script Example (sh_04_curl_to_hookbin.sh) ...................................................... 148 5.2.3.2. Python Example: ex_04_http_to_hookbin.py ............................................................... 150 5.2.3.3. C/C++ Example (c_04_http_to_hookbin) ..................................................................... 152 5.2.3.4. C/C++ Example (c_05_http_put_post_get).................................................................. 154 5.3. Connecting to the Cloud: M2X and Flow ................................................................................ 157 5.3.1. M2X QuickStart Demo .................................................................................................... 158 5.3.1.1. Obtain a Master M2X API Key ....................................................................................... 158 5.3.1.2. Run the QuickStart Demo with Your Own M2X Key ..................................................... 160 5.3.1.3. Viewing QuickStart Data in M2X ................................................................................... 162 5.3.2. Using M2X ........................................................................................................................ 164 5.3.2.1. Using M2X with Python .................................................................................................. 164 5.3.2.1.1. Python Example (iot_m2x_example.py) ................................................................ 165 5.3.2.1.2. Python Examples (m2x examples folder) .............................................................. 167 5.3.2.1.3. Python Example (m2x_examples/example.py)..................................................... 170 5.3.2.2. Using M2X with C/C++ .................................................................................................. 171 5.3.2.2.1. C/C++ Example (c_07_m2x_create_device_stream_value) ............................... 171 5.3.3. Flow .................................................................................................................................. 177 5.3.3.1. Starting up Flow ............................................................................................................. 178 5.3.3.2. Flow Example – Timestamp/Debug (ex_09_timestamp_debug_flow.json) ............... 179 5.3.3.3. Exporting/Importing Flows............................................................................................. 182 5.3.3.3.1. Export procedure .................................................................................................... 182 5.3.3.3.2. Import Procedure.................................................................................................... 185 5.3.3.4. Flow Example – HTTP/Debug ........................................................................................ 186 5.3.3.4.1. Creating the Flow Project (ex_10_flow.json) ........................................................ 186 5.3.3.4.2. cURL Example (ex_10_curl_to_flow.sh) ................................................................ 190 5.3.3.4.3. Python Example – Sending Data to Flow .............................................................. 191 5.3.3.4.4. C/C++ Example – Sending Data to Flow .............................................................. 193 5.4. Sending SMS Messages .......................................................................................................... 195 5.4.1. Twilio ................................................................................................................................ 195 5.4.1.1.1. Setting up a Twilio Account .................................................................................... 195 5.4.1.1.2. Flow ......................................................................................................................... 196 5.4.1.1.3. From the SK2 via cURL .......................................................................................... 196 5.4.2. IFTTT ................................................................................................................................. 198 AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 132 Modem Abstraction Layer (MAL) 5.1. Modem Abstraction Layer (MAL) As described in Chapter 1, the AT&T IoT Starter Kit (2nd Generation) (nicknamed ‘SK2) contains both an applications processor – which we can program in C/C++ or Python – as well as an LTE modem to establish and manage cellular network communications over the WWAN. Applications can access and configure the modem using the MAL library API (application programming interface). After using the MAL to turn on the radio and establish connection to the cellular 3G/4G LTE network, applications are free to communicate over traditional networking protocols, such as HTTP, cURL, and so on. 5.1.1. Connecting to the MAL Using the LTE API Both Python and C/C++ languages support connections to the Modem Abstraction Layer. Each language’s API is documented in its respective manual: • Python: LTE_IoT_API_Guide • C/C++: Avnet M18Qx LTE IoT API Guide The MAL API consists of four groups of functions: 1. WWAN: Control the LTE module and retrieve status information. 2. Network: Control the system network. 3. System: Provide information about the system (e.g. the module’s ICCID). 4. Location: Managing GPS location data. Communicating with the MAL involves sending and receiving JSON packets to the modem. Code examples are provided for each language in this section. AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 133 Modem Abstraction Layer (MAL) 5.1.1.1. Python Example (ex_01_mal_api_example.py) The Python “iot_mal” module makes it easy connecting to the LTE Modem on the SK2. After importing the module, you can instantiate a Python object for each of the API’s function groups. The following example utilizes the “system” API to read the SIM Card’s number (i.e. ICCID) from the SK2 hardware. Listing 5.1: ex_01_mal_api_example.py (Python) The Python module neatly handles creating and sending the JSON packet to the modem for you. The API function returns a dictionary variable with the results as shown on the first line of the response below. Figure 5.1 - Results of ex_01_connect_to_mal.py Various Python functions can be used to extract and format the results. This example used the .get() function to extract the “iccid” field from the dictionary variable and then formatted it into a pretty output. AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 134 Modem Abstraction Layer (MAL) 5.1.1.2. C/C++ Example (c_01_mal_api_example) The following example extracts information from the MAL using the C/C++ language. The C/C++ version requires more project code than the Python example, demonstrating that Python is easier to use. Unlike Python, the C/C++ example requires a number of support files to package, send, and receive the MAL commands to and from the modem. These files were taken from Avnet’s “iot_monitor” (i.e. QuickStart) example. Using them, our main.cpp can start the data service and extract a variety of information from the MAL. • iot_monitor.h: Contains definitions for the iot_monitor application, which was the basis for the C/C++ MAL example. The simple MAL example does not require all these elements, but to keep things simple, it was copied directly from the Avnet iot_monitor example. • mal.cpp/mal.hpp: Provides an easy set of C functions for calling the MAL API. Along with getting system information from the modem, there are functions for starting and configuring cellular connections. • jsmn.c/jsmn.h/maljson.cpp: Files provided with the iot_monitor application for creating, parsing and managing JSON packets when communicating with the MAL API. These files are required by the mal.cpp when communicating with the MAL API. AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 135 Modem Abstraction Layer (MAL) Listing 5.2: c_01_mal_api_example (C/C++) AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 136 Modem Abstraction Layer (MAL) Running this example prints the following results: Figure 5.2 – Results from ex_01_mal_api_example AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 137 Modem Abstraction Layer (MAL) 5.1.2. Using WWAN API to Get Network Time The second example uses a WWAN MAL function to extract the time from the network. 5.1.2.1. Python Example (ex_02_get_network_time) Using the iot_mal.wwan() function, Python can access the time from the WWAN network. As in the previous example, the result is returned in a Python dictionary variable. The following example extracts the time from the variable and adjusts it for Central Standard Time (CST). Listing 5.3: ex_02_get_network_time.py The results for this example are shown below. Notice that there’s a 6-hour time difference between “network time” (GMT) and local time (CST). Figure 5.3 - ex_02_get_network_time.py Output AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 138 Modem Abstraction Layer (MAL) 5.1.2.2. C/C++ Example (c_02_get_network_time) As discussed in Section 5.1.1, commands sent to the modem (i.e. MAL) must be sent as JSON packets. To simplify coding, c_01_mal_api_example (Listing 5.2) reused the mal.cpp file from the “iot_monitor” C++ QuickStart demo program, because it already contained a set of functions for accessing data from the MAL. Unfortunately, mal.cpp does not contain a function to access the network time. Example c_02_get_network_time works around this limitation by adding a get_networkTime() function to mal.cpp. While this could have been added to main.cpp, we preferred to consolidate all the mal functions in mal.cpp. To make these changes we first added a new function prototype to mal.hpp: Listing 5.4: c_02_get_network_time/src/mal.hpp Creating the new function was simple. Opening up mal.cpp, make a copy of get_ipAddr() and then rename it to get_networkTime(). The only change required, besides the function name, was the command being sent to the MAL. In this case, the command needed is “get_wwan_network_time”. (This was found in the Avnet LTE API Guide.) Listing 5.5: c_02_get_network_time/src/mal.cpp AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 139 Modem Abstraction Layer (MAL) Since the main() function already referenced mal.cpp, the appropriate references were already included. That meant we only needed to add the get_networkTime() call to our code to get the time. Listing 5.6: c_02_get_network_time/src/main.cpp Thankfully, the arguments for get_networkTime(om, sizeof(om)) were easy to fill in since they are the same as the get_ipAddr() call found earlier in main.cpp. 5.1.3. Python MAL Example The final MAL information example obtains system and connection data. 5.1.3.1. Python Example (ex_03_get_system_info.py) The third MAL example turns on the modem using the network set_connection_mode() function, then retrieves system data as well as information about the connection itself. To enhance the printout, a simple parse_state() function was created in Python to translate the Connection State from a numerical value to something more readable. AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 140 Modem Abstraction Layer (MAL) Listing 5.7: ex_03_get_system_info.py AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 141 Modem Abstraction Layer (MAL) The following output was generated by this example: Figure 5.4 - ex_03_get_system_info.py Output AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 142 Modem Abstraction Layer (MAL) 5.1.3.2. C/C++ Example (c_03_get_system_info) This example expands on 5.1.2.2 C/C++ Example (c_02_get_network_time) by adding a call to WWANStatus(), which passes WWAN and Network information back for printing to the terminal. Listing 5.8: Chapter_05\c_03_system_info\src\main.cpp Rather than code this information directly into main.cpp, the new function was added to its own file to make it easier to reuse the code. In fact, you may need to obtain this information more than once if, for example, your program needs to react based on the changing value of a setting, such as connection time. AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 143 Modem Abstraction Layer (MAL) The files defining the new WWANStatus() function include wwan_status.hpp and wwan_status.cpp. The header (.hpp) file defines two data structures passed into, and updated within, the function. These were defined in a similar way to the sysinfo structure found in iot_monitor.h. Listing 5.9: Chapter_05\c_03_system_info\src\wwan_status.hpp #ifndef __WWAN_STATUS_H__ #define __WWAN_STATUS_H__ #ifdef __cplusplus typedef struct { std::string radioMode; std::string sigStrength; std::string sigLevel; std::string radioState; std::string cirSwState; std::string packSwState; std::string regState; } wwanInfo; extern wwanInfo myWwan; #endif #ifdef __cplusplus typedef struct { std::string connType; std::string connState; std::string connTime; std::string provider; std::string radioMode; std::string dbTech; std::string roamStatus; std::string sigStrength; std::string sigLevel; std::string lte; std::string wcdma; std::string ipv6; } netInfo; extern netInfo myNetw; #endif #ifdef __cplusplus extern "C" { #endif void WWANStatus(wwanInfo *, netInfo *); #ifdef __cplusplus } #endif #endif // __WWAN_STATUS_H__ AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 144 Modem Abstraction Layer (MAL) The WWANStatus() function in the wwan_status.cpp file is styled similar to how the mySystem structure (based on sysinfo) was filled out in main(). Here is a snippet of the file: Listing 5.10: Chapter_05\c_03_system_info\src\wwan_status.cpp The calls to the MAL are highlighted in the example above. These two functions, get_wwan_status() and get_connection_status(), are found in mal.cpp where they make calls into the MAL using the following two queries, respectively: • get_wwan_serving_system_status • get_network_connection_status Remember, you can find the C/C++ MAL documented in the Avnet M18Qx LTE IoT API Guide. AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 145 Communicating over HTTP/HTTPS 5.2. Communicating over HTTP/HTTPS There are many protocols supporting communication over the Internet, but none quite as ubiquitous as the HyperText Transport Protocol (HTTP). The mainstay of communication with the World Wide Web (WWW), it’s also useful sending and receiving data for a while range of uses, such as IoT data transfers. 5.2.1. cURL This section provides HTTP examples whether you are using Shell Scripts, Python, or C/C++. When communicating from the command-line – or within Shell Scripts – our examples utilize the cURL utility, which is short for “command-line URL”. cURL is defined as: Command line tool and library for transferring data with URLs. We demonstrate making HTTP requests using all three types of coding explored in this book: Shell Scripts: Uses the cURL utility found in the SK2’s Linux distribution. Python: While Python cURL libraries exist (e.g. PyCurl), these modules are not included in the SK2. Rather, these Python examples use the simple HTTP Requests library module, which is installed on the SK2. C/C++: Uses the cURL library that’s already included in the C/C++ tools. Like HTTP transactions, cURL lets you send data and headers to a URL. Look to Section 5.2.3.1 for an example showing the cURL command-line syntax. AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 146 Communicating over HTTP/HTTPS 5.2.2. Hookbin.com To demonstrate HTTP connections, this example communicates with the website Hookbin.com. Upon request, this free site provides a unique URL for each session, which allows you to simply post data to the site and then view those posts via a web browser. 5.2.2.1. Getting Started with Hookbin.com To get started with Hookbin, go to www.hookbin.com and create a new Hookbin Endpoint (that is, request a Hookbin URL). Figure 5.5 - Creating a New Endpoint at Hookbin.com Here is the URL we received. We’ve used it within the following examples. Figure 5.6 - Hookbin Endpoint AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 147 Communicating over HTTP/HTTPS 5.2.3. Hookbin.com Examples The following examples – in Shell Script, Python, and C – demonstrate sending the value of the User Button (on the SK2) to Hookbin.com. Note: The following examples depend upon the Hookbin.com endpoint that was established in the previous section (Section 5.2.2.1). 5.2.3.1. Shell-Script Example (sh_04_curl_to_hookbin.sh) The following Shell Script example borrows heavily from one of the GPIO examples found in the User Guide’s GPIO Appendix: Chapter_99_Appendix\GPIO\userButtonLed.sh Instead of modifying the RGB LED, though, this example sends the button’s value to Hookbin.com. Listing 5.11: Chapter_05\sh_04_curl_to_hookbin.sh In brief, the cURL syntax is really just a call to the cURL utility while providing the necessary commandline options. The Hookbin.com example includes four options after the “curl” command: • URL endpoint: For example, Hookbin.com endpoint you established in Section 5.2.2.1 • HTTP headers: This example included a content-type header • Transaction type: For example, we did an HTTP ‘POST’ • Data: The data (i.e. payload) you want to send (in the case of a POST) Check out the cURL website for more information: https://curl.haxx.se AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 148 Communicating over HTTP/HTTPS Running the script results in the following output to the Linux terminal: Figure 5.7 – Running sh_04_curl_to_hookbin.sh But more importantly, refresh your Hookbin.com page to see the cURL result. The Body in this example shows that our button was being held down. Figure 5.8 – Hookbin.com results for sh_04_curl_to_hookbin.sh AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 149 Communicating over HTTP/HTTPS 5.2.3.2. Python Example: ex_04_http_to_hookbin.py The SK2 Python image includes the simple HTTP requests library, making it easy to initiate HTTP transfers and allowing you to get or post information to the web. The Hookbin example utilizes the GPIO code from Chapter 4 to read the state of the SK2’s USER BUTTON and post that data to Hookbin.com. Note: While we agree that using “Requests” is simple, it’s really the developers who claim the module is “A simple HTTP library for Python, built for human beings”.) Notice the Hookbin URL, that was copied from their website, #defined in the code. This is the URL that we’ll post our button state value to. Listing 5.12: ex_04_http_to_hookbin.py AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 150 Communicating over HTTP/HTTPS This code example breaks into three sections: 1. Enable the network radio connection. 2. Get the state of the USER Button 3. Configure the “URL”, HTTP Headers, and DATA variables, then call the requests.post() function. Like using cURL in the Shell Scripts example, our HTTP post requires the same information. In this case, the “POST” command is part of the function call, while the other elements are passed as parameters. After executing the example with the USER BUTTON in the up-state, then refreshing the Hookbin.com page, the following POST information appeared. Figure 5.9 - ex_04_http_to_hookbin.py AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 151 Communicating over HTTP/HTTPS 5.2.3.3. C/C++ Example (c_04_http_to_hookbin) The C/C++ example builds upon the previous examples in this chapter by sending the module’s Connection Time to Hookbin.com. (It would have been just as easy sending the button value, but in this case, we used one of the WWAN status values read from the MAL.) Here’s the listing for main.cpp: Listing 5.13: c_04_http_to_hookbin/src/main.cpp Only four lines were added to c_03_system_info/src/main.cpp in order to send the data to Hookbin.com: 1. Include the header file for the curl_post() function. 2. The URL was #defined. (You will need to update this with your own endpoint address.) 3. Formatting the ConnectionTime into a string to pass to Hookbin. 4. Sending the data via cURL, passing the URL and string. AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 152 Communicating over HTTP/HTTPS While libcurl may already be part of the installed software, there is a little more code required to perform a cURL post. This example borrowed the http-post.c routine provided by the cURL site. We only changed their code by: • Converting main() into a function call curl_post() • Replacing the hardcoded URL and data values with parameters passed to the function Otherwise, the cURL post example provided a simple way to perform HTTP transactions. Listing 5.14: c_04_http_to_hookbin/src/my_curl_post.cpp Hint: If you look carefully through the QuickStart’s iot_monitor program, you will find they used the same method to post HTTP data. AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 153 Communicating over HTTP/HTTPS 5.2.3.4. C/C++ Example (c_05_http_put_post_get) The original QuickStart demo does not provide easy developer access to the HTTP routines used by the example, but with a few modifications they can be used in your own programs. The c_05_http_put_post_get example discards the my_curl_post.cpp/.hpp files from the previous example, replacing it with the http.c/.h files from the QuickStart IoT_Monitor example. The two big difficulties in using http.c are: • The HTTP post and put functions are static (i.e. not available external to the file). • There is a bit of preparation coding required before the HTTP functions can be used. To solve these problems, three new routines were added to http.c/.h: − do_http_put() − do_http_post() − do_http_get() The main() function in the example utilizes each of these for connecting to Hookbin.com, which was explored in the previous example. (These functions are also used in the C/C++ M2X examples in Section 5.3). Here’s a snippet of main.cpp and the results of running the example. AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 154 Communicating over HTTP/HTTPS Listing 5.15: Chapter_05/c_05_http_put_post_get/src/main.cpp AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 155 Communicating over HTTP/HTTPS d Figure 5.10 - c_05_http_put_post_get output The results at Hookbin.com are like the previous example, although you will see GET (highlighted below) and PUT results, as well as the POST version seen earlier. The differences aren’t remarkable in this context, but it shows we were able to communicate using three HTTP transaction types. Figure 5.11 - c_05_http_put_post_get Hookbin results AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 156 Connecting to the Cloud: M2X and Flow 5.3. Connecting to the Cloud: M2X and Flow AT&T provides two platform tools which make it easy to get your IoT device data into the Cloud: • M2X: Register and manage your devices, while providing storage for your data • Flow: Build custom data flows (i.e. JavaScript programs) to transform and utilize your data While a thorough investigation of these tools is outside the scope of this book, this section provides a brief explanation for these useful Cloud tools – as well as some code examples to get you started. M2X M2X is an excellent resource for IoT developers. It’s device centric, which makes it intuitive to use. You can add “devices” to your account in order to represent the devices you have in the field. Within your M2X device you can add data “streams” to represent each of the data items you want to send from your device to the Cloud. For example, if you were creating a thermostat, you might have: • M2X Device: Main Level Thermostat − Stream 1: Temperature Value − Stream 2: Humidity Value − Stream 3: Temperature Setting With this set, you could have your actual thermostat hardware send the three data values to your M2X device every minute – or whatever makes sense for your application requirements. (This was just an arbitrary example. We’ll see how the SK2 QuickStart uses M2X in the next section.) While M2X provides a nice graphical interface for letting you create and setup your devices and their associated data streams, this could be tedious if you are making and deploying a fleet of IoT hardware devices. To that end, M2X provides an extensive API letting you do almost everything from your keyboard… or better yet, from the IoT device itself. For example, using the QuickStart demo, your SK2 will create its own M2X device and data streams – and then send data to each stream every time you press the USER BUTTON. To learn more about M2X, check out: https://m2x.att.com/developer/get-started Flow AT&T Flow is based upon Node-Red which describes itself as “Flow-based programming for the Internet of Things”. Being both intuitive and easy-to-use, Flow provides you with an excellent way to manage and react to your data in the Cloud. To get started with Flow, we suggest their introductory tutorial: https://flow.att.io/help/start AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 157 Connecting to the Cloud: M2X and Flow 5.3.1. M2X QuickStart Demo We begin examining M2X using the QuickStart demo that ran automatically on your SK2 (when you pulled it out of the box) whenever it was powered up. (Note that it’s OK if you already turned off the autorun feature of this demo, we show you how to run it from the command-line.) As described in Chapter 1, the QuickStart demo collects sensor data from the SK2 and sends it to the Cloud whenever the USER BUTTON is pressed. Until now, most users could only visualize this by watching the RGB LED, as it indicated each of these steps in sequence. But, since the QuickStart demo sends the data to M2X, we can now view the sensor data in the M2X cloud. 5.3.1.1. Obtain a Master M2X API Key You need to obtain a M2X authorization key in order to send data from your QuickStart app to the M2X service. You can retrieve your key by logging into M2X and accessing your account profile. Follow these steps to access your M2X API (i.e. authorization) key. 1. Open M2X in your web browser. (Log in, if necessary). Open the following URL in your browser: m2x.att.com The upper right-corner of the service shows if you’re logged in or not. Log into the service if you’re not already logged in using your AT&T Marketplace USERID and Password (obtained in Chapter 1). Figure 5.12 - M2X service AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 158 Connecting to the Cloud: M2X and Flow 2. Open your Account Settings. In the upper-right corner of the web page, select: Manage → Account Settings as shown below. Figure 5.13 - Opening M2X Account Settings 3. Record your M2X master API Key. From the Account Settings page, record (copy) your Master API Key. Figure 5.14 - M2X Master Key Master Key ________________________________________________________________________ Protect your Master Key since it allows full access to your M2X account. Later on, we’ll see that you can create authorization keys for individual devices, but this is the Master Key. Hint: If yours becomes public, like in the case above where we shared our in print, you can use the circular arrow button to the right of the key to regenerate a new key. AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 159 Connecting to the Cloud: M2X and Flow 5.3.1.2. Run the QuickStart Demo with Your Own M2X Key Run the QuickStart demo while passing your M2X key on the command line. This will direct the output to your M2X account rather than to the Starter Kit AMOC Dashboard. Note: If you reimaged your SK2 for Python, you will need to rebuild and install the QuickStart demo C/C++ program (named “iot_monitor”) before you can continue with the remaining steps in this section. This procedure is described in Section 3.2. 4. Open an ADB remote connection to your SK2. adb shell 5. Navigate to the /CUSTAPP/iot directory. This is the location for the original QuickStart program. You may need to choose a different location if you rebuilt the program and placed it in a different location on your SK2. 6. Copy the run_demo.sh script file. We recommend making a copy of the original run_demo.sh script. cp run_demo.sh run_demo.original Hint: If you don’t have a run_demo.sh, skip to the next step. 7. Edit and save your run_demo.sh, adding your M2X API key. We used vi to edit our script: vi run_demo.sh Edit the file replacing the string after “–a” with your M2X key from Section 5.3.1.1. Figure 5.15 – Editing run_demo.sh Note: If you don’t have the run_demo.sh file, create the file and specify the correct path to your iot_monitor program, and include your M2X API key. 8. Run the QuickStart app using the run_demo.sh script. ./run_demo.sh This is the script that runs automatically when your SK2 is new. We can also run it manually. AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 160 Connecting to the Cloud: M2X and Flow 9. Send data to M2X. Once the program initializes and the LED turns Green, push the USER BUTTON to send data to the Cloud. After the LED turns green again, go ahead and push it again to send another set of data. 10. Exit the QuickStart demo. (Although, don’t exit the demo if you want to see live data received by M2X.) Following the directions printed to the terminal, you can exit the demo by pressing the USER BUTTON for more than 3 seconds. Hint: If you leave the program running and jump to the next section, you can continue to press the USER BUTTON and see new data posted live to M2X. Here’s the terminal display when following these instructions. Figure 5.16 – Running the steps from Section 5.3.1.2 AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 161 Connecting to the Cloud: M2X and Flow 5.3.1.3. Viewing QuickStart Data in M2X Returning to your M2X account, selecting the Devices button should reveal a new device named: Global Starter Kit When running the QuickStart demo, it automatically: a) Added the Global Starter Kit device to your M2X account. b) Added data streams for ADC, TEMP, XVALUE, YVALUE, and ZVALUE Each time you press the USER BUTTON, the program sends the sensor data to the five streams. Figure 5.17 – Viewing the Global Starter Kit M2X device AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 162 Connecting to the Cloud: M2X and Flow Clicking on the Global Starter Kit link (circled above) takes you to an expanded view of your device. This view lets you view a graph of your data – or view the log of data received. It also contains the Device ID, Endpoint, Device Key, and Device Serial # values which allows you to interact with your M2X device using the M2X API. Figure 5.18 – Getting Further Details on Your Device Hint: Clicking the “API Cheat Sheet” button (middle-right) brings up a series of cURL commands that can be used to interact with your M2X device. These commands can be run from your device – to say, post new data values – or on your computer to retrieve data stored in M2X. AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 163 Connecting to the Cloud: M2X and Flow 5.3.2. Using M2X At its most basic, using M2X involves creating one or more devices with streams. While there’s a lot more to the service, we will limit the discussion to these features. If you have already read the preceding parts of Section 5.3, we mentioned that you can interact with M2X in one (or all) of three ways: • M2X Web-based GUI • HTTP Rest API (e.g. using cURL) • Language Specific API libraries To make your efforts easier, the language specific API’s have been ported to the SK2 for Python. We will explore M2X through the example code provided for both Python and C/C++. 5.3.2.1. Using M2X with Python The SK2 Python IDE includes twelve examples to make it easy to work with M2X. Figure 5.19 – SK2 Python IDE’s M2X examples In this discussion, we examine three of the provided M2X examples in order to help you figure out how to use them with SK2 devices. AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 164 Connecting to the Cloud: M2X and Flow 5.3.2.1.1. Python Example (iot_m2x_example.py) This example is designed to send the SK2’s light_sensor value (discussed in a later chapter) to an M2X device. Before using this example, you need to create an M2X device with a stream named “light_sensor”. Set up M2X You can create a new device from the M2X Devices dashboard by clicking the “Create New” button and selecting “Device”. Figure 5.20 – Creating an M2X device When the create device dialog appears, give it a name – for example, “Test” – and then click the Create button at the bottom of the dialog. Scroll down the page and click on the “Add Stream” button. Set the “Stream ID” to “light_sensor” and click Save. Figure 5.21 – Creating a stream AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 165 Connecting to the Cloud: M2X and Flow Edit iot_m2x_example.py For the Python code example to find your M2X device and have the appropriate authorization, you’ll need to copy two values from your M2X device into the code example. The values are highlighted below in the M2X GUI as well as in the code listing. Figure 5.22 – Getting Device ID and Key from M2X “Test” Device Dashboard Run the Example Once you have added the two values to the appropriate Python variables, go ahead and run the Python example. In fact, try running it multiple times while changing the amount of light hitting your SK2 board. Then view the data in M2X device log (or graph). Figure 5.23 – Results after running iot_m2x_example.py multiple times AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 166 Connecting to the Cloud: M2X and Flow 5.3.2.1.2. Python Examples (m2x examples folder) Opening the m2x_examples directory in the Python IDE lists eleven examples which can be used to manage and control M2X from your SK2. In this section, we’ll utilize the two highlighted in the graphic below. Figure 5.24 – Viewing m2x_examples folder These examples were designed to be run from the command line – which means that we can call all them as shown below to create a new device and stream. The comments inside each example roughly describe how the file is to be invoked. For example, create_device.py should be called with: API_KEY= python example.py Hint: When using the M2X API functions provided as part of the Python SDK, you may find the following resources helpful: https://m2x.att.com/developer/documentation/v2/device https://github.com/attm2x/m2x-python/tree/master/m2x/v2 https://github.com/attm2x/m2x-python/blob/master/USAGE.md AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 167 Connecting to the Cloud: M2X and Flow The following shell script provides an example for running these two Python scripts as well as posting data to the stream. Originally, we planning to use post_value.py to post the data values, but this file is a self-contained example creating a device, stream and then posting data. But that’s OK because this allows us to show an example of using the HTTP REST API for interacting with M2X. Listing 5.16: sh_06_m2x_example.sh AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 168 Connecting to the Cloud: M2X and Flow Running the shell script results in the following output: Figure 5.25 – sh_06_m2x_example.sh Output AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 169 Connecting to the Cloud: M2X and Flow 5.3.2.1.3. Python Example (m2x_examples/example.py) Once you have a device that contains some stream data the example.py code will print out information about the device. Before you try out example.py beware of a few caveats: • The pprint module is not installed, therefore you need to comment out “import pprint” and change the pprint() function to printf(). • The command-line arguments for this example are different than the other examples. Rather than “API_KEY” this example calls it “KEY”. Similarly, “DEVICE_ID” is now “DEVICE”. Here’s simple script to try out, making sure you fill in your own DEVICE and KEY (and correct the items from above). Listing 5.17: ex_08_m2x_print_values.sh # Note: Your AT&T IoT Starter Kit (2nd generation) must have the Python image installed # for this example to work M2X_EXAMPLES_PATH="/CUSTAPP/iot_files/m2x_examples" MASTER_API_KEY=b2762079a8b9115e0f11060b5d73098a M2X_DEVICE_ID="293f7c83e3fb261fdbdd8ea7a3b17ff3" # Set location of your m2x_examples dir # Replace the KEY with yours # Need to replace this one, too DEVICE=$M2X_DEVICE_ID KEY=$MY_MASTER_API_KEY python $M2X_EXAMPLES_PATH/example1.py AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 170 Connecting to the Cloud: M2X and Flow 5.3.2.2. Using M2X with C/C++ The C/C++ M2X library has not been ported over to the SK2, but there are still plenty of ways to communicate with the IoT service. • Use HTTP transfers – which is what is shown in our code example below. • Run Linux cURL utility from within your C/C++ programs The QuickStart demo includes a few M2X functions which are leveraged by our example. In those cases where specific M2X functions are not available – or were too proprietary to the needs of the QuickStart demo – this example borrows from HTTP Get/Put/Post functionality. 5.3.2.2.1. C/C++ Example (c_07_m2x_create_device_stream_value) Given the following information: #define M2X_API_KEY #define M2X_DEVICE_NAME #define M2X_STREAM_NAME "b2762079a8b9115e0f11060b5d73098a" "CTEST" "temp" This example obtains the System, WWAN, and Network status info (same as examples from Section 5.1), then implements the following M2X tasks: • Given a Master M2X_API_KEY, gets a list of M2X devices for that account. • Creates a new M2X device for M2X_DEVICE_NAME, if it doesn’t already exist for this account. • Gets the streams available for M2X_DEVICE_NAME. • Creates a new stream for M2X_STREAM_NAME if it wasn’t on the downloaded list of streams. • Writes the value ‘2’ (arbitrary value) to M2X_STREAM_NAME. To use this example, you need to: • Create an M2X account. (If you don’t already have one.) • Replace the value for M2X_API_KEY with the value from your account. (Find this key as described in Section 5.3.1.1). While this example is longer than some of the others we have discussed, it breaks down nicely into manageable parts. The next four subsections describe each of these parts. AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 171 Connecting to the Cloud: M2X and Flow 5.3.2.2.1.1. Get List of M2X Devices This example uses HTTP get to access the list of devices for a user’s account. The API help for this can be found at https://m2x.att.com/developer/documentation/v2/device#List-Devices. Listing 5.18: Chapter_05/c_07_m2x_create_device_stream_value/src/main.cpp (lines 120-173) AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 172 Connecting to the Cloud: M2X and Flow 5.3.2.2.1.2. Create M2X Device (if needed) M2X uses HTTP post to create a new device. This is only done if that device name doesn’t already exist in the list we just downloaded. The API help for this can be found at https://m2x.att.com/developer/documentation/v2/device#Create-Device. Listing 5.19: Chapter_05/c_07_m2x_create_device_stream_value/src/main.cpp (lines 176-210) AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 173 Connecting to the Cloud: M2X and Flow 5.3.2.2.1.3. Get the Device’s Stream Names Like earlier when getting the list of devices, HTTP get is used to download the list of streams available for the specified device. The API help for this can be found at https://m2x.att.com/developer/documentation/v2/device#List-Data-Streams. Listing 5.20: Chapter_05/c_07_m2x_create_device_stream_value/src/main.cpp (lines 212-248) AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 174 Connecting to the Cloud: M2X and Flow 5.3.2.2.1.4. Create the Stream, then Add a Value to It The SK2 QuickStart demo code already contains generic functions for creating a stream and another for adding a value to it. Like the HTTP get/put/post functions, they are in the http.h/http.c files. Listing 5.21: Chapter_05/c_07_m2x_create_device_stream_value/src/main.cpp (lines 251-269) AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 175 Connecting to the Cloud: M2X and Flow 5.3.2.2.1.5. Results and Terminal Output After executing this program successfully, your M2X account will contain a device (named ‘CTEST’) with a stream named ‘temp’. Whether these existed before or not, the value ‘2’ will be added to ‘temp’. Here’s a record from running the program on our SK2: Figure 5.26 – Results from running c_07_m2x_create_device_stream_value Reading through this output, it appears that we had already run the program at least once before this execution because we see that both the device and stream already existed. AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 176 Connecting to the Cloud: M2X and Flow 5.3.3. Flow AT&T Flow, as is its progenitor Node-Red, is an excellent rapid-prototyping tool, as well as a production environment. Figure 5.27 – The AT&T Flow Tool The visceral, drag-and-drop environment is intuitive, making it fun and easy to use. Behind the scenes, once you hit the Deploy button, your design begins running in the ‘Cloud’ without any further effort required. Thankfully, we don’t need to worry about the details of server allocation, load balancing, and all that IT stuff which can slow you down on other platforms. This section only explores the very basic elements of Flow – that is, sending data to Flow and getting a response back. Later, in Section 5.4, we explore how to send SMS messages from Flow. Hint: At the time of writing, we had problems opening Flow in Google Chrome. Though, it works fine when using Firefox. AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 177 Connecting to the Cloud: M2X and Flow 5.3.3.1. Starting up Flow Head to https://flow.att.io to open Flow. Like M2X, Flow uses the same login settings as your AT&T Marketplace account. Flow opens to the Flow Dashboard where you can see the previous projects you’ve created. Figure 5.28 – Starting a new Flow If you’re new to flow, you may want to go check out the Resources → Get Started tutorial. Additionally, under Resources you will also find Code Examples, although most of them are not well suited for beginners. You can also access the FAQ and Community Projects from here. (The Community Projects may also be difficult for new users. If you are looking for beginner-ware, you may want to do an Internet search for Node-Red beginner projects.) To get started with a blank canvas, click the blue + button. (We’ll do this in the next section.) AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 178 Connecting to the Cloud: M2X and Flow 5.3.3.2. Flow Example – Timestamp/Debug (ex_09_timestamp_debug_flow.json) After starting Flow, we’ll create a simple, starter project. While simple, we’ll build on it with our SK2. Hint: This Flow example can be imported using the ex_09_timestamp_debug_flow.json file found in the SK2 User’s Guide GitHub site. Please refer to Section 5.3.3.3.2 for “how to” import Flow projects. 1. Create a new Flow project. Click the blue + button in the lower-right corner of the Flow Dashboard, as shown in Figure 5.28. 2. Complete the New Project dialog and click Create. We recommend calling the project: Timestamp-Debug. The Flow canvas should open after the project is created (which may take a few seconds). Note: While we explain many features about the Flow canvas when though our example, it’s outside the scope of this user guide to provide an in-depth explanation of Flow. 3. Add the Inject node to the Flow canvas. The palette to the left of the canvas contains a wide range of nodes (bubbles, functions, or whatever you want to call them). The nodes are grouped – for example, the first ones are Inputs and the second group are Outputs. Drag and drop the Inject node (from Inputs) to the canvas. (It’s about 15 nodes down the list.) After dropping the node, it should say “timestamp” with “INJECT”. AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 179 Connecting to the Cloud: M2X and Flow 4. Add the Debug node to the Flow canvas. Next, let’s add the Debug node from the Output group. Hint: Type Debug into the node search box to filter down the long list of nodes. After filtering the list using the Search box (as shown above), drag Debug onto the canvas. Note that its name will change to “msg.payload” with a small “DEBUG”. The node is telling us that it will write the payload of the incoming message (i.e. msg.payload) to the Debug window. (Which we’ll see shortly. While you can change the names of the nodes on the canvas, as well as other options, we recommend leaving them as is, for now. 5. Connect the two nodes – Inject output to Debug input. Start by clicking the white output bubble on the right-side of the Inject node… and then dragging to the white input bubble on the Debug node. 6. Deploy your design. Click the Deploy button in the upper-right corner. This turns your design into a real-world cloud server application. Note that the first time you deploy a design takes a couple of minutes to complete. Subsequent deploys (after you make changes to your design) go quickly. AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 180 Connecting to the Cloud: M2X and Flow 7. Click the Inject button (on the left side of the node). Clicking this button will inject (i.e. send out) a timestamp value. More specifically, the node will output a JSON message that contains a payload with the current timestamp. 8. Open the Debug window to view Inject node’s output. The Debug tab displays the output from Debug nodes (all Debug nodes, if you have more than one in your flow). Clicking the arrow (highlighted by the red circle) opens and closes the tabbed windows at the bottom of the display. You may need to click it to view the Debug window contents. You can toggle a Debug node on/off by clicking the button on its right side. This can be especially helpful if you have multiple Debug nodes in your Flow project. In fact, try clicking the Inject button with the Debug node turned off. AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 181 Connecting to the Cloud: M2X and Flow 5.3.3.3. Exporting/Importing Flows We can export a copy of our Flow project. Even though Flow projects are stored in your account. They can be shared and linked to Git repositories. But sometimes you might want to save a copy to your computer. Or export it so that you can send it to a colleague. Importing and Exporting are two of the options on the menu under the Deploy button. Figure 5.29 – Flow project canvas controls 5.3.3.3.1. Export procedure 1. Select all nodes (or at least the ones you want to export). Select the nodes by dragging your mouse over them. Or better yet, using Control-A. 2. Select the Export to Clipboard option. Click the hamburger menu (i.e. button with three horizontal lines), then Export, and then Clipboard. Menu → Export → Clipboard AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 182 Connecting to the Cloud: M2X and Flow 3. Copy the selected JSON text using your keyboard. (e.g. Control-C). After you click Clipboard in step 2, the following dialog appears. Export caveats: • At least one node must be selected to enable the Export menu item. • Text is not automatically sent to the clipboard. • The text must be selected in order to be copied. • Use either a keyboard shortcut or the right-click context menu to copy the text. − • It appears like you cannot copy the text with the right-click menu because a red warning sign appears at the cursor, but it does let you copy the selected text. Clicking the dialog buttons appeared to de-select the text but clicking the mouse over the text re-selects it. 4. Paste and save the copied text to a JSON file. You can save the text in any manner you prefer, but we saved our previous example to: ex_09_timestamp_debug_flow.json AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 183 Connecting to the Cloud: M2X and Flow The resulting file looks like: Listing 5.22: ex_09_timestamp_debug_flow.json AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 184 Connecting to the Cloud: M2X and Flow 5.3.3.3.2. Import Procedure Importing nodes is like exporting them. 1. Using the ‘hamburger’ menu in the upper-right corner, import from clipboard. ≡ → Import → Clipboard 2. Paste the JSON node description into the Import nodes dialog, then click Import. 3. Place the resulting nodes by moving your mouse to an appropriate location and then clicking. After clicking the Import button in the previous step, the nodes will appear (grouped together), ready for you to place them by clicking your mouse. Move your mouse around until you like the positioning of the imported nodes and then click your mouse. Try it out After exporting nodes from a Flow project, create a new Flow project by clicking the blue + button in the lower right-corner. Name the project something, such as “Import Test”. When Flow opens to a new empty project, follow the Import Procedure outlined above. When done, deploy your new flow and then test it out. After testing is complete, you can delete the Test project. Alternatively, if you want to keep the project we recommend that you set it into offline mode using the button shown in Figure 5.29 (on page 182). AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 185 Connecting to the Cloud: M2X and Flow 5.3.3.4. Flow Example – HTTP/Debug The Timestamp/Debug example is a great way to get started with Flow but doesn’t exercise the SK2. The HTTP/Debug example takes an input from an HTTP post, which will be sent by the SK2. This example is broken into four sections: 1. The first part (in Section 5.3.3.4.1) discusses the Flow project. 2. The second part (in Section 0) sends data to Flow using cURL. 3. The third part (in Section 5.3.3.4.3) sends data to Flow using Python. 4. The fourth part (in Section 5.3.3.4.4) sends data to Flow using C/C++. You only need to complete two sections to run the example. For instance, if you are only interested in programming in Python, you would need to complete #1 and #3. 5.3.3.4.1. Creating the Flow Project (ex_10_flow.json) Creating the project follows the basic procedure outlined in Section 5.3.3.2. Starting with the Timestamp/Debug project, this one requires adding three additional nodes. The first two nodes are HTTP Input (HTTP IN) and HTTP Response (HTTP RESPONSE). Figure 5.30 – HTTP Input and Response Nodes When sending an HTTP post to Flow, the HTTP response is not returned to the sender unless you add an HTTP Response node. Depending upon how you code your application posting data using HTTP, it will hang waiting for a response that never arrives. The HTTP RESPONSE node – when configured as shown in Figure 5.30 – will echo back the incoming data to the posting program. AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 186 Connecting to the Cloud: M2X and Flow But it might be more fun to do something with the incoming data. By adding a FUNCTION node to the Flow, you can create a Javascript function that will modify the payload being sent to the HTTP RESPONSE node – effectively changing what is being returned to the sender. Figure 5.31 – HTTP/Debug Flow Project Hint: The project described here can be imported using the ex_10_flow.json file. Procedure Create this Flow project using the following steps. 1. Re-use or re-create the Timestamp/Debug project from Section Flow Example – Timestamp/Debug (ex_09_timestamp_debug_flow.json)from Section 5.3.3.2. The original project contained two nodes: INJECT, DEBUG. 2. Add three new nodes to the project. Drag three more nodes onto the project canvas: − HTTP IN − HTTP RESPONSE − FUNCTION Hint: Once again, the search box at the top of the palette makes it easier to find the nodes. AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 187 Connecting to the Cloud: M2X and Flow 3. Arrange and connect the nodes as shown in Figure 5.31. 4. Configure “HTTP IN” node. Double-click on the HTTP IN node to configure it. Doing so will open a configuration panel: Method: Select Post. Any would work for this project, but POST seems appropriate. URL: The URL entered here will be appended to your Flow project’s Endpoint URL, making the URL for this node unique. This unique endpoint allows us to talk directly to this node. Name: Name the node anything you want. This is just displayed in the canvas. 5. Configure HTTP Response node. The only configuration parameter is its name. (And you don’t even have to give it a name.) 6. Configure the FUNCTION node. The Function node provides a blank canvas, so to speak, for creating a JavaScript function. We’ll use this to modify the message payload being sent from HTTP IN to HTTP RESPONSE. In our earlier description for this project we stated that we wanted to send a different value, one for the “led” color, in our HTTP RESPONSE – basing the value upon whether the incoming number data was even or odd. The following FUNCTION code implements this: var v = msg.payload.value; if ( v % 2 ) { // odd msg.payload.led node.log("Value } else { // even msg.payload.led node.log("Value } = 'green'; was 'odd'"); = 'blue'; was 'even'"); return msg; Most Flow nodes send messages with a payload. If our sending application sends the data “value=56”, the HTTP IN adds this to the payload it sends out. The FUNCTION’s JavaScript code AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 188 Connecting to the Cloud: M2X and Flow picks up this ‘value’ and then tests whether it’s odd/even. Setting an ‘led’ value to ‘green’ or ‘blue’ in the process. Hint: Setting msg.payload.led both adds ‘led’ to the message payload as well as sets its value. We suggest that you read more about Node-Red if you’d like to better understand how Flow works. Here’s the dialog we used to configure the FUNCTION node: 7. Deploy your project. Once the project has been configured, make sure you deploy it. Hint: If you hadn’t noticed before now, the little blue dots in the upper-right corner of nodes, such as in Figure 5.30, indicates that node has been modified since the Flow was deployed. With the Flow project complete, follow along with one of the next three sections in order to send data to the Flow and see its response. AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 189 Connecting to the Cloud: M2X and Flow 5.3.3.4.2. cURL Example (ex_10_curl_to_flow.sh) Sending a value to Flow is straightforward using cURL from a shell script. Here’s an example sending the two numbers 25, then 320. Listing 5.23: ex_10_curl_to_flow.sh The results from this are shown below. Figure 5.32 – Results from ex_10_curl_to_flow.sh Let us note that we didn’t use the response data from Flow in the shell script to light the LEDs. While eminently possible, we didn’t implement this. AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 190 Connecting to the Cloud: M2X and Flow 5.3.3.4.3. Python Example – Sending Data to Flow This Python example is like the earlier example: ex_04_http_to_hookbin.py The modifications from the earlier example include: 1. Changing the URL to point to Flow. 2. Adding in the code (from leds_blink.py) to initialize the RGB LED (this code is hidden by the cut-out we used to squeeze the program onto one page). 3. Selecting a random number to send as data. 4. Adding a block to turn on the ‘Blue’ or ‘Green’ LED. Listing 5.24: ex_10_http_to_flow.py AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 191 Connecting to the Cloud: M2X and Flow The results from the running the program are shown below. As well, we can confirm that the Blue or Green LED is being lit by the program. AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 192 Connecting to the Cloud: M2X and Flow Figure 5.33 –Results from ex_10_http_to_flow.py 5.3.3.4.4. C/C++ Example – Sending Data to Flow Listing 5.25: c_10_http_to_flow/src/main.cpp AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 193 Connecting to the Cloud: M2X and Flow Figure 5.34 –Results from c_10_http_to_flow/src/main.cpp AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 194 Sending SMS Messages 5.4. Sending SMS Messages SMS (short message service) is a popular way to send Alerts and other short pieces of information. It’s also an easy way to communicate from your IoT project during development. While the SK2 does not have built-in SMS messaging capabilities, it’s easy to get your kit sending messages through a third party service. We highlight two of the most popular – and easiest to work with – in this section. 5.4.1. Twilio Twilio is one of the leading mobile communications services. After setting up an account with them you can try sending SMS messages right to your phone from your connected SK2. Twilio is the larger, more professional of the two services we have provided examples for. They’ve been working in the mobile communications space for a long time. While they are not the only service available today, they make it easy to their services. 5.4.1.1.1. Setting up a Twilio Account Twilio, as of this writing, still offers free trial accounts that allow you to try out the service. Once you have signed up, you’ll need to copy down a few items that will be needed when sending SMS messages. From the Dashboard you’ll need your Account SID and Auth Token. You can paste these into the shellscript or Python examples that we’ve provided. Figure 5.35 –Twilio Dashboard The third item that you will need is either a Twilio or Verified phone number. You can find out more by visiting their trial account page. (Note that we used a Twilio number when developing these examples. It was very inexpensive over the two months we needed it.) AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 195 Sending SMS Messages 5.4.1.1.2. Flow AT&T Flow makes it easy to send SMS messages through Twilio, as shown in the following Flow project. This project takes IoT temperature data, coming from M2X (via the HTTP IN node) and processes the data. After processing, the data was posted to HookBin.com and SMS (via Twilio). Figure 5.36 –AT&T Flow project with Twilio Node The red Twilio node can be dragged from the palette and configured using the information from your account. Configuring the Twilio node is a two-step process. Clicking on the Edit icon in the dialog on the left takes you to a second dialog where you can enter your Twilio account details. Figure 5.37 –Configuring a Twilio Node in AT&T Flow 5.4.1.1.3. From the SK2 via cURL The second method uses cURL to send a message to Twilio, who then forwards it to your recipient. Twilio provides an API for development, but their Python SDK has not been ported to the SK2. We couldn’t get an HTTP post working either, but thankfully, cURL works well from either Python or a shellscript. (A C/C++ example hasn’t been created, but since example c_10_http_to_flow uses cURL, it would be easy to adapt for this purpose.) AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 196 Sending SMS Messages The following Python example sends an SMS message using Twilio. You can find the shell-script version of this example in the Chapter_05 directory in the SK2 User Guide Git. The example only requires filling in the four items of information highlighted below. Listing 5.26: Chapter_05/ex_11_send_twilio_sms.py AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 197 Sending SMS Messages 5.4.2. IFTTT The maker channel of If This Then That (IFTTT) provides another easy way to send yourself SMS messages for free. While not recommended for production systems, this service works fine for maker projects and the like. Sending SMS messages from your SK2 requires a few steps: 1. Signing up for a free IFTTT account. 2. Adding your SMS (i.e. mobile phone) number to your IFTTT account. https://ifttt.com/services/sms/settings 3. Creating an IFTTT Webhooks applet. https://ifttt.com/maker_webhooks Using the maker webhooks you can generate an IFTTT event. These events can be used to trigger any applet, though we just used it to trigger an SMS message. Clicking on the Documentation link takes you to a screen that explains how the service works. AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 198 Sending SMS Messages Your IFTTT account will generate a unique key, such as that shown below (phi0VVW9_4847GHBSSi). Using this key, you can create custom URLs to signify different maker events. Try filling in the “event” field on the documentation screen, then hitting “Test It”. AT&T IoT Starter Kit (2nd Generation) User's Guide - Wide Area Networking with LTE pg. 199 Appendix Topics Appendix ................................................................................................................................................. 200 Topics..................................................................................................................................................... 200 A1. Glossary .......................................................................................................................................... 201 A2. What is, and how do you configure, the APN? .............................................................................. 203 What is “APN”? ................................................................................................................................. 203 Starter Kit APN value ........................................................................................................................ 203 Prerequisites ..................................................................................................................................... 203 View APN ........................................................................................................................................... 203 Modify APN ........................................................................................................................................ 205 A3. General Purpose Bit I/O (GPIO) ..................................................................................................... 207 What is GPIO? ................................................................................................................................... 207 SK2 GPIO Pins for LEDs and Pushbuttons ...................................................................................... 208 GPIO Pin Numbers – WNC vs Qualcomm ........................................................................................ 209 Linux GPIO Drivers ............................................................................................................................ 210 Deallocating GPIO Resources .......................................................................................................... 214 A4. More Details about the Linux Boot Sequence .............................................................................. 217 Getting to custapp-postinit.sh .......................................................................................................... 217 A5. Troubleshooting “adb devices” ...................................................................................................... 220 A5.1 Cannot find ADB command ..................................................................................................... 220 A5.2 Execute From ADB Directory ................................................................................................... 221 A5.3 WNC_ADB unauthorized .......................................................................................................... 222 AT&T IoT Starter Kit (2nd Generation) User's Guide - Appendix pg. 200 A1. Glossary A1. Glossary APN (Access Point Name) The APN is the endpoint where cellular communications enter a cellular carrier’s mobile network. Or, as Wikipedia says, an Access Point Name (APN) is the name of a gateway between a GSM, GPRS, 3G or 4G mobile network and another computer network, frequently the public Internet. The APN’s network must be provisioned to recognize each SIM card that wants communicate with it. Based on this, most cellular phone SIM cards will not be able to communicate with IoT APN’s and vice versa. Embedded System Embedded Systems are small systems that generally provide a static set of functionalities aimed at addressing a problem. Think, for example, that your microwave oven cooks food, but that’s about it. Similarly, your thermostat controls your heating and air conditioning, but is limited to that functionality, too. EOL (End of Line) The end-of-line character(s) – also known as “newline” – tell software reading a document that a line of text has ended. While this is a relatively straightforward concept, Mac/Linux/Unix and Windows use different characters (or sets of characters) to signify EOL. − Mac / Linux / Unix use a line-feed (LF) to signify the end of a line. − Windows uses line-feed (LF) and a carriage-return (CR) to end a line. GPIO (General Purpose Input/Output) Processors (e.g. microprocessors, microcontrollers) have various ways to communicate with external devices, the most basic of which is GPIO. GPIO generally refers to talking across a single pin of the device. With a single pin the device can receive or send (i.e. the input and output in GPIO) an “On” or “Off” value using a higher or lower voltage, respectively. Programmers describe this On/Off communication using a “bit” (binary digit) which can have the value “1” or “0”. In light of this, it’s easy to understand why many users commonly define GPIO as “General Purpose Bit I/O”. LED (Light Emitting Diode) A light-emitting diode is a semiconductor light source. It’s a diode that emits light a suitable current is applied to it. LEDs can be created in a variety of colors. Microcontroller (MCU) / Microprocessor (MPU) The terms processor, microprocessor, and microcontroller are used fairly interchangeably nowadays. They generally refer to an integrated circuit (i.e. semiconductor) that can be programmed with software to implement a variety of tasks. The microprocessor originally consisted of a block called the central processing unit (CPU) which handled the execution of software mainly consisting of logical, arithmetic, and control instructions. The term “micro” processor referred to their small size as compared to the original computers (which were often room-size). While processor is a general term for “processing” things, it has also become an abbreviated way to reference microprocessors. Likewise, the acronym “MPU” is used for a long list of terms, one of which is “microprocessor”. AT&T IoT Starter Kit (2nd Generation) User's Guide - Appendix pg. 201 A1. Glossary The term microcontroller (MCU) was created in 1971 when engineers from Texas Instruments put all the building blocks of a computer onto a single integrated semiconductor. You can think of MCU’s as a superset of the microprocessor. Along with the CPU (found in the microprocessor), they added memory and input/output peripherals. Over the years both types of processors have become more and more integrated with the addition of different types of memory and peripherals. In fact, it can difficult to tell them apart in todays processor market. Vendors still use the term microcontroller, though, to refer to their processor chips which include Read Only Memory (ROM) – such as Flash EEPROM (electrically eraseable programmable read only memory). Devices use ROM memory to store software instructions, thus making them stand alone computer devices. Microprocessors, on the other hand, require an external ROM-like memory chip to store their instructions, which are usually loaded into fast RAM (read-write memory) at boot time (i.e. startup). In these days of highly integrated circuits, microprocessors still use an external memory chip because inexpensive read-only memory circuits are not fast enough to keep up with the high clock rates of MPU’s. Operating System (OS or O/S) An operating system is system software that manages computer – or embedded system – hardware and software resources and provides common services for computer programs. The OS is often thought of the support infrastructure for the program that users what to run. For example, a user may want to run a want to run a word processor. The OS does not include a program such as this, but it provides underlaying software support for such programs. Similarly, looking at an embedded system example – say, an Internet connected thermostat. The operating system would not provide the logic to control the heating and ventilation (HVAC) unit, but it would provide services to the embedded software that runs the HVAC unit. SIM (Subscriber Identity Module) A subscriber identity module or subscriber identification module, widely known as a SIM card, is an integrated circuit that is intended to securely store the international mobile subscriber identity number and its related key. These are used to identify and authenticate subscribers on mobile telephony devices AT&T IoT Starter Kit (2nd Generation) User's Guide - Appendix pg. 202 A2. What is, and how do you configure, the APN? A2. What is, and how do you configure, the APN? What is “APN”? According to Wikipedia: An Access Point Name (APN) is the name of a gateway between a GSM, GPRS, 3G or 4G mobile network and another computer network, frequently the public Internet. In other words, the APN is the endpoint for the cellular network that your IoT Starter Kit connects to. This value is not embedded into the SIM card; therefore, you may need to configure this if it’s not connecting to the network properly. Note, AT&T cellular phones (as well as other vendors) use different APN addresses. As such, you cannot generally use a SIM card provisioned for a cellular phone in your AT&T IoT Starter Kit. You must use the SIM card that comes with the Starter Kit or purchase a new IoT SIM from the AT&T Marketplace. (Note that SIM cards are defined in Chapter 1.) Starter Kit APN value The APN for our Starter Kit: m2m.com.attz Your board should be pre-configured with this value. If not, you will need to modify your board’s configuration before it can connect with the network. Prerequisites The following procedure requires: • • ADB connection to your starter kit. (Chapter 2 - ADB) Rudimetary knowledge of Linux filesystem. (Chapter 2 - Filesystems) View APN The APN for your SK2 is stored on your kit in the malmanager.cfg file. If you are comfortable with editing using the “vi” editor, you could connect to your SK2 (using “ADB shell”) and directly view this file. Alternatively, you can pull this file over to your computer and view it with any text editor. The following command will “pull” a copy of the malmanage configuration file from your SK2 filesystem to the “adb” folder on your computer. adb pull /data/user/mm_conf/malmanager.cfg C:\adb\ You don’t have to use the “adb” folder, but that is where we copied it to on our Windows computer. AT&T IoT Starter Kit (2nd Generation) User's Guide - Appendix pg. 203 A2. What is, and how do you configure, the APN? Once the file is on your computer, you can search for “name” to see if it’s set to the correct value (i.e. m2m.com.attz). You can see a picture of the “name” in the diagram below. For the comparison in Figure (Appendix) A-1, we copied the malmanger.cfg from both a working SK2 (left) and a non-working SK2 (right). Notice how the APN in the working system includes “m2m.com.attz”, while the non-working system does not. Figure (Appendix) A-1 – Malmanager.cfg comparison AT&T IoT Starter Kit (2nd Generation) User's Guide - Appendix pg. 204 A2. What is, and how do you configure, the APN? Modify APN To modify the APN for your SK2, you need to edit malmanager.cfg to include the proper APN value specified by your cellular carrier. For the SK2, that means using “m2m.com.attz”. Edit in Place You can edit your APN “in place” by connecting to the SK2 and changing the APN. 1. Verify that your computer is connected to the SK2. ADB devices 2. Open a remote session on your SK2. ADB shell 3. Change to the mm_conf directory. cd /data/user/mm_conf 4. Edit malmanager.cfg with vi. vi malmanager.cfg 5. Change the APN, as required using “vi”. See Chapter 2 - vi for more info. 6. Power-cycle your SK2. AT&T IoT Starter Kit (2nd Generation) User's Guide - Appendix pg. 205 A2. What is, and how do you configure, the APN? Edit on your Computer Alternatively, you can pull the malmanager.cfg file over to your computer. Edit it and then push it back onto the SK2. 1. Verify that your computer is connected to the SK2. adb devices 2. Pull the malmanager.cfg file onto your computer. (We chose to place it into our “adb” folder.) adb pull /data/user/mm_conf/malmanager.cfg C:\adb\ Replace C:\adb\ as needed for your OS and preference. 3. Change the APN, as required using your favorite text editor. Windows users, make sure you save the file using Unix/Linux/Mac line-endings. 4. Rename the original file. adb shell mv /data/user/mm_conf/malmanager.cfg /data/user/mm_conf/malmanager.cfg.orig 5. Push the file back onto your SK2. adb push malmanger.cfg /data/user/mm_conf/ 6. View the new and original files. adb ls /data/user/mm_conf 7. Power-cycle your SK2 to utilize the new APN. AT&T IoT Starter Kit (2nd Generation) User's Guide - Appendix pg. 206 A3. General Purpose Bit I/O (GPIO) A3. General Purpose Bit I/O (GPIO) What is GPIO? From the glossary we find GPIO defined as: Processors (e.g. microprocessors, microcontrollers) have various ways to communicate with external devices, the most basic of which is GPIO. GPIO generally refers to talking across a single pin of the device. With a single pin the device can receive or send (i.e. the input and output in GPIO) an “On” or “Off” value using a higher or lower voltage, respectively. Programmers describe this On/Off communication using a “bit” (binary digit) which can have the value “1” or “0”. In light of this, it’s easy to understand why many users commonly define GPIO as “General Purpose Bit I/O”. In other words, GPIO allows us to send or receive a single bit of information at a time through one of the GPIO pins on a processor. While multiple GPIO pins on a device could be grouped together to send larger numerical values than 1 or 0, a single bit of information is actually quite useful in embedded systems. With a single bit we can control lights (e.g. LED) or read the value of a switch. Similarly, we could use it to control whether a motor – or just about anything – is on or off. Of course, there is a limited amount of power that can be supplied by a microcontroller’s pin, but the GPIO pin can be used to control a relay or driver that can supply a much greater amount of power to a circuit. Looking at at a simple circuit connecting an LED to a GPIO pin we see: Figure (Appendix) 2 - Generic LED Circuit In this example, the GPIO pin is supplying the voltage and current which travels through a resistor, the LED, and then into ground. When the pin is set to low (i.e. “0”), there is little to no voltage difference between the pin and ground and therefore the LED is off. Conversely, when the pin is set high (i.e. “1”), the voltage drop between the pin and ground is large enough to allow the LED to turn on. Note: If you were building this circuit, you would choose a resistor value that allows the full (or desired) brightness of the LED without burning it out. The LED circuits on the SK2 board are a bit fancier than what we have shown here, but the premise still holds. By setting the GPIO pin on the processor module to “1” or “0” we can turn the associated LED on or off. AT&T IoT Starter Kit (2nd Generation) User's Guide - Appendix pg. 207 A3. General Purpose Bit I/O (GPIO) SK2 GPIO Pins for LEDs and Pushbuttons As shown in Chapter 1 (Hardware Overview), the SK2 provides a few user-controllable items connected to GPIO lines on the WNC module. They include: • WWAN LED – which uses 1 GPIO pin. • RGB LED – which uses 3 GPIO pins to control the Red, Green, and Blue individual colors. • User push-button switch – which uses a GPIO pin to input the physical state of the switch. The SK2 schematic shows how the GPIO lines are connected to each user component. For example, here’s a clip of the schematic showing the RGB LED. From this diagram, we can see that the following GPIO pins are connected to the RGB LED colors: GPIO92 Red LED GPIO101 Green LED GPIO102 Blue LED Therefore, we need to set the values on these three pins to turn the associated LEDs on/off, which is discussed in Chapter 2 where we demonstrate controlling LEDs from the Linux Shell. In fact, one of the examples takes this a step further by showing how to blink an LED, turning it off/on once per second. Figure (Appendix) 3 - RGB By speeding up the blinking to a rate fast enough that the human eye LED Schematic doesn’t perceive blinking anymore, you could effectively control the brightness of each LED. And with the RGB LED, by similarly controlling all three LEDs and their brighnesses, it’s possible to create the effect of generating a wide array of colors. AT&T IoT Starter Kit (2nd Generation) User's Guide - Appendix pg. 208 A3. General Purpose Bit I/O (GPIO) GPIO Pin Numbers – WNC vs Qualcomm As discussed earlier in this document, the IoT Starter Kit (2nd generation) board includes the WNC M18Q2FG-1 LTE module. If we could look inside the WNC module, we would find it contains a Qualcomm processor, which is at the heart of the SK2. Figure (Appendix) 4 - SK2 Nested Processor Modules The GPIO pins from the Qualcomm processor are routed to pins on the WNC module… which are then routed to the various components on the SK2, such as the LEDs. As often happens when building systems up from various components, WNC pin numbers don’t exactly match with those coming from the Qualcomm processor. Here’s a table that describes the GPIO pin numbers we are concerned with: SK2 Component WNC Pin Number Qualcomm Pin Number USER Button GPIO98 GPIO_MDM_GPIO23 RGB – Red LED GPIO92 GPIO_MDM_GPIO38 RGB – Green LED GPIO101 GPIO_MDM_GPIO21 RGB – Blue LED GPIO102 GPIO_MDM_GPIO22 Using this table as a key, we can figure out how to design the hardware or software. Since the SK2 hardware designers were building the board using the WNC module, their design schematics show the WNC GPIO pin numbers (e.g. Red LED connected to GPIO92). On the other hand, since software actually runs on the Qualcomm processor inside the WNC module, software should be written using the Qualcomm pin number. For example, from the Linux shell we can use the Linux “echo” command to write a “1” to Pin 38 to turn on the Red LED. (We explain what “/value” means in the next section.) echo 1 > gpio38/value Note that code examples for controlling LED’s using Python and C will be described in Chapters 3 and 4. Note: The WWAN LED is driven by the WWAN pin on the WNC module. As such, it does not connect to a general purpose GPIO pin which is why it was not listed in the WNC vs Qualcomm table. AT&T IoT Starter Kit (2nd Generation) User's Guide - Appendix pg. 209 A3. General Purpose Bit I/O (GPIO) Linux GPIO Drivers By choosing Linux for the SK2, its developers were granted access to the various services in the O/S. In this case, it means they were able to utilize the Linux GPIO driver architecture. But it’s not only the developers who benefit by using standard Linux drivers, SK2 users also get to use a common, standard driver API for GPIO. If you’re experienced with Linux, the following should be familiar to you; if you’re new to Linux, you’ll not only learn how to use the GPIO driver for the SK2, but this knowledge will likely by useful if you ever use another Linux based system. GPIO Driver Architecture As discussed in Chapter 2 (Kernel Space vs User Space), the Linux Kernel owns all the hardware resources. Users must request access – or call Kernel functions – to gain access to these resources. Such is the case with GPIO. The Linux GPIO driver architecture provides a standard methodology for accessing and reading/writing the available GPIO pins in the system. When a User request is granted by the Linux Kernel, it will become available under the Sysfs (“system file system”) directory in the Linux filesystem. Specifically, it will be found in: /sys/class/gpio Also mentioned back in Chapter 2 (Virtual Files), that while its obvious that a GPIO pin is not a real file, upon request, Linux will create a virtual file interface for each available GPIO pin that you can read or write. For example, writing a “1” to this virtual file will set the associated GPIO pin “on” (i.e. high voltage). GPIO Control Interface The Linux GPIO driver provides two functions for controlling User access to a GPIO pin: export unexport Request kernel to export control of GPIO pin to userspace “Return” control of GPIO pin back to kernel Note that once you “export” a pin, unless you export it, it will be available until you power-down or reset the device. In other words, it’s common to “export” the pins you need during your programs system initialization code. GPIO Signal Interface Once exported, access to GPIO pins are found along the /sys/class/gpio path. For example, gpio38 would be found in the filesystem at: /sys/class/gpio/gpio38 Even further, working with each GPIO is structured around a standard set of read/write attributes. direction Defines which direction (“in” or “out”) should be assigned to a given pin. Note that the the SK2 hardware is fixed for the GPIO pins being discussed; in other words, you cannot change how the hardware works by using this signal, rather, you must apply the value as assigned by the hardware (i.e. “out” for LED, “in” for button). value Represents the “value” of the pin. For input direction, reads as either a 0 (low) or 1 (high). When used as an output, writing a 0 sets the pin “low”, while any non-zero value sets it “high”. AT&T IoT Starter Kit (2nd Generation) User's Guide - Appendix pg. 210 A3. General Purpose Bit I/O (GPIO) LED Examples Considering the previous discussions for the SK2 GPIO assignments and the Linux GPIO driver architecture, the following shell code example turns “on” the RED. Listing (Appendix) 1 - # TurnOnRedLed.sh # TurnOnRedLed.sh # # This simple example turns on the Red RGB LED # cd /sys/class/gpio echo 38 > export echo out > gpio38/direction echo 1 > gpio38/value Listing (Appendix) 2 - Turn off Red LED # TurnOffRedLed.sh # # This simple example turns off the Red RGB LED # cd /sys/class/gpio echo 38 > export echo out > gpio38/direction echo 0 > gpio38/value Like the export command, the direction persists until the system is reset or powered off. Thus it can also be set once in your program’s initialization code. The following blink example simply blinks the Blue LED five times. Listing (Appendix) 3 - Blink the Blue LED five times # blinkBlue.sh # # This is a simple example for blinking the Blue RGB LED five times # - The For loop executes once per character (a thru e) # - 'sleep 1' causes the cpu to wait 1 second # - At the end of the script, the LED is turned off # cd /sys/class/gpio echo 22 > export echo out > gpio22/direction for var in a b c d e; do echo 0 > gpio22/value sleep 1 echo 1 > gpio22/value sleep 1 done echo 0 > gpio22/value AT&T IoT Starter Kit (2nd Generation) User's Guide - Appendix pg. 211 A3. General Purpose Bit I/O (GPIO) USER Button Examples The USER button on the SK2 is like the LED example except that we set it up as an input and read the value from the virtual file. Hint: The SK2 button hardware was designed so that the button is “up” by default and therefore reads as “1”. When pressed down, the button will read as “0”. The first button example makes use of the Linux “cat” command. You may remember that this will read the contents of a file and write it to the standard output (i.e. your ADB shell terminal – refer to Chapter 2 for a listing of common Linux shell commands as well as how to use the ADB shell.) The example also sleeps for 3 seconds after reading the switch, letting you change the state of the button – that is, pressing it down – before reading the button again. Listing (Appendix) 4 - Reading USER Button # userButtonCat.sh # # This is a simple example reads the value of the user button # and outputs the value (using 'cat') to the command line. # It then waits 3 seconds and does it again# cd /sys/class/gpio echo 23 > export echo in > gpio23/direction cat gpio23/value sleep 3 # now hold-down the USER button and press up-arrow to repeat previous command cat gpio23/value AT&T IoT Starter Kit (2nd Generation) User's Guide - Appendix pg. 212 A3. General Purpose Bit I/O (GPIO) The second button example reads the value of the button and turns on either the Red or Green LED. Listing (Appendix) 5 - USER Button Lights Green or Red LED # userButtonLed.sh # # This example reads the value of the user button and turns # on either the Green or Red RGB LED depending upon the value # of the user button # # Go to the GPIO directory cd /sys/class/gpio # Grant user-space access to all 3 LEDs and the USER button # USER button echo 23 > export echo in > gpio23/direction # Green LED echo 21 > export echo out > gpio21/direction # Blue LED echo 22 > export echo out > gpio22/direction # Red LED echo 38 > export echo out > gpio38/direction # Turn echo 0 echo 0 echo 0 off all three LEDs > gpio38/value > gpio22/value > gpio21/value # Read the value of the USER push button into "val" val=$(cat gpio23/value) echo $val # Turn on LED if [ $val -gt 0 ] then # If "up" turn on Green LED echo 1 > gpio21/value else # If "down" turn on Red LED echo 1 > gpio38/value fi Further Reading For further details, you may want to refer to: https://www.kernel.org/doc/Documentation/gpio/sysfs.txt AT&T IoT Starter Kit (2nd Generation) User's Guide - Appendix pg. 213 A3. General Purpose Bit I/O (GPIO) Deallocating GPIO Resources It likely goes without saying that most programmers realize that they should deallocate any resources they used at the end of their programs. Needless to say, our early blink LED examples did not, which caused problems when running and debugging them. To address this, we added the deinit() function as well as testing for whether we obtained the resource during init(). The differences can be seen in this comparison: This Appendix discusses what went wrong with the original example as well as our experiences debugging the example. AT&T IoT Starter Kit (2nd Generation) User's Guide - Appendix pg. 214 A3. General Purpose Bit I/O (GPIO) What’s wrong with this example? The original code (api_red_led/src/main.c) runs, so what’s wrong with it? Try running it a second time (without power-cycling the board) and you see that it fails. This is because we allocated the GPIO pin to our program but did not deallocate it before exiting the program. In fact, even when we fixed this problem (discussed next) it can still cause problems when debugging buggy code. We can easily solve the allocation/deallocation problem by inserting the following line of code at the end of the program: gpio_deinit( &myGpio ); This line deallocates the GPIO pin resource once we are done using the pin, but before exiting the program. It’s always good programming practice to release any resources – especially shared hardware resources – before exiting your programs. But wait, there’s another problem with this code example… we never checked for a valid return (“ret”) from the gpio_init() function. Therefore, this example doesn’t even recognize the case where the GPIO pin might have been allocated to a different program. These types of resource collisions can be very difficult to find. It’s always good practice to verify function return values and handle the problem ‘elegantly’ when a resource conflict occurs. You can find an example that addresses both issues in the User Guide code examples. Look for the following Chapter 3 project: Chapter_03/api_red_led_with_deinit AT&T IoT Starter Kit (2nd Generation) User's Guide - Appendix pg. 215 A3. General Purpose Bit I/O (GPIO) API GPIO Init Problems When Debugging It’s not uncommon to iterate between editing and debugging your code – whether writing in C, shell scripts, or Python. We invariably start out with bugs in our code and slowly fix them all until the program is running smoothly. What happens when the program fails between initializing a GPIO pin (as in the preceding example) and using it? Since we don’t finish executing the program, the GPIO pin doesn’t get de-initialized. Thus, unless you’re rebooting your SK2 between each iteration, the next call to initialize the same GPIO pin will fail. And, since your new program did not initialize the resource, you cannot even call the gpio_deinit() API function to de-initialize it. Looking back to the file i/o version of the program, we can guess that the gpio_init() function is – among other things – exporting the pin to user space. Once exported, the gpio_init() function was not written such that it can re-export the pin. You can simulate this problem by running the fileio_red_led program, which exports the red LED pin (but doesn’t unexport it), before running the api_red_led program. The “api” version of the program fails because it cannot successfully initialize the pin with gpio_init(). > ./fileio_red_led > ./api_red_led <--- Fails to run You can solve this problem by “unexporting” the pin before calling the api_red_led program. Doing this allows the gpio_init() function to successfully allocate the pin. The programs fileio_export and fileio_unexport allow you to easily export or unexport the GPIO pins, which can be handy when testing and debugging your programs. > ./fileio_red_led > ./fileio_unexport > ./api_red_led <--- Successfully runs Besides debugging, how might this affect you? 1. When your program is running in production, it’s not likely that you will run into this problem – unless your program fails and it’s restarted without rebooting the board. 2. Your program can borrow from the fileio_unexport program, forcing the GPIO pin to be made available by writing to the GPIO pin’s unexport virtual file. 3. Forcing a pin to be available (i.e. unexported) in a program may solve ‘your’ problem… but this may create problems with ‘other’ programs. Unlike non-Linux embedded systems, Linux allows us to execute many programs simultaneously. This can be a convenient way to build (or add) functionality into your embedded system. But “stealing” resources (as described in #2) will cause one program to run while crashing another. 4. If two programs MUST share a hardware resource, such as a pin, you must handle this in advance. There are many examples discussed across the Internet – and in Universities – for handling resource conflicts. We’ve even seen cases where one program thread owns the resource and handles requests from many other program threads. In the end, you will need to plan how – and where – to allocate the resources available to your system. AT&T IoT Starter Kit (2nd Generation) User's Guide - Appendix pg. 216 A4. More Details about the Linux Boot Sequence A4. More Details about the Linux Boot Sequence Chapter 2 (Linux Boot Sequence) provided the simple answer to “How does the QuickStart boot automatically run at startup?” The QuickStart program (called iot_monitor) is started by the script /CUSTAPP/custapp-postinit.sh which is always run by Linux once the boot process has completed. This chapter provides further details for how this script gets run. The following discussion is only background information, though, since the scripts leading up to custapp-postinit.sh reside in read-only memory on the SK2. Getting to custapp-postinit.sh We won’t start at the beginning of the Linux boot sequence, but rather at the at the point where it runs a set of scripts found in the “/etc/rc5.d” directory. Figure (Appendix) 5 - Listing /etc/rc5.d Ideally a very skilled system administrator can modify these scripts files to change the system options and programs that get started at boot time. (But as we said above, on the SK2 these files reside in read-only memory and cannot be changed.) AT&T IoT Starter Kit (2nd Generation) User's Guide - Appendix pg. 217 A4. More Details about the Linux Boot Sequence During the boot process, Linux executes these files in numerical order. “S01” is executed first, followed by “S15”, then “S20”, and so on. The following diagram highlights this sequence. Figure (Appendix) 6 - Linux Boot Sequence - running files from /etc/rc5.d Note that S25host-mode-preinit.sh executes 4th – or better put, very early in the boot process – while S100host-mode-postinit.sh executes last or very late in the process. Viewing the contents of /etc/rc5.d/S25host-mode-preinit.sh we see: Listing (Appendix) 6 - /etc/rc5.d/S25host-mode-preinit.sh #!/bin/sh if [ -e /data/custapp-preinit.sh ]; then chmod +x /data/custapp-preinit.sh . /data/custapp-preinit.sh fi Looking at this file, we see that the S25host-mode-preinit.sh file calls /data/custapppreinit.sh, and this is started early in the process. AT&T IoT Starter Kit (2nd Generation) User's Guide - Appendix pg. 218 A4. More Details about the Linux Boot Sequence From Chapter 2, remember /data is a link to /CUSTAPP. Examining that directory: /CUSTAPP # total 1144 drwxrwxrwx drwxr-xr-x -rw-r--r--rwxrwxrwx drwxr-xr-x drwxrwxrwx drw-r--r-lrwxrwxrwx drwxr-xr-x ls -la 6 122 129 1128 Feb 8 20:09 . 24 root root 2048 Feb 7 20:34 .. 1 root root 170378 Feb 8 20:38 all.log 1 root root 0 Feb 7 19:51 custapp-postinit.sh 2 root root 304 Jan 1 1970 fwup 2 root root 304 Feb 6 22:39 iot 2 root root 312 Jan 3 1970 psm 1 root root 11 Jan 1 1970 upload -> /mnt/upload 5 root root 592 Jan 2 1970 user we find there is not a file called custapp-preinit.sh. That is okay, though, since the script tests for the existence of the file before executing it (using the “-e” option). Further down the list of /etc/rc5.d files is a second script S100host-mode-postinit.sh that executes after all the board “services” are set up and running. This script: Listing (Appendix) 7 - /etc/rc5.d/S100host-mode-postinit.sh #!/bin/sh if [ -e /data/custapp-postinit.sh ]; then chmod +x /data/custapp-postinit.sh . /data/custapp-postinit.sh fi also tests for and executes a program in the /data (i.e. /CUSTAPP) directory called custapppostinit.sh. This is the same file we discussed in Chapter 2 (How Does the QuickStart Run). Examining it we find: Listing (Appendix) 8 - /CUSTAPP/custapp-postinit.sh start-stop-daemon -S -b -x /CUSTAPP/iot/run_demo.sh Following the chain to /CUSTAPP/iot/run_demo.sh file, we find that it finally points to the QuickStart demo executable, called iot_monitor. Listing (Appendix) 9 - run_demo.sh iot_monitor -q5 -a a2e26b03f4e77aab23dbc5294b277d69 That’s quite a long process to start the “iot_monitor” QuickStart demo, but this chain of events provides a great deal of flexibility for the Linux operating system. In our case, we can create/edit the two init scripts in the /CUSTAPP directory to kick off programs early or late in the boot process, as needed: custapp-preinit.sh custapp-postinit.sh This process was explored, for custapp-postinit.sh, in Chapter 2. AT&T IoT Starter Kit (2nd Generation) User's Guide - Appendix pg. 219 A5. Troubleshooting “adb devices” A5. Troubleshooting “adb devices” Chapter 2 (Section 2.4) describes how to connect the AT&T IoT Starter Kit (2nd Generation) (i.e. SK2) to your development computer using ADB. This includes both installing ADB as well as the commands that can be issued to start the service, find your device, and connect to it remotely. Ideally, when you enter the “adb devices” command into your terminal, the response will be: WNC_ADB device This appendix topic provides a few troubleshooting suggestions for when this expected response doesn’t occur. Here are the troubleshooting topics: − A5.1 Cannot find ADB command − A5.2 Execute From ADB Directory − A5.3 WNC_ADB unauthorized A5.1 Cannot find ADB command For example, when executing the “adb devices” command, we received the following error. Figure (Appendix) 7 - Mac/Linux/PowerShell needs “./” There are three reasons the ADB commands might not be recognized by your system. 5. ADB was not installed (or improperly installed) on your computer. If this is the case, go review and implement the installation directions in Section 2.4.1. 6. Not running ADB from the “adb” folder. When following the ADB installation directions in this guide (and most Internet sites), you need to execute ADB commands from the ADB installation folder. The exception to that in this guide was if you installed ADB with apt-get on an Ubuntu (i.e. Debian) Linux computer. Please refer to the next topic (Section A5.2.) 7. Precede the ADB command with ./ A good rule of thumb would be, “If the adb devices command doesn’t work on your computer, then try ./adb devices.” When using Windows PowerShell, Mac, or Linux, you need to precede commands with the ./ characters. Therefore, you should do the same with ADB commands. ./adb devices Note that PowerShell also accepts using the backslash character: .\adb devices AT&T IoT Starter Kit (2nd Generation) User's Guide - Appendix pg. 220 A5. Troubleshooting “adb devices” A5.2 Execute From ADB Directory The ADB executable wasn’t found: Figure (Appendix) 8 – Execute from the ADB Folder Since “./adb” was used correctly for PowerShell, we know that wasn’t the issue. But it appears we were trying to run ADB from the “C:/” drive location. Unless you modify your Windows configuration (i.e. PATH variable), you either need to specify the full path to ADB… or simply run ADB from the folder you installed it to. Change to the ADB folder by using the “cd” command as shown above. Since we installed ADB to the “C:\adb” directory, and our cursor resides at “C:\”, we only need to use: cd adb adb devices to get to the proper location before running the “adb devices” command. AT&T IoT Starter Kit (2nd Generation) User's Guide - Appendix pg. 221 A5. Troubleshooting “adb devices” A5.3 WNC_ADB unauthorized When executing the “adb devices”, the command returns the error: WNC_ADB unauthorized Such as in this example: Figure (Appendix) 9 – WNC_ADB unauthorized In this case, it appears that the ADB server started and found the SK2 (our WNC_ADB) device but did not find the proper credentials to access the device. This error occurs when ADB cannot find the correct authorization key in your .android directory. Examine your .android directory. It should now contain two files: Figure (Appendix) 10 – adb keys adbkey is a private key generated by the ADB Server based upon the adbkey.pub file we placed in our .android directory, if you followed our ADB Installation directions in Section 2.4.1). If you examine adbkey with a text editor, you will notice it looks something like: Figure (Appendix) 11 - Private key If our device is unauthorized, then something is likely wrong with this file. Since it is generated from adbkey.pub, it is likely that the correct adbkey.pub was not present before running “adb devices” or has been corrupted. (For some reason, starting the ADB server sometimes overwrites adbkey.pub with an incorrect hash string.) AT&T IoT Starter Kit (2nd Generation) User's Guide - Appendix pg. 222 A5. Troubleshooting “adb devices” Procedure to Correct “WNC_ADB unauthorized” 1. Double-check that adbkey.pub still contains the single word “wnc000000” (without the quotes). If it doesn’t, delete the contents of this file and replace it with this word. You can do this by manually enter the word or by downloading this file from the Avnet GitHub. Figure (Appendix) 12 - adbkey.pub Hint: The adbkey.pub file should contain only this word. It should not contain either a carriage-return or line-feed. 2. Run the following ADB command to stop the adb server from running. adb kill-server or ./adb kill-server 3. Run the “adb devices” command again. You can see the sequence we followed below. Replace corrupt contents of “adbkey.pub” with the single word: wnc000000 Then run kill-server command Figure (Appendix) 13 - kill-server and re-running adb devices AT&T IoT Starter Kit (2nd Generation) User's Guide - Appendix pg. 223 A5. Troubleshooting “adb devices” If the preceding three steps do not result in “WNC_ADB device”, here’s a few more things to try. 4. Try killing and starting the server several times by repeating this sequence of commands. Each time, confirm that the adbkey.pub file is still 9 bytes. If not, correct it as shown above. Then run the “adb devices” command again. adb kill-server adb start-server adb devices (or ./adb kill-server) (or ./adb start-server) (or ./adb devices) Did it work? Does adbkey.pub still only contain 9-bytes? Try repeating it again. 5. If you are using Linux, try using SUDO. Linux users report that starting the server with sudo (i.e. as a root user) can often help to get ADB working. Make sure the ADB server is off, by using kill-server, then try starting the server with sudo. adb kill-server sudo adb start-server adb devices Did it work? Does adbkey.pub still only contain 9-bytes? Try repeating it again. AT&T IoT Starter Kit (2nd Generation) User's Guide - Appendix pg. 224
Source Exif Data:
File Type : PDF File Type Extension : pdf MIME Type : application/pdf PDF Version : 1.7 Linearized : No Author : www.mindshareadvantage.com Create Date : 2019:02:08 23:38:24-06:00 Modify Date : 2019:02:10 16:24:21-06:00 Subject : AT&T IoT Starter Kit (2nd Generation) User's Guide Has XFA : No Tagged PDF : Yes XMP Toolkit : Adobe XMP Core 5.6-c016 91.163616, 2018/10/29-16:58:49 Metadata Date : 2019:02:10 16:24:21-06:00 Creator Tool : Acrobat PDFMaker 19 for Word Format : application/pdf Title : Preface Description : AT&T IoT Starter Kit (2nd Generation) User's Guide Creator : www.mindshareadvantage.com Document ID : uuid:08ac4af8-5e15-4f32-8b64-efb9bf83e797 Instance ID : uuid:54b6647f-a0a7-415c-98c4-d2de3cac6e79 Producer : Adobe PDF Library 19.10.96 Page Count : 224EXIF Metadata provided by EXIF.tools