getting_started.rst 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. ***************
  2. Getting Started
  3. ***************
  4. Add TinyUSB to your project
  5. ---------------------------
  6. It is relatively simple to incorporate tinyusb to your (existing) project
  7. * Copy or ``git submodule`` this repo into your project in a subfolder. Let's say it is *your_project/tinyusb*
  8. * Add all the .c in the ``tinyusb/src`` folder to your project
  9. * Add *your_project/tinyusb/src* to your include path. Also make sure your current include path also contains the configuration file tusb_config.h.
  10. * Make sure all required macros are all defined properly in tusb_config.h (configure file in demo application is sufficient, but you need to add a few more such as CFG_TUSB_MCU, CFG_TUSB_OS since they are passed by IDE/compiler to maintain a unique configure for all boards).
  11. * If you use the device stack, make sure you have created/modified usb descriptors for your own need. Ultimately you need to implement all **tud descriptor** callbacks for the stack to work.
  12. * Add tusb_init() call to your reset initialization code.
  13. * Call ``tud_int_handler()`` (device) and/or ``tuh_int_handler()`` (host) in your USB IRQ Handler
  14. * Implement all enabled classes's callbacks.
  15. * If you don't use any RTOSes at all, you need to continuously and/or periodically call tud_task()/tuh_task() function. All of the callbacks and functionality are handled and invoked within the call of that task runner.
  16. .. code-block::
  17. int main(void)
  18. {
  19. your_init_code();
  20. tusb_init(); // initialize tinyusb stack
  21. while(1) // the mainloop
  22. {
  23. your_application_code();
  24. tud_task(); // device task
  25. tuh_task(); // host task
  26. }
  27. }
  28. Examples
  29. --------
  30. For your convenience, TinyUSB contains a handful of examples for both host and device with/without RTOS to quickly test the functionality as well as demonstrate how API() should be used. Most examples will work on most of `the supported boards <supported.rst>`_. Firstly we need to ``git clone`` if not already
  31. .. code-block::
  32. $ git clone https://github.com/hathach/tinyusb tinyusb
  33. $ cd tinyusb
  34. Some TinyUSB examples also requires external submodule libraries in ``/lib`` such as FreeRTOS, Lightweight IP to build. Run following command to fetch them
  35. .. code-block::
  36. $ git submodule update --init lib
  37. In addition, MCU driver submodule is also needed to provide low-level MCU peripheral's driver. To download these depencies for your board, run the ``get-dpes`` as follow.
  38. .. code-block::
  39. $ make BOARD=feather_nrf52840_express get-deps
  40. Some modules will also require a module-specific SDK (e.g. RP2040) or binary (e.g. Sony Spresense) to build examples.
  41. Note: some examples especially those that uses Vendor class (e.g webUSB) may requires udev permission on Linux (and/or macOS) to access usb device. It depends on your OS distro, typically copy ``/examples/device/99-tinyusb.rules`` file to /etc/udev/rules.d/ then run ``sudo udevadm control --reload-rules && sudo udevadm trigger`` is good enough.
  42. Build
  43. ^^^^^
  44. To build example, first change directory to an example folder.
  45. .. code-block::
  46. $ cd examples/device/cdc_msc
  47. Some modules (e.g. RP2040 and ESP32s2) require the project makefiles to be customized using CMake. If necessary apply any setup steps for the platform's SDK.
  48. Then compile with ``make BOARD=[board_name] all``\ , for example
  49. .. code-block::
  50. $ make BOARD=feather_nrf52840_express all
  51. Note: ``BOARD`` can be found as directory name in ``hw/bsp``\ , either in its family/boards or directly under bsp (no family).
  52. Port Selection
  53. ~~~~~~~~~~~~~~
  54. If a board has several ports, one port is chosen by default in the individual board.mk file. Use option ``PORT=x`` To choose another port. For example to select the HS port of a STM32F746Disco board, use:
  55. .. code-block::
  56. $ make BOARD=stm32f746disco PORT=1 all
  57. Port Speed
  58. ~~~~~~~~~~
  59. A MCU can support multiple operational speed. By default, the example build system will use the fastest supported on the board. Use option ``SPEED=full/high`` e.g To force F723 operate at full instead of default high speed
  60. .. code-block::
  61. $ make BOARD=stm32f746disco SPEED=full all
  62. Size Analysis
  63. ~~~~~~~~~~~~~
  64. First install `linkermap tool <https://github.com/hathach/linkermap>`_ then ``linkermap`` target can be used to analyze code size. You may want to compile with ``NO_LTO=1`` since -flto merges code across .o files and make it difficult to analyze.
  65. .. code-block::
  66. $ make BOARD=feather_nrf52840_express NO_LTO=1 all linkermap
  67. Debug
  68. ^^^^^
  69. To compile for debugging add ``DEBUG=1``\ , for example
  70. .. code-block::
  71. $ make BOARD=feather_nrf52840_express DEBUG=1 all
  72. Log
  73. ~~~
  74. Should you have an issue running example and/or submitting an bug report. You could enable TinyUSB built-in debug logging with optional ``LOG=``. LOG=1 will only print out error message, LOG=2 print more information with on-going events. LOG=3 or higher is not used yet.
  75. .. code-block::
  76. $ make BOARD=feather_nrf52840_express LOG=2 all
  77. Logger
  78. ~~~~~~
  79. By default log message is printed via on-board UART which is slow and take lots of CPU time comparing to USB speed. If your board support on-board/external debugger, it would be more efficient to use it for logging. There are 2 protocols:
  80. * `LOGGER=rtt`: use `Segger RTT protocol <https://www.segger.com/products/debug-probes/j-link/technology/about-real-time-transfer/>`_
  81. * Cons: requires jlink as the debugger.
  82. * Pros: work with most if not all MCUs
  83. * Software viewer is JLink RTT Viewer/Client/Logger which is bundled with JLink driver package.
  84. * ``LOGGER=swo``\ : Use dedicated SWO pin of ARM Cortex SWD debug header.
  85. * Cons: only work with ARM Cortex MCUs minus M0
  86. * Pros: should be compatible with more debugger that support SWO.
  87. * Software viewer should be provided along with your debugger driver.
  88. .. code-block::
  89. $ make BOARD=feather_nrf52840_express LOG=2 LOGGER=rtt all
  90. $ make BOARD=feather_nrf52840_express LOG=2 LOGGER=swo all
  91. Flash
  92. ^^^^^
  93. ``flash`` target will use the default on-board debugger (jlink/cmsisdap/stlink/dfu) to flash the binary, please install those support software in advance. Some board use bootloader/DFU via serial which is required to pass to make command
  94. .. code-block::
  95. $ make BOARD=feather_nrf52840_express flash
  96. $ make SERIAL=/dev/ttyACM0 BOARD=feather_nrf52840_express flash
  97. Since jlink can be used with most of the boards, there is also ``flash-jlink`` target for your convenience.
  98. .. code-block::
  99. $ make BOARD=feather_nrf52840_express flash-jlink
  100. Some board use uf2 bootloader for drag & drop in to mass storage device, uf2 can be generated with ``uf2`` target
  101. .. code-block::
  102. $ make BOARD=feather_nrf52840_express all uf2
  103. IAR Support
  104. ^^^^^^^^^^^
  105. IAR Project Connection files are provided to import TinyUSB stack into your project.
  106. * A buldable project of your MCU need to be created in advance.
  107. * Take example of STM32F0:
  108. - You need `stm32l0xx.h`, `startup_stm32f0xx.s`, `system_stm32f0xx.c`.
  109. - `STM32L0xx_HAL_Driver` is only needed to run examples, TinyUSB stack itself doesn't rely on MCU's SDKs.
  110. * Open `Tools -> Configure Custom Argument Variables` (Switch to `Global` tab if you want to do it for all your projects)
  111. Click `New Group ...`, name it to `TUSB`, Click `Add Variable ...`, name it to `TUSB_DIR`, change it's value to the path of your TinyUSB stack,
  112. for example `C:\\tinyusb`
  113. Import stack only
  114. ~~~~~~~~~~~~~~~~~
  115. 1. Open `Project -> Add project Connection ...`, click `OK`, choose `tinyusb\\tools\\iar_template.ipcf`.
  116. Run examples
  117. ~~~~~~~~~~~~
  118. 1. (Python3 is needed) Run `iar_gen.py` to generate .ipcf files of examples:
  119. .. code-block::
  120. cd C:\tinyusb\tools
  121. python iar_gen.py
  122. 2. Open `Project -> Add project Connection ...`, click `OK`, choose `tinyusb\\examples\\(.ipcf of example)`.
  123. For example `C:\\tinyusb\\examples\\device\\cdc_msc\\iar_cdc_msc.ipcf`