{"id":9769,"date":"2024-03-25T11:43:02","date_gmt":"2024-03-25T11:43:02","guid":{"rendered":"https:\/\/www.bairesdev.com\/tools\/tessel\/?p=9769"},"modified":"2024-05-09T11:05:56","modified_gmt":"2024-05-09T11:05:56","slug":"technical-overview","status":"publish","type":"post","link":"https:\/\/www.bairesdev.com\/tools\/tessel\/docs\/technical-overview\/","title":{"rendered":"Technical Overview"},"content":{"rendered":"\n<p>This guide is intended to help code contributors understand how relevant system components of Tessel 2 work, where to find code and design files, and accelerate the development process through technical transparency.<\/p>\n\n\n\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_66_1 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title \" >Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/www.bairesdev.com\/tools\/tessel\/docs\/technical-overview\/#Relevant_Github_Repositories\" title=\"Relevant Github Repositories\">Relevant Github Repositories<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/www.bairesdev.com\/tools\/tessel\/docs\/technical-overview\/#Tessel_2_Core_Repos\" title=\"Tessel 2 Core Repos:\">Tessel 2 Core Repos:<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/www.bairesdev.com\/tools\/tessel\/docs\/technical-overview\/#Tessel_2_Tools\" title=\"Tessel 2 Tools\">Tessel 2 Tools<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/www.bairesdev.com\/tools\/tessel\/docs\/technical-overview\/#Hardware_Designs\" title=\"Hardware Designs\">Hardware Designs<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/www.bairesdev.com\/tools\/tessel\/docs\/technical-overview\/#Modules\" title=\"Modules\">Modules<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/www.bairesdev.com\/tools\/tessel\/docs\/technical-overview\/#System_Architecture\" title=\"System Architecture\">System Architecture<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/www.bairesdev.com\/tools\/tessel\/docs\/technical-overview\/#High_Level_Look_At_Hardware\" title=\"High Level Look At Hardware\">High Level Look At Hardware<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/www.bairesdev.com\/tools\/tessel\/docs\/technical-overview\/#Software_Architecture\" title=\"Software Architecture\">Software Architecture<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/www.bairesdev.com\/tools\/tessel\/docs\/technical-overview\/#A_Code_Deploy_Example\" title=\"A Code Deploy Example\">A Code Deploy Example<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/www.bairesdev.com\/tools\/tessel\/docs\/technical-overview\/#More_Useful_Links\" title=\"More Useful Links\">More Useful Links<\/a><\/li><\/ul><\/nav><\/div>\n<h2 class=\"wp-block-heading\" id=\"relevant-github-repositories\"><span class=\"ez-toc-section\" id=\"Relevant_Github_Repositories\"><\/span>Relevant Github Repositories<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Quick guide to the Tessel stack (in order of complexity):<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Level<\/th><th>Stack<\/th><th>Repo<\/th><\/tr><\/thead><tbody><tr><td>User \/ Module Code<\/td><td>JS<\/td><td>(Many)<\/td><\/tr><tr><td>CLI<\/td><td>JS<\/td><td><a href=\"https:\/\/github.com\/tessel\/t2-cli\" target=\"_blank\" rel=\"noreferrer noopener\">t2-cli<\/a><\/td><\/tr><tr><td>Tessel Library<\/td><td>Linux \/ JS \/ Comms<\/td><td><a href=\"https:\/\/github.com\/tessel\/t2-firmware\" target=\"_blank\" rel=\"noreferrer noopener\">t2-firmware<\/a><\/td><\/tr><tr><td>OpenWRT<\/td><td>Linux \/ C \/ Shell \/ More<\/td><td>t2-firmware<\/td><\/tr><tr><td>SSH\/GPIO&nbsp;Daemons<\/td><td>Linux \/ C<\/td><td>t2-firmware<\/td><\/tr><tr><td>Firmware<\/td><td>C \/ Comms<\/td><td>t2-firmware<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"tessel-2-core-repos\"><span class=\"ez-toc-section\" id=\"Tessel_2_Core_Repos\"><\/span>Tessel 2 Core Repos:<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>You can find all of the Tessel repositories&nbsp;<a href=\"https:\/\/github.com\/tessel\/\" target=\"_blank\" rel=\"noreferrer noopener\">on the organization page<\/a>&nbsp;but this section provides some guidance over relevant Tessel 2-specific repositories.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"tessel-2-command-line-interface-cli\"><a href=\"https:\/\/www.github.com\/tessel\/t2-cli\" target=\"_blank\" rel=\"noreferrer noopener\">Tessel 2 Command Line Interface<\/a>&nbsp;(CLI)<\/h5>\n\n\n\n<p>The&nbsp;<a href=\"https:\/\/web.archive.org\/web\/20220129201706\/https:\/\/tessel.gitbooks.io\/t2-docs\/content\/GLOSSARY.html#cli\" target=\"_blank\" rel=\"noopener\">CLI<\/a>&nbsp;is the primary method of interacting with Tessel for users and developers. It provides useful functions like listing available Tessels, deploying code, and setting wifi credentials on the device.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"tessel-2-operation-system-openwrt\"><a href=\"https:\/\/www.github.com\/tessel\/openwrt-tessel\" target=\"_blank\" rel=\"noreferrer noopener\">Tessel 2 Operation System (OpenWRT)<\/a><\/h5>\n\n\n\n<p>The primary processor of the Tessel 2 runs a very lightweight version of Linux called OpenWRT. OpenWRT provides all of the TCP\/IP drivers, threading\/schedule support, and runs Node, Rust or whatever other language you&#8217;re using with Tessel 2. This repo contains all of the source files of the Tessel build of OpenWRT.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"tessel-2-co-processor-firmware\"><a href=\"https:\/\/www.github.com\/tessel\/t2-firmware\" target=\"_blank\" rel=\"noreferrer noopener\">Tessel 2 Co-processor Firmware<\/a><\/h5>\n\n\n\n<p>Tessel 2 features a SAMD21 co-processor that manages a handful of responsibilities like routing USB communication from the&nbsp;CLI&nbsp;and the realtime operations on the&nbsp;GPIO&nbsp;pins&nbsp;of the two module&nbsp;ports. This repo contains not only the firmware that drives this microcontroller but hardware-related scripts that define the interface to other languages (like&nbsp;<a href=\"https:\/\/www.github.com\/tessel\/t2-firmware\/node\/tessel.js\" target=\"_blank\" rel=\"noreferrer noopener\">tessel.js<\/a>&nbsp;for Node scripts) so that the available hardware functionality doesn&#8217;t get out of sync with what is exposed to the OpenWRT processor.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"tessel-2-tools\"><span class=\"ez-toc-section\" id=\"Tessel_2_Tools\"><\/span>Tessel 2 Tools<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"tessel-2-virtual-machine-vm\"><a href=\"https:\/\/www.github.com\/tessel\/t2-vm\" target=\"_blank\" rel=\"noreferrer noopener\">Tessel 2 Virtual Machine<\/a>&nbsp;(VM)<\/h5>\n\n\n\n<p>The VM is used primarily by Tessel developers who either don&#8217;t have hardware available or want to develop on a faster computer. The repo provides the ability to create and run these Tessel virtual machines. You can use the&nbsp;CLI&nbsp;(see above) to interact with the running VM just as you would an actual Tessel 2. The VM has the limitation of not being able to set wifi credentials (it passes through the host network interface). It is not able to use 10-pin hardware modules but USB devices do get passed through.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"tessel-2-compiler\"><a href=\"https:\/\/www.github.com\/tessel\/t2-compiler\" target=\"_blank\" rel=\"noreferrer noopener\">Tessel 2 Compiler<\/a><\/h5>\n\n\n\n<p>The Tessel 2 compiler is another virtual machine with all the build tools needed to develop&nbsp;<a href=\"https:\/\/nodejs.org\/api\/addons.html\" target=\"_blank\" rel=\"noreferrer noopener\">native add-ons<\/a>&nbsp;to Node modules. These add-ons are built to perform faster or interact with lower level hardware than JS alone would provide. The compiler is being used, for example, to develop the&nbsp;<a href=\"https:\/\/github.com\/tessel\/node-audiovideo\" target=\"_blank\" rel=\"noreferrer noopener\">audio-video Node module<\/a>&nbsp;for webcams and recording audio from microphones.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"hardware-designs\"><span class=\"ez-toc-section\" id=\"Hardware_Designs\"><\/span>Hardware Designs<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"tessel-2-hardware-design-files\"><a href=\"https:\/\/www.github.com\/tessel\/t2-hardware\" target=\"_blank\" rel=\"noreferrer noopener\">Tessel 2 Hardware Design Files<\/a><\/h5>\n\n\n\n<p>These are the production schematic and assembly files for the Tessel 2 hardware. You can find information about the parts that are used and how they are all connected to each other. These files were created with&nbsp;KiCad, a completely open source electronics design tool.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"tessel-parts-library\"><a href=\"https:\/\/github.com\/tessel\/tm-kicad-library\" target=\"_blank\" rel=\"noreferrer noopener\">Tessel Parts Library<\/a><\/h5>\n\n\n\n<p>This repo contains all of the KiCad part models for all Tessel hardware (not just Tessel 2). You will need this library in order to recreate the schematic and PCB of the hardware design files above.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"modules\"><span class=\"ez-toc-section\" id=\"Modules\"><\/span>Modules<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"10-pin-modules\">10-Pin Modules<\/h5>\n\n\n\n<p>There are 9 compatible 10-pin hardware modules for Tessel 2 available at the time of this writing. Each of these modules have a repo that contains the JavaScript driver. These repos can also be found on NPM under their respective Node modules names.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/github.com\/tessel\/ambient-attx4\" target=\"_blank\" rel=\"noreferrer noopener\">Ambient (Light &amp; Sound) Module<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/tessel\/rfid-pn532\" target=\"_blank\" rel=\"noreferrer noopener\">RFID\/NFC Module<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/tessel\/accel-attx4\" target=\"_blank\" rel=\"noreferrer noopener\">Accelerometer Module<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/tessel\/ble-ble113a\" target=\"_blank\" rel=\"noreferrer noopener\">Bluetooth Low Energy Module<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/tessel\/climate-si7020\" target=\"_blank\" rel=\"noreferrer noopener\">Climate (temperature &amp; humidity) Module<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/tessel\/gps-a2235h\" target=\"_blank\" rel=\"noreferrer noopener\">GPS Module<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/tessel\/ir-attx4\" target=\"_blank\" rel=\"noreferrer noopener\">Infrared Module<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/tessel\/relay-mono\" target=\"_blank\" rel=\"noreferrer noopener\">Relay Module<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/tessel\/servo-pca9685\" target=\"_blank\" rel=\"noreferrer noopener\">Servo Module<\/a><\/li>\n<\/ul>\n\n\n\n<h5 class=\"wp-block-heading\" id=\"usb-modules\">USB Modules<\/h5>\n\n\n\n<p>Tessel supports interfacing with USB devices. Here are libraries we support for Tessel to interoperate with USB modules, available from many vendors:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/github.com\/sandeepmistry\/noble\" target=\"_blank\" rel=\"noreferrer noopener\">Bluetooth Low Energy Dongles<\/a><\/li>\n\n\n\n<li>Cellular (3G\/4G) Dongles (no Github module, it just works through the Node&nbsp;<code>http<\/code>&nbsp;module and similar for other languages)<\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/tessel\/node-audiovideo\" target=\"_blank\" rel=\"noreferrer noopener\">Audio Recording\/Playback<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/tessel\/node-audiovideo\" target=\"_blank\" rel=\"noreferrer noopener\">Video Cameras (specifically, webcams)<\/a><\/li>\n\n\n\n<li>Flash Storage Devices (no Github module, it just works through the Node&nbsp;<code>fs<\/code>&nbsp;module and similar for other languages)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"system-architecture\"><span class=\"ez-toc-section\" id=\"System_Architecture\"><\/span>System Architecture<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"high-level-look-at-hardware\"><span class=\"ez-toc-section\" id=\"High_Level_Look_At_Hardware\"><\/span>High Level Look At Hardware<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Below is a high level diagram of the hardware architecture:&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img fetchpriority=\"high\" decoding=\"async\" width=\"960\" height=\"720\" src=\"https:\/\/www.bairesdev.com\/tools\/tessel\/wp-content\/uploads\/2024\/03\/T2-Hardware-4.png\" alt=\"\" class=\"wp-image-10131\" srcset=\"https:\/\/www.bairesdev.com\/tools\/tessel\/wp-content\/uploads\/2024\/03\/T2-Hardware-4.png 960w, https:\/\/www.bairesdev.com\/tools\/tessel\/wp-content\/uploads\/2024\/03\/T2-Hardware-4-300x225.png 300w, https:\/\/www.bairesdev.com\/tools\/tessel\/wp-content\/uploads\/2024\/03\/T2-Hardware-4-768x576.png 768w, https:\/\/www.bairesdev.com\/tools\/tessel\/wp-content\/uploads\/2024\/03\/T2-Hardware-4-400x300.png 400w\" sizes=\"(max-width: 960px) 100vw, 960px\" \/><\/figure>\n\n\n\n<p>As you can see from the diagram, the Atmel co-processor manages the USB connection and can communicate with the MediaTek through a&nbsp;SPI&nbsp;bus. The MediaTek can execute user scripts, and when it interprets hardware commands (like pulling a&nbsp;GPIO&nbsp;high or sending data over&nbsp;I2C), it packages it up and sends it over to the Atmel over a pre-defined protocol on that&nbsp;SPI&nbsp;bus.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"software-architecture\"><span class=\"ez-toc-section\" id=\"Software_Architecture\"><\/span>Software Architecture<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>The MediaTek is responsible for managing the two USB Host\u00a0ports, the ethernet port, and the WiFi network interace directly from the OpenWRT Operating System.<\/p>\n\n\n\n<p>The USB Port on the Atmel actually has three interfaces to the to the MediaTek:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>A&nbsp;UART&nbsp;connection that acts a&nbsp;serial&nbsp;terminal to the MediaTek. You can use a program like&nbsp;<code>dterm<\/code>&nbsp;to access the console through this connection.<\/li>\n\n\n\n<li>A direct connection to the&nbsp;SPI&nbsp;Flash bus of the MediaTek. This allows the Atmel to rewrite the OpenWRT image and helps prevent the Tessel from becoming bricked by any corruptions to OS.<\/li>\n\n\n\n<li>A&nbsp;SPI&nbsp;bus connection to the MediaTek for arbitrary data.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"a-code-deploy-example\"><span class=\"ez-toc-section\" id=\"A_Code_Deploy_Example\"><\/span>A Code Deploy Example<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>A good method of understanding all the components of the system is to go through an example of running a simple script on Tessel 2:<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"the-user-code-to-light-up-an-led\">The user code to light up an LED<\/h4>\n\n\n\n<p>The user might have code like the example below to light up&nbsp;LED&nbsp;0 on Tessel 2.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>var tessel = require('tessel');\ntessel.led&#91;0].high();\n<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"deploy-with-the-cli\">Deploy with the CLI<\/h4>\n\n\n\n<p>First, the user will use the&nbsp;<a href=\"https:\/\/www.github.com\/tessel\/t2-cli\" target=\"_blank\" rel=\"noreferrer noopener\">command line interface<\/a>&nbsp;to deploy the script from the host computer:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>t2 run index.js\n<\/code><\/pre>\n\n\n\n<p>The&nbsp;CLI&nbsp;will compress the code and break this simple&nbsp;<code>run<\/code>&nbsp;command into a&nbsp;<a href=\"https:\/\/github.com\/tessel\/t2-cli\/blob\/master\/lib\/tessel\/commands.js\" target=\"_blank\" rel=\"noreferrer noopener\">number of bash commands<\/a>&nbsp;required to deploy the code like&nbsp;<a href=\"https:\/\/github.com\/tessel\/t2-cli\/blob\/90bb45d4c82f019f6de97306a6fecf15e64d0a04\/lib\/tessel\/commands.js#L17\" target=\"_blank\" rel=\"noreferrer noopener\">untarring the code<\/a>&nbsp;and&nbsp;<a href=\"https:\/\/github.com\/tessel\/t2-cli\/blob\/90bb45d4c82f019f6de97306a6fecf15e64d0a04\/lib\/tessel\/commands.js#L20\" target=\"_blank\" rel=\"noreferrer noopener\">running it with Node<\/a>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"accepting-usb-communication-on-the-atmel\">Accepting USB Communication On The Atmel<\/h4>\n\n\n\n<p>The utf-8 encoding of each command is sent over the USB connection via a&nbsp;USB pipe. The USB pipe driver hands off the data to the general purpose&nbsp;<a href=\"https:\/\/github.com\/tessel\/t2-firmware\/blob\/85c37ea67c9a85cf4f2d87aa8c27c7e0f41c4ffc\/firmware\/bridge.c\" target=\"_blank\" rel=\"noreferrer noopener\">SPI bridge<\/a>&nbsp;(labeled as &#8220;SPI&nbsp;SLAVE&nbsp;SERCOMMx&#8221; in the diagram above) which transfers the command to the MediaTek.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"relaying-data-to-the-mediatek-spi-daemon\">Relaying Data to the MediaTek SPI Daemon<\/h4>\n\n\n\n<p>On the MediaTek, the&nbsp;<a href=\"https:\/\/github.com\/tessel\/t2-firmware\/blob\/85c37ea67c9a85cf4f2d87aa8c27c7e0f41c4ffc\/soc\/spid.c\" target=\"_blank\" rel=\"noreferrer noopener\">SPI Daemon<\/a>&nbsp;is constantly waiting for data over the&nbsp;SPI&nbsp;bus and checks whether this data is from one of the module&nbsp;ports&nbsp;(for example, if an&nbsp;analog&nbsp;voltage was previously requested and was now returning the result) or from the USB port.<\/p>\n\n\n\n<p>The&nbsp;shell script&nbsp;that starts up the&nbsp;SPI&nbsp;Daemon on boot also creates three unix domain sockets: one for&nbsp;Module Port&nbsp;A (\/var\/run\/tessel\/port_a), one for&nbsp;Module Port&nbsp;B (\/var\/run\/tessel\/port_b), and one for USB (\/var\/run\/tessel\/usb). We&#8217;ll get to the two module&nbsp;ports&nbsp;in a moment, but first, the data from the&nbsp;CLI&nbsp;is passed into the USB domain socket.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"one-more-relay-into-the-usb-daemon\">One More Relay Into The USB Daemon<\/h4>\n\n\n\n<p>Waiting on the other end of the domain socket is&nbsp;the USB Daemon. This program has the thrilling task of accepting shell commands, initializing new threads to execute them, and routing stdin, stdout, and stderr of those threads back to the&nbsp;<a href=\"https:\/\/web.archive.org\/web\/20220129201706\/https:\/\/tessel.gitbooks.io\/t2-docs\/content\/GLOSSARY.html#cli\" target=\"_blank\" rel=\"noopener\">CLI<\/a>.<\/p>\n\n\n\n<p>So by this point, the&nbsp;CLI&nbsp;has executed&nbsp;<a href=\"https:\/\/github.com\/tessel\/t2-cli\/blob\/90bb45d4c82f019f6de97306a6fecf15e64d0a04\/lib\/tessel\/deploy.js#L24-L48\" target=\"_blank\" rel=\"noreferrer noopener\">a handful of bash commands<\/a>&nbsp;that transferred the code onto the Tessel 2 and started a Node process to run it. The next question is how we actually do anything with the hardware.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"accessing-hardware-through-tesseljs\">Accessing Hardware Through&nbsp;<code>tessel.js<\/code><\/h4>\n\n\n\n<p>For JavaScript files, the answer comes from the&nbsp;<code>var tessel = require('tessel')<\/code>&nbsp;line of the user script. When Node executes this on the MediaTek, it finds the&nbsp;<a href=\"https:\/\/github.com\/tessel\/t2-firmware\/blob\/85c37ea67c9a85cf4f2d87aa8c27c7e0f41c4ffc\/node\/tessel.js\" target=\"_blank\" rel=\"noreferrer noopener\"><code>tessel<\/code>&nbsp;module<\/a>&nbsp;in&nbsp;<code>\/usr\/lib\/node\/tessel.js<\/code>. When this file is executed,&nbsp;<a href=\"https:\/\/github.com\/tessel\/t2-firmware\/blob\/85c37ea67c9a85cf4f2d87aa8c27c7e0f41c4ffc\/node\/tessel.js#L12-L15\" target=\"_blank\" rel=\"noreferrer noopener\">it connects to a domain socket for each module port<\/a>: two of the three domain sockets created by the&nbsp;SPI&nbsp;Daemon earlier! That means that whenever you run a command on a port like&nbsp;<code>tessel.led[0].high()<\/code>, it&#8217;s&nbsp;<a href=\"https:\/\/github.com\/tessel\/t2-firmware\/blob\/85c37ea67c9a85cf4f2d87aa8c27c7e0f41c4ffc\/node\/tessel.js#L298\" target=\"_blank\" rel=\"noreferrer noopener\">packaging that command into a array of bytes<\/a>&nbsp;and sending it back over the&nbsp;SPI&nbsp;bus to the Atmel bridge firmware! That firmware then parses the command as pulling the specific&nbsp;GPIO&nbsp;high, and executes it. It can then return the result of that operation back through the&nbsp;SPI&nbsp;bus to the MediaTek&nbsp;SPI&nbsp;Daemon.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"why-domain-sockets\">Why Domain Sockets?<\/h4>\n\n\n\n<p>The beauty of this architecture with domain sockets is that most legitimate programming langauges have the capability to utilize domain sockets. This is how Tessel 2 can be used by any language, not just JavaScript (the code that packages up the commands into array bytes just has to be ported to that language first).<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"how-does-deploying-code-over-lan-work-into-this\">How Does Deploying Code over LAN Work Into This?<\/h4>\n\n\n\n<p>In the case of a&nbsp;LAN&nbsp;connection over WiFi or Ethernet, the procedure is much the same except all of the shell commands are executed over SSH. All of the&nbsp;module port&nbsp;communication between the&nbsp;SPI&nbsp;Daemon and the USB Bridge firmware is entirely the same. That&#8217;s why the&nbsp;CLI&nbsp;is able to abstract out USB and&nbsp;LAN&nbsp;interfaces&nbsp;into a single&nbsp;Connection&nbsp;object&nbsp;that simply accepts shell commands and returns a process object with the three streams (stdin, stdout, stderr) regardless of physical connection.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"what-is-uciubus-on-the-diagram-above\">What is UCI\/ubus on the diagram above?<\/h4>\n\n\n\n<p>UCI&nbsp;and&nbsp;ubus&nbsp;are unique features of OpenWRT that essentially let you access system configuration programmatically and receive results in a JSON format. It&#8217;s very handy for the command line interface. You can see that the&nbsp;CLI&nbsp;makes&nbsp;<a href=\"https:\/\/github.com\/tessel\/t2-cli\/blob\/90bb45d4c82f019f6de97306a6fecf15e64d0a04\/lib\/tessel\/commands.js#L35\" target=\"_blank\" rel=\"noreferrer noopener\">use of these features<\/a>&nbsp;heavily, especially for wifi related settings.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"more-useful-links\"><span class=\"ez-toc-section\" id=\"More_Useful_Links\"><\/span>More Useful Links<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/github.com\/tessel\/t2-cli#development-milestones\" target=\"_blank\" rel=\"noreferrer noopener\">Current CLI Development Roadmap<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/openwrt.org\/\" target=\"_blank\" rel=\"noreferrer noopener\">OpenWRT website<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/www.bairesdev.com\/tools\/tessel\/blog\/\" target=\"_blank\" rel=\"noreferrer noopener\">Tessel Project Blog<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>This guide is intended to help code contributors understand how relevant system components of Tessel 2 work, where to find code and design files, and accelerate the development process through technical transparency. Relevant Github Repositories Quick guide to the Tessel stack (in order of complexity): Level Stack Repo User \/ Module Code JS (Many) CLI [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[58,4],"tags":[],"class_list":["post-9769","post","type-post","status-publish","format-standard","hentry","category-debugging","category-docs"],"_links":{"self":[{"href":"https:\/\/www.bairesdev.com\/tools\/tessel\/wp-json\/wp\/v2\/posts\/9769","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.bairesdev.com\/tools\/tessel\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.bairesdev.com\/tools\/tessel\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.bairesdev.com\/tools\/tessel\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.bairesdev.com\/tools\/tessel\/wp-json\/wp\/v2\/comments?post=9769"}],"version-history":[{"count":6,"href":"https:\/\/www.bairesdev.com\/tools\/tessel\/wp-json\/wp\/v2\/posts\/9769\/revisions"}],"predecessor-version":[{"id":10133,"href":"https:\/\/www.bairesdev.com\/tools\/tessel\/wp-json\/wp\/v2\/posts\/9769\/revisions\/10133"}],"wp:attachment":[{"href":"https:\/\/www.bairesdev.com\/tools\/tessel\/wp-json\/wp\/v2\/media?parent=9769"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.bairesdev.com\/tools\/tessel\/wp-json\/wp\/v2\/categories?post=9769"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.bairesdev.com\/tools\/tessel\/wp-json\/wp\/v2\/tags?post=9769"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}