transplant.rst 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. General Chip Porting Guide
  2. =======================================
  3. This section mainly introduces the general steps and precautions for porting CherryUSB host and device protocol stacks to all chips with USB IP. Before porting, you need to **prepare a basic project that can print helloworld**. Default printing uses `printf`. If it's host mode, **you need to prepare a basic project that can execute OS scheduling normally**.
  4. USB Device Porting Key Points
  5. -------------------------------------
  6. - Copy CherryUSB source code to the project directory and add source files and header file paths as needed. It's recommended to add all header file paths. Among them, `usbd_core.c` and `usb_dc_xxx.c` are required items. `usb_dc_xxx.c` is the USB IP DCD driver corresponding to the chip. If you don't know which USB IP your chip belongs to, refer to the readme of different USB IPs under the **port** directory. If the USB IP you're using is not supported, you'll have to implement it yourself
  7. - Copy `cherryusb_config_template.h` file to your project directory, rename it to `usb_config.h`, and add the corresponding directory header file path
  8. - Implement `usb_dc_low_level_init` function (this function is mainly responsible for USB clock, pin, and interrupt initialization). This function can be placed in any C file that participates in compilation. For USB clock, pin, interrupt initialization, please add them yourself according to the source code provided by your chip manufacturer.
  9. - Call `USBD_IRQHandler` in the interrupt function and pass `busid`. If `USBD_IRQHandler` already exists in the interrupt entry of your SDK, please change the name in the USB protocol stack
  10. - If the chip has cache, refer to the :ref:`usb_cache` section for cache modifications
  11. - Register descriptors and call `usbd_initialize`, fill in `busid` and USB IP's `reg base`. `busid` starts from 0 and cannot exceed `CONFIG_USBDEV_MAX_BUS`. You can directly use templates under the demo directory
  12. USB Host Porting Key Points
  13. -------------------------------------
  14. - Copy CherryUSB source code to project directory and add source files and header file paths as needed. It's recommended to add all header file paths. Among them, `usbh_core.c`, `usb_hc_xxx.c` and source files under the **osal** directory (choose corresponding source files according to different OS) are required. `usb_hc_xxx.c` is the USB IP HCD driver corresponding to the chip. If you don't know which USB IP your chip belongs to, refer to the readme of different USB IPs under the **port** directory. If the USB IP you're using is not supported, you'll have to implement it yourself
  15. - Copy `cherryusb_config_template.h` file to your project directory, rename it to `usb_config.h`, and add the corresponding directory header file path
  16. - Implement `usb_hc_low_level_init` function (this function is mainly responsible for USB clock, pin, and interrupt initialization). This function can be placed in any C file that participates in compilation. For USB clock, pin, interrupt initialization, please add them yourself according to the source code provided by your chip manufacturer.
  17. - Call `usbh_initialize` and fill in `busid`, USB IP's `reg base`, and `event_handler` (can be omitted as NULL). `busid` starts from 0 and cannot exceed `CONFIG_USBHOST_MAX_BUS`
  18. - Call `USBH_IRQHandler` in the interrupt function and pass `busid`. If `USBH_IRQHandler` already exists in the interrupt entry of your SDK, please change the name in the USB protocol stack
  19. - Refer to the :ref:`usbh_link_script` section for linker script modifications
  20. - If the chip has cache, refer to the :ref:`usb_cache` section for cache modifications
  21. - Call `usbh_initialize`, fill in `busid`, USB IP's `reg base`, and `event_handler` (can be omitted as NULL). `busid` starts from 0 and cannot exceed `CONFIG_USBHOST_MAX_BUS`. For basic CDC + HID + MSC, refer to the `usb_host.c` file. For others, refer to adaptations under the **platform** directory
  22. .. _usbh_link_script:
  23. Host Linker Script Modifications
  24. -------------------------------------
  25. When using the host, if you haven't modified the linker script, you will encounter `__usbh_class_info_start__` and `__usbh_class_info_end__` undefined errors. This is because the host protocol stack requires adding a section to the linker script to store class information.
  26. - No modification needed if using KEIL
  27. - If using GCC, add the following code to the linker script (needs to be placed in flash location, recommended at the end):
  28. .. code-block:: C
  29. // Add the following code to the ld file
  30. . = ALIGN(4);
  31. __usbh_class_info_start__ = .;
  32. KEEP(*(.usbh_class_info))
  33. __usbh_class_info_end__ = .;
  34. GCC example:
  35. .. code-block:: C
  36. /* The program code and other data into "FLASH" Rom type memory */
  37. .text :
  38. {
  39. . = ALIGN(4);
  40. *(.text) /* .text sections (code) */
  41. *(.text*) /* .text* sections (code) */
  42. *(.glue_7) /* glue arm to thumb code */
  43. *(.glue_7t) /* glue thumb to arm code */
  44. *(.eh_frame)
  45. KEEP (*(.init))
  46. KEEP (*(.fini))
  47. . = ALIGN(4);
  48. __usbh_class_info_start__ = .;
  49. KEEP(*(.usbh_class_info))
  50. __usbh_class_info_end__ = .;
  51. . = ALIGN(4);
  52. _etext = .; /* define a global symbols at end of code */
  53. } > FLASH
  54. - Segger Embedded Studio example:
  55. .. code-block:: C
  56. define block cherryusb_usbh_class_info { section .usbh_class_info };
  57. define exported symbol __usbh_class_info_start__ = start of block cherryusb_usbh_class_info;
  58. define exported symbol __usbh_class_info_end__ = end of block cherryusb_usbh_class_info + 1;
  59. place in AXI_SRAM { block cherryusb_usbh_class_info };
  60. keep { section .usbh_class_info};
  61. .. _usb_cache:
  62. cache Configuration Modification
  63. --------------------------------------
  64. For chips with cache functionality, the protocol stack and port will not clean or invalidate RAM in the cache region, so a non-cache RAM area needs to be used for maintenance.
  65. `USB_NOCACHE_RAM_SECTION` macro specifies variables to be placed in non-cache RAM. By default, `USB_NOCACHE_RAM_SECTION` is defined as `__attribute__((section(".noncacheable")))`.
  66. Therefore, users need to add a no cache RAM section in the corresponding linker script, and the section must include `.noncacheable`.
  67. .. note:: Note that just modifying the nocache section in the linker script is not sufficient. You also need to configure the RAM in that section to be truly nocache, which typically requires configuring MPU attributes (for ARM, refer to the stm32h7 demo).
  68. GCC:
  69. .. code-block:: C
  70. MEMORY
  71. {
  72. RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K - 64K
  73. RAM_nocache (xrw) : ORIGIN = 0x20030000, LENGTH = 64K
  74. FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 512K
  75. }
  76. ._nocache_ram :
  77. {
  78. . = ALIGN(4);
  79. *(.noncacheable)
  80. } >RAM_nocache
  81. SCT:
  82. .. code-block:: C
  83. LR_IROM1 0x08000000 0x00200000 { ; load region size_region
  84. ER_IROM1 0x08000000 0x00200000 { ; load address = execution address
  85. *.o (RESET, +First)
  86. *(InRoot$$Sections)
  87. .ANY (+RO)
  88. .ANY (+XO)
  89. }
  90. RW_IRAM2 0x24000000 0x00070000 { ; RW data
  91. .ANY (+RW +ZI)
  92. }
  93. USB_NOCACHERAM 0x24070000 0x00010000 { ; RW data
  94. *(.noncacheable)
  95. }
  96. }
  97. ICF:
  98. .. code-block:: C
  99. define region NONCACHEABLE_RAM = [from 0x1140000 size 256K];
  100. place in NONCACHEABLE_RAM { section .noncacheable, section .noncacheable.init, section .noncacheable.bss }; // Noncacheable