{"id":21508650,"url":"https://github.com/artfulbytes/nsumo_video","last_synced_at":"2025-04-09T16:41:16.136Z","repository":{"id":134050306,"uuid":"538007193","full_name":"artfulbytes/nsumo_video","owner":"artfulbytes","description":"A microcontroller-based embedded project written from scratch in a video series on YouTube.","archived":false,"fork":false,"pushed_at":"2023-12-04T20:22:12.000Z","size":3904,"stargazers_count":92,"open_issues_count":0,"forks_count":17,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-23T18:52:14.902Z","etag":null,"topics":["c","embedded","microcontroller","msp430","robot"],"latest_commit_sha":null,"homepage":"https://youtube.com/playlist?list=PLS_iNJJVTtiRV0DZRDcTHnvAuDrKGPN40","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/artfulbytes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2022-09-18T05:11:43.000Z","updated_at":"2025-03-17T13:46:03.000Z","dependencies_parsed_at":null,"dependency_job_id":"b4b39c7e-bc36-4527-bf86-54166b9ecee8","html_url":"https://github.com/artfulbytes/nsumo_video","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artfulbytes%2Fnsumo_video","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artfulbytes%2Fnsumo_video/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artfulbytes%2Fnsumo_video/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artfulbytes%2Fnsumo_video/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/artfulbytes","download_url":"https://codeload.github.com/artfulbytes/nsumo_video/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248068951,"owners_count":21042584,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","embedded","microcontroller","msp430","robot"],"created_at":"2024-11-23T21:08:44.503Z","updated_at":"2025-04-09T16:41:16.112Z","avatar_url":"https://github.com/artfulbytes.png","language":"C","readme":"# Nsumo\nThis repository tracks the code of Nsumo (500g 10x10cm Sumobot) as I re-write it\nfrom scratch and show the complete process in a [YouTube series](https://www.youtube.com/watch?v=g9KbXJydf8I\u0026t=1s).\nYou find the hardware design [here](https://github.com/artfulbytes/nsumo_hardware.git).\nThe project is meant to serve as an educational example and case study of a\nmicrocontroller-based embedded project.\n\n\u003cimg src=\"/docs/nsumo.jpg\"\u003e\n\n## Directory structure\nThe directory structure is based on the\n[pitchfork layout](https://github.com/vector-of-bool/pitchfork), and I describe it\nmore in [this video](https://www.youtube.com/watch?v=6oJ2LLxfP3s).\n\n| Directory    | Description                                                  |\n|--------------|--------------------------------------------------------------|\n| build/       | Build output (object files + executable)                     |\n| docs/        | Documentation (e.g., coding guidelines, images)              |\n| src/         | Source files (.c/.h)                                         |\n| src/app/     | Source files for the application layer (see SW architecture) |\n| src/common/  | Source files for code used across the project                |\n| src/drivers/ | Source files for the driver layer (see SW architecture)      |\n| src/test/    | Source files related to test code                            |\n| external/    | External dependencies (as git submodules if possible)        |\n| tools/       | Scripts, configs, binaries                                   |\n| .github/     | Configuration file for GitHub actions                        |\n\n## Build\nThe two most common ways to build code for a microcontroller are from\nan IDE (often supplied by the vendor) or from the command-line through a build\nsystem (for example, make). There are pros and cons to both ways, and I describe\nthem in [this video](https://www.youtube.com/watch?v=H1HToCzku9Y) and\n[this video](https://www.youtube.com/watch?v=HCfq44NNBaU).\n\nIn short, using an IDE is the most straightforward approach, but\nat the same time less flexible because it forces you into a particular environment.\nA build system is more complicated to set up, but it can be combined with your editor\nof choice, gives more control over the build process, is great for automation (see CI),\nand allows for a command-line based environment, which transfers better across projects.\nThis project can be built both ways, however, _make_ is the preferred way, but the IDE\nis helpful when step-debugging the code.\n\n## make (Makefile)\nThe code targets the MSP430G2553 and must be built with a cross-toolchain. While\nthere are several toolchains for this microcontroller, msp430-gcc is the one used in this project,\nwhich is available on [TI's website](https://www.ti.com/tool/MSP430-GCC-OPENSOURCE).\nWatch [this video](https://www.youtube.com/watch?v=HCfq44NNBaU) and\n[this video](https://www.youtube.com/watch?v=dh1NFAIoZCI) for more details.\n\nThere is a _Makefile_ to build the code with _make_ from the command-line:\n``` Bash\nTOOLS_PATH=\u003cINSERT TOOLS PATH\u003e make HW=\u003cINSERT TARGET\u003e\n```\n\nThe path to the toolchain must be specified with the environment variable _TOOLS_PATH_.\n\nThe argument _HW_ specifies which hardware to target, either _NSUMO_\n(Robot with 28-pin msp430g2553) or _LAUNCHPAD_ (evaluation board with 20-pin\nmsp430g2553).\n\nFor example, if the toolchain is available at _/home/artfulbytes/dev/tools/msp430-gcc_,\nand targeting the evaluation board:\n\n```\nTOOLS_PATH=$HOME/dev/tools make HW=LAUNCHPAD\n```\n\n## IDE\nThe IDE provided by the vendor (TI) for the MSP430 family of microcontrollers is\ncalled Code Composer Studio (CCSSTUDIO). It's an eclipse-based IDE, and is available\nat [TI's website](https://www.ti.com/tool/CCSTUDIO). The below steps have\nbeen verified to work with version CCSTUDIO 11.1 and MSP430-GCC 9.3.1.11.\n\n1. Install CCSTUDIO and MSP430-GCC, and make sure the GCC compiler can be selected\n   from inside CCSTUDIO.\n2. Create a new CCS project\n    - Target: MSP430G2553\n    - Compiler version: GNU v9.3.1.11\n    - Empty project (no main file)\n3. Drag the src/ folder into the project explorer and link to files and\n   folders\n4. Under properties\n    - Add src/ directory to include paths\n    - Add define symbols (see Makefile), e.g. LAUNCHPAD\n\n## Tests\nThere are no unit tests, but there are test functions inside src/test/test.c, which\nare written to test isolated parts of the code. They run on target but are not built\nas part of the normal build. Only one test function can be built at a time, and it's\nbuilt as follows (test_assert as an example):\n\n``` C\nmake TARGET=LAUNCHPAD TEST=test_assert\n```\n\n## Pushing a new change\nThese are the typical steps taken for each change.\n\n1. Create a local branch\n2. Make the code changes\n3. Build the code\n4. Flash and test the code on the target\n5. Static analyse the code\n6. Format the code\n7. Commit the code\n8. Push the branch to GitHub\n9. Open a pull-request\n10. Merge the pull request (must pass CI first)\n\nThis workflow is described further in [this video](https://www.youtube.com/watch?v=dh1NFAIoZCI).\n\n## Commit message\nCommit messages should follow the specification laid out by\n[Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/). See\n[this video](https://www.youtube.com/watch?v=TFhbv6gw2Wo) for more details.\n\n## Continuous Integration (CI)\nThere is simple continuous integration (CI)\nsystem in place to have some form of protection against breaking code changes. This system is realized\nthrough GitHub actions and is configured in **ci.yml** located under\n**.github/workflows**. The action builds and analyses (cppcheck) each commit pushed to GitHub and blocks\nthem from being merged until they pass. The action runs inside a docker container, which has the\nrequired cross-toolchain installed. The dockerfile is located under **tools/**, and the docker image is\navailable in a [repository at Docker Hub](https://hub.docker.com/r/artfulbytes/msp430-gcc-9.3.1.11).\nThe CI system is described in detail in [this video](https://www.youtube.com/watch?v=dh1NFAIoZCI).\n\nNote, the CI system provides weak protection against breaking code changes since it only builds and\nstatic analyses the code. It's mainly there to demonstrate the principle. A more rigorous CI system\n(professional environment) would unit-test the code and test it on the real target.\n\n## Code formatter\nThe codebase follows certain formatting rules, which are enforced by the code formatter\n**clang-format**. These rules are specified in the **.clang-format** located in the root\ndirectory. There is a rule in the **Makefile** to format all source files with one command\n(requires clang-format to be installed).\n\n``` Bash\nmake format\n```\n\nSometimes it's desirable to ignore these formatting rules, and this can be achieved with special comments.\n\n``` C\n// clang-format off\ntypedef enum {\n    IO_10, IO_11, IO_12, IO_13, IO_14, IO_15, IO_16, IO_17,\n    IO_20, IO_21, IO_22, IO_23, IO_24, IO_25, IO_26, IO_27,\n    IO_30, IO_31, IO_32, IO_33, IO_34, IO_35, IO_36, IO_37,\n} io_generic_e;\n// clang-format on\n```\n\n## Coding guidelines\nApart from the basic formatting rules, the codebase also follows certain coding guidelines.\nThese are described in **docs/coding_guidelines.md**.\n\n## Static analysis\nTo catch coding mistakes early on (in addition to the ones the compiler catches), I use a static\nanalyzer, **cppcheck**. There is a rule in the **Makefile** to analyse all files with **cppcheck**.\n\n``` Bash\nmake cppcheck\n```\n\nI explain it more in [this video](https://www.artfulbytes.com/analysis-with-cppcheck).\n\n## Memory footprint analysis\nThe memory footprint on a microcontroller is very limited. The MSP430G2553 only has\n16 KB (16 000 bytes) of read-only memory (ROM) or flash memory. This means one has to\nbe conscious of how much space each code snippet takes, which is one of the challenges\nwith microcontroller programming. For this reason, it's useful to have tools in place\nto analyse the space occupied. There are two such programs available in the toolchain\n(_readelf_ and _objdump_), and two corresponding rules in the _Makefile_.\n\nOne rule to see how much total space is occupied,\n```\nmake size\n```\nand another rule to see how much space is occupied by individual symbols (functions + variables):\n```\nmake symbols\n```\nwhich is useful to track down the worst offenders.\n\n## Assert\nSeveral things happen when an assert occurs to make it easy to detect and localize.\nFirst it triggers a breakpoint (if a debugger is attached), then it traces the address\nof the assert, and finally it endlessly blinks an LED. The address printed, is the\nprogram counter, and _addr2line can be used to retrieve the file and line number,\nand there is a makefile rule for it. For example, if an assert triggered at address\n0x1234, you can run\n\n```\nmake HW=LAUNCHPAD addr2line ADDR=0x1234\n```\n\n## Diagrams\nThere are some PlantUML diagrams under _docs/_. The plaintext can be converted into\na viewable image with\n\n```\njava -jar plantuml.jar diagram.uml\n```\n\nDownload plantuml.jar from [PlantUML website](https://plantuml.com/), and install\ndependencies (on Ubuntu) with\n\n```\nsudo apt install default-jre\nsudo apt install graphviz\n```\n\n## Schematic\n\u003cimg src=\"/docs/schematic.png\"\u003e\n\n## Software architecture\n\u003cimg src=\"/docs/sw_arch.png\"\u003e\n\n## Block diagram\n\u003cimg src=\"/docs/sysdiag.jpg\"\u003e\n\n## State machine\n\u003cimg src=\"/docs/state_machine.png\"\u003e\n\u003cimg src=\"/docs/retreat_state.png\"\u003e\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fartfulbytes%2Fnsumo_video","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fartfulbytes%2Fnsumo_video","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fartfulbytes%2Fnsumo_video/lists"}