Ver código fonte

【增加】版本控制

Signed-off-by: armink <armink.ztl@gmail.com>
armink 5 anos atrás
commit
1e674b0545
100 arquivos alterados com 8573 adições e 0 exclusões
  1. 42 0
      .gitattributes
  2. 33 0
      .github/PULL_REQUEST_TEMPLATE.md
  3. 36 0
      .gitignore
  4. 127 0
      .travis.yml
  5. 45 0
      AUTHORS
  6. 1224 0
      ChangeLog.md
  7. 3 0
      Kconfig
  8. 201 0
      LICENSE
  9. 84 0
      README.md
  10. 97 0
      README_zh.md
  11. 490 0
      bsp/qemu-vexpress-a9/.config
  12. 150 0
      bsp/qemu-vexpress-a9/.cproject
  13. 44 0
      bsp/qemu-vexpress-a9/.gitignore
  14. 54 0
      bsp/qemu-vexpress-a9/.project
  15. 28 0
      bsp/qemu-vexpress-a9/Kconfig
  16. 105 0
      bsp/qemu-vexpress-a9/README.md
  17. 14 0
      bsp/qemu-vexpress-a9/SConscript
  18. 32 0
      bsp/qemu-vexpress-a9/SConstruct
  19. 11 0
      bsp/qemu-vexpress-a9/applications/SConscript
  20. 19 0
      bsp/qemu-vexpress-a9/applications/lcd_init.c
  21. 11 0
      bsp/qemu-vexpress-a9/applications/main.c
  22. 19 0
      bsp/qemu-vexpress-a9/applications/mnt.c
  23. 32 0
      bsp/qemu-vexpress-a9/drivers/Kconfig
  24. 23 0
      bsp/qemu-vexpress-a9/drivers/SConscript
  25. 9 0
      bsp/qemu-vexpress-a9/drivers/audio/SConscript
  26. 121 0
      bsp/qemu-vexpress-a9/drivers/audio/drv_ac97.c
  27. 63 0
      bsp/qemu-vexpress-a9/drivers/audio/drv_ac97.h
  28. 409 0
      bsp/qemu-vexpress-a9/drivers/audio/drv_pl041.c
  29. 237 0
      bsp/qemu-vexpress-a9/drivers/audio/drv_pl041.h
  30. 342 0
      bsp/qemu-vexpress-a9/drivers/audio/drv_sound.c
  31. 15 0
      bsp/qemu-vexpress-a9/drivers/audio/drv_sound.h
  32. 57 0
      bsp/qemu-vexpress-a9/drivers/board.c
  33. 33 0
      bsp/qemu-vexpress-a9/drivers/board.h
  34. 133 0
      bsp/qemu-vexpress-a9/drivers/drv_clcd.c
  35. 16 0
      bsp/qemu-vexpress-a9/drivers/drv_clcd.h
  36. 471 0
      bsp/qemu-vexpress-a9/drivers/drv_keyboard.c
  37. 6 0
      bsp/qemu-vexpress-a9/drivers/drv_keyboard.h
  38. 297 0
      bsp/qemu-vexpress-a9/drivers/drv_mouse.c
  39. 6 0
      bsp/qemu-vexpress-a9/drivers/drv_mouse.h
  40. 467 0
      bsp/qemu-vexpress-a9/drivers/drv_sdio.c
  41. 47 0
      bsp/qemu-vexpress-a9/drivers/drv_sdio.h
  42. 559 0
      bsp/qemu-vexpress-a9/drivers/drv_smc911x.c
  43. 402 0
      bsp/qemu-vexpress-a9/drivers/drv_smc911x.h
  44. 130 0
      bsp/qemu-vexpress-a9/drivers/drv_timer.c
  45. 17 0
      bsp/qemu-vexpress-a9/drivers/drv_timer.h
  46. 330 0
      bsp/qemu-vexpress-a9/drivers/realview.h
  47. 59 0
      bsp/qemu-vexpress-a9/drivers/secondary_cpu.c
  48. 183 0
      bsp/qemu-vexpress-a9/drivers/serial.c
  49. 39 0
      bsp/qemu-vexpress-a9/drivers/serial.h
  50. 37 0
      bsp/qemu-vexpress-a9/drivers/vexpress_a9.h
  51. 101 0
      bsp/qemu-vexpress-a9/link.lds
  52. 4 0
      bsp/qemu-vexpress-a9/makefile.targets
  53. 6 0
      bsp/qemu-vexpress-a9/qemu-dbg.bat
  54. 6 0
      bsp/qemu-vexpress-a9/qemu-dbg.sh
  55. 6 0
      bsp/qemu-vexpress-a9/qemu-nographic.bat
  56. 6 0
      bsp/qemu-vexpress-a9/qemu-nographic.sh
  57. 6 0
      bsp/qemu-vexpress-a9/qemu.bat
  58. 5 0
      bsp/qemu-vexpress-a9/qemu.sh
  59. 275 0
      bsp/qemu-vexpress-a9/rtconfig.h
  60. 87 0
      bsp/qemu-vexpress-a9/rtconfig.py
  61. 62 0
      bsp/stm32/README.md
  62. 87 0
      bsp/stm32/docs/STM32绯诲垪BSP澶栬椹卞姩浣跨敤鏁欑▼.md
  63. 288 0
      bsp/stm32/docs/STM32绯诲垪BSP鍒朵綔鏁欑▼.md
  64. 63 0
      bsp/stm32/docs/STM32绯诲垪椹卞姩浠嬬粛.md
  65. 162 0
      bsp/stm32/docs/STM32绯诲垪澶栬椹卞姩娣诲姞鎸囧崡.md
  66. BIN
      bsp/stm32/docs/figures/CubeMX_1.png
  67. BIN
      bsp/stm32/docs/figures/CubeMX_2.png
  68. BIN
      bsp/stm32/docs/figures/CubeMX_3.png
  69. BIN
      bsp/stm32/docs/figures/CubeMX_4.png
  70. BIN
      bsp/stm32/docs/figures/CubeMX_5.png
  71. BIN
      bsp/stm32/docs/figures/Kconfig.png
  72. BIN
      bsp/stm32/docs/figures/Kconfig2.png
  73. BIN
      bsp/stm32/docs/figures/Peripheral.png
  74. BIN
      bsp/stm32/docs/figures/SConscript.png
  75. BIN
      bsp/stm32/docs/figures/adc_config1.png
  76. BIN
      bsp/stm32/docs/figures/adc_config2.png
  77. BIN
      bsp/stm32/docs/figures/adc_config3.png
  78. BIN
      bsp/stm32/docs/figures/adc_config4.png
  79. BIN
      bsp/stm32/docs/figures/board_1.png
  80. BIN
      bsp/stm32/docs/figures/board_2.png
  81. BIN
      bsp/stm32/docs/figures/board_h.png
  82. BIN
      bsp/stm32/docs/figures/bsp_template_dir.png
  83. BIN
      bsp/stm32/docs/figures/complise.png
  84. BIN
      bsp/stm32/docs/figures/config.png
  85. BIN
      bsp/stm32/docs/figures/config1.png
  86. BIN
      bsp/stm32/docs/figures/config2.png
  87. BIN
      bsp/stm32/docs/figures/config3.png
  88. BIN
      bsp/stm32/docs/figures/config4.png
  89. BIN
      bsp/stm32/docs/figures/config5.png
  90. BIN
      bsp/stm32/docs/figures/copy.png
  91. BIN
      bsp/stm32/docs/figures/cube_spi3.png
  92. BIN
      bsp/stm32/docs/figures/cubemx.png
  93. BIN
      bsp/stm32/docs/figures/exit.png
  94. BIN
      bsp/stm32/docs/figures/frame.png
  95. BIN
      bsp/stm32/docs/figures/heap_config.png
  96. BIN
      bsp/stm32/docs/figures/i2c_device.png
  97. BIN
      bsp/stm32/docs/figures/link_icf.png
  98. BIN
      bsp/stm32/docs/figures/link_lds.png
  99. BIN
      bsp/stm32/docs/figures/linker_scripts.png
  100. BIN
      bsp/stm32/docs/figures/linkscripts_change.png

+ 42 - 0
.gitattributes

@@ -0,0 +1,42 @@
+* text=auto
+
+*.S text
+*.asm text
+*.c text
+*.cc text
+*.cpp text
+*.cxx text
+*.h text
+*.htm text
+*.html text
+*.in text
+*.ld text
+*.m4 text
+*.mak text
+*.mk text
+*.py text
+*.rb text
+*.s text
+*.sct text
+*.sh text
+*.txt text
+*.xml text
+SConscript text
+Makefile text
+AUTHORS text
+COPYING text
+
+*.LZO -text
+*.Opt -text
+*.Uv2 -text
+*.ewp -text
+*.eww -text
+*.vcproj -text
+*.bat -text
+*.dos -text
+*.icf -text
+*.inf -text
+*.ini -text
+*.sct -text
+*.xsd -text
+Jamfile -text

+ 33 - 0
.github/PULL_REQUEST_TEMPLATE.md

@@ -0,0 +1,33 @@
+## 拉取/合并请求描述:(PR description)
+
+[
+这段方括号里的内容是您**必须填写并替换掉**的,否则PR不可能被合并。**方括号外面的内容不需要修改,但请仔细阅读。**
+The content in this square bracket must be filled in and replaced, otherwise PR can not be merged. The contents outside square brackets need not be changed, but please read them carefully.
+
+请在这里填写您的PR描述,可以包括以下之一的内容:为什么提交这份PR;解决的问题是什么,你的解决方案是什么;
+Please fill in your PR description here, which can include one of the following items: why to submit this PR; what is the problem solved and what is your solution;
+
+并确认并列出已经在什么情况或板卡上进行了测试。
+And confirm in which case or board have been tested.
+]
+
+以下的内容不应该在提交PR时的message修改,修改下述message,PR会被直接关闭。请在提交PR后,浏览器查看PR并对以下检查项逐项check,没问题后逐条在页面上打钩。
+The following content must not be changed in submitted PR message. Otherwise, the PR will be closed immediately. After submitted PR, please use web browser to visit PR, and check items one by one, and ticked them if no problem.
+
+### 当前拉取/合并请求的状态 Intent for your PR
+
+必须选择一项 Choose one (Mandatory):
+
+- [ ] 本拉取/合并请求是一个草稿版本 This PR is for a code-review and is intended to get feedback
+- [ ] 本拉取/合并请求是一个成熟版本 This PR is mature, and ready to be integrated into the repo
+
+### 代码质量 Code Quality:
+
+我在这个拉取/合并请求中已经考虑了 As part of this pull request, I've considered the following:
+
+- [ ] 已经仔细查看过代码改动的对比 Already check the difference between PR and old code
+- [ ] 代码风格正确,包括缩进空格,命名及其他风格 Style guide is adhered to, including spacing, naming and other style
+- [ ] 没有垃圾代码,代码尽量精简,不包含`#if 0`代码,不包含已经被注释了的代码 All redundant code is removed and cleaned up
+- [ ] 所有变更均有原因及合理的,并且不会影响到其他软件组件代码或BSP All modifications are justified and not affect other components or BSP
+- [ ] 对难懂代码均提供对应的注释 I've commented appropriately where code is tricky
+- [ ] 本拉取/合并请求代码是高质量的 Code in this PR is of high quality

+ 36 - 0
.gitignore

@@ -0,0 +1,36 @@
+*.pyc
+*.map
+*.dblite
+*.elf
+*.bin
+*.hex
+*.axf
+*.exe
+*.pdb
+*.idb
+*.ilk
+*.old
+build
+Debug
+documentation/html
+*~
+*.o
+*.obj
+*.bak
+*.dep
+*.lib
+*.a
+*.i
+*.d
+tools/kconfig-frontends/kconfig-mconf
+packages
+cconfig.h
+GPUCache
+
+#cscope files
+cscope.*
+ncscope.*
+
+#ctag files
+tags
+

+ 127 - 0
.travis.yml

@@ -0,0 +1,127 @@
+language: c
+
+notifications:
+  email: false
+
+before_script:
+# travis has changed to 64-bit and we require 32-bit compatibility libraries
+  - sudo apt-get update
+  # clang
+  - "sudo apt-get -qq install gcc-multilib libc6:i386 libgcc1:i386 libstdc++5:i386 libstdc++6:i386 libsdl-dev scons || true"
+  # - sudo apt-get -qq install gcc-arm-none-eabi
+  # - "[ $RTT_TOOL_CHAIN = 'sourcery-arm' ] && export RTT_EXEC_PATH=/usr/bin && arm-none-eabi-gcc --version || true"
+  # - "[ $RTT_TOOL_CHAIN = 'sourcery-arm' ] && curl -s https://sourcery.mentor.com/public/gnu_toolchain/arm-none-eabi/arm-2014.05-28-arm-none-eabi-i686-pc-linux-gnu.tar.bz2 | sudo tar xjf - -C /opt && export RTT_EXEC_PATH=/opt/arm-2014.05/bin && /opt/arm-2014.05/bin/arm-none-eabi-gcc --version || true"
+  - "[ $RTT_TOOL_CHAIN = 'sourcery-arm' ] && wget -q https://github.com/RT-Thread/toolchains-ci/releases/download/arm-2017q2-v6/gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2 && sudo tar xjf gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2 -C /opt && export RTT_EXEC_PATH=/opt/gcc-arm-none-eabi-6-2017-q2-update/bin && /opt/gcc-arm-none-eabi-6-2017-q2-update/bin/arm-none-eabi-gcc --version || true"
+  - "[ $RTT_TOOL_CHAIN = 'sourcery-mips' ] && wget -q https://github.com/RT-Thread/toolchains-ci/releases/download/v1.1/mips-2016.05-7-mips-sde-elf-i686-pc-linux-gnu.tar.bz2 && sudo tar xjf mips-2016.05-7-mips-sde-elf-i686-pc-linux-gnu.tar.bz2 -C /opt && export RTT_EXEC_PATH=/opt/mips-2016.05/bin && /opt/mips-2016.05/bin/mips-sde-elf-gcc --version || true"
+  # - "[ $RTT_TOOL_CHAIN = 'sourcery-ppc' ] && curl -s https://sourcery.mentor.com/public/gnu_toolchain/powerpc-eabi/freescale-2011.03-39-powerpc-eabi-i686-pc-linux-gnu.tar.bz2 | sudo tar xjf - -C /opt && export RTT_EXEC_PATH=/opt/freescale-2011.03/bin && /opt/freescale-2011.03/bin/powerpc-eabi-gcc --version || true"
+  # - "[ $RTT_TOOL_CHAIN = 'atmel-avr32' ] && curl -s http://www.atmel.com/images/avr32-gnu-toolchain-3.4.1.348-linux.any.x86.tar.gz | sudo tar xzf - -C /opt && export RTT_EXEC_PATH=/opt/avr32-gnu-toolchain-linux_x86/bin && /opt/avr32-gnu-toolchain-linux_x86/bin/avr32-gcc --version && curl -sO http://www.atmel.com/images/avr-headers-3.2.3.970.zip && unzip -qq avr-headers-3.2.3.970.zip -d bsp/$RTT_BSP || true"
+  - export RTT_ROOT=`pwd`
+  - "[ x$RTT_CC == x ] && export RTT_CC='gcc' || true"
+
+env:
+#  - RTT_BSP='simulator' RTT_CC='clang-analyze' RTT_EXEC_PATH=/usr/share/clang/scan-build
+  - RTT_BSP='CME_M7' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='apollo2' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='asm9260t' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='at91sam9260' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='allwinner_tina' RTT_TOOL_CHAIN='sourcery-arm'
+#  - RTT_BSP='avr32uc3b0' RTT_TOOL_CHAIN='atmel-avr32'
+#  - RTT_BSP='bf533' # no scons
+  - RTT_BSP='efm32' RTT_TOOL_CHAIN='sourcery-arm'
+#  - RTT_BSP='es32f0334' RTT_TOOL_CHAIN='sourcery-arm' # not support gcc
+#  - RTT_BSP='es32f0654' RTT_TOOL_CHAIN='sourcery-arm' # not support gcc
+  - RTT_BSP='gd32e230k-start' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='gd32303e-eval' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='gd32450z-eval' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='gkipc' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='imx6sx/cortex-a9' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='imxrt/imxrt1052-atk-commander' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='imxrt/imxrt1052-fire-pro' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='imxrt/imxrt1052-nxp-evk' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='lm3s8962' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='lm3s9b9x' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='lm4f232' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='tm4c129x' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='lpc43xx/M4' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='lpc176x' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='lpc178x' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='lpc408x' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='lpc1114' RTT_TOOL_CHAIN='sourcery-arm'
+#  - RTT_BSP='lpc824' RTT_TOOL_CHAIN='sourcery-arm' # not support gcc
+  - RTT_BSP='lpc2148' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='lpc2478' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='lpc5410x' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='lpc54114-lite' RTT_TOOL_CHAIN='sourcery-arm'
+#  - RTT_BSP='lpc54608-LPCXpresso' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='ls1bdev' RTT_TOOL_CHAIN='sourcery-mips'
+  - RTT_BSP='ls1cdev' RTT_TOOL_CHAIN='sourcery-mips'
+#  - RTT_BSP='m16c62p' # m32c
+  - RTT_BSP='mb9bf500r' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='mb9bf506r' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='mb9bf618s' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='mb9bf568r' RTT_TOOL_CHAIN='sourcery-arm'
+#  - RTT_BSP='microblaze' # no scons
+  - RTT_BSP='mini2440' RTT_TOOL_CHAIN='sourcery-arm'
+#  - RTT_BSP='mini4020' # no scons
+#  - RTT_BSP='mm32l07x' # not support gcc
+#  - RTT_BSP='nios_ii' # no scons
+  - RTT_BSP='nuvoton_nuc472' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='nuvoton_m05x' RTT_TOOL_CHAIN='sourcery-arm'
+#  - RTT_BSP='pic32ethernet' # no scons
+  - RTT_BSP='qemu-vexpress-a9' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='qemu-vexpress-gemini' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='sam7x' RTT_TOOL_CHAIN='sourcery-arm'
+#  - RTT_BSP='simulator' # x86
+  - RTT_BSP='stm32/stm32f072-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32f091-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32f103-atk-nano' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32f103-atk-warshipv3' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32f103-dofly-lyc8' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32f103-dofly-M3S' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32f103-fire-arbitrary' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32f103-hw100k-ibox' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32f103-mini-system' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32f103-yf-ufun' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32f107-uc-eval' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32f401-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32f405-smdz-breadfruit' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32f407-atk-explorer' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32f407-st-discovery' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32f411-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32f427-robomaster-a' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32f429-armfly-v6' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32f429-atk-apollo' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32f429-fire-challenger' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32f429-st-disco' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32f446-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32f469-st-disco' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32f746-st-disco' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32f767-atk-apollo' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32f767-fire-challenger' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32f767-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32g071-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32g431-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32h743-atk-apollo' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32h743-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32l4r9-st-eval' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32l053-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32l432-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32l475-atk-pandora' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32l475-st-discovery' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32l476-st-nucleo' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32/stm32l496-ali-developer' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='stm32f20x' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='swm320-lq100' RTT_TOOL_CHAIN='sourcery-arm'
+#  - RTT_BSP='taihu' RTT_TOOL_CHAIN='sourcery-ppc'
+#  - RTT_BSP='upd70f3454' # iar
+#  - RTT_BSP='x86' # x86
+  - RTT_BSP='beaglebone' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='zynq7000' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='frdm-k64f' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='fh8620' RTT_TOOL_CHAIN='sourcery-arm'
+  - RTT_BSP='x1000' RTT_TOOL_CHAIN='sourcery-mips'
+  - RTT_BSP='xplorer4330/M4' RTT_TOOL_CHAIN='sourcery-arm'
+
+stage: compile
+script:
+  - scons -C bsp/$RTT_BSP

+ 45 - 0
AUTHORS

@@ -0,0 +1,45 @@
+Kernel Design & Implementation
+- Bernard Xiong <bernard.xiong@gmail.com>
+
+LwIP 1.3.0/1.3.1/1.3.2/1.4.0
+- Porting
+  Qiu Yi
+  Mbbill
+- Testing
+  Bernard Xiong
+
+Filesystem
+- Porting and Add Virtual Filesystem
+- Testing
+  Qiu Yi
+  prife
+
+RTGUI
+- Design and Implemenation
+  Bernard Xiong
+  Grissiom
+
+BSP
+Bernard Xiong
+- ATMEL AT91SAM7S64 & AT91SAM7X256 Porting
+- STM32 Porting
+- S3C4510 Porting
+
+Mbbill
+- ATMEL AT91SAM7X256
+
+Xulong Cao
+- QEMU/x86
+
+Aozima
+- LPC 2148 Porting
+- STM32 Porting
+
+Jing Lee
+- LPC 2478 Porting
+
+Qiu Yi
+- S3C2410 & S3C2440 Porting
+- TI LM3S
+
+others...

+ 1224 - 0
ChangeLog.md

@@ -0,0 +1,1224 @@
+# RT-Thread v4.0.1 Change Log
+
+## Kernel
+
+* Fix the `rt_tick_from_millisecond()` compilation warning issue;
+* Remove unnecessary code that disable interrupt several times during startup initialization;
+* Fix the issue that the system object is not detached when handling defunct threads. 
+* Add the value checking of semaphore (the maximum value of semaphore is up to 65535)
+* Fix the 64-bit issue in kservice.c
+* Add the checking and assertion of re-initialization of object.
+* In the rt_enter_critical/rt_exit_critical function, add the checking of whether scheduler is startup or not.
+* Fix the signal issue under SMP and the issue of signal information list in signal.
+* Add 64-bit processor support in slab memory allocation.
+* Fix the definition issue of `ENOTSUP` in libc_errno.h.
+* Simplify the rtdbg.h file and use ulog to make log/debug system easier to use.
+* Add the configuration of RT_USING_ARCH_DATA_TYPE, `rt_int8_t/.../rt_uint32_t` and other basic data types can be defined by BSP itself. (It is recommended to put them into the rtconfig_project.h file, so that this file can be automatically included in rtconfig.h when menuconfig generates it.)
+* Add `RT_Device_Class_Sensor` type devices;
+* In the case of single core, the definition of `rt_hw_spin_lock/rt_hw_spin_unlock` is redefined as the disable/enable interrupt.
+* Add the `rt_strnlen()` function in kservice.c.
+* Support the long long type in rt_kprintf (HubertXie);
+
+## Components
+
+* Remove CMSIS and move to software package as CMSIS package.
+* Remove logtrace component. The system log system switches to ulog;
+* Add more code to support AC6 tool chain in some BSP and components;
+* In DFS file system component, clean up the log and fix the mkfs issue when index may be out of range.
+* Split the running mode from sleep mode in power management, and the frequency change should be clearer. Power management is not use idle hook but execute the sleep action in idle thread directly. (How to use power management, please visit programming document for details)
+* Cleanup the log of MMC/SD driver framework;
+* Rewrite Sensor Framework, replace the original C++ implementation with C version, and add some corresponding sensor software packages; To use the sensor packages, please use this release;
+* Add the DMA transmission operation in the serial driver framework;
+* Add the consistency protection to tc_flush routine of serial driver (loogg).
+* Add rt_sfud_flash_find_by_dev_name API in SFUD.
+* When the Pipe device closed, if it is an unnamed Pipe device and the open count is 0, this Pipe device will be deleted.
+* The delayed work implementation is added to workqueue, and the workqueue of the system is added as an option.
+* Fix the data loss issue when using DMA transmission in USB CDC.
+* Change the return type of finsh_getchar to int;
+* Fix the errno issue in newlib/GCC tool chain.
+* Change the management of pthreads to POSIX thread array instead of mapping pthread_t directly to rt_thread_t; Change the fields definition more similar with newlib/glibc in pthreads.
+* Fix the thread name output in ulog.
+* Add loop parameter in utest, then executes test cases repeatedly; Add thread parameter in utest to execute testcase in a new thread.
+* Add delay in handshake phase to protect incomplete data reception in YModem component.
+* Add netdev component, abstract netdev concept, used to management and control network interface device, and provide netdev operation commands, including ping/ifconfig/dns/netstat etc;
+* Modify SAL for netdev, that is, adds the judgment of netdev status and information when the socket creating and data transmitting;
+* Add options and types for UDP multicast traffic handling and IPPROTO_IP in SAL;
+* Fix `itctrol()` function not support to control socketfd issues in SAL;
+* Improve error log processing in AT socket;
+* Fix serial receive data failed issues when AT client initialization is not completed;
+
+## BSP
+
+* Add ES32 chip BSP from Shanghai Eastsoft Microelectronics Co., Ltd. (EastSoft provides maintenance and support);
+* Add GD32E230K-start, with ARM Cortex-M23 core BSP (xuzhuoyi)
+* Add IMXRT1021-EVK BSP (NXP provides maintenance and support);
+* Add the ETH hardware checksum option in IMXRT1052 ETH driver;
+* Add more peripheral drivers, GPIO, LCD, SPI, camera, etc. in Kendryte K210 BSP.
+* Cleanup the LPC 4088 BSP to use main function entry and support menuconfig;
+* Add LPC1114 BSP with UART driver (SASANO Takayoshi, Japan);
+* The double Frame Buffer mechanism and touch screen driver are added in Godson 1C BSP, then it can better to support Persimmon UI (sundm75).
+* Add watchdog driver in Godson 1C BSP(sundm75);
+* Add MM32 chip BSP from Shanghai MindMotion Microelectronics Co., Ltd. (MindMotion provides maintenance and support);
+* Fix the SysTick interrupt handling issue in nRF52832 and add menuconfig configuration file.
+* Add QSPI and SPI flash driver to Nuvoton M487 BSP (bluebear 233)
+* Change the CPU porting to libcpu/arm/cortex-a folder in QEMU-VExpress A9/IMX6UL BSP;
+* In QEMU-VExpress A9 BSP, the MAC address associated with the local MAC address is used for a unified MAC address in the network.
+* remove stm32f0x, stm32f7-disco, stm32f107, stm32f40x, stm32l072, stm32l475-iot-disco, stm32l476-nucleo BSP (when the new STM32 BSP can completely replace these old BSP, these BSP will be removed);
+* For the new STM32 BSP:
+  * Add CAN driver (ylz0923)
+  * Add CAN driver to stm32f103-fire-arbitrary (ylz0923)
+  * stm32f746-st-disco with LCD, watchdog, SDCard, ethernet, Flash and other drivers (Jinsheng)
+* More board support is added to the new STM32 BSP:
+  * stm32f103-atk-warship V3 ATK Warship V3 (daizhiwang)
+  * STm32f103-dofly-M3S Dofly STM32F103 Development Board
+  * stm32f103-mini-system, the minimum system board for STM32F103 (daizhiwang)
+  * stm32f401-st-nucleo
+  * stm32f405-smdz-breadfruit sanmu electronic stm32405 development board (sunlichao)
+  * stm32f469-st-disco
+  * stm32h743-atk-apollo (whj4674672)
+  * stm32l4r9-st-eval
+  * stm32l053-st-nucleo (sun_shine)
+  * stm32l475-st-discovery
+  * stm32l476-st-nucleo (Vincent-VG)
+  * stm32l496-ali-developer
+
+* Add the ARC support for Synopsys Design Ware ARC EM Starter Kit (Synopsys provides maintenance and support);
+* The SCI driver is added to the TMS320F28379D BSP (xuzuoyi).
+* Add W60X Wi-Fi SoC chip BSP from Winner Microelectronics Co.,Ltd. (Winner Micro and RealThread provide maintenance and support);
+* Fix the UART2 IO configuration issue in X1000 UART driver (Zhou Yanjie);
+* Add SConscript file for each CPU porting.
+* Cleanup the libcpu/arm/cortex-a code;
+* The _rt_hw_context_switch_interrupt/_rt_hw_context_switch is separated in TI DSP TMS320F28379D BSP (xuzuoyi);
+
+## Tool
+
+* Add Makefile generation feature in scons with command `scons –target=makefile -s`. Then developer can use make to build RT-Thread under Linux or Windows.
+* Add Eclipse project generation feature in scons with command `scons –target=eclipse -s`, which will put the necessary information in `.cproject` and `.project` files in current BSP folder. The developer can use Eclipse to build RT-Thread.
+* Fix the multi-group same name issue when generating Keil MDK project file and add a library file into the SConscript (Eric Qiang);
+* Fix the GCC Version Comparing issue
+* ENV version updated to v1.1.2
+  * Update scons version to 3.0.5
+  * Fix VC++ warning issue
+  * Fix Unicode error issue
+
+# RT-Thread v4.0.0 Change Log
+
+## Kernel
+
+* Add SMP support;
+* Add support for 64-bit processors;
+* When the thread is running on CPU, the state of this thread is changed to RUNNING stat instead of READY state in previous version;
+
+## Components
+
+* When formatting the file system, adds FM_SFD option to create a volume in SFD format for FatFs; (HubretXie)
+* Add file system handle pointer in `struct dfs_fd' structure;
+* Fix stdio fd issue when POSIX api is used; (gbcwbz)
+* Fix the `fd_is_open()` issue: when the sub-path is the same in different mounted filesystem. 
+* Change the critical lock/unlock to dfs_lock/unlock in `getcwd()` function of DFS (the critical lock/unlock is different in SMP environment);
+* Rewrite `list_thread/list_*` implementation of finsh cmd to avoid multi-core competition case;
+* Fix the `aio_result` issue, which is returned by `aio_read_work` in AIO; (fullhan)
+* Fix the mmap issue when the addr parameter is NULL; (fullhan)
+* Modify the `_sys_istty` function in armlibc to correctly handle STDIN/STDOUT/STDERR; (gbcwbz)
+* Modify the `_write_r` function in newlib to correctly handle stdout.
+* Add lightweight processes (lwP) and corresponding system calls;
+  * the lwP user application environment will be added later;
+* Fix the at_socket issue when socket is a null pointer; (thomas onegd)
+* Fix the select event issue in `at_recvfrom()` function in at_socket;
+* Divide SAL into `sal_socket_ops/sal_proto_ops` and sal_proto_ops is implemented with gethostbyname/getaddrinfo ops etc.
+* Add socket TLS layer in SAL, that is, upper application can be supported by encrypted transmission without considering lowlevel TLS at all.
+* Fix the length issue of `ulog_strcpy`, which should be not exceed `ULOG_LINE_BUF_SIZE`;
+* Add the macro definition of hexadecimal log output to ulog; (HubretXie)
+* Add uTest component. The uTest is a unit test framework on RT-Thread, and can also be used for automatic testing on board with external Python scripts.
+* Fix some compilation warnings and enumeration mismatches in drivers/audio;
+* Fix the `can_rx/can_tx` issue, which is not cleared to NULL when CAN device is closed in drivers/can; (xeonxu)
+* Fix drivers/hwtimer, time acquisition issue with counting down mode;
+* Add drivers/adc driver framework;
+* Fix the tick compensation issue when enable interrupt too early; (geniusgogo)
+* Add `RT_SERIAL_USING_DMA` option in drivers/serial;
+* Add QSPI support in drivers/spi framework;
+* Add QSPI support in SFUD (based on the QSPI peripheral of stm32); SFUD is upgraded to version 1.1.0;
+* Optimize SPI take/release function call in spi_msd;
+* Fix the `blk_size` issue in `rt_rbb_blk_alloc()`;
+* Fix the FS USB issue in `_get_descriptor` function;
+* Fix the empty password issue in AP mode of drivers/wlan;
+* Fix the return type issue in drivers/wlan;
+* Remove the duplicate opening file check when open a file;
+
+# BSP
+
+* Change the name parameter to `cosnt char *` in `rt_hw_interrupt_install` function; (liruncong)
+* Rewrite the RISC-V porting layer to make as a common and standalone porting layer for RISC-V IMAC 32/64;
+* Fix `$` warning issue in Kconfig files of each BSP;
+* Add the LPC54114-lite BSP, including GPIO, I2C, SDCard, SPI, SPI Flash, UART driver;
+* Add Nuvoton-M487 BSP, including UART, EMAC driver; (Bluebear 233)
+* Add Kendryte K210 BSP with RISC-V64 dual-core SMP BSP, including UART driver, also verified with micropython;
+* Add RV32M1 VEGA BSP, including GPIO, I2C, SDCard, UART and other drivers;
+* Fix the CAN driver issue in STM32F4XX-HAL BSP; (xeonxu)
+* Fix UART DMA settings issue in STM32F10x/STM32F40x BSP; (zhouchuanfu)
+* Fix the HEAP_BEGIN definition issue in STM32H743-Nucleo BSP; (nongxiaoming)
+* Fix GPIO configuration issue in stm32f10x-HAL; (Wu Han)
+* Change stm32f107 BSP as main function entry; (whj4674672)
+* Fix the serial interrupt handling issue in stm32f10x BSP;
+* Add PWM, RTC and watchdog drivers to stm32f10x-HAL BSP; (XXXXzzzz000)
+* Fix the watchdog driver issue in stm32f4xx-HAL BSP; (XXXXzzzz000)
+* Use lwIP version 2.x in stm32f40x/stm32f107 BSP.
+* Fix the link issue when enable cmBacktrace package in stm32f4xx-HAL BSP; (xeonxu)
+* Support Audio and microphones features in stm32f429-apollo BSP;
+* Enable dlmodule support in x86 BSP; (SASANO Takayoshi)
+* Addd uTest section in the link script of qemu-vexpress-a9/stm32f429-atk-apollo BSP for automatic testing;
+* Change the license to Apache License v2.0 in Godson 1C BSP; (sundm75)
+* Add the new BSP framework for STM32 serial chip, such as STM32 G0/F0/L0/F1/F4/F7/H7. In new BSP framework, the SoC drivers is reused. And in same time, lots of STM32 boards are supportted with new BSP framework:
+  * STM32F091-Nucleo Development Board BSP
+  * STM32F411-Nucleo Development Board BSP
+  * STM32L432-Nucleo Development Board BSP; (sun_shine)
+  * STM32F407-Discovery Development Board BSP
+  * STM32F446-Nucleo Development Board BSP; (andeyqi)
+  * STM32F746-Discovery Development Board BSP; (jinsheng)
+  * STM32F767-Nucleo Development Board BSP; (e31207077)
+  * STM32G071-Nucleo Development Board BSP;
+  * ATK STM32F103 NANO Development Board BSP
+  * ATK STM32F407 Explorer Development Board BSP
+  * ATK STM32F429 Apollo Development Board BSP
+  * ATK STM32F767 Apollo Development Board BSP
+  * ATK STM32L475 Pandora IoT Development Board BSP
+  * Fire STM32F103 Arbitrary Development Board BSP
+  * Fire STM32F429 Challenger Development Board BSP
+  * Fire STM32F767 Challenger Development Board BSP; (Hao Zhu)
+  * ArmFly STM32F429-v6 Development Board BSP
+  * STM32F103 iBox development board BSP; (dingo1688)
+  * Dofly STM32F103 Development Board; (FindYGL)
+  * STM32F107 uC/Eval Development Board BSP; (whj4674672)
+  * and more, there are more developers involved for stm32 BSP framework, they are HubretXie, Hao Zhu, e190, etc. to improve the STM32 public driver.
+* Add SWM320 BSP of Synwit.cn, including GPIO, HW Timer, I2C, Watchdog, PWM, RTC, SPI, UART, etc.; (provided and maintained by Synwit)
+* Add TI TMS320F28379D BSP, the first DSP chip supported on RT-Thread; (xuzhuoyi)
+* Fix USB driver issue in X1000; (Zhou YanJie)
+* Add BSP for Synopsys Design Ware ARC EM Starter Kit, bsp/synopsys/emsk_em9d, EM9D core, including GPIO, UART and other drivers; (provided and maintained by Synopsys)
+
+# Tool
+
+* Provide more inforamtion when the tool chain does not exist;
+* Add a draft Segger Embedded Studio project file generation command. Note that the tool chain in SES is a special version not the newlib.
+* Fix the IAR library link command issue when use scons command line under;
+* Fix the BSP path issue in scons `str(Dir('#'))`;
+* Add `scons --pyconfig-silent` command to add some Kconfig configurations and to generate `.config` and `rtconfig.h` files;
+* Update the `scons --dist` command to adapt to the new BSP framework;
+* Modify the mkromfs.py script. Fix the corresponding C code generation When the romfs contains empty files or empty folders;
+* Fix the issue of version string comparison issue for GNU GCC version in utils.py;
+* ENV updated to V1.1.0
+  * Provide better prompt information to improve user experience;
+  * Add `system32` path to environment variables to avoid the `cmd` command cannot be found;
+  * Add `PYTHONHOME` variable to environment variables to avoid PYTHON environment issue;
+
+# RT-Thread v3.1.1 Change Log
+
+## Kernel
+
+* Support the configuration of the upward growth stack which is defined by the `ARCH_CPU_STACK_GROWS_UPWARD` macro. Because there are fewer ARCH for stacks growing upward, this configuration item does not display directly in menuconfig. When a CPU ARCH needs stacks growing upward, the configuration of `ARCH_CPU_STACK_GROWS_UPWARD` can be selected by BSP Kconfig file in default.
+* Support for ARMCC V6 and later compiler (LLVM-based Compiler); currently it's mainly used in Keil MDK IDE. Please notes that the "Warnings" needs to use `Moderate Warnings` in project configuration in C/C++ (AC6) TAB; After using ARMCC v6, RT-Thread will add an additional `CLANG_ARM` macro definition; (liruncong, nongxiaoming, bernard)
+* The `RT_USING_IDLE_HOOK` configuration in Kconfig becomes a separate configuration item, not limited to `RT_USING_HOOK`; (geniusgogo)
+
+## Components
+
+* Improve the PWM driver framework and add more interfaces.
+* Fix the F_SETFL handling in ioctrl function; Fix the return value issue of fcntl function which is always 0 value.
+* Fix the memheap object type issue when creating a ramfs object.
+* Add power management framework for low power applications.
+* Add multi-segment support for read and write operations in MC/SDIO driver framework (for stm32, you can choose a separate stm32_sdio package); (weety)
+* Add ringblk_buf component for the block mode but in ringbuffer applications;
+* Improve WLAN management framework with unified interfaces, management, commands, to provide more friendly support to developers and users;
+* Add the conditional macro in the finsh when the MSH component is not enabled, even if the code files are compiled.
+* Remove gdbstub and move to rt-thread packages.
+* Upgrade and improve SAL and AT components: (linuxhan, eddylin83, slyant, luofanlu, Hubert Xie, Lawlieta, zhaojuntao, armink)
+  * Fix the none cleared issue when closing socket in SAL, which lead to the socket is always holding.
+  * Fix the `select()` issue for UDP communication in AT component. Add the receiving data handling to complete the clearing of received event;
+  * Add the errno value when receive data timeout in at_recvfrom function in the AT component.
+  * Add the receive data timeout handling in at_client_recv function in the AT component.
+* Fix a possible issue in fputc function implementation when using microlib;
+* Add gmtime_r implementation for ARMCC, IAR tool chain;
+* Improve time function support in IAR and support 64bit time; (hichard)
+* DHCPD's support for IPv6;
+* Remove lwIP-1.3.2 porting and add lwIP-2.1.0 porting; lwIP-2.0.2 is still the default version.
+* Add a lightweight ulog component and automatically replace the debug macro of the original rtdbg.h when it's enable.
+* USB stack update
+  * HOST, optimize the USB HOST timeout mechanism; fix the un-alignment visit issue in F4xx-HAL USB host driver;
+  * Device: Add the check when class drivers are illegally registered; Fix the un-aligned access issue in some platforms; optimize CDC VCOM classes, add the timeout mechanism and ID definition.
+
+## BSP
+
+* Upgrade the wlan adaptor to the new version of Wi-Fi management framework in amebaz BSP.
+* Add airkiss wifi configuration code to amebaz BSP.
+* Update Apollo2 BSP with ADC, GPIO, I2C, PDM, SPI, UART and other drivers; (Haleyl)
+* BeagleBone BSP is changed to main function mode, and adds Kconfig configuration file.
+* DM365 BSP adds Kconfig configuration file;
+* Update HiFive1 BSP and add more documentation.
+* Update imx6sx BSP to main function mode, and add Kconfig configuration file.
+* Change the old imxrt1052-evk BSP. The imxrt1052-related BSPs are classified into the `bsp/imxrt` directory; A touch framework is added to `bsp/imxrt`, and later will be moved into `components/drivers` directory;
+* Improve stm32f4xx-HAL BSP with PWM, I2C, USB Host driver; (XuanZe, xuzhuoyi)
+* Improve stm32f10x BSP with CAN driver and increase I2C driver; (wuhanstudio, AubrCool)
+* Improve stm32f10x-HAL BSP with I2C, IWG, PWM, RTC and other drivers, improve UART driver; (XuanZe)
+* Improve stm32f429-disco BSP and add I2C, LCD, Touch driver; (xuzhuoyi)
+* Improve x86 BSP, support dlmodule function; (SASANO Takayoshi, parai)
+
+## Tool
+
+* Modify the building script to support Python 3; <Python 3 patches have been submitted to scons and need to wait for next scons release,maybe scons-3.0.2> (Arda)
+* Add `scons --pyconfig` mode, which has a TK UI configurator; (weety)
+* Support for GNU GCC 7/8 version toolchains (The `-std=c99` is not added into C-compiler flags), but please note: PThreads component failed in 2.5 and new version of newlib.
+
+# RT-Thread 3.1.0 Change Log
+
+## Kernel
+
+* The main thread priority can be configured by Kconfig;
+* Add the checking of kernel object type, which can effectively avoid the problem of continuing to use kernel objects after they are destroyed.
+* Add the idle hook list to mount multiple idle hook, and can be configured by Kconfig.
+* Add the device_ops operation set to reduce the footprint of device object.
+* Remove the special memory operation in application module when using SLAB memory management algorithm.
+* Move application module from the kernel to `libc/libdl`.
+* Enhance the debug information output of `rtdbg.h` file.
+* In Keil/IAR tool chain, the `RT_USED` is used to keep symbols and avoid to add more argument or section in link phrase.
+
+## Components
+
+* Remove all of external codes, which will be moved to packages in the future.
+* Add initialization flag for shell, file system, network protocol stack etc to prevent repeated initialization;
+* Enable the long file name feature of ELM FatFs in default.
+* Change DFS FD to dynamic allocation mode. The maximum number of allocation is still DFS_FD_MAX.
+* Add dfs_fdtable_get() function to get different fdtable;
+* Add more DFS error messages, and provide easy to understand log when abnormal.
+* Fix the disk format issue of FatFs file system when multiple FatFs file systems are mounted.
+* Remove the folder enter feature in msh when input a folder name;
+* Add `int finsh_set_prompt (const char * prompt);` routine for setting a custom prompt for msh;
+* Add the VBUS configuration in Kconfig.
+* Move the application module from kernel to `libc/libdl` component;
+* Rewrite most of the management code for application module: replace the original object container with the object list; split the symbol resolution code into different processor architecture etc.
+* Update the application module chapter in the programming guide, and change it into dynamic module chapter.
+* Overwrite the exit() function of newlib to take over the processing of exit for a dlmodule.
+* Add SAL (Socket Abstraction Layer) component for adapting different protocol stacks and network implementations, and update the relevant sections of the programming guide;
+* Add AT component, including AT client, AT server and AT Socket function;
+* Remove the poll/select API of DFS_NET and move them to SAL component.
+* Remove the strong dependence of lwIP component for DFS_NET and replace it with Kconfig configuration in SAL.
+* Add the DHCP server function with lwIP raw API;
+* Fix the wait queue none-initialization issue in socket allocation of lwIP.
+* When a thread is about to block on a wait queue, fix the wake up issue for `rt_wqueue_wakeup' is executed to wake up that thread;
+* Add the PWM driver framework;
+* Fix the sdio_irq_wakeup release issue in the MMC/SD framework.
+* Fix the problem of DMA handling in the serial driver framework.
+* Update SFUD to v1.0.6 version;
+
+## BSP
+
+* Fix the SP issue when hard fault occurs for ARM Cortex-M arch;
+* Add C-Sky CK802 architecture porting;
+* Add Realtek amebaz WiFi SOC (rtl8710bn) BSP;
+* Update imxrt1052-evk firmware SDK to support B model chip.
+* Fix the copying packets issue in the Godson 1C BSP when sending message.
+* The Nuvoton m05x/m451 BSP are changed into the main() entry mode, and supports GCC compilation;
+* Fix the inconsistency issue between touch range and LCD resolution in qemu-vexpress-a9.
+* Add qemu-vexpress-gemini BSP for dual core A9 (RT-Thread + Linux) arch;
+* Add the basic porting for Raspberry Pi 2B ;
+* Add CAN and PWM drivers in stm32f4xx-HAL BSP;
+* Optimize the GPIO driver in stm32f4xx-HAL BSP;
+* Add UART3 driver in stm32f4xx-HAL BSP;
+* Fix the I2C1 driver clock in stm32f10x BSP and WDG control interface.
+* Add rt_hw_us_delay interface in stm32f10x-HAL BSP;
+* Optimize the GPIO driver in stm32f10x-HAL BSP;
+* Add GPIO driver and RTC driver in stm32f107 BSP;
+
+## Tool
+
+* ENV update to v1.0.0 final version.
+* ENV added the China mirror for software package, which can speed up the software package download, update  etc.
+* Fix the ENV known bugs and enhance the interaction with users.
+* Add building script to detect the version of GCC & newlib;
+* Add building script to detect the version of armcc;
+* Add `scons --dist` function to make distribution for a BSP.
+* Add `scons - dist - strip' function to make a minimal files of distribution for a BSP.
+* Add `ASFLAGS/LOCAL_ASFLAGS' parameters for defined a group and pass them to assembler;
+* Fix some errors in building script under the Linux environment.
+* Add the C-Sky CDK IDE project generation.
+* Add `scons --target=vsc -s` to generate friendly configuration files for VSCode;
+
+# RT-Thread 3.0.4 Change Log
+
+## Kernel
+
+* Change the location of hook invoking in rt_event_send, which can better reflect the event value to the system view.
+* Fix the rt_realloc() issue in memheap;
+* Fix the vstart_addr issue in the dynamic library.
+* Ensure that signal is more standardized and remove si_errno members from siginfo_t;
+* Add rt_thread_mdelay() API for millisecond delay in thread.
+
+## Components
+
+* Fix the DFS mkfs issue of FatFs (which is a merge issue introduced in RT-Thread V3.0 upgrade).
+* Fix dfs_net poll issue, if there is already received data, the upper layer can not wake up and deal with data.
+* Fix the socket issue in dfs_net if lwip_socket failed(Bluebear233);
+* If the dfs_net/socket feature is used within lwIP 1.x version, a compiler error will be returned.
+* Fix the DFS df() information issue;
+* Fix the audio device write issue while the interrupt is not properly recovered.
+* Fix the one-shot timeout issue in the hardware timer driver framework.
+* In ENC28J60 driver, the "link change interrupt" is enable in initialization.
+* Fix the data issue in put data into ringbuffer.
+* Add UDP information display in netstat command;
+* Fix the USB HS issue when sending 1 bytes of data will cause two times of transmission.
+* Change the registration mechanism of USB Class Driver and Class Driver can be registered in package.
+* Add USB Device driver framework for HS USB.
+* Enhance the compatibility of time() function for different compilers;
+* Add more configuration items for DHCPD in menuconfig.
+
+## BSP
+
+* Temporarily remove the Andes AE210P transplant because of the mistakenly use SVC for context switching.
+* Add SD/MMC drive in Allwinner ARM9 BSP;
+* Add SPI and SPI Flash drivers to Allwinner ARM9 BSP.
+* Add GD32's gd32303e-eval development board support;
+* gd32450z-eval supports GNU GCC compilation;
+* Rewriting the hifive1 board level support package for the risc-v architecture;
+* About i.MX RT1052, we have completed various development board support: ATK, Fire, seeed studio;
+* On i.MX RT1052, add the cache-ops functions;
+* On i.MX RT1052, add I2S driver and WM8960 codec driver support;
+* Improve ETH driver support (including support for Fire development board) on i.MX RT1052.
+* Add Hardware Timer driver support on i.MX RT1052.
+* On i.MX RT1052, add GPIO driver;
+* On i.MX RT1052, add RTC driver;
+* On i.MX RT1052, improve SD/MMC driver;
+* On i.MX RT1052, add SPI driver and SPI Flash driver (connect to SFUD component);
+* Add USB Device driver on i.MX RT1052.
+* Add README files and KConfig files in LPC408x BSP;
+* Add README documents in LPC5460x-LPCXpresso BSP;
+* Add the display controller driver (Sundm75) in Godson 1C BSP.
+* Add CAN driver in Loongson 1C BSP(Sundm75);
+* In GPIO driver of Loongson 1C BSP, add (external) interrupt feature (Zhuangwei);
+* Use SPI automatic initialization in Loongson 1C BSP.
+* Add I2C driver in Loongson1C BSP(Sundm75);
+* Add resistive touch screen driver in Loongson 1C BSP(Sundm75);
+* In Loongson 1C BSP, the components initiliazation and main function is enable(Zhuangwei).
+* Add self bootup in Loongson1C BSP (Zhuangwei);
+* Add README files and KConfig files to Loongson 1C BSP(Zhuangwei).
+* Fix the rx descriptor issue in init_rx_desc function in NUC472 BSP (Bluebear233);
+* Add AC97 Audio driver in QEMU-VExpress-A9 BSP;
+* Add README description file in QEMU-VExpress-A9;
+* Add I2C driver in stm32f4xx-HAL BSP, and README description file;
+* Add cache-ops in stm32f7-disco BSP, and README description file;
+* Add README description file in stm32f10x/stm32f10x-HAL;
+* Add README specification files and KConfig configuration files in stm32f40x BSP;
+* Add KConfig configuration file in stm32f20x BSP;
+* Add README description file to stm32f411-nucleo BSP and enable GNU GCC tool chain support;
+* Add GPIO driver and README description file in stm32f429-apollo BSP;
+* Add KConfig configuration files in stm32f429-armfly BSP;
+* Add README description file in stm32l476-nucleo BSP;
+* Because V2M-MPS2 does not support in 32-bit machine simulation operation, temporarily remove this BSP.
+* Add README description file and some firmware file, such as u-boot.bin, wifi firmware etc, in X1000 BSP;
+Tools
+* Add detection feature for the version of GNU GCC tool chain and libc function feature.
+* Add the function of VSCode editor assistance, and support scons --target=vsc -s under BSP folder to generate configuration files for VSCode.
+* Add the detection of verson of IAR;
+* Add the ProjectInfo (Env) function to get information about target: all source files should be compiled, all header files, all macro definitions, the search paths for header file etc.
+
+# RT-Thread 3.0.3 Change Log
+
+## Kernel
+
+* Add scheduler protection when do cleanup for a detached thread;
+* Fix the object_find issue when enable module feature;
+* Improve POSIX signal support and add rt_signal_wait function and POSIX sigwait interface;
+* When enable finsh shell, rtthread.h header file includes the API file of finsh. Therefore, the application code can use command export feature without finsh.h file;
+* Improve the comments of rtdbg.h file. In RT-Thread, just use following code to add debug log feature:
+
+```c
+    #define DBG_ENABLE
+
+    #define DBG_SECTION_NAME    "[ MOD]"
+    #define DBG_LEVEL           DBG_INFO
+    #define DBG_COLOR
+    #include <rtdbg.h>
+```
+
+When close the DBG_ENABLE definition, the debug log will be closed. Otherwise, the `dbg_log(level, fmt, ...)` can be used to print debug information. 
+
+DBG_SECTION_NAME - The prefix information for each log line;
+DBG_LEVEL - The debug log level;
+DBG_COLOR - Whether use color log in console.
+
+## Components
+
+* Fix the flag issue of fopen in GNU GCC;
+* Fix the pthread_detach issue when used for a detached pthread;
+* Fix the _TIMESPEC_DEFINED issue in IAR 8;
+* Add libc_stdio_get_console() interface for returns the fd of console;
+* Move UI engine component as a standalone package;
+* Add a unify TF/SD card driver on SPI device bus;
+* Add soft-RTC device, therefore device can synchronize with network time and maintains the time with OS tick later;
+* Change the open/fcntl/ioctl API to POSIX standard  interface;
+* Fix ramfs issue when update with RTT 3.0.x;
+* Fix the elm fatfs umount issue; (liu2guang)
+* ignore the O_CREAT flag when open a device file;
+* Improve VCOM class driver in USB stack; (ChunfengMu, Aubr.Cool)
+
+## BSP
+
+* Fix the potential issue when enable Cortex-M hardware FPU;
+* Add v2m-mps2 bsp, which is used in Keil MDK5 for Cortex-M4/M7/M23/M33 simulation;
+* Add sdcard driver for stm32f10x-HAL;(liu2guang)
+* Improve GNU GCC support for stm32f10x-HAL;(Xeon Xu)
+* simulator bsp can be used in Windows/Visual C++ and update SDL to v2.0.7;
+* Add gk7102 bsp by gokemicro;(gokemicro)
+* Add allwinner F1C100s ARM9 bsp;(uestczyh222)
+* Fix some issues in peripherals drive library of NXP LPC54608/i.MX RT; (Valeriy Van)
+
+## Tools
+
+* scons building script will automatically add `_REENT_SMALL` macro when enable newlib nanao;
+* Modify building script for Python 3.x and scons 3.0
+
+# RT-Thread v3.0.2 Change log
+
+## Platform
+
+* Make sure the Object_Class to a fixed value
+* Add `rt_device_create/destroy` API
+* Add memory trace for small memory management algorithm for memory leak and overwritten.
+* Add a first version of asynchronous I/O API
+* Add cputime for high resolution counter
+* Add pipe device functions in DeviceDrivers
+* USB Host available in stm32f4 with mass storage class
+* Add 'df' command in msh
+* Update UI engine and add an example
+* Split `clock_time` from pthreads and add a new clock id: `CLOCK_CPUTIME_ID`
+* Enable IPv6 in lwIP 2.0.2 version
+* Add memlog in logtrace
+* Fix closesocket issue in dfs_net
+* Fix IPv6 issue in NFS
+* Update JFFS2 file system with new DFS API
+* Fix the issue of stat "/.." of lwext4 (parai)
+* Fix the fs type search issue in mkfs
+* Fix the select issue in dfs_net
+
+## Tools
+
+* scons: add '--useconfig' command to use an exist config file
+* scons: force to use g++ for link when enable `RT_USING_CPLUSPLUS` in GNU GCC configuration
+* Enable package feature in Linux/MacOS host
+
+## BSP
+
+* Add NUC472 bsp (bluebear)
+* Update SD/MMC driver for qemu-vexpress-A9
+* Add keyboard/mouse driver for qemu-vexpress-a9
+* Add ADC/I2C/Flash/PWM/RTC/smbus/SPI driver for apollo2 (Haleyl)
+* Add I2C/LCD/Touch driver for i.MXRT1052-EVK
+* Update SD/MMC driver for mini2440 (kuangdazzidd)
+* Update simulator to adapt VC++ compiler
+* Add USB host driver in stm32f4xx-HAL (uestczyh222)
+* Update EMAC driver for IPv6 in stm32f40x/stm32f107
+* Add stm32h743-nucleo bsp (polariss)
+
+# RT-Thread v3.0.1 Change log
+
+## Platform:
+
+* Add mmap()/munmap() API for POSIX compatibility.
+* Fix the filesystem_operation_table issue.
+* Enhance USB stack for USB slave (HID/ECM/RNDIS/WINUSB or composite device);
+* Enhance USB stack for USB host (HID/MSC etc);
+* Fix memory leak issue when close a pipe.  
+* Fix the romfs open issue;
+* Add SoftAP device in Wi-Fi framework;
+* Re-order the lwIP/ETH initialization;
+* Add IPv6 options in Kconfig;
+* Fix the module_id issue in _rt_thread_init;
+
+## Tools:
+
+* Add menuconfig for Linux/Mac platform: use `scons --memuconfig` to enable it;
+* Add LIBS feature for IAR project;
+
+## BSP:
+
+* Enhance LPC54608 BSP for kinds of compiler;
+* Add GPIO/I2C/SPI driver for Loongson 1C;
+* Add csd cmd in sdcard driver of mini2440;
+* Add SDIO/EMAC driver for qemu-vexpress-a9 bsp;
+* Enable VC++ to compile simulator bsp;
+* Add stm32f4xx-HAL bsp for kinds of STM32F4 series <User can use menuconfig to select chip>;
+* Fix the PHY reset in stm32f429-apollo bsp;
+* Add Audio/MMC/SLCD/Touch/USB slave/RTC/SPI/SFC Flash driver in Ingenic X1000 bsp;
+
+# RT-Thread v3.0.0 Change log
+## Platform:
+
+* Add more POSIX features, for example poll/select, signal, termios etc.
+* Add waitqueue for poll feature.
+* Use fops for file operation. There are two ways to visit device object: rt_device_* API, the file API(open/read/write/close etc).
+* Change the type of cmd from uint8_t to int in control interface.
+* Add more C++ object for RT-Thread Kernel Object.
+* Add wlan driver framework for wlan device operation.
+* Integrate SFUD into RT-Thread to unify the operations of spi flash.
+* Update lwIP to v2.0.2 version.
+
+## Tools:
+
+* Enable packages, with ENV tool.
+* menuconfig & Kconfig.
+* Add scons --dist for make a distribution for specified BSP.
+
+## BSP:
+
+* more MCU porting.
+
+## IoT:
+
+* put more IoT components as packages, for example, MQTT, CoAP, HTTP, TLS etc.
+
+# RT-Thread v2.1.0 Change log
+
+This release is the final release for RT-Thread v2.1.0 branch. This release has been delayed many time. After committed fh8620 and x1000 bsp, we are proud to announce this branch release of the official version.
+
+The change log since last stable version:
+
+## Kernel:
+
+* Move the init component to the kernel.
+* Fix the device open flag issue.
+* Add assertion hook.
+* Better application module support.
+* Does not lock scheduler when invoking soft-timer timeout function.
+
+## Board Support Package:
+
+* fh8620, which is provided by Shanghai Fullhan Microelectronics Co., Ltd. It's a IP camera chip with ARM1176, 300MHz, 16KB I-Cache and 16kB D-Cache.
+* x1000 bsp. The CPU is a XBurst CPU 1.0GHz, MIPS-based, from Ingenic Semiconductor Co.,Ltd.
+* imx6sx bsp, only the Cortex-A9 core porting in the NXP i.MX6 solox. BTW, another full Kinetis series porting was created in rt-thread_fsl, which is maintained by NXP employee.
+* lpc5410x bsp, only the Cortex-M4 core porting.
+* ls1cdev bsp for Loogson1C board.
+* dm365 bsp.
+* nRF51822/nRF52832 bsp.
+* stm32f7-disco bsp, the first ARM Cortex-M7 porting in RT-Thread.
+* stm32f411-nucleo bsp.
+* Add IAR compiler support in beaglebone bsp.
+
+## Components:
+
+* Add more socket fd operators in DFS with a virtual lwIP file system ops.
+* Add CAN/Hardware Timer device drivers.
+* Fix the SDIO issue to support sdio wifi device.
+* Add eMMC support in SD/MMC device drivers;
+* Fix the NAT configured enter reset issue in lwIP NAT.
+* RTGUI come back, but as a UI engine for blend point/line/rect and bitmap etc.
+* Add nanopb porting, a small code-size Protocol Buffers implementation;
+* Add paho-mqtt porting, the Eclipse Paho MQTT C/C++ client for Embedded platforms;
+* Update freetype to 2.5.4 version.
+* Enhance msh for file operations.
+* Split the exported commands of finsh shell to a standalone section: ".rodata.name"
+
+# RT-Thread v2.1.0 beta版本更改说明
+
+## BSP部分
+
+* BeagleBone加入GPIO驱动;
+* 京微雅格M7,更新驱动库并改进EMAC驱动程序;
+* 新加入dm365移植(包括EMAC、GPIO、I2C、MMC/SD、SPI等驱动);
+* LPC4088加入EMC、硬件定时器、CAN驱动;
+* 新加入龙芯1C,智龙v2开发板移植(包括多串口驱动);
+* 更改mini2440移植为applications/drivers等的目录方式;
+* 更新simulator在MS VC++上的移植,处理好初始化代码工作,完善UART控制台驱动;
+* 新加入stm32f7-disco移植;
+* 在stm32f10x中新加入CAN驱动及应用代码示例;
+* 在stm32f40x中加入硬件定时器驱动,RTC驱动;
+* 调整stm32f107为新的串口驱动框架;
+
+## 组件
+
+* DFS的struct stat定义中移除st_blksize成员(可以兼容于VC++中的stat定义);
+* 修正DFS中select实现的问题;
+* 修正DFS中文件操作出错、关闭时的fd处理问题;
+* 修正DFS中mkdir和lseek出错时的fd处理问题;
+* 修正lwIP中SYS_ARCH_PROTECT/SYS_ARCH_UNPROTECT保护的问题;
+* 增加CAN驱动框架;
+* 增加硬件定时器驱动框架;
+* SD/MMC驱动框架中增加eMMC支持;
+* 修正注册SDIO驱动时驱动关联的问题;
+* 修正串口驱动框架DMA发送时激活标志的问题;
+* SPI Flash驱动中加入对GD25Q spi flash芯片支持;
+* 增加paho-mqtt组件移植;
+* 增加msh的脚本执行能力,可以在msh下执行*.sh脚本;
+* 增加msh下的mkfs命令;
+* 修正在Linux Telnet下使用finsh shell回车符处理的问题;
+* 增加应用模块在使用armcc、gnu gcc编译器时的libc符号导出;
+* 在以太网网卡驱动框架中增加ETHIF_LINK_AUTOUP/PHYUP参数用于指定初始时的链路Up/Down状态;
+* 在组件初始化中导出log_trace组件;
+
+## 内核
+
+* 更改UNUSED/USED等更改成RT_UNUSED/RT_USED;
+* 链接时增加.rodata.name section,当空间资源受限时可以把它放到性能低的内存区域;
+* 完善IAR编译器下的组件自动初始化;
+* 增加rt_assert_hook,在触发断言时可以执行这个钩子函数;
+* 修正应用模块分散加载情况下的问题;
+
+## 工具
+
+* scons中定义Group时加入了本Group内的编译参数定义;
+* 修正了如果Group中即包含代码,也包含二进制库时,生成的Keil MDK工程文件有两个重名Group的问题;
+
+版本: RT-Threadv2.0.1及v2.1.0 alpha
+
+RT-Thread v2.0.1是2.0这个系列的bug修正版,而v2.1.0 alpha则是当前开发主干的一个技术预览版本,它给出了v2.1.0这个版本系列的技术预览情况,不建议用于实际产品中,因为它可能存在大量的一些bug。
+
+# RT-Thread v2.0.1更改说明
+
+*  IAR用的dlib,加入THREAD_SUPPORT 和 FILE_DESCRIPTOR的支持;
+*  修正finsh中echo回显模式的问题;
+*  修正USB host代码的编译错误;
+*  修正sensor框架回调函数的问题;
+*  修正pin设备注册时的设备名称问题;
+ 
+而v2.1.0 alpha这个技术预览版则沿着最初设定的roadmap技术路线进行,这其中主要包括:
+
+*  lwip更深度的集成:把它集成到RT-Thread的文件系统接口中,这样Linux/Unix下的一些socket网络应用能够更顺利的移植到RT-Thread上,也为以后可以应用到更多地方的select接口铺路。
+
+*  这部分是和RT-Thread发布本身无关,但也是这个版本系列设定的目标之一:开启一个云端集成开发环境的时代!云端会是什么样的,请用现代化的浏览器打开[CloudIDE](http://lab.rt-thread.org/cloudide/simulator/index.html)
+
+# RT-Thread 2.0.0正式版更改说明
+
+经历了大约1年的时间,RT-Thread v2.0.0的最终版本终于发布出来了。自这个版本开发以来,引入了多项功能、修改、增强等。感谢参与的诸位开发人员!
+以下是自v2.0.0 RC版本以来的详细更改记录。后续我还会给出v2.0.0版本自v1.2.x版本的主要不同、看点,以及给出下一个版本的roadmap规划。
+
+## 内核
+ 
+*  console以RT_DEVICE_FLAG_STREAM参数打开字符设备;
+*  在rt_memheap_free中加入更多的断言检查;
+
+## 组件
+
+*  更新RW009驱动以支持Wi-Fi SoftAP模式(aozima);
+*  修正sensor框架的一些问题,并加入C API接口(睿赛德服务公司提供);
+*  加入MPU6050 sensor的代码(bernard, Coing);
+*  加入BMI055 sensor的代码(Coing);
+*  当未使能heap时,修正finsh/msh中list_memheap的问题;
+*  修正LIBC编译的警告;
+*  加入IAR dlib相关的移植,使得应用能够使用标准的API接口;
+*  修正YMode握手时可能引起的竞争问题(grissiom);
+*  更新FreeType版本到2.5.4
+*  单独把C++的全局对象初始化放到cplusplus_system_init函数中,并在初始化线程中调用;
+*  finsh中以RT_DEVICE_FLAG_STREAM参数打开字符设备;
+*  添加VBUS组件用于Linux与RT-Thread系统之间,RT-Thread与RT-Thread系统之间通信(睿赛德服务公司捐赠);
+*  增加lwIP/NAT组件,可以做多个网口间的地址转换(Hicard);
+*  增加lwIP/DHCP服务端,用于向客户端分配IP地址(睿赛德服务公司提供);
+ 
+## BSP
+
+*  修正LPC4357串口驱动初始化时过早打开中断的问题(nongxiaoming);
+*  重写LPC4357串口驱动,并让芯片上M4/M0核心分别都执行RT-Thread系统,两核心之间以VBUS组件进行系统间通信(睿赛德服务公司捐赠);
+*  新增RX移植(limxuzheng);
+*  新增NuMicro M051 Series移植,支持GCC、Keil MDK编译器(bright-pan);
+*  新增LPC54102移植(Coing);
+*  移除STM32F4 BSP中不需要的RT_TIMER_TICK_PER_SECOND配置(pangweishen);
+*  在Linux Clang编译分析中,强制以32位模式进行编译(grissiom);
+*  修正STM32F103中串口驱动中断过早打开的问题(armink);
+
+## 工具
+
+*  增加scons中的MD5支持(bright-pan);
+
+# RT-Thread 2.0.0 RC 更改说明
+
+发布时间:2014/11/4
+
+随着RT-Thread功能越来越多,如何发布版本也成为一件头疼的事情,因为需要仔细对比最近三个月来的修改记录。这次的发布距离上一次beta版本依然是三个月的时间,但按照发布计划已然推迟了一个月进行发布。 
+
+在这三个月中,开源社区上也发生了很多有趣的事情:
+
+阿嘉的使用RT-Thread的四轴飞行器毕业设计惊艳亮相,采用了1个STM32F4 + 8个STM32F1进行飞行控制,总计9个MCU的另类实现方式;沿循四轴飞行器的路线,与国内匿名团队合作,采用RW009 Wi-Fi控制的迷你四轴飞行器也在稳步推进过程中。
+
+RT-Thread做为一个开源组织参与的CSDN开源夏令营结出了丰硕的果实:
+由hduffddybz参与的IPv6协议栈移植(最新版本的lwIP-head版本移植)在这次发布中已经包括进来,从而能够在使用RT-Thread的小型设备上实现TCP/IP v4/v6双栈的支持;
+由wzyy2参与的GDB stub实现,也完美的支持BeagleBoneBlack开发板和STM32F4平台;
+CSDN开源夏令营其他的成果,例如bluedroid移植也有了初步的成果,希望能够在后续的版本(可能会是2.1.0系列版本?)包含进来。CSDN开源夏令营是一次非常棒的活动,能够让学生提前进入实战,了解软件开发的初步知识。对开源社区来说,也是一次非常有益的社区互动活动。希望明年这个活动可以继续,关注RT-Thread、嵌入式开发的同学可以关注明年的动向。
+
+当前智能化设备是一个备受关注的领域,针对这一领域的特点,RT-Thread也相应的做出了积极的响应,所以这个版本开始加入sensor的应用框架(APP/算法 <--> sensor framework <--> RT-Thread device driver <--> 硬件外设)。希望在小型化的RT-Thread操作系统基础上融合智能化相关的技术,让RT-Thread成为这方面可选的OS系统之一。RT-Thread操作系统的sensor框架也尝试新的实现方式,即采用C++的方式来实现(当然也会考虑C方面的兼容,无疑C++的面向对象特性会更好,所以最终选择了C++),在这个基础上也可能融合其他的一些生态技术,例如ARM mbed平台上的一些社区组件技术。所以这个发布版本中既包括sensor框架,也包括了C++底层的一些基础支撑。
+
+这个版本是RT-Thread 2.0.0系列正式版本的候选版本,正式版本预计会在年底正式发布,距离正式版本还会加入更完善的一些支撑(例如各种传感器驱动)。也计划2014年11月22日,在上海浦东举行RT-Thread嵌入式系统沙龙活动,欢迎大家关注并参与进行RT-Thread方方面面的技术交流。
+
+以下是这个版本的更改记录:
+
+## 内核
+
+* 修正当采用高级别优化编译时,idle任务中查询是否有僵尸线程的潜在bug;
+
+* 修正memory pool中的竞争问题;
+
+* 在console中打开设备时,加入流标志进行打开;
+
+## 组件
+
+* 加入C++基础支撑组件。C++组件依赖于RT_USING_LIBC库,当使用GCC编译器时请注意查看其中的说明文档并更改ld script;
+* 修正DFS中NFS打开目录的bug;
+* 更改DFS ROMFS默认romfs_root为弱化符号;
+* 添加DFS中dfs_file_lseek接口中关于fs的检查;
+* 移除I2C core中无用的core lock锁;
+* 添加sensor framework(采用C++的方式支持各种sensor);
+* 修正serial框架中DMA发送的bug(heyuanjie87);
+* 移除SPI框架中不必要的device初始化代码;
+* 完善SPI Wi-Fi网卡RW009驱动并提供RSSI相关的命令;
+* 修正MSH中未定义DFS_USING_WORKDIR时更改当前目录的bug;
+* 修正MSH中未定义RT_LWIP_TCP时依然定义了netstat命令的bug;
+* 修正MSH中未定义RT_USING_HEAP时依然定义了free命令的bug;
+* 修正finsh中FINSH_USING_HISTORY相关的裁剪;
+* 加入gdb stub组件,当前支持ARM Cortex-A8和Cortex-M3/4(wzyy2);
+* 统一不同编译器下使用LIBC的宏为RT_USING_LIBC,原有的宏定义RT_USING_NEWLIB/RT_USING_ARM_LIBC需要从rtconfig.h中移除,并替换成RT_USING_LIBC;
+* 加入最新的lwIP分支:lwip-head,以提供IPv4/v6双栈的功能(hduffddybz);
+* YMode中打开串口设备时,添加open flag(armink);
+
+## bsp
+
+* 加入北京京微雅格的M7(华山)低功耗FPGA的ARM Cortex-M3移植(aozima);
+* 加入北京京微雅格的M7 EMAC以太网驱动(aozima);
+* AT91SAM9260分支中更改RT_USING_NEWLIB为RT_USING_LIBC;
+* BeagleBoneBlack分支中加入gdb stub支持(wzyy2);
+* LPC176x分支中加入C++支持;
+* LPC176x分支中修正SD卡驱动返回卡信息的bug;
+* 修正LPC408x分支中GCC编译时的问题;
+* LPC408x分支中加入C++支持;
+* 龙芯1B分支中加入UART3驱动;
+* 加入飞索半导体的MB9BF568 FM4分支移植(yangfasheng);
+* mini2440分支中更改RT_USING_NEWLIB为 RT_USING_LIBC;
+* stm32f0x分支中移除不同编译器下的LIBC定义,统一更改为RT_USING_LIBC;
+* stm32f0x分支中加入串口接收溢出中断处理(armink);
+* stm32f40x分支中加入gdb stub支持并添加UART6驱动(wzzy2);
+* zynq7000分支中更改RT_USING_NEWLIB为RT_USING_LIBC;
+* 加入ARM Cortex-M4芯片指令级的ffs实现;
+* 修正MB0BF618S分支中缺少timer初始化的bug(mike mao);
+
+## 工具
+
+* 移除Python 2.6中未支持的语法(xfguo);
+* 移除Windows平台中的startupinfo信息(对Python版本兼容性更好);
+* 修正CPPPATH被打乱的bug;
+
+# RT-Thread 2.0.0 Beta更改说明
+
+发布时间:2014/8/1
+
+v2.0.0这个版本系列是RT-Thread当前的开发分支,如果要上新项目,建议使用这个版本来进行,预计这个版本的正式版会在年底发布。欢迎对这个版本进行测试、并反馈问题,能够早日进入到稳定版。
+
+v2.0.0版本的开发相对活跃些,开源社区提供了强有力的支持:如Arda贡献的TM4C129x移植,Romeo贡献的frdm-k64f移植,xiaonong的LPC4300移植等,以及睿赛德服务公司捐赠的Zynq7000移植,MB9BF618S移植,以及SPI WiFi网卡的驱动代码等。
+
+更改记录
+
+## 内核
+
+* 移除rt_device_init_all()函数:在系统启动时不需要再调用这个函数来初始化驱动,而是由上层应用执行rt_device_open时自动进行设备初始化;
+* 修正设备对象引用计数在打开设备失败依然递增的问题;
+* 增加WEAK宏用于定义/声明弱符号;
+* 在执行静态内存块分配前,重置线程的errno;
+* 修正timer未打开调试选项时,无用的静态函数定义(导致编译警告);
+* 启动timer前,对timer进行强制移除;
+* 在执行soft timer超时函数时,打开调度器锁;
+* 新增块设备的自动刷新参数,RT_DEVICE_CTRL_BLK_AUTOREFRESH;
+ 
+## 工具
+
+* 修正scons命令编译时,选择keil mdk (armcc)编译器时,命令行太长编译失败的问题;
+
+## 移植
+
+* 移除rt_device_init_all()相关的调用;
+* 根据串口框架调整相关的驱动代码;
+* 新增frdm-k64f移植(FreeScale K64芯片);
+* 移除K60Fxxxx移植;
+* 新增LPC43xx移植(NXP LPC4357芯片);
+* 移除LPC176x中的组件初始化配置;
+* 修正龙芯1B移植(ls1bdev)中链接脚本关于组件初始化部分的配置;
+* 修正STM32F40x中UART3的配置;
+* 修正STM32F40x中GNU GCC连接脚本中ROM/RAM大小的配置;
+* 移除STM32F107中的组件初始化配置;
+* 增强STM32F107 EMAC驱动性能,同时加入自动查找PHY芯片地址功能;
+* 重写xplorer4330(NXP LPC4330芯片)移植(xiaonong完成);
+* 新增Zynq7000 ARM Dual Cortex-A9移植;
+* 新增MB9BF618S移植;
+* 新增tm4c129x移植,并加入相应的EMAC以太网驱动;
+
+## 组件
+
+* DFS: 新增根据设备对象获得其上装载文件系统路径的函数:dfs_filesystem_get_mounted_path(struct rt_device* device);
+* DFS: 修正readdir在GNU GCC下的编译警告;
+* DeviceDrivers:新增workqueue实现;
+* DeviceDrivers: 修正USB Device栈中的一些拼写错误;
+* DeviceDrivers: 重写serial框架,能够让串口设备驱动同时支持三种模式:poll、interrupt、DMA。模式选择需要在执行rt_device_open时,由open flags指定;
+* DeviceDrivers: 加入更多的SPI设备驱动,例如RW009的SPI WiFi网口驱动(2.4G 802.11 b/g/n,WEP/WPA/WPA2,SoftAP/Station),SPI NorFlash块设备驱动,ENC28J60以太网网卡驱动;
+* Finsh: list_device()命令中增加refcount的信息;
+* Finsh: 修正'0'零常量无法识别的错误;
+* Finsh: mv命令,实现把一个文件移动到一个目录中;
+* Finsh: ifconfig命令支持对一个网络接口的基本配置;
+* Finsh: 新增netstat命令,用于显示当前系统中TCP连接的状态;
+* Finsh: 修正当命令行太长导致的缓冲区移除的问题;
+* libc: 修正arm libc中未使用DFS时的编译警告;
+* libc: 修正newlib中使用DFS时的系统调用编译警告(GNU GCC下);
+* lwIP 1.4.1: 默认打开LWIP_SO_SNDTIMEO以支持连接发送超时;
+* lwIP 1.4.1: 修正MEMP_NUM_TCP_SEG定义错误的问题;
+* lwIP 1.4.1: 加入RT_LWIP_REASSEMBLY_FRAG选项定义以支持IP分组及合并;
+* lwIP 1.4.1: ethnet网络接口支持定义LWIP_NO_TX_THREAD/LWIP_NO_RX_THREAD,以关闭etx/erx线程;
+* lwIP 1.4.1: 用户可以重新定义RT_LWIP_ETH_MTU,以修改网络中的MTU值;
+* lwIP 1.4.1: 修正LWIP_NETIF_LINK_CALLBACK条件编译的问题;
+* lwIP 1.4.1: 完善移植相关的注释;
+* log trace: 增加log_session_lvl接口;
+* log trace: log trace中的session引用更改成常量形式;
+* ymodem: 增强数据接收的稳定性;
+
+# RT-Thread 2.0.0 Alpha更改说明
+
+发布时间:2014/4/8
+	
+RT-Thread 2.0.0分支的第一个技术预览版本,仅用于展示2.0.0发展分支的演化动向(按照roadmap,2.0.0这个分支会有一部分RT-Thread和Linux互补性的技术,为Linux增加更好的实时性,为RT-Thread增加更多的功能性,这份技术预览版正是朝着这个目标而努力),欢迎反馈建议和问题。
+
+## 组件
+
+* msh: bugfix 和功能性增强。新的 msh 在调用外部模块方面更加方便。
+* DFS: nfs 的 bugfix 和内置命令的增强。ELM FatFS加入对扇区不匹配情况下的信息输出,这样能够及时定位问题。
+* JS:新添了轻量级Javascript引擎,可以在RT-Thread中直接运行javascript脚本。
+* VMM:可以在qemu中运行的 Virtual Machine Module 组件。暂时只支持 realview-pb-a8 的 bsp。
+* CMSIS:版本更新至 3.20
+* drivers:USB 协议栈的重构。新的框架中编写驱动变得更加容易了。
+
+## BSP
+
+* beaglebone:串口驱动更新
+* realview-a8:添加了 VMM 组件
+
+## 工具
+
+* 固件加入scons --target=ua -s,用于准备用户应用环境;
+
+[发布后记]
+
+RT-Thread 2.0.0. Alpha版本相比于RT-Thread 1.2.1,新的特性主要有两部分:
+- RT-Thread + Linux双系统,这部分以RealView-A8处理器(ARM Cortex-A8单核)为蓝本,给出一个简单的双系统并行运行的demo;在没有硬件的环境下,可以使用QEMU软件虚拟方式的执行。这个链接中包含一个编译好的Linux及RT-Thread二进制包,可以直接下载进行体验。
+
+目录中有 Linux 的内核镜像 zImage,ramdisk rootfs.cpio.gz。可以用
+qemu-system-arm -M realview-pb-a8 -kernel zImage -initrd rootfs.cpio.gz -serial vc -serial vc
+来启动。启动之后 Linux 的控制台在第一个串口上(Atl + Ctrl + 3),可以直接无密码以 root 用户登录。登录之后加载内核模块:
+insmod rtvmm.ko
+来启动 RT-Thread。RT-Thread 启动之后控制台在第二个串口上(Atl + Ctrl + 4)。第一个串口Linux shell依然可以使用,第二个串口则是RT-Thread的shell。
+- JavaScript解析器,这个是由牛头哥移植的,可以在一个非常小资料的MCU上以JavaScript脚本方式进行编程、开发。根据这种方式,也提供了RN001JS的以太网硬件模块:以JavaScript脚本语言作为二次开发,提供在线web(即WebIDE)进行编程并运行JavaScript程序。JavaScript作为一门轻量级、解释型的语言,更容易上手,配合WebIDE、及提供的一些example可以使得开发变得非常的轻松,也包括一些传感器的JavaScript例子,让做网页的人也可以玩硬件了!
+
+# RT-Thread 1.2.1更改说明
+
+发布时间: 2014/4/8
+	
+在原有的1.2.0版本的bug修正版本,也是1.2.0系列的第一个修正版本,原则上不添加任何的新功能,我们尽量会按照每个季度一个修订版本的方式推进。大家在使用的过程中有什么问题还请反馈给我们,这些问题很可能会在下个版本中修正!
+
+以下是更改记录:
+
+## 内核
+
+* 用户应用,增加用户应用命令行参数支持;
+* 在挂起一个任务时,把相应的定时器也关闭;
+
+## BSP
+
+* BeagleBone,加入更多串口驱动支持;
+* 移除BSP中rt_device_init_all函数调用,改成打开设备时自动进行初始化;
+* LPC176x,移除components初始化管理器;
+* LPC4088,修正LED驱动的问题;
+* STM32F107,移除components初始化管理器;
+
+## 组件
+
+* 文件系统,ELM FatFS加入对扇区不匹配情况下的信息输出,这样能够及时定位问题;
+* 文件系统,NFS网络文件系统修正相关的一些编译警告信息;
+* 文件系统,copy命令加入文件夹方式复制功能;
+* 文件系统,RAMFS,加入到components初始化管理器中;
+* 文件系统,ROMFS,用于转换文件的工具mkromfs.py,增加Linux主机的支持;
+* CMSIS更新到3.2.0版本;
+* 串口驱动框架加入serial->ops->control的调用;
+* 命令行系统,优化msh,支持用户应用的命令行参数;
+* 命令行系统,当使用msh时,默认使用msh >的命令行提示符;
+* TCP/IP协议栈,导出更多的lwIP接口给用户应用;
+* POSIX thread,修正了同时使用lwIP组件时的编译警告;
+* 第三方组件,加入TJPGD的移植,加入libpng的移植;
+
+## 工具
+
+* 固件加入scons --target=ua -s,用于准备用户应用环境;
+
+[发布后记]
+* RT-Thread携带了众多的BSP,不一定能够一一保证每个分支上把RT-Thread上相应的功能使用起来。所以针对这种情况,我们有一款评估用的硬件开发板:RealBoard 4088,在上面力求把一些相关例程都添加上,这样在一个基本的BSP基础上,可以对照着把其他的组件、功能添加进去;
+* RealBoard 4088使用的RT-Thread版本主要以RT-Thread 1.2.1版本为主。
+
+# RT-Thread 1.2.0正式版本更改说明
+
+发布时间: 2014/1/6 
+
+实现roadmap中提到的大部分内容
+	
+1,文档方面已完成《RT-Thread编程手册》,同时还有论坛上jiezhi童鞋的《一起来学RT-Thread系列连载教程》
+2,BSP分支方面新增cortext-A8(beaglebone),cortext-R4(rm48x50),UNITY-2(SEP6200),lpc408x的移植
+3,组件方面:
+- 加入msh(类似linux shell的风格),能够直接执行应用程序
+- 新增freemodbus 1.6.0的移植
+- 新增开源的嵌入式关系数据库SQLite 3.8.1的移植
+- 新增Ymodem协议
+- 默认使用lwIP 1.4.1
+
+下面是自RT-Thread 1.2.0 RC版本发布以来具体的变更履历:
+
+## 内核
+
+* timer.c - 使用跳跃表(skip list)实现系统定时器链表,并在bsp中的startup.c中重新加入定时器初始化函数rt_system_timer_init()
+* rtdebug.h - 新增宏定义RT_DEBUG_IN_THREAD_CONTEXT
+* idle.c - 在函数rt_thread_idle_excute()中一次清除所有的死线程
+* scheduler.c - 新增API rt_critical_level()返回调度器上锁次数
+
+## 移植
+
+* cortex-m0 - 修正 cortex-m0 GCC移植中hardfault的问题点
+* cortex-r4 - 在startup后释放IRQ堆栈空间
+* cortex-r4 - 按字节长度分配堆栈空间
+
+## BSP分支
+
+* 新增lpc408x移植
+* bsp/stm32f0x - 增加USART1,USART2驱动,支持finsh,支持组件初始化
+* bsp/simulator - 当RTGUI配置无效时打印错误信息
+* bsp/simulator - 默认情况下关闭RTGUI选项
+* bsp/simulator - 增加createdef.py文件来生成VS的def文件
+* bsp/simulator - 当使用VC++编译时去除_TIME_T_DEFINED的定义
+* bsp/xplorer4330 - 重命名文件Retarget.c为retarget.c,否则linux系统中编译会报错
+* bsp/xplorer4330 - 修正GCC编译链接时关于ENTRY的警告
+* bsp/rm48x50 - 新增GCC的移植
+* bsp/K60Fxxxx - 修正一个编译错误
+
+## 组件
+
+* dfs - 正确处理mkfs未实现的情况
+* dfs - 使用指针代替index变量
+* dfs - 在函数dfs_filesystem_lookup()将含义模糊的指针变量名称empty重命名为fs
+* dfs - 修正dfs_unmount问题点
+* dfs - 在设备打开错误时令挂载失败
+* dfs/elmfat - 令elmfatfs每次都检查扇区大小
+* net - 新增freemodbus 1.6.0的移植
+* finsh - 新增FINSH_USING_MSH_ONLY选项
+* finsh - 只有当shell设备为空时调用rt_console_get_device()
+* finsh - 修正FINSH_USING_SYMTAB未定义的错误
+* finsh - 重构control按键的处理
+* msh - 增加文件和路径名称自动补全的功能
+* msh - msh内增加执行module的功能
+* msh - msh内增加更多的命令
+* libc - 修正 _sys_read()/_sys_write()问题点
+* external - 增加开源的嵌入式关系数据库SQLite 3.8.1的移植
+* pthreads - 避免ESHUTDOWN重复定义
+* mtd_nand - 在MTD nand中增加更多的调试措施
+* mtd_nand - 修正操作MTD nand时起始块错误的问题
+* lwip-1.4.1 - 在lwIP内加入更多的RT-Thread选项设置
+* log_trace - 修正函数memmove()参数使用错误的问题
+* drivers/pipe - 增加一个control命令来获得pipe剩余的空间
+* drivers/serial - 如果读写长度为0,则立即返回
+
+## 例程
+
+* examples - 用rt_sem_control()中的RT_IPC_CMD_RESET命令rt_sem_trytake()来清除信号量
+* examples - 始终打印输出测试结果
+* examples - 在所有的测试结束后打印输出简报
+* examples - 在TC线程中清除变量_tc_stat的TC_STAT_RUNNING状态
+* examples - 重新实现loop功能,并新增finsh命令tc_loop
+* examples - 在tc_stop中增加延时,由原来的延时RT_TICK_PER_SECOND/2调整为10 * RT_TICK_PER_SECOND
+* examples - 在SConscript中判断TC如果被使能,在CPPPATH中增加TC路径
+* examples - 新增一个in-mem-log的例子
+* semaphore_priority.c - 在cleanup时释放信号量
+* heap_realloc.c - 检查调用realloc(ptr, 0)是否成功
+* thread_delete.c - tc线程的延时应该比tid2的延时长,保证其测试过程中正常运行
+* thread_delay.c - 放宽超时判断条件,因为当RT_TICK_PER_SECOND为1000时,容易产生1个tick的误差
+* semaphore_static.c - 放宽超时判断条件,因为当RT_TICK_PER_SECOND为1000时,容易产生1个tick的误差
+* semaphore_dynamic.c - 放宽超时判断条件,因为当RT_TICK_PER_SECOND为1000时,容易产生1个tick的误差
+
+其他:
+* 更新README.md
+	
+# RT-Thread 1.2.0RC更改说明
+
+发布时间: 2013/10/10/ 10:19
+	 
+主要说明: 该版本新增ARM Cortex-A8的支持(BeagleBone),新增UNITY-2内核的支持(SEP6200),新增Ymodem协议。
+
+变更履历
+========
+
+[内核]
+
+* 修正rtdef.h中的拼写错误(_MSC_VER_ -> _MSC_VER)
+* 修正scheduler.c中的调试打印输出错误
+* ipc - 在函数rt_event_recv()中增加对参数option有效性的检查
+* device - 增加统计设备引用次数的变量ref_count
+* memheap - 修正内存块分割问题点
+* memheap - 优化函数rt_memheap_realloc()
+* kservice - 函数声明使用rt_vsnprintf代替vsnprintf
+
+
+[组件]
+
+* dfs - 修正dfs_file.c中一处变量参数类型错误的问题
+* dfs - 增加mount table
+* dfs - 在building脚本中加入ramfs的支持
+* dfs - 修正ramfs中O_APPEND write的问题
+* dfs/elm - 在mkfs中加入device_open/close
+* dfs/jffs2 - 修正jffs2_opn/opendir中的f_flag初始化问题
+* dfs/jffs2 - 修正jffs2卸载问题
+* pthread - 修正一处编译警告
+* drivers/pipe - 增加rt_pipe_init/rt_pipe_detach
+* drivers/pipe - 增加非阻塞读写和强制写模式
+* drivers/pipe - 当恢复读的时候调用函数rx_indicate()
+* drivers/pipe - 增加一个设备类型(pipe类型)
+* drivers/portal - 实现portal设备类型
+* drivers/ringbuffer - 修改一些模糊不清的函数名称
+* drivers/ringbuffer - 新增put_force和putchar_force接口函数
+* finsh - 当set_device时增加设备检查
+* finsh - 在rx_ind中增加对shell设备的自动设置
+* finsh - 增加pipe和portal设备的描述
+* finsh - 在变量定义时使用别名
+* finsh - 当关闭设备时注销rx_indicate
+* finsh - 修正命令行太长的问题
+* finsh/msh - 只有当DFS_USING_WORKDIR使能时才声明cd/pwd
+* init - 为新的组件初始化机制更新连接脚本
+* init - 增加组件初始化调试代码
+* logtrace - 整理代码,去除编译警告
+* logtrace - 增加LOG_TRACE_VERBOSE
+* logtrace - 调整log values
+* logtrace - 只有当finsh使能的时候才声明cmd
+* libc/minilibc - 在sys/time.h中增加gettimeofday的声明
+* utilities - 新增ymodem
+
+工具:
+
+* building.py - 增加clang静态缝隙器的支持
+* building.py - 为Keil MDK增加buildlib功能
+* building.py - 在clang-analyze中执行'clang -Wall -fsyntas-only'
+* clang-analyze.py - 增加一个定制工具实现clang静态分析
+
+分支:
+
+* 新增BeagleBone的移植
+* 新增SEP6200的移植
+* 新增K60Fxxxx的移植
+* 修正Linux中的编译错误(lm4f232, stm32f40x, xplorer4330)
+* cortex-m3 - 加强hard fault的异常处理函数
+* at91sam9260 - 更新串口驱动,使用组件中的通用串口驱动
+* at91sam9260 - 更新工程目录结构
+* at91sam9260 - 修正编译错误
+* at91sam9260 - 内嵌GPLv2许可
+* stm32f10x - 删除无用的文件
+* stm32f10x - 更新工程目录结构
+* stm32f10x - 更新工程文件
+* stm32f10x - 为使用新的组件初始化更新连接脚本
+* stm32f10x - 为使用新的组件初始化更新SD card驱动
+* stm32f10x - 为使用新的组件初始化更新DM9000驱动
+* stm32f10x - 更新串口驱动,使用组件中的通用串口驱动
+* stm32f10x - 修正rtgui初始化问题
+* simulator - 为使用新的组件初始化更新代码,以便支持mingw
+* simulator - 支持Linux系统
+* simulator - 修正Linux系统中的SDL初始化问题
+* simulator - 在rt_components_init之后初始化SDL
+* simulator - 将对SDL设置的内容移入drivers/SConstruct
+* simulator - 在env中获得CORSS_TOOL和EXEC_PATH的值
+* simulator - 支持clang-analyze
+* simulator - 增加tap netif driver
+
+//----------------------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------------------
+
+
+版本: RT-Thread 1.2.0 Beta 版本
+
+发布时间: 2013/6/30
+		
+进过开发人员三个月的努力,RT-Thread 1.2.0 Beta 版本如期发布。
+该版本默认采用lwIP 1.4.1协议栈,USB device stack也进一步完善。加入 log_trace 子系统,加入组件初始化升级版本,加入 ARM Cortex-R 的移植。
+
+主要变化:
+
+* 1,新增组件初始化功能
+- 详情请看论坛帖子[新功能] 组件初始化
+* 2,支持ARM Cortex-R系列处理器
+- Grissiom 完成 ARM Cortex-R 的移植,目前BSP中已有TI RM48x50分支(仅支持TI CCS开发环境)
+* 3,文件系统中新增 RAMFS
+* 4,加入 log_trace 子系统
+* 5,优化Cortex-M4线程上下文切换,使用了浮点运算的线程才保存及恢复FPU寄存器
+- 详情请看论坛帖子[优化]cortex-m4f线程切换,优化FPU寄存器
+* 6,新增API rt_memheap_realloc()
+* 7,重新实现ringbuffer,采用镜像的方法区分“满”和“空”,同时支持任意大小的buffer
+* 8,内核中加入RT_KERNEL_MALLOC/RT_KERNEL_FREE/RT_KERNEL_REALLOC宏。
+如果用户未定义这些宏,将默认指向rt_malloc/rt_free/rt_realloc。
+同时内核仅局限于使用这些宏来使用动态内存
+* 9,在 building.py 中新增生成 cscope database 的选项
+* 10,USB组件新增reset函数,支持热插拔
+* 11,scons编译系统支持CCS开发环境
+* 12,USB组件新增状态信息(USB_STATE_NOTATTACHED,USB_STATE_ATTACHED,USB_STATE_POWERED...)
+
+修复问题点:
+
+* 1,USB组件HOST可以挂起endpoints
+* 2,simulator分支,修复 serial_write 问题
+* 3,udisk可以被弹出
+* 4,iar.py中修复绝对路径的问题
+* 5,dfs_fs.h内增加dfs_mkfs()函数的申明
+* 6,生成MDK工程文件的时候加入library文件
+* 7,当PC不再接受数据的时候,重置VCOM相应的状态
+* 8,USB组件:返回正确的LangID字符串长度给HOST
+* 9,Cortex-M0,Cortex-M3,Cortex-M4上下文切换时,回收系统初始化时用到的栈空间
+
+//----------------------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------------------
+
+
+
+版本: RT-Thread 1.2.0 Alpha版本
+
+发布时间: 2013/4/10
+	
+遵循2013年RT-Thread roadmap,RT-Thread 1.2.0 Alpha版本发布,Alpha意味着此版本为技术预览版,仅用于展示RT-Thread 1.2.0未来的发展方向,并不适合于开发正式产品。RT-Thread 1.2.0版本是1.1.x系列的下一个分支,这个分支主要体现的是RT-Thread 1.x系列的文档情况。当然也有一些功能、代码方面的增强。
+
+伴随着新版本的到来,RT-Thread有几个重大的转变:
+1,代码托管从google code(SVN)迁移到github(GIT)
+2,RT-Thread与RTGUI区分开来,并成为两个独立的开发分支
+3,重视文档,将文档建设作为1.2.0版本的首要任务来抓
+
+内核主要变化:
+1,加入__rt_ffs函数用于实现32位整数中获取第一个置1的位;同时调度器中位图相关算法直接使用__rt_ffs函数;CPU移植时,可定义RT_USING_CPU_FFS,使用芯片指令完成。
+
+2,新的中断注册机制
+weety加入interrupt description功能,用于为interrupt增加更多的信息,同时中断服务例程也可以携带用户自定义的参数类型。
+* 这部分对ARM7、ARM9、MIPS等影响很大,需要对CPU移植做相应的一些修改。
+* 这部分对ARM Cortex-M系列芯片没有影响。
+
+3,调整定时器插入位置,为相同超时定时的后面。
+
+组件主要变化:
+1,添加lwIP 1.4.1。
+2,在finsh shell中加入module shell功能。finsh shell本身是一个C语言表达式的shell命令行,而module shell更类似于一个传统的命令行,由命令,参数等方式构成。
+
+分支主要变化:
+1,完善simulator分支,支持RTGUI,支持应用模块。
+2,完善at91sam9260分支的移植及驱动更新。
+
+编译系统主要变化:
+1,开启省略编译时长命令特性,如果需要查看编译时命令行,可以使用scons --verbose查看。
+2,加入生成CodeBlocks工程特性。
+3,修正当系统安装使用Keil MDK 4.6+版本的问题。
+
+github主要提交履历:
+5646189b29: elm fatfs支持mkfs,并且无需提前执行dfs_mount; mount/umount/mkfs操作也不会引起reset
+22786f8817: 允许用户自定义PID和VID
+0001344105: 更明确的定时器运行机制,如果两个定时器在同一个时刻发生超时,那么先开始的定时器先处理
+5d68ef8ec1: 修正使用64位GCC时编译finsh过程中发生错误的问题
+a4d661dcf1: 修正dfs_elm.c中一处内存泄露,并且在mount fatfs失败时执行 umount fatfs操作
+43228aeb9c: 修正list_tcps问题:ipaddr_ntoa不是可重入的函数。
+3de4b92a68: 修正AT91SAM9260分支中PHY link状态错误的问题。
+1abaa0492d

+ 3 - 0
Kconfig

@@ -0,0 +1,3 @@
+source "$RTT_DIR/src/Kconfig"
+source "$RTT_DIR/libcpu/Kconfig"
+source "$RTT_DIR/components/Kconfig"

+ 201 - 0
LICENSE

@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   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.

+ 84 - 0
README.md

@@ -0,0 +1,84 @@
+# RT-Thread #
+
+[中文页](README_zh.md) |
+
+[![GitHub](https://img.shields.io/github/license/RT-Thread/rt-thread.svg)](https://github.com/RT-Thread/rt-thread/blob/master/LICENSE)
+[![GitHub release](https://img.shields.io/github/release/RT-Thread/rt-thread.svg)](https://github.com/RT-Thread/rt-thread/releases)
+[![Build Status](https://travis-ci.org/RT-Thread/rt-thread.svg)](https://travis-ci.org/RT-Thread/rt-thread)
+[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/RT-Thread/rt-thread?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+[![GitHub pull-requests](https://img.shields.io/github/issues-pr/RT-Thread/rt-thread.svg)](https://github.com/RT-Thread/rt-thread/pulls)
+[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat)](https://github.com/RT-Thread/rt-thread/pulls)
+
+RT-Thread is an open source IoT operating system from China, which has strong scalability: from a tiny kernel running on a tiny core, for example ARM Cortex-M0, or Cortex-M3/4/7, to a rich feature system running on MIPS32, ARM Cortex-A8, ARM Cortex-A9 DualCore etc.
+
+## Overview ##
+
+RT-Thread RTOS like a traditional real-time operating system. The kernel has real-time multi-task scheduling, semaphore, mutex, mail box, message queue, signal etc. However, it has three different things:
+
+* Device Driver;
+* Component;
+* Dynamic Module
+
+The device driver is more like a driver framework, UART, IIC, SPI, SDIO, USB device/host, EMAC, MTD NAND etc. The developer can easily add low level driver and board configuration, then combined with the upper framework, he/she can use lots of features.
+
+The Component is a software concept upon RT-Thread kernel, for example a shell (finsh/msh shell), virtual file system (FAT, YAFFS, UFFS, ROM/RAM file system etc), TCP/IP protocol stack (lwIP), POSIX (thread) interface etc. One component must be a directory under RT-Thread/Components and one component can be descripted by a SConscript file (then be compiled and linked into the system).
+
+The Dynamic Module, formerly named as User Applicaion (UA) is a dynamic loaded module or library, it can be compiled standalone without Kernel. Each Dynamic Module has its own object list to manage thread/semaphore/kernel object which was created or initialized inside this UA. More information about UA, please visit another [git repo](https://github.com/RT-Thread/rtthread-apps).
+
+## Board Support Package ##
+
+RT-Thread RTOS can support many architectures:
+
+* ARM Cortex-M0
+* ARM Cortex-M3/M4/7
+* ARM Cortex-R4
+* ARM Cortex-A8/A9
+* ARM920T/ARM926 etc
+* MIPS32
+* x86
+* Andes
+* C-Sky
+* RISC-V
+* PowerPC
+
+## License ##
+
+RT-Thread is Open Source software under the Apache License 2.0 since RT-Thread v3.1.1. License and copyright information can be found within the code.
+
+    /*
+     * Copyright (c) 2006-2018, RT-Thread Development Team
+     *
+     * SPDX-License-Identifier: Apache-2.0
+     */
+
+Since 9th of September 2018, PRs submitted by the community may be merged into the main line only after signing the Contributor License Agreement(CLA).
+
+## Usage ##
+
+RT-Thread RTOS uses [scons](http://www.scons.org) as building system. Therefore, please install scons and Python 2.7 firstly. 
+So far, the RT-Thread scons building system support the command line compile or generate some IDE's project. There are some option varaibles in the scons building script (rtconfig.py):
+
+* ```CROSS_TOOL``` the compiler which you want to use, gcc/keil/iar. 
+* ```EXEC_PATH``` the path of compiler. 
+
+In SConstruct file:
+
+```RTT_ROOT``` This variable is the root directory of RT-Thread RTOS. If you build the porting in the bsp directory, you can use the default setting. Also, you can set the root directory in ```RTT_ROOT``` environment variable and not modify SConstruct files.
+
+When you set these variables correctly, you can use command:
+
+    scons
+
+under BSP directory to simplely compile RT-Thread RTOS.
+
+If you want to generate the IDE's project file, you can use command:
+
+    scons --target=mdk/mdk4/mdk5/iar/cb -s
+
+to generate the project file.
+
+NOTE: RT-Thread scons building system will tailor the system according to your rtconfig.h configuration header file. For example, if you disable the lwIP in the rtconfig.h by commenting the ```#define RT_USING_LWIP```, the generated project file should have no lwIP related files.
+
+## Contribution ##
+
+Please refer the contributors in the github. Thank all of RT-Thread Developers.

+ 97 - 0
README_zh.md

@@ -0,0 +1,97 @@
+# RT-Thread #
+
+[![GitHub release](https://img.shields.io/github/release/RT-Thread/rt-thread.svg)](https://github.com/RT-Thread/rt-thread/releases)
+[![Build Status](https://travis-ci.org/RT-Thread/rt-thread.svg)](https://travis-ci.org/RT-Thread/rt-thread)
+[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/RT-Thread/rt-thread?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+[![GitHub pull-requests](https://img.shields.io/github/issues-pr/RT-Thread/rt-thread.svg)](https://github.com/RT-Thread/rt-thread/pulls)
+[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat)](https://github.com/RT-Thread/rt-thread/pulls)
+
+RT-Thread是一个来自中国的开源物联网操作系统,它提供了非常强的可伸缩能力:从一个可以运行在ARM Cortex-M0芯片上的极小内核,到中等的ARM Cortex-M3/4/7系统,甚至是运行于MIPS32、ARM Cortex-A系列处理器上功能丰富系统。
+
+## 简介 ##
+
+RT-Thread包含了一个自有的、传统的硬实时内核:可抢占的多任务实时调度器,信号量,互斥量,邮箱,消息队列,信号等。当然,它和传统的实时操作系统还存在着三种不同:
+
+* 设备驱动框架;
+* 软件组件;
+* 应用模块
+
+设备驱动框架更类似一套驱动框架,涉及到UART,IIC,SPI,SDIO,USB从设备/主设备,EMAC,NAND闪存设备等。它会把这些设备驱动中的共性抽象/抽取出来,而驱动工程师只需要按照固定的模式实现少量的底层硬件操作及板级配置。通过这样的方式,让一个硬件外设更容易地对接到RT-Thread系统中,并获得RT-Thread平台上的完整软件栈功能。
+
+软件组件是位于RT-Thread内核上的软件单元,例如命令行(finsh/msh shell),虚拟文件系统(FAT,YAFFS,UFFS,ROM/RAM文件系统等),TCP/IP网络协议栈(lwIP),Libc/POSIX标准层等。一般的,一个软件组件放置于一个目录下,例如RT-Thread/components目录下的文件夹,并且每个软件组件通过一个 SConscript文件来描述并被添加到RT-Thread的构建系统中。当系统配置中开启了这一软件组件时,这个组件将被编译并链接到最终的RT-Thread固件中。
+
+注:随着RT-Thread 3.0中的包管理器开启,越来越多的软件组件将以package方式出现在RT-Thread平台中。而RT-Thread平台更多的是指:
+
+* RT-Thread内核;
+* shell命令行;
+* 虚拟文件系统;
+* TCP/IP网络协议栈;
+* 设备驱动框架;
+* Libc/POSIX标准层。
+
+更多的IoT软件包则以package方式被添加到RT-Thread系统中。
+
+应用模块,或者说用户应用(User Application,UA)是一个可动态加载的模块:它可以独立于RT-Thread固件而单独编译。一般的,每个UA都包含一个main函数入口;一个它自己的对象链表,用于管理这个应用的任务/信号量/消息队列等内核对象,创建、初始化、销毁等。更多关于UA的信息,请访问另外一个 [git 仓库](https://github.com/RT-Thread/rtthread-apps) 了解。
+
+## 支持的芯片架构 ##
+
+RT-Thread支持数种芯片体系架构,已经覆盖当前应用中的主流体系架构:
+
+* ARM Cortex-M0
+* ARM Cortex-M3/M4/7
+* ARM Cortex-R4
+* ARM Cortex-A8/A9
+* ARM920T/ARM926 etc
+* MIPS32
+* x86
+* Andes
+* C-Sky
+* RISC-V
+* PowerPC
+
+## 许可证 ##
+
+RT-Thread从v3.1.1版本开始,是一个以Apache许可证2.0版本授权的开源软件,许可证信息以及版权信息一般的可以在代码首部看到:
+
+    /*
+     * Copyright (c) 2006-2018, RT-Thread Development Team
+     *
+     * SPDX-License-Identifier: Apache-2.0
+     */
+
+从2018/09/09开始,开发者提交PR需要签署贡献者许可协议(CLA)。
+
+注意:
+
+以Apache许可协议v2.0版本授权仅在RT-Thread v3.1.1正式版发布之后才正式实施,当前依然在准备阶段(准备所有原有开发者签署CLA协议)。
+
+## 编译 ##
+
+RT-Thread使用了[scons](http://www.scons.org)做为自身的编译构建系统,并进行一定的定制以满足自身的需求(可以通过scons --help查看RT-Thread中额外添加的命令)。在编译RT-Thread前,请先安装Python 2.7.x及scons。
+
+截至目前,RT-Thread scons构建系统可以使用命令行方式编译代码,或者使用scons来生成不同IDE的工程文件。在使用scons时,需要对构建配置文件(rtconfig.py)中如下的变量进行配置:
+
+* ```CROSS_TOOL``` 指定希望使用的工具链,例如gcc/keil/iar. 
+* ```EXEC_PATH``` 工具链的路径. 
+
+注:在SConstruct文件中:
+
+```RTT_ROOT``` 这个变量指向了RT-Thread的发布源代码根目录。如果你仅计划编译bsp目录下的target,这个`RTT_ROOT`可以使用默认配置。另外,你也可以设置同名的环境变量来指向不同的RT-Thread源代码根目录。
+
+当你把相关的配置都配置正确后,你可以在具有目标目录下(这个目录应包括rtconfig.py、SContruct文件)执行以下命令:
+
+    scons 
+
+从而简单地就编译好RT-Thread。
+
+如果你希望使用IDE来编译RT-Thread,你也可以使用命令行:
+
+    scons --target=mdk/mdk4/mdk5/iar/cb -s 
+
+来生成mdk/iar等的工程文件。而后在IDE中打开project前缀的工程文件来编译RT-Thread。
+
+注意:RT-Thread的scons构建系统会根据配置头文件rtconfig.h来裁剪系统。例如,如果你关闭了rtconfig.h中的lwIP定义(通过注释掉```#define RT_USING_LWIP```的方式),则scons生成的IDE工程文件中将自动不包括lwIP相关的文件。而在RT-Thread 3.0版本中,可以通过menuconfig的方式来配置整个系统,而不需要再手工更改rtconfig.h配置头文件。
+
+## 贡献者 ##
+
+请访问github上RT-Thread项目上的contributors了解已经为RT-Thread提交过代码,PR的贡献者。感谢所有为RT-Thread付出的开发者们!

+ 490 - 0
bsp/qemu-vexpress-a9/.config

@@ -0,0 +1,490 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# RT-Thread Project Configuration
+#
+
+#
+# RT-Thread Kernel
+#
+CONFIG_RT_NAME_MAX=8
+# CONFIG_RT_USING_ARCH_DATA_TYPE is not set
+CONFIG_RT_USING_SMP=y
+CONFIG_RT_CPUS_NR=2
+CONFIG_RT_ALIGN_SIZE=4
+# CONFIG_RT_THREAD_PRIORITY_8 is not set
+CONFIG_RT_THREAD_PRIORITY_32=y
+# CONFIG_RT_THREAD_PRIORITY_256 is not set
+CONFIG_RT_THREAD_PRIORITY_MAX=32
+CONFIG_RT_TICK_PER_SECOND=100
+CONFIG_RT_USING_OVERFLOW_CHECK=y
+CONFIG_RT_USING_HOOK=y
+CONFIG_RT_USING_IDLE_HOOK=y
+CONFIG_RT_IDLE_HOOK_LIST_SIZE=4
+CONFIG_IDLE_THREAD_STACK_SIZE=1024
+CONFIG_RT_USING_TIMER_SOFT=y
+CONFIG_RT_TIMER_THREAD_PRIO=4
+CONFIG_RT_TIMER_THREAD_STACK_SIZE=1024
+CONFIG_RT_DEBUG=y
+CONFIG_RT_DEBUG_COLOR=y
+# CONFIG_RT_DEBUG_INIT_CONFIG is not set
+# CONFIG_RT_DEBUG_THREAD_CONFIG is not set
+# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set
+# CONFIG_RT_DEBUG_IPC_CONFIG is not set
+# CONFIG_RT_DEBUG_TIMER_CONFIG is not set
+# CONFIG_RT_DEBUG_IRQ_CONFIG is not set
+# CONFIG_RT_DEBUG_MEM_CONFIG is not set
+# CONFIG_RT_DEBUG_SLAB_CONFIG is not set
+# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set
+# CONFIG_RT_DEBUG_MODULE_CONFIG is not set
+
+#
+# Inter-Thread communication
+#
+CONFIG_RT_USING_SEMAPHORE=y
+CONFIG_RT_USING_MUTEX=y
+CONFIG_RT_USING_EVENT=y
+CONFIG_RT_USING_MAILBOX=y
+CONFIG_RT_USING_MESSAGEQUEUE=y
+CONFIG_RT_USING_SIGNALS=y
+
+#
+# Memory Management
+#
+CONFIG_RT_USING_MEMPOOL=y
+CONFIG_RT_USING_MEMHEAP=y
+# CONFIG_RT_USING_NOHEAP is not set
+CONFIG_RT_USING_SMALL_MEM=y
+# CONFIG_RT_USING_SLAB is not set
+# CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set
+CONFIG_RT_USING_MEMTRACE=y
+CONFIG_RT_USING_HEAP=y
+
+#
+# Kernel Device Object
+#
+CONFIG_RT_USING_DEVICE=y
+CONFIG_RT_USING_DEVICE_OPS=y
+CONFIG_RT_USING_INTERRUPT_INFO=y
+CONFIG_RT_USING_CONSOLE=y
+CONFIG_RT_CONSOLEBUF_SIZE=256
+CONFIG_RT_CONSOLE_DEVICE_NAME="uart0"
+CONFIG_RT_VER_NUM=0x40002
+CONFIG_ARCH_ARM=y
+# CONFIG_RT_USING_CPU_FFS is not set
+CONFIG_ARCH_ARM_CORTEX_A=y
+CONFIG_ARCH_ARM_CORTEX_A9=y
+# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set
+
+#
+# RT-Thread Components
+#
+CONFIG_RT_USING_COMPONENTS_INIT=y
+CONFIG_RT_USING_USER_MAIN=y
+CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048
+CONFIG_RT_MAIN_THREAD_PRIORITY=10
+
+#
+# C++ features
+#
+CONFIG_RT_USING_CPLUSPLUS=y
+
+#
+# Command shell
+#
+CONFIG_RT_USING_FINSH=y
+CONFIG_FINSH_THREAD_NAME="tshell"
+CONFIG_FINSH_USING_HISTORY=y
+CONFIG_FINSH_HISTORY_LINES=5
+CONFIG_FINSH_USING_SYMTAB=y
+CONFIG_FINSH_USING_DESCRIPTION=y
+# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set
+CONFIG_FINSH_THREAD_PRIORITY=20
+CONFIG_FINSH_THREAD_STACK_SIZE=4096
+CONFIG_FINSH_CMD_SIZE=80
+# CONFIG_FINSH_USING_AUTH is not set
+CONFIG_FINSH_USING_MSH=y
+CONFIG_FINSH_USING_MSH_DEFAULT=y
+# CONFIG_FINSH_USING_MSH_ONLY is not set
+CONFIG_FINSH_ARG_MAX=10
+
+#
+# Device virtual file system
+#
+CONFIG_RT_USING_DFS=y
+CONFIG_DFS_USING_WORKDIR=y
+CONFIG_DFS_FILESYSTEMS_MAX=2
+CONFIG_DFS_FILESYSTEM_TYPES_MAX=8
+CONFIG_DFS_FD_MAX=16
+# CONFIG_RT_USING_DFS_MNTTABLE is not set
+CONFIG_RT_USING_DFS_ELMFAT=y
+
+#
+# elm-chan's FatFs, Generic FAT Filesystem Module
+#
+CONFIG_RT_DFS_ELM_CODE_PAGE=437
+CONFIG_RT_DFS_ELM_WORD_ACCESS=y
+# CONFIG_RT_DFS_ELM_USE_LFN_0 is not set
+# CONFIG_RT_DFS_ELM_USE_LFN_1 is not set
+# CONFIG_RT_DFS_ELM_USE_LFN_2 is not set
+CONFIG_RT_DFS_ELM_USE_LFN_3=y
+CONFIG_RT_DFS_ELM_USE_LFN=3
+CONFIG_RT_DFS_ELM_MAX_LFN=255
+CONFIG_RT_DFS_ELM_DRIVES=2
+CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=4096
+# CONFIG_RT_DFS_ELM_USE_ERASE is not set
+CONFIG_RT_DFS_ELM_REENTRANT=y
+CONFIG_RT_USING_DFS_DEVFS=y
+CONFIG_RT_USING_DFS_ROMFS=y
+CONFIG_RT_USING_DFS_RAMFS=y
+# CONFIG_RT_USING_DFS_UFFS is not set
+# CONFIG_RT_USING_DFS_JFFS2 is not set
+# CONFIG_RT_USING_DFS_NFS is not set
+
+#
+# Device Drivers
+#
+CONFIG_RT_USING_DEVICE_IPC=y
+CONFIG_RT_PIPE_BUFSZ=512
+CONFIG_RT_USING_SYSTEM_WORKQUEUE=y
+CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=2048
+CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23
+CONFIG_RT_USING_SERIAL=y
+CONFIG_RT_SERIAL_USING_DMA=y
+CONFIG_RT_SERIAL_RB_BUFSZ=64
+# CONFIG_RT_USING_CAN is not set
+# CONFIG_RT_USING_HWTIMER is not set
+# CONFIG_RT_USING_CPUTIME is not set
+CONFIG_RT_USING_I2C=y
+CONFIG_RT_USING_I2C_BITOPS=y
+CONFIG_RT_USING_PIN=y
+# CONFIG_RT_USING_ADC is not set
+# CONFIG_RT_USING_PWM is not set
+CONFIG_RT_USING_MTD_NOR=y
+CONFIG_RT_USING_MTD_NAND=y
+CONFIG_RT_MTD_NAND_DEBUG=y
+# CONFIG_RT_USING_MTD is not set
+# CONFIG_RT_USING_PM is not set
+CONFIG_RT_USING_RTC=y
+# CONFIG_RT_USING_ALARM is not set
+CONFIG_RT_USING_SOFT_RTC=y
+CONFIG_RT_USING_SDIO=y
+CONFIG_RT_SDIO_STACK_SIZE=512
+CONFIG_RT_SDIO_THREAD_PRIORITY=15
+CONFIG_RT_MMCSD_STACK_SIZE=1024
+CONFIG_RT_MMCSD_THREAD_PREORITY=22
+CONFIG_RT_MMCSD_MAX_PARTITION=16
+# CONFIG_RT_SDIO_DEBUG is not set
+CONFIG_RT_USING_SPI=y
+# CONFIG_RT_USING_QSPI is not set
+CONFIG_RT_USING_SPI_MSD=y
+CONFIG_RT_USING_SFUD=y
+CONFIG_RT_SFUD_USING_SFDP=y
+CONFIG_RT_SFUD_USING_FLASH_INFO_TABLE=y
+# CONFIG_RT_SFUD_USING_QSPI is not set
+# CONFIG_RT_DEBUG_SFUD is not set
+# CONFIG_RT_USING_ENC28J60 is not set
+# CONFIG_RT_USING_SPI_WIFI is not set
+CONFIG_RT_USING_WDT=y
+# CONFIG_RT_USING_AUDIO is not set
+# CONFIG_RT_USING_SENSOR is not set
+# CONFIG_RT_USING_TOUCH is not set
+
+#
+# Using Hardware Crypto drivers
+#
+# CONFIG_RT_USING_HWCRYPTO is not set
+
+#
+# Using WiFi
+#
+# CONFIG_RT_USING_WIFI is not set
+
+#
+# Using USB
+#
+# CONFIG_RT_USING_USB_HOST is not set
+# CONFIG_RT_USING_USB_DEVICE is not set
+
+#
+# POSIX layer and C standard library
+#
+CONFIG_RT_USING_LIBC=y
+CONFIG_RT_USING_PTHREADS=y
+CONFIG_PTHREAD_NUM_MAX=8
+CONFIG_RT_USING_POSIX=y
+CONFIG_RT_USING_POSIX_MMAP=y
+CONFIG_RT_USING_POSIX_TERMIOS=y
+CONFIG_RT_USING_POSIX_AIO=y
+# CONFIG_RT_USING_MODULE is not set
+
+#
+# Network
+#
+
+#
+# Socket abstraction layer
+#
+CONFIG_RT_USING_SAL=y
+
+#
+# protocol stack implement
+#
+CONFIG_SAL_USING_LWIP=y
+CONFIG_SAL_USING_POSIX=y
+
+#
+# Network interface device
+#
+CONFIG_RT_USING_NETDEV=y
+CONFIG_NETDEV_USING_IFCONFIG=y
+CONFIG_NETDEV_USING_PING=y
+CONFIG_NETDEV_USING_NETSTAT=y
+CONFIG_NETDEV_USING_AUTO_DEFAULT=y
+# CONFIG_NETDEV_USING_IPV6 is not set
+CONFIG_NETDEV_IPV4=1
+CONFIG_NETDEV_IPV6=0
+# CONFIG_NETDEV_IPV6_SCOPES is not set
+
+#
+# light weight TCP/IP stack
+#
+CONFIG_RT_USING_LWIP=y
+# CONFIG_RT_USING_LWIP141 is not set
+CONFIG_RT_USING_LWIP202=y
+# CONFIG_RT_USING_LWIP210 is not set
+# CONFIG_RT_USING_LWIP_IPV6 is not set
+# CONFIG_RT_LWIP_IGMP is not set
+CONFIG_RT_LWIP_ICMP=y
+# CONFIG_RT_LWIP_SNMP is not set
+CONFIG_RT_LWIP_DNS=y
+CONFIG_RT_LWIP_DHCP=y
+CONFIG_IP_SOF_BROADCAST=1
+CONFIG_IP_SOF_BROADCAST_RECV=1
+
+#
+# Static IPv4 Address
+#
+CONFIG_RT_LWIP_IPADDR="192.168.1.30"
+CONFIG_RT_LWIP_GWADDR="192.168.1.1"
+CONFIG_RT_LWIP_MSKADDR="255.255.255.0"
+CONFIG_RT_LWIP_UDP=y
+CONFIG_RT_LWIP_TCP=y
+CONFIG_RT_LWIP_RAW=y
+# CONFIG_RT_LWIP_PPP is not set
+CONFIG_RT_MEMP_NUM_NETCONN=8
+CONFIG_RT_LWIP_PBUF_NUM=16
+CONFIG_RT_LWIP_RAW_PCB_NUM=4
+CONFIG_RT_LWIP_UDP_PCB_NUM=4
+CONFIG_RT_LWIP_TCP_PCB_NUM=4
+CONFIG_RT_LWIP_TCP_SEG_NUM=40
+CONFIG_RT_LWIP_TCP_SND_BUF=8196
+CONFIG_RT_LWIP_TCP_WND=8196
+CONFIG_RT_LWIP_TCPTHREAD_PRIORITY=10
+CONFIG_RT_LWIP_TCPTHREAD_MBOX_SIZE=8
+CONFIG_RT_LWIP_TCPTHREAD_STACKSIZE=1024
+# CONFIG_LWIP_NO_RX_THREAD is not set
+# CONFIG_LWIP_NO_TX_THREAD is not set
+CONFIG_RT_LWIP_ETHTHREAD_PRIORITY=12
+CONFIG_RT_LWIP_ETHTHREAD_STACKSIZE=1024
+CONFIG_RT_LWIP_ETHTHREAD_MBOX_SIZE=8
+CONFIG_RT_LWIP_REASSEMBLY_FRAG=y
+CONFIG_LWIP_NETIF_STATUS_CALLBACK=1
+CONFIG_LWIP_NETIF_LINK_CALLBACK=1
+CONFIG_SO_REUSE=1
+CONFIG_LWIP_SO_RCVTIMEO=1
+CONFIG_LWIP_SO_SNDTIMEO=1
+CONFIG_LWIP_SO_RCVBUF=1
+# CONFIG_RT_LWIP_NETIF_LOOPBACK is not set
+CONFIG_LWIP_NETIF_LOOPBACK=0
+# CONFIG_RT_LWIP_STATS is not set
+# CONFIG_RT_LWIP_USING_HW_CHECKSUM is not set
+CONFIG_RT_LWIP_USING_PING=y
+# CONFIG_RT_LWIP_DEBUG is not set
+
+#
+# Modbus master and slave stack
+#
+# CONFIG_RT_USING_MODBUS is not set
+
+#
+# AT commands
+#
+# CONFIG_RT_USING_AT is not set
+# CONFIG_LWIP_USING_DHCPD is not set
+
+#
+# VBUS(Virtual Software BUS)
+#
+# CONFIG_RT_USING_VBUS is not set
+
+#
+# Utilities
+#
+# CONFIG_RT_USING_RYM is not set
+# CONFIG_RT_USING_ULOG is not set
+# CONFIG_RT_USING_UTEST is not set
+CONFIG_RT_USING_LWP=y
+
+#
+# RT-Thread online packages
+#
+
+#
+# IoT - internet of things
+#
+# CONFIG_PKG_USING_PAHOMQTT is not set
+# CONFIG_PKG_USING_WEBCLIENT is not set
+# CONFIG_PKG_USING_WEBNET is not set
+# CONFIG_PKG_USING_MONGOOSE is not set
+# CONFIG_PKG_USING_WEBTERMINAL is not set
+# CONFIG_PKG_USING_CJSON is not set
+# CONFIG_PKG_USING_JSMN is not set
+# CONFIG_PKG_USING_LIBMODBUS is not set
+# CONFIG_PKG_USING_LJSON is not set
+# CONFIG_PKG_USING_EZXML is not set
+# CONFIG_PKG_USING_NANOPB is not set
+
+#
+# Wi-Fi
+#
+
+#
+# Marvell WiFi
+#
+# CONFIG_PKG_USING_WLANMARVELL is not set
+
+#
+# Wiced WiFi
+#
+# CONFIG_PKG_USING_WLAN_WICED is not set
+# CONFIG_PKG_USING_RW007 is not set
+# CONFIG_PKG_USING_COAP is not set
+# CONFIG_PKG_USING_NOPOLL is not set
+# CONFIG_PKG_USING_NETUTILS is not set
+# CONFIG_PKG_USING_AT_DEVICE is not set
+# CONFIG_PKG_USING_ATSRV_SOCKET is not set
+# CONFIG_PKG_USING_WIZNET is not set
+
+#
+# IoT Cloud
+#
+# CONFIG_PKG_USING_ONENET is not set
+# CONFIG_PKG_USING_GAGENT_CLOUD is not set
+# CONFIG_PKG_USING_ALI_IOTKIT is not set
+# CONFIG_PKG_USING_AZURE is not set
+# CONFIG_PKG_USING_TENCENT_IOTHUB is not set
+# CONFIG_PKG_USING_NIMBLE is not set
+# CONFIG_PKG_USING_OTA_DOWNLOADER is not set
+# CONFIG_PKG_USING_IPMSG is not set
+# CONFIG_PKG_USING_LSSDP is not set
+# CONFIG_PKG_USING_AIRKISS_OPEN is not set
+# CONFIG_PKG_USING_LIBRWS is not set
+
+#
+# security packages
+#
+# CONFIG_PKG_USING_MBEDTLS is not set
+# CONFIG_PKG_USING_libsodium is not set
+# CONFIG_PKG_USING_TINYCRYPT is not set
+
+#
+# language packages
+#
+# CONFIG_PKG_USING_LUA is not set
+# CONFIG_PKG_USING_JERRYSCRIPT is not set
+# CONFIG_PKG_USING_MICROPYTHON is not set
+
+#
+# multimedia packages
+#
+# CONFIG_PKG_USING_OPENMV is not set
+# CONFIG_PKG_USING_MUPDF is not set
+# CONFIG_PKG_USING_STEMWIN is not set
+
+#
+# tools packages
+#
+# CONFIG_PKG_USING_CMBACKTRACE is not set
+# CONFIG_PKG_USING_EASYFLASH is not set
+# CONFIG_PKG_USING_EASYLOGGER is not set
+# CONFIG_PKG_USING_SYSTEMVIEW is not set
+# CONFIG_PKG_USING_RDB is not set
+# CONFIG_PKG_USING_QRCODE is not set
+# CONFIG_PKG_USING_ULOG_EASYFLASH is not set
+# CONFIG_PKG_USING_ADBD is not set
+
+#
+# system packages
+#
+# CONFIG_PKG_USING_GUIENGINE is not set
+# CONFIG_PKG_USING_PERSIMMON is not set
+# CONFIG_PKG_USING_CAIRO is not set
+# CONFIG_PKG_USING_PIXMAN is not set
+# CONFIG_PKG_USING_LWEXT4 is not set
+# CONFIG_PKG_USING_PARTITION is not set
+# CONFIG_PKG_USING_FAL is not set
+# CONFIG_PKG_USING_SQLITE is not set
+# CONFIG_PKG_USING_RTI is not set
+# CONFIG_PKG_USING_LITTLEVGL2RTT is not set
+# CONFIG_PKG_USING_CMSIS is not set
+# CONFIG_PKG_USING_DFS_YAFFS is not set
+# CONFIG_PKG_USING_LITTLEFS is not set
+# CONFIG_PKG_USING_THREAD_POOL is not set
+
+#
+# peripheral libraries and drivers
+#
+# CONFIG_PKG_USING_SENSORS_DRIVERS is not set
+# CONFIG_PKG_USING_REALTEK_AMEBA is not set
+# CONFIG_PKG_USING_SHT2X is not set
+# CONFIG_PKG_USING_STM32_SDIO is not set
+# CONFIG_PKG_USING_ICM20608 is not set
+# CONFIG_PKG_USING_U8G2 is not set
+# CONFIG_PKG_USING_BUTTON is not set
+# CONFIG_PKG_USING_PCF8574 is not set
+# CONFIG_PKG_USING_SX12XX is not set
+# CONFIG_PKG_USING_SIGNAL_LED is not set
+# CONFIG_PKG_USING_LEDBLINK is not set
+# CONFIG_PKG_USING_WM_LIBRARIES is not set
+# CONFIG_PKG_USING_KENDRYTE_SDK is not set
+# CONFIG_PKG_USING_INFRARED is not set
+# CONFIG_PKG_USING_ROSSERIAL is not set
+# CONFIG_PKG_USING_AT24CXX is not set
+# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set
+# CONFIG_PKG_USING_AD7746 is not set
+# CONFIG_PKG_USING_PCA9685 is not set
+# CONFIG_PKG_USING_I2C_TOOLS is not set
+# CONFIG_PKG_USING_NRF24L01 is not set
+# CONFIG_PKG_USING_TOUCH_DRIVERS is not set
+
+#
+# miscellaneous packages
+#
+# CONFIG_PKG_USING_LIBCSV is not set
+# CONFIG_PKG_USING_OPTPARSE is not set
+# CONFIG_PKG_USING_FASTLZ is not set
+# CONFIG_PKG_USING_MINILZO is not set
+# CONFIG_PKG_USING_QUICKLZ is not set
+# CONFIG_PKG_USING_MULTIBUTTON is not set
+# CONFIG_PKG_USING_CANFESTIVAL is not set
+# CONFIG_PKG_USING_ZLIB is not set
+# CONFIG_PKG_USING_DSTR is not set
+# CONFIG_PKG_USING_TINYFRAME is not set
+# CONFIG_PKG_USING_KENDRYTE_DEMO is not set
+# CONFIG_PKG_USING_DIGITALCTRL is not set
+
+#
+# samples: kernel and components samples
+#
+# CONFIG_PKG_USING_KERNEL_SAMPLES is not set
+# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set
+# CONFIG_PKG_USING_NETWORK_SAMPLES is not set
+# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
+# CONFIG_PKG_USING_HELLO is not set
+# CONFIG_PKG_USING_VI is not set
+# CONFIG_PKG_USING_NNOM is not set
+CONFIG_SOC_VEXPRESS_A9=y
+CONFIG_RT_USING_UART0=y
+CONFIG_RT_USING_UART1=y
+CONFIG_BSP_DRV_EMAC=y
+# CONFIG_BSP_DRV_AUDIO is not set

Diferenças do arquivo suprimidas por serem muito extensas
+ 150 - 0
bsp/qemu-vexpress-a9/.cproject


+ 44 - 0
bsp/qemu-vexpress-a9/.gitignore

@@ -0,0 +1,44 @@
+*.pyc
+*.map
+*.dblite
+*.elf
+*.bin
+*.hex
+*.axf
+*.exe
+*.pdb
+*.idb
+*.ilk
+*.old
+build
+Debug
+documentation/html
+packages/
+*~
+*.o
+*.obj
+*.out
+*.bak
+*.dep
+*.lib
+*.i
+*.d
+.DS_Stor*
+.config 3
+.config 4
+.config 5
+Midea-X1
+*.uimg
+GPATH
+GRTAGS
+GTAGS
+.vscode
+JLinkLog.txt
+JLinkSettings.ini
+DebugConfig/
+RTE/
+settings/
+*.uvguix*
+cconfig.h
+.settings
+drivers/automac.h

+ 54 - 0
bsp/qemu-vexpress-a9/.project

@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>qemu-vexpress-a9</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+			<triggers>clean,full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+			<triggers>full,incremental,</triggers>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.cdt.core.cnature</nature>
+		<nature>org.eclipse.cdt.core.rttnature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+		<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+	</natures>
+	<linkedResources>
+		<link>
+			<name>rt-thread</name>
+			<type>2</type>
+			<locationURI>virtual:/virtual</locationURI>
+		</link>
+		<link>
+			<name>rt-thread/components</name>
+			<type>2</type>
+			<locationURI>$%7BPARENT-2-PROJECT_LOC%7D/components</locationURI>
+		</link>
+		<link>
+			<name>rt-thread/include</name>
+			<type>2</type>
+			<locationURI>$%7BPARENT-2-PROJECT_LOC%7D/include</locationURI>
+		</link>
+		<link>
+			<name>rt-thread/libcpu</name>
+			<type>2</type>
+			<locationURI>$%7BPARENT-2-PROJECT_LOC%7D/libcpu</locationURI>
+		</link>
+		<link>
+			<name>rt-thread/src</name>
+			<type>2</type>
+			<locationURI>$%7BPARENT-2-PROJECT_LOC%7D/src</locationURI>
+		</link>
+	</linkedResources>
+</projectDescription>

+ 28 - 0
bsp/qemu-vexpress-a9/Kconfig

@@ -0,0 +1,28 @@
+mainmenu "RT-Thread Project Configuration"
+
+config BSP_DIR
+    string
+    option env="BSP_ROOT"
+    default "."
+
+config RTT_DIR
+    string
+    option env="RTT_ROOT"
+    default "../.."
+
+config PKGS_DIR
+    string
+    option env="PKGS_ROOT"
+    default "packages"
+
+source "$RTT_DIR/Kconfig"
+source "$PKGS_DIR/Kconfig"
+
+config SOC_VEXPRESS_A9
+    bool
+    select ARCH_ARM_CORTEX_A9
+    select RT_USING_COMPONENTS_INIT
+    select RT_USING_USER_MAIN
+    default y
+
+source "$BSP_DIR/drivers/Kconfig"

+ 105 - 0
bsp/qemu-vexpress-a9/README.md

@@ -0,0 +1,105 @@
+# QEMU/VExpress A9板级支持包说明
+
+## 1. 简介
+
+Versatile Express系统由ARM Ltd提供,作为CortexA9四核处理器的开发环境,硬件由uATX主板和CoreTile Express A9x4子板组成。有关该系统的详细信息,可以访问 [ARM官方页面][1] 。
+
+Versatile Express的核心是一套FPGA的开发环境,Cortex-A芯片基于FPGA上的硬件逻辑,所以本身是不存在这么一款真实芯片。
+
+QEMU/VExpress A9是QEMU模拟器针对ARM VExpress-A9 FPGA开发板进行软件模拟的指令级虚拟机。QEMU/VExpress因为是软件仿真模式,可以配置成多种模式,例如单核Cortex-A9,多核Cortex-A9,以及多核Cortex-A15等。同时也能够模拟出VExpress FPGA开发板上大多数的外设。
+
+这份RT-Thread BSP是针对QEMU/VExpress-A9的一份移植,也并未在真实的VExpress FPGA开发板上运行过,主要是提供给开发者一定的便利,能够使用、验证一定的功能。对于真实FPGA开发板的执行情况,不做任何假设。
+
+当前QEMU/VExpress-A9对应的硬件特性:
+
+| 硬件 | 描述 |
+| -- | -- |
+| CPU | ARM Cortex-A9(单核) |
+| 主频 | NA |
+| Memory | 128MB(0x60000000 - 0x68000000) |
+
+## 2. 编译说明
+
+推荐使用[env工具][2],可以在console下进入到`bsp/qemu-vexpress-a9`目录中,运行以下命令:
+
+    scons
+
+来编译这个板级支持包。如果编译正确无误,会产生rtthread.elf、rtthread.bin文件。在QEMU中一般使用elf方式来运行,所以只需要使用rtthread.elf文件即可。
+
+**注:** RT-Thread/ENV中携带的工具版本是:
+
+    gcc version 5.4.1 20160919 (release) [ARM/embedded-5-branch revision 240496]
+
+如果在Linux下使用,请自行下载[GNU GCC工具链][3]。
+
+## 3. 执行
+
+当要执行编译好的RT-Thread时,在这个bsp目录下已经提供了运行脚本文件:qemu.bat/qemu.sh
+
+这个执行脚本默认把串口输出到stdio(即控制台)上,所以直接执行脚本后就可以输出结果了。
+
+```text
+ \ | /
+- RT -     Thread Operating System
+ / | \     3.0.4 build May  4 2018
+ 2006 - 2018 Copyright by rt-thread team
+SD card capacity 65536 KB
+probe mmcsd block device!
+hello rt-thread
+msh />
+```
+
+## 4. 支持情况
+
+| 驱动 | 支持情况  |  备注  |
+| ------ | ----  | :------:  |
+| UART | 支持 | UART0/1 |
+| SD/MMC | 支持 |  |
+| CLCD | 支持 |  |
+| Key | 支持 |  |
+| Mouse | 支持 |  |
+| EMAC | 支持 |  |
+
+### 4.1 使用VSCode编辑、编译、调试
+
+在qemu-vexpress-a9中已经携带了部分vscode的配置,需要配合着env一起来使用。步骤包括:
+
+先使用env打开console,然后在console中切换都qemu-vexpress-a9 bsp的目录下,
+
+```bash
+scons --target=vsc -s
+```
+
+更新vscode需要用到的C/C++头文件搜索路径信息(不是每次都需要更新,只有在使用了menuconfig重新配置了RT-Thread或更改了rtconfig.h头文件时才需要)
+
+然后在console下输入
+
+```bash
+code .
+```
+
+启动vscode。使用vscode,目前包含如下的一些功能:
+
+* 编译 `Ctrl+Shift+B` - 开启vscode内置终端,调用scons进行编译;如果有编译错误也会侦测问题,双击问题跳到指定代码文件、代码行;
+* 包含执行`qemu`模拟器,`scons -c`进行目标文件清理的任务
+* `F5` 一键开启QEMU调试模式,并断点停留在`main`函数上;(需要更改下qemu-dbg.bat文件,在qemu-system-arm前加入`start`),即
+
+```batch
+@echo off
+if exist sd.bin goto run
+qemu-img create -f raw sd.bin 64M
+
+:run
+start qemu-system-arm -M vexpress-a9 -kernel rtthread.elf -serial stdio -sd sd.bin -S -s
+```
+
+**已知问题** 如果在vscode的目录中额外添加了文件夹,会导致调试不能够启动。
+
+## 5. 联系人信息
+
+维护人:[bernard][4]
+
+  [1]: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.subset.boards.express/index.html
+  [2]: https://www.rt-thread.org/page/download.html
+  [3]: https://launchpad.net/gcc-arm-embedded/5.0/5-2016-q3-update/+download/gcc-arm-none-eabi-5_4-2016q3-20160926-linux.tar.bz2
+  [4]: https://github.com/BernardXiong

+ 14 - 0
bsp/qemu-vexpress-a9/SConscript

@@ -0,0 +1,14 @@
+# for module compiling
+import os
+Import('RTT_ROOT')
+
+cwd = str(Dir('#'))
+objs = []
+list = os.listdir(cwd)
+
+for d in list:
+    path = os.path.join(cwd, d)
+    if os.path.isfile(os.path.join(path, 'SConscript')):
+        objs = objs + SConscript(os.path.join(d, 'SConscript'))
+
+Return('objs')

+ 32 - 0
bsp/qemu-vexpress-a9/SConstruct

@@ -0,0 +1,32 @@
+import os
+import sys
+import rtconfig
+
+if os.getenv('RTT_ROOT'):
+    RTT_ROOT = os.getenv('RTT_ROOT')
+else:
+    RTT_ROOT = os.path.join(os.getcwd(), '..', '..')
+
+sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
+from building import *
+
+TARGET = 'rtthread.' + rtconfig.TARGET_EXT
+
+DefaultEnvironment(tools=[])
+env = Environment(tools = ['mingw'],
+    AS   = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
+    CC   = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS,
+    CXX  = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS,
+    AR   = rtconfig.AR, ARFLAGS = '-rc',
+    LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
+env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
+env['ASCOM'] = env['ASPPCOM']
+
+Export('RTT_ROOT')
+Export('rtconfig')
+
+# prepare building environment
+objs = PrepareBuilding(env, RTT_ROOT)
+
+# make a building
+DoBuilding(TARGET, objs)

+ 11 - 0
bsp/qemu-vexpress-a9/applications/SConscript

@@ -0,0 +1,11 @@
+Import('RTT_ROOT')
+Import('rtconfig')
+from building import *
+
+cwd     = GetCurrentDir()
+src     = Glob('*.c') + Glob('*.cpp')
+CPPPATH = [cwd, str(Dir('#'))]
+
+group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 19 - 0
bsp/qemu-vexpress-a9/applications/lcd_init.c

@@ -0,0 +1,19 @@
+#include <rtthread.h>
+
+#if defined(RT_USING_RTGUI) || defined(PKG_USING_GUIENGINE)
+
+#include <rtgui/driver.h>
+int lcd_init(void)
+{
+    struct rt_device *device;
+    device = rt_device_find("lcd");
+    if (device)
+    {
+        rtgui_graphic_set_device(device);
+    }
+
+    return 0;
+}
+INIT_APP_EXPORT(lcd_init);
+
+#endif

+ 11 - 0
bsp/qemu-vexpress-a9/applications/main.c

@@ -0,0 +1,11 @@
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(void)
+{
+    printf("hello rt-thread\n");
+
+    return 0;
+}
+

+ 19 - 0
bsp/qemu-vexpress-a9/applications/mnt.c

@@ -0,0 +1,19 @@
+#include <rtthread.h>
+
+#ifdef RT_USING_DFS
+#include <dfs_fs.h>
+
+int mnt_init(void)
+{
+    rt_thread_delay(RT_TICK_PER_SECOND);
+
+    if (dfs_mount("sd0", "/", "elm", 0, 0) == 0)
+    {
+        rt_kprintf("file system initialization done!\n");
+    }
+
+    return 0;
+}
+INIT_ENV_EXPORT(mnt_init);
+#endif
+

+ 32 - 0
bsp/qemu-vexpress-a9/drivers/Kconfig

@@ -0,0 +1,32 @@
+config RT_USING_UART0
+    bool "Enable UART0"
+    default n
+
+config RT_USING_UART1
+    bool "Enable UART1"
+    default y
+
+config BSP_DRV_CLCD
+    bool "CLCD driver"
+    depends on PKG_USING_GUIENGINE
+    default y
+
+if BSP_DRV_CLCD
+    config BSP_LCD_WIDTH
+    int "Width of LCD panel"
+    default 640
+
+    config BSP_LCD_HEIGHT
+    int "Height of LCD panel"
+    default 480
+endif
+
+config BSP_DRV_EMAC
+    bool "EMAC driver"
+    depends on RT_USING_LWIP
+    default y
+
+config BSP_DRV_AUDIO
+    bool "Audio driver"
+    select RT_USING_AUDIO
+    default n

+ 23 - 0
bsp/qemu-vexpress-a9/drivers/SConscript

@@ -0,0 +1,23 @@
+from building import *
+
+cwd  = GetCurrentDir()
+src  = Glob('*.c')
+list = os.listdir(cwd)
+CPPPATH = [cwd]
+objs = []
+
+if not GetDepend('BSP_DRV_EMAC'):
+    SrcRemove(src, ['drv_smc911x.c'])
+
+if not GetDepend('BSP_DRV_CLCD'):
+    SrcRemove(src, ['drv_clcd.c'])
+
+group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
+
+for d in list:
+    path = os.path.join(cwd, d)
+    if os.path.isfile(os.path.join(path, 'SConscript')):
+        objs = objs + SConscript(os.path.join(d, 'SConscript'))
+objs = objs + group
+
+Return('objs')

+ 9 - 0
bsp/qemu-vexpress-a9/drivers/audio/SConscript

@@ -0,0 +1,9 @@
+from building import *
+
+cwd = GetCurrentDir()
+src = Glob('*.c') + Glob('*.S')
+CPPPATH = [cwd]
+
+group = DefineGroup('drv_audio', src, depend = ['BSP_DRV_AUDIO'], CPPPATH = CPPPATH)
+
+Return('group')

+ 121 - 0
bsp/qemu-vexpress-a9/drivers/audio/drv_ac97.c

@@ -0,0 +1,121 @@
+/*
+ * File      : drv_ac97.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-05-25     RT-Thread    the first version
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+#include "drv_pl041.h"
+#include "drv_ac97.h"
+
+void ac97_reset(void)
+{
+    aaci_ac97_write(AC97_RESET, 0xFFFF);
+}
+
+rt_err_t ac97_set_vol(int vol)
+{
+    rt_uint16_t tmp = vol | (vol << 8);
+
+    if (vol < 0 || vol > 0x3f)
+    {
+        return -RT_ERROR;
+    }
+
+    aaci_ac97_write(AC97_MASTER, tmp);
+    aaci_ac97_write(AC97_HEADPHONE, tmp);
+    aaci_ac97_write(AC97_MASTER_MONO, tmp);
+    aaci_ac97_write(AC97_PCM, tmp);
+
+    return RT_EOK;
+}
+
+int ac97_get_vol(void)
+{
+    rt_uint16_t v;
+
+    v = aaci_ac97_read(AC97_MASTER);
+    if (v == (~0x0))
+    {
+        v = 0;
+    }
+    return 0x3F & v;
+}
+
+rt_err_t ac97_set_rate(int rate)
+{
+    if (rate < 0)
+    {
+        return -RT_ERROR;
+    }
+    aaci_ac97_write(AC97_PCM_FRONT_DAC_RATE, rate);
+    return 0;
+}
+
+int ac97_get_rate(void)
+{
+    rt_uint16_t v;
+
+    v = aaci_ac97_read(AC97_PCM_FRONT_DAC_RATE);
+    if (v == (~0x0))
+    {
+        v = 0;
+    }
+    return v;
+}
+
+#if 0
+#define AC97_DUMP(_v)    rt_kprintf("%32s:addr:0x%08x data:0x%08x\n", #_v, (_v), (aaci_ac97_read(_v)))
+int _ac97_reg_dump(int argc, char **argv)
+{
+    AC97_DUMP(AC97_RESET);
+    AC97_DUMP(AC97_MASTER);
+    AC97_DUMP(AC97_HEADPHONE);
+    AC97_DUMP(AC97_MASTER_MONO);
+    AC97_DUMP(AC97_MASTER_TONE);
+    AC97_DUMP(AC97_PC_BEEP);
+    AC97_DUMP(AC97_PHONE);
+    AC97_DUMP(AC97_MIC);
+    AC97_DUMP(AC97_LINE);
+    AC97_DUMP(AC97_CD);
+    AC97_DUMP(AC97_VIDEO);
+    AC97_DUMP(AC97_AUX);
+    AC97_DUMP(AC97_PCM);
+    AC97_DUMP(AC97_REC_SEL);
+    AC97_DUMP(AC97_REC_GAIN);
+    AC97_DUMP(AC97_REC_GAIN_MIC);
+    AC97_DUMP(AC97_GENERAL_PURPOSE);
+    AC97_DUMP(AC97_3D_CONTROL);
+    AC97_DUMP(AC97_INT_PAGING);
+    AC97_DUMP(AC97_POWERDOWN);
+    AC97_DUMP(AC97_PCM_FRONT_DAC_RATE);
+    AC97_DUMP(AC97_PCM_SURR_DAC_RATE);
+    AC97_DUMP(AC97_PCM_LFE_DAC_RATE);
+    AC97_DUMP(AC97_PCM_LR_ADC_RATE);
+    AC97_DUMP(AC97_PCM_MIC_ADC_RATE);
+    AC97_DUMP(AC97_DAC_SLOT_MAP);
+    AC97_DUMP(AC97_ADC_SLOT_MAP);
+    return 0;
+}
+FINSH_FUNCTION_EXPORT_ALIAS(_ac97_reg_dump, __cmd_ac97_dump, ac97 dump reg.);
+
+#endif

+ 63 - 0
bsp/qemu-vexpress-a9/drivers/audio/drv_ac97.h

@@ -0,0 +1,63 @@
+/*
+ * File      : drv_ac97.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-05-25     RT-Thread    the first version
+ */
+
+#ifndef __DRV_AC97_H__
+#define __DRV_AC97_H__
+
+/* Register offsets */
+#define AC97_RESET				0x00
+#define AC97_MASTER				0x02
+#define AC97_HEADPHONE			0x04
+#define AC97_MASTER_MONO		0x06
+#define AC97_MASTER_TONE		0x08
+#define AC97_PC_BEEP			0x0A    //mixer volume
+#define AC97_PHONE				0x0C
+#define AC97_MIC				0x0E    //qwert db
+#define AC97_LINE				0x10		
+#define AC97_CD					0x12
+#define AC97_VIDEO				0x14
+#define AC97_AUX				0x16
+#define AC97_PCM				0x18
+#define AC97_REC_SEL			0x1A	//0 represent mic
+#define AC97_REC_GAIN			0x1C
+#define AC97_REC_GAIN_MIC		0x1E
+#define AC97_GENERAL_PURPOSE	0x20
+#define AC97_3D_CONTROL			0x22
+#define AC97_INT_PAGING			0x24    //qwert
+#define AC97_POWERDOWN			0x26
+#define AC97_PCM_FRONT_DAC_RATE 0x2c	/* PCM Front DAC Rate */
+#define AC97_PCM_SURR_DAC_RATE	0x2e	/* PCM Surround DAC Rate */
+#define AC97_PCM_LFE_DAC_RATE	0x30	/* PCM LFE DAC Rate */
+#define AC97_PCM_LR_ADC_RATE	0x32	/* PCM LR ADC Rate */
+#define AC97_PCM_MIC_ADC_RATE	0x34	/* PCM MIC ADC Rate */
+#define AC97_DAC_SLOT_MAP		0x6C
+#define AC97_ADC_SLOT_MAP		0x6E
+
+void ac97_reset(void);
+rt_err_t ac97_set_vol(int vol);
+int ac97_get_vol(void);
+rt_err_t ac97_set_rate(int rate);
+int ac97_get_rate(void);
+
+#endif

+ 409 - 0
bsp/qemu-vexpress-a9/drivers/audio/drv_pl041.c

@@ -0,0 +1,409 @@
+/*
+ * File      : drv_pl041.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-05-25     RT-Thread    the first version
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+#include "drv_pl041.h"
+#include "drv_ac97.h"
+#include "realview.h"
+
+#define DBG_TAG  "PL041"
+// #define DBG_LVL         DBG_LOG
+// #define DBG_LVL         DBG_INFO
+#define DBG_LVL  DBG_WARNING
+// #define DBG_LVL         DBG_ERROR
+#include <rtdbg.h>
+
+#define FRAME_PERIOD_US    (50)
+#define PL041_CHANNLE_NUM  (4)
+
+#define PL041_READ(_a)        (*(volatile rt_uint32_t *)(_a))
+#define PL041_WRITE(_a, _v)   (*(volatile rt_uint32_t *)(_a) = (_v))
+
+struct pl041_irq_def
+{
+    pl041_irq_fun_t fun;
+    void *user_data;
+};
+
+static struct pl041_irq_def irq_tbl[PL041_CHANNLE_NUM];
+
+static void aaci_pl041_delay(rt_uint32_t us)
+{
+    volatile int i;
+
+    for (i = us * 10; i != 0; i--);
+}
+
+static void aaci_ac97_select_codec(void)
+{
+    rt_uint32_t v, maincr;
+
+    maincr = AACI_MAINCR_SCRA(0) | AACI_MAINCR_IE | AACI_MAINCR_SL1RXEN | \
+             AACI_MAINCR_SL1TXEN | AACI_MAINCR_SL2RXEN | AACI_MAINCR_SL2TXEN;
+
+    v = PL041_READ(&PL041->slfr);
+    if (v & AACI_SLFR_2RXV)
+    {
+        PL041_READ(&PL041->sl2rx);
+    }
+    if (v & AACI_SLFR_1RXV)
+    {
+        PL041_READ(&PL041->sl1rx);
+    }
+
+    if (maincr != PL041_READ(&PL041->maincr))
+    {
+        PL041_WRITE(&PL041->maincr, maincr);
+        aaci_pl041_delay(1);
+    }
+}
+
+void aaci_ac97_write(rt_uint16_t reg, rt_uint16_t val)
+{
+    rt_uint32_t v, timeout;
+
+    aaci_ac97_select_codec();
+
+    PL041_WRITE(&PL041->sl2tx, val << 4);
+    PL041_WRITE(&PL041->sl1tx, reg << 12);
+
+    aaci_pl041_delay(FRAME_PERIOD_US);
+
+    timeout = FRAME_PERIOD_US * 8;
+    do
+    {
+        aaci_pl041_delay(1);
+        v = PL041_READ(&PL041->slfr);
+    }
+    while ((v & (AACI_SLFR_1TXB | AACI_SLFR_2TXB)) && --timeout);
+
+    if (v & (AACI_SLFR_1TXB | AACI_SLFR_2TXB))
+    {
+        LOG_E("timeout waiting for write to complete");
+    }
+}
+
+rt_uint16_t aaci_ac97_read(rt_uint16_t reg)
+{
+    rt_uint32_t v, timeout, retries = 10;
+
+    aaci_ac97_select_codec();
+
+    PL041_WRITE(&PL041->sl1tx, (reg << 12) | (1 << 19));
+    aaci_pl041_delay(FRAME_PERIOD_US);
+
+    timeout = FRAME_PERIOD_US * 8;
+    do
+    {
+        aaci_pl041_delay(1);
+        v = PL041_READ(&PL041->slfr);
+    }
+    while ((v & AACI_SLFR_1TXB) && --timeout);
+
+    if (v & AACI_SLFR_1TXB)
+    {
+        LOG_E("timeout on slot 1 TX busy");
+        v = ~0x0;
+        return v;
+    }
+
+    aaci_pl041_delay(FRAME_PERIOD_US);
+    timeout = FRAME_PERIOD_US * 8;
+    do
+    {
+        aaci_pl041_delay(1);
+        v = PL041_READ(&PL041->slfr) & (AACI_SLFR_1RXV | AACI_SLFR_2RXV);
+    }
+    while ((v != (AACI_SLFR_1RXV | AACI_SLFR_2RXV)) && --timeout);
+
+    if (v != (AACI_SLFR_1RXV | AACI_SLFR_2RXV))
+    {
+        LOG_E("timeout on RX valid");
+        v = ~0x0;
+        return v;
+    }
+
+    do
+    {
+        v = PL041_READ(&PL041->sl1rx) >> 12;
+        if (v == reg)
+        {
+            v = PL041_READ(&PL041->sl2rx) >> 4;
+            break;
+        }
+        else if (--retries)
+        {
+            LOG_E("ac97 read back fail. retry");
+            continue;
+        }
+        else
+        {
+            LOG_E("wrong ac97 register read back (%x != %x)", v, reg);
+            v = ~0x0;
+        }
+    }
+    while (retries);
+
+    return v;
+}
+
+int aaci_pl041_channle_disable(int channle)
+{
+    rt_uint32_t v;
+    void *p_rx, *p_tx;
+
+    p_rx = (void *)((rt_uint32_t)(&PL041->rxcr1) + channle * 0x14);
+    p_tx = (void *)((rt_uint32_t)(&PL041->txcr1) + channle * 0x14);
+    v = PL041_READ(p_rx);
+    v &= ~AACI_CR_EN;
+    PL041_WRITE(p_rx, v);
+    v = PL041_READ(p_tx);
+    v &= ~AACI_CR_EN;
+    PL041_WRITE(p_tx, v);
+    return 0;
+}
+
+int aaci_pl041_channle_enable(int channle)
+{
+    rt_uint32_t v;
+    void *p_rx, *p_tx;
+
+    p_rx = (void *)((rt_uint32_t)(&PL041->rxcr1) + channle * 0x14);
+    p_tx = (void *)((rt_uint32_t)(&PL041->txcr1) + channle * 0x14);
+    v = PL041_READ(p_rx);
+    v |= AACI_CR_EN;
+    PL041_WRITE(p_rx, v);
+    v = PL041_READ(p_tx);
+    v |= AACI_CR_EN;
+    PL041_WRITE(p_tx, v);
+    return 0;
+}
+
+int aaci_pl041_channle_read(int channle, rt_uint16_t *buff, int count)
+{
+    void *p_data, *p_status;
+    int i = 0;
+
+    p_status = (void *)((rt_uint32_t)(&PL041->sr1) + channle * 0x14);
+    p_data = (void *)((rt_uint32_t)(&(PL041->dr1[0])) + channle * 0x20);
+    for (i = 0; (!(PL041_READ(p_status) & AACI_SR_RXFE)) && (i < count); i++)
+    {
+        buff[i] = (rt_uint16_t)PL041_READ(p_data);
+    }
+    return i;
+}
+
+int aaci_pl041_channle_write(int channle, rt_uint16_t *buff, int count)
+{
+    void *p_data, *p_status;
+    int i = 0;
+
+    p_status = (void *)((rt_uint32_t)(&PL041->sr1) + channle * 0x14);
+    p_data = (void *)((rt_uint32_t)(&(PL041->dr1[0])) + channle * 0x20);
+    for (i = 0; (!(PL041_READ(p_status) & AACI_SR_TXFF)) && (i < count); i++)
+    {
+        PL041_WRITE(p_data, buff[i]);
+    }
+    return i;
+}
+
+int aaci_pl041_channle_cfg(int channle, pl041_cfg_t cgf)
+{
+    rt_uint32_t v;
+    void *p_rx, *p_tx;
+
+    p_rx = (void *)((rt_uint32_t)(&PL041->rxcr1) + channle * 0x14);
+    p_tx = (void *)((rt_uint32_t)(&PL041->txcr1) + channle * 0x14);
+    v = AACI_CR_FEN | AACI_CR_SZ16 | cgf->itype;
+    PL041_WRITE(p_rx, v);
+    v = AACI_CR_FEN | AACI_CR_SZ16 | cgf->otype;
+    PL041_WRITE(p_tx, v);
+
+    ac97_set_vol(cgf->vol);
+    ac97_set_rate(cgf->rate);
+
+    return 0;
+}
+
+void aaci_pl041_irq_enable(int channle, rt_uint32_t vector)
+{
+    rt_uint32_t v;
+    void *p_irq;
+
+    vector &= vector & 0x7f;
+    p_irq = (void *)((rt_uint32_t)(&PL041->iie1) + channle * 0x14);
+    v = PL041_READ(p_irq);
+    v |= vector;
+    PL041_WRITE(p_irq, v);
+}
+
+void aaci_pl041_irq_disable(int channle, rt_uint32_t vector)
+{
+    rt_uint32_t v;
+    void *p_irq;
+
+    vector &= vector & 0x7f;
+    p_irq = (void *)((rt_uint32_t)(&PL041->iie1) + channle * 0x14);
+    v = PL041_READ(p_irq);
+    v &= ~vector;
+    PL041_WRITE(p_irq, v);
+}
+
+rt_err_t aaci_pl041_irq_register(int channle, pl041_irq_fun_t fun, void *user_data)
+{
+    if (channle < 0 || channle >= PL041_CHANNLE_NUM)
+    {
+        LOG_E("%s channle:%d err.", __FUNCTION__, channle);
+        return -RT_ERROR;
+    }
+    irq_tbl[channle].fun = fun;
+    irq_tbl[channle].user_data = user_data;
+    return RT_EOK;
+}
+
+rt_err_t aaci_pl041_irq_unregister(int channle)
+{
+    if (channle < 0 || channle >= PL041_CHANNLE_NUM)
+    {
+        LOG_E("%s channle:%d err.", __FUNCTION__, channle);
+        return -RT_ERROR;
+    }
+    irq_tbl[channle].fun = RT_NULL;
+    irq_tbl[channle].user_data = RT_NULL;
+    return RT_EOK;
+}
+
+static void aaci_pl041_irq_handle(int irqno, void *param)
+{
+    rt_uint32_t mask, channle, m;
+    struct pl041_irq_def *_irq = param;
+    void *p_status;
+
+    mask = PL041_READ(&PL041->allints);
+    PL041_WRITE(&PL041->intclr, mask);
+
+    for (channle = 0; (channle < PL041_CHANNLE_NUM) && (mask); channle++)
+    {
+        mask = mask >> 7;
+        m = mask & 0x7f;
+        if (m & AACI_ISR_ORINTR)
+        {
+            LOG_W("RX overrun on chan %d", channle);
+        }
+
+        if (m & AACI_ISR_RXTOINTR)
+        {
+            LOG_W("RX timeout on chan %d", channle);
+        }
+
+        if (mask & AACI_ISR_URINTR)
+        {
+            LOG_W("TX underrun on chan %d", channle);
+        }
+
+        p_status = (void *)((rt_uint32_t)(&PL041->sr1) + channle * 0x14);
+        if (_irq[channle].fun != RT_NULL)
+        {
+            _irq[channle].fun(PL041_READ(p_status), _irq[channle].user_data);
+        }
+    }
+}
+
+rt_err_t aaci_pl041_init(void)
+{
+    rt_uint32_t i, maincr;
+
+    maincr  = AACI_MAINCR_SCRA(0) | AACI_MAINCR_IE | AACI_MAINCR_SL1RXEN | \
+              AACI_MAINCR_SL1TXEN | AACI_MAINCR_SL2RXEN | AACI_MAINCR_SL2TXEN;
+
+    for (i = 0; i < 4; i++)
+    {
+        void *base = (void *)((rt_uint32_t)(&PL041->rxcr1) + i * 0x14);
+
+        PL041_WRITE(base + AACI_IE, 0);
+        PL041_WRITE(base + AACI_TXCR, 0);
+        PL041_WRITE(base + AACI_RXCR, 0);
+    }
+
+    PL041_WRITE(&PL041->intclr, 0x1fff);
+    PL041_WRITE(&PL041->maincr, maincr);
+
+    PL041_WRITE(&PL041->reset, 0);
+    aaci_pl041_delay(2);
+    PL041_WRITE(&PL041->reset, RESET_NRST);
+
+    rt_hw_interrupt_install(43, aaci_pl041_irq_handle, &irq_tbl, "aaci_pl041");
+    rt_hw_interrupt_umask(43);
+
+    return 0;
+}
+
+#if 0
+#define PL041_DUMP(_v)    rt_kprintf("%32s:addr:0x%08x data:0x%08x\n", #_v, &(_v), (_v))
+int _aaci_pl041_reg_dump(int argc, char **argv)
+{
+    PL041_DUMP(PL041->rxcr1);
+    PL041_DUMP(PL041->txcr1);
+    PL041_DUMP(PL041->sr1);
+    PL041_DUMP(PL041->isr1);
+    PL041_DUMP(PL041->iie1);
+    PL041_DUMP(PL041->rxcr2);
+    PL041_DUMP(PL041->txcr2);
+    PL041_DUMP(PL041->sr2);
+    PL041_DUMP(PL041->isr2);
+    PL041_DUMP(PL041->iie2);
+    PL041_DUMP(PL041->rxcr3);
+    PL041_DUMP(PL041->txcr3);
+    PL041_DUMP(PL041->sr3);
+    PL041_DUMP(PL041->isr3);
+    PL041_DUMP(PL041->iie3);
+    PL041_DUMP(PL041->rxcr4);
+    PL041_DUMP(PL041->txcr4);
+    PL041_DUMP(PL041->sr4);
+    PL041_DUMP(PL041->isr4);
+    PL041_DUMP(PL041->iie4);
+    PL041_DUMP(PL041->sl1rx);
+    PL041_DUMP(PL041->sl1tx);
+    PL041_DUMP(PL041->sl2rx);
+    PL041_DUMP(PL041->sl2tx);
+    PL041_DUMP(PL041->sl12rx);
+    PL041_DUMP(PL041->sl12tx);
+    PL041_DUMP(PL041->slfr);
+    PL041_DUMP(PL041->slistat);
+    PL041_DUMP(PL041->slien);
+    PL041_DUMP(PL041->intclr);
+    PL041_DUMP(PL041->maincr);
+    PL041_DUMP(PL041->reset);
+    PL041_DUMP(PL041->sync);
+    PL041_DUMP(PL041->allints);
+    PL041_DUMP(PL041->mainfr);
+    PL041_DUMP(PL041->dr1[0]);
+    PL041_DUMP(PL041->dr2[0]);
+    PL041_DUMP(PL041->dr3[0]);
+    PL041_DUMP(PL041->dr4[0]);
+    return 0;
+}
+FINSH_FUNCTION_EXPORT_ALIAS(_aaci_pl041_reg_dump, __cmd_pl041_dump, aaci pl041 dump reg.);
+#endif

+ 237 - 0
bsp/qemu-vexpress-a9/drivers/audio/drv_pl041.h

@@ -0,0 +1,237 @@
+/*
+ * File      : drv_pl041.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2017, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-05-25     RT-Thread    the first version
+ */
+
+#ifndef __DRV_PL041_H__
+#define __DRV_PL041_H__
+
+#define PL041_BASE_ADDR    (0x10004000)
+
+/* offsets in CTRL_CH */
+#define AACI_RXCR        0x00	/* 29 bits Control Rx FIFO */
+#define AACI_TXCR        0x04	/* 17 bits Control Tx FIFO */
+#define AACI_SR          0x08	/* 12 bits Status */
+#define AACI_ISR         0x0C	/* 7 bits  Int Status */
+#define AACI_IE          0x10	/* 7 bits  Int Enable */
+
+/* both for AACI_RXCR and AACI_TXCR */
+#define AACI_CR_FEN           (1 << 16)  /* fifo enable */
+#define AACI_CR_COMPACT       (1 << 15)  /* compact mode */
+#define AACI_CR_SZ16          (0 << 13)  /* 16 bits */
+#define AACI_CR_SZ18          (1 << 13)  /* 18 bits */
+#define AACI_CR_SZ20          (2 << 13)  /* 20 bits */
+#define AACI_CR_SZ12          (3 << 13)  /* 12 bits */
+#define AACI_CR_SL12          (1 << 12)
+#define AACI_CR_SL11          (1 << 11)
+#define AACI_CR_SL10          (1 << 10)
+#define AACI_CR_SL9           (1 << 9)
+#define AACI_CR_SL8           (1 << 8)
+#define AACI_CR_SL7           (1 << 7)
+#define AACI_CR_SL6           (1 << 6)
+#define AACI_CR_SL5           (1 << 5)
+#define AACI_CR_SL4           (1 << 4)
+#define AACI_CR_SL3           (1 << 3)
+#define AACI_CR_SL2           (1 << 2)
+#define AACI_CR_SL1           (1 << 1)
+#define AACI_CR_EN            (1 << 0)	/* receive enable */
+
+/* status register bits */
+#define AACI_SR_RXTOFE        (1 << 11)  /* rx timeout fifo empty */
+#define AACI_SR_TXTO          (1 << 10)  /* rx timeout fifo nonempty */
+#define AACI_SR_TXU           (1 << 9)   /* tx underrun */
+#define AACI_SR_RXO           (1 << 8)   /* rx overrun */
+#define AACI_SR_TXB           (1 << 7)   /* tx busy */
+#define AACI_SR_RXB           (1 << 6)   /* rx busy */
+#define AACI_SR_TXFF          (1 << 5)   /* tx fifo full */
+#define AACI_SR_RXFF          (1 << 4)   /* rx fifo full */
+#define AACI_SR_TXHE          (1 << 3)   /* tx fifo half empty */
+#define AACI_SR_RXHF          (1 << 2)   /* rx fifo half full */
+#define AACI_SR_TXFE          (1 << 1)   /* tx fifo empty */
+#define AACI_SR_RXFE          (1 << 0)   /* rx fifo empty */
+
+#define AACI_ISR_RXTOFEINTR   (1 << 6)    /* rx fifo empty */
+#define AACI_ISR_URINTR       (1 << 5)    /* tx underflow */
+#define AACI_ISR_ORINTR       (1 << 4)    /* rx overflow */
+#define AACI_ISR_RXINTR       (1 << 3)    /* rx fifo */
+#define AACI_ISR_TXINTR       (1 << 2)    /* tx fifo intr */
+#define AACI_ISR_RXTOINTR     (1 << 1)    /* rx timeout */
+#define AACI_ISR_TXCINTR      (1 << 0)    /* tx complete */
+
+/* interrupt enable */
+#define AACI_IE_RXTOIE        (1 << 6)   /*rx timeout interrupt enable*/
+#define AACI_IE_URIE          (1 << 5)   /*Transmit underrun interrupt enable*/
+#define AACI_IE_ORIE          (1 << 4)	 /*Overrun receive interrupt enable*/
+#define AACI_IE_RXIE          (1 << 3)   /*Receive interrupt enable*/
+#define AACI_IE_TXIE          (1 << 2)   /*Transmit interrupt enable*/
+#define AACI_IE_RXTIE         (1 << 1)   /*Receive timeout interrupt enable*/
+#define AACI_IE_TXCIE         (1 << 0)	 /*Transmit complete interrupt enable*/
+
+/* interrupt status */
+#define AACI_ISR_RXTOFE	(1 << 6)	/* rx timeout fifo empty */
+#define AACI_ISR_UR		(1 << 5)	/* tx fifo underrun */
+#define AACI_ISR_OR		(1 << 4)	/* rx fifo overrun */
+#define AACI_ISR_RX		(1 << 3)	/* rx interrupt status */
+#define AACI_ISR_TX		(1 << 2)	/* tx interrupt status */
+#define AACI_ISR_RXTO	(1 << 1)	/* rx timeout */
+#define AACI_ISR_TXC	(1 << 0)	/* tx complete */
+
+/* interrupt enable */
+#define AACI_IE_RXTOFE	(1 << 6)	/* rx timeout fifo empty */
+#define AACI_IE_UR		(1 << 5)	/* tx fifo underrun */
+#define AACI_IE_OR		(1 << 4)	/* rx fifo overrun */
+#define AACI_IE_RX		(1 << 3)	/* rx interrupt status */
+#define AACI_IE_TX		(1 << 2)	/* tx interrupt status */
+#define AACI_IE_RXTO	(1 << 1)	/* rx timeout */
+#define AACI_IE_TXC		(1 << 0)	/* tx complete */
+
+/* slot flag register bits */
+#define AACI_SLFR_RWIS        (1 << 13)    /* raw wake-up interrupt status */
+#define AACI_SLFR_RGPIOINTR   (1 << 12)    /* raw gpio interrupt */
+#define AACI_SLFR_12TXE       (1 << 11)    /* slot 12 tx empty */
+#define AACI_SLFR_12RXV       (1 << 10)    /* slot 12 rx valid */
+#define AACI_SLFR_2TXE        (1 << 9)     /* slot 2 tx empty */
+#define AACI_SLFR_2RXV        (1 << 8)     /* slot 2 rx valid */
+#define AACI_SLFR_1TXE        (1 << 7)     /* slot 1 tx empty */
+#define AACI_SLFR_1RXV        (1 << 6)     /* slot 1 rx valid */
+#define AACI_SLFR_12TXB       (1 << 5)     /* slot 12 tx busy */
+#define AACI_SLFR_12RXB       (1 << 4)     /* slot 12 rx busy */
+#define AACI_SLFR_2TXB        (1 << 3)     /* slot 2 tx busy */
+#define AACI_SLFR_2RXB        (1 << 2)     /* slot 2 rx busy */
+#define AACI_SLFR_1TXB        (1 << 1)     /* slot 1 tx busy */
+#define AACI_SLFR_1RXB        (1 << 0)     /* slot 1 rx busy */
+
+/* Interrupt clear register */
+#define AACI_ICLR_RXTOFEC4    (1 << 12)      /* Receive timeout FIFO empty clear */
+#define AACI_ICLR_RXTOFEC3    (1 << 11)      /* Receive timeout FIFO empty clear */
+#define AACI_ICLR_RXTOFEC2    (1 << 10)      /* Receive timeout FIFO empty clear */
+#define AACI_ICLR_RXTOFEC1    (1 << 9)       /* Receive timeout FIFO empty clear */
+#define AACI_ICLR_TXUEC4      (1 << 8)       /* Transmit underrun error clear */
+#define AACI_ICLR_TXUEC3      (1 << 7)       /* Transmit underrun error clear */
+#define AACI_ICLR_TXUEC2      (1 << 6)       /* Transmit underrun error clear*/
+#define AACI_ICLR_TXUEC1      (1 << 5)       /* Transmit underrun error clear */
+#define AACI_ICLR_RXOEC4      (1 << 4)       /* Receive overrun error clear */
+#define AACI_ICLR_RXOEC3      (1 << 3)       /* Receive overrun error clear */
+#define AACI_ICLR_RXOEC2      (1 << 2)       /* Receive overrun error clear */
+#define AACI_ICLR_RXOEC1      (1 << 1)       /* Receive overrun error clear */
+#define AACI_ICLR_WISC        (1 << 0)       /* Wake-up interrupt status clear */
+                                
+/* Main control register bits AACI_MAINCR */
+#define AACI_MAINCR_SCRA(x)   ((x) << 10)     /* secondary codec reg access */
+#define AACI_MAINCR_DMAEN     (1 << 9)        /* dma enable */
+#define AACI_MAINCR_SL12TXEN  (1 << 8)        /* slot 12 transmit enable */
+#define AACI_MAINCR_SL12RXEN  (1 << 7)        /* slot 12 receive enable */
+#define AACI_MAINCR_SL2TXEN   (1 << 6)        /* slot 2 transmit enable */
+#define AACI_MAINCR_SL2RXEN   (1 << 5)        /* slot 2 receive enable */
+#define AACI_MAINCR_SL1TXEN   (1 << 4)        /* slot 1 transmit enable */
+#define AACI_MAINCR_SL1RXEN   (1 << 3)        /* slot 1 receive enable */
+#define AACI_MAINCR_LPM       (1 << 2)        /* low power mode */
+#define AACI_MAINCR_LOOPBK    (1 << 1)        /* loopback */
+#define AACI_MAINCR_IE        (1 << 0)        /* aaci interface enable */
+
+/* Reset register bits. P65 */
+#define RESET_NRST   (1 << 0)
+
+/* Sync register bits. P65 */
+#define SYNC_FORCE   (1 << 0)
+
+/* Main flag register bits. P66 */
+#define MAINFR_TXB   (1 << 1)	/* transmit busy */
+#define MAINFR_RXB   (1 << 0)	/* receive busy */
+
+#define PL041_CHANNLE_LEFT_DAC    (0x1 << 3)
+#define PL041_CHANNLE_RIGHT_DAC   (0x1 << 3)
+#define PL041_CHANNLE_LEFT_ADC    (0x1 << 3)
+#define PL041_CHANNLE_RIGHT_ADC   (0x1 << 3)
+
+struct reg_pl041
+{
+volatile rt_uint32_t  rxcr1;    /* 0x000 */
+volatile rt_uint32_t  txcr1;    /* 0x004 */
+volatile rt_uint32_t  sr1;      /* 0x008 */
+volatile rt_uint32_t  isr1;     /* 0x00c */
+volatile rt_uint32_t  iie1;     /* 0x010 */
+volatile rt_uint32_t  rxcr2;    /* 0x014 */
+volatile rt_uint32_t  txcr2;    /* 0x018 */
+volatile rt_uint32_t  sr2;      /* 0x01c */
+volatile rt_uint32_t  isr2;     /* 0x020 */
+volatile rt_uint32_t  iie2;     /* 0x024 */
+volatile rt_uint32_t  rxcr3;    /* 0x028 */
+volatile rt_uint32_t  txcr3;    /* 0x02c */
+volatile rt_uint32_t  sr3;      /* 0x030 */
+volatile rt_uint32_t  isr3;     /* 0x034 */
+volatile rt_uint32_t  iie3;     /* 0x038 */
+volatile rt_uint32_t  rxcr4;    /* 0x03c */
+volatile rt_uint32_t  txcr4;    /* 0x040 */
+volatile rt_uint32_t  sr4;      /* 0x044 */
+volatile rt_uint32_t  isr4;     /* 0x048 */
+volatile rt_uint32_t  iie4;     /* 0x04c */
+volatile rt_uint32_t  sl1rx;    /* 0x050 */
+volatile rt_uint32_t  sl1tx;    /* 0x054 */
+volatile rt_uint32_t  sl2rx;    /* 0x058 */
+volatile rt_uint32_t  sl2tx;    /* 0x05c */
+volatile rt_uint32_t  sl12rx;   /* 0x060 */
+volatile rt_uint32_t  sl12tx;   /* 0x064 */
+volatile rt_uint32_t  slfr;     /* 0x068 */
+volatile rt_uint32_t  slistat;  /* 0x06c */
+volatile rt_uint32_t  slien;    /* 0x070 */
+volatile rt_uint32_t  intclr;   /* 0x074 */
+volatile rt_uint32_t  maincr;   /* 0x078 */
+volatile rt_uint32_t  reset;    /* 0x07c */
+volatile rt_uint32_t  sync;     /* 0x080 */
+volatile rt_uint32_t  allints;  /* 0x084 */
+volatile rt_uint32_t  mainfr;   /* 0x088 */
+volatile rt_uint32_t  res08c;
+volatile rt_uint32_t  dr1[8];   /* 0x090 */
+volatile rt_uint32_t  dr2[8];   /* 0x0b0 */
+volatile rt_uint32_t  dr3[8];   /* 0x0d0 */
+volatile rt_uint32_t  dr4[8];   /* 0x0f0 */
+};
+
+typedef struct reg_pl041 *reg_pl041_t;
+
+#define PL041  ((reg_pl041_t)PL041_BASE_ADDR)
+
+struct pl041_cfg
+{
+    rt_uint32_t itype;
+    rt_uint32_t otype;
+    int vol;
+    int rate;
+};
+typedef struct pl041_cfg *pl041_cfg_t;
+
+typedef void (*pl041_irq_fun_t)(rt_uint32_t status, void * user_data);
+
+rt_err_t aaci_pl041_init(void);
+void aaci_ac97_write(rt_uint16_t reg, rt_uint16_t val);
+rt_uint16_t aaci_ac97_read(rt_uint16_t reg);
+int aaci_pl041_channle_cfg(int channle, pl041_cfg_t cfg);
+int aaci_pl041_channle_write(int channle, rt_uint16_t *buff, int count);
+int aaci_pl041_channle_read(int channle, rt_uint16_t *buff, int count);
+int aaci_pl041_channle_enable(int channle);
+int aaci_pl041_channle_disable(int channle);
+rt_err_t aaci_pl041_irq_register(int channle, pl041_irq_fun_t fun, void *user_data);
+rt_err_t aaci_pl041_irq_unregister(int channle);
+void aaci_pl041_irq_disable(int channle, rt_uint32_t vector);
+void aaci_pl041_irq_enable(int channle, rt_uint32_t vector);
+#endif

+ 342 - 0
bsp/qemu-vexpress-a9/drivers/audio/drv_sound.c

@@ -0,0 +1,342 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ * 
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Date           Author       Notes
+ * 2019-07-23     Zero-Free    first implementation
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#include <drv_sound.h>
+#include <drv_pl041.h>
+#include <drv_ac97.h>
+
+#define DBG_TAG              "drv.sound"
+#define DBG_LVL              DBG_INFO
+#include <rtdbg.h>
+
+#define TX_FIFO_SIZE         (3840)
+
+struct sound_device
+{
+    struct rt_audio_device audio;
+    struct rt_audio_configure replay_config;
+    rt_uint8_t *tx_fifo;
+    rt_uint8_t volume;
+};
+
+static struct sound_device snd_dev = {0};
+
+static void rt_hw_aaci_isr(rt_uint32_t status, void *user_data)
+{
+    if (status & AACI_SR_TXHE)
+    {
+        rt_audio_tx_complete(&snd_dev.audio);
+    }
+}
+
+static rt_err_t sound_getcaps(struct rt_audio_device *audio, struct rt_audio_caps *caps)
+{
+    rt_err_t result = RT_EOK;
+    struct sound_device *snd_dev;
+
+    RT_ASSERT(audio != RT_NULL);
+    snd_dev = (struct sound_device *)audio->parent.user_data;
+
+    switch (caps->main_type)
+    {
+    case AUDIO_TYPE_QUERY: /* qurey the types of hw_codec device */
+    {
+        switch (caps->sub_type)
+        {
+        case AUDIO_TYPE_QUERY:
+            caps->udata.mask = AUDIO_TYPE_OUTPUT | AUDIO_TYPE_MIXER;
+            break;
+
+        default:
+            result = -RT_ERROR;
+            break;
+        }
+
+        break;
+    }
+
+    case AUDIO_TYPE_OUTPUT: /* Provide capabilities of OUTPUT unit */
+    {
+        switch (caps->sub_type)
+        {
+        case AUDIO_DSP_PARAM:
+            caps->udata.config.samplerate   = snd_dev->replay_config.samplerate;
+            caps->udata.config.channels     = snd_dev->replay_config.channels;
+            caps->udata.config.samplebits   = snd_dev->replay_config.samplebits;
+            break;
+
+        case AUDIO_DSP_SAMPLERATE:
+            caps->udata.config.samplerate   = snd_dev->replay_config.samplerate;
+            break;
+
+        case AUDIO_DSP_CHANNELS:
+            caps->udata.config.channels     = snd_dev->replay_config.channels;
+            break;
+
+        case AUDIO_DSP_SAMPLEBITS:
+            caps->udata.config.samplebits   = snd_dev->replay_config.samplebits;
+            break;
+
+        default:
+            result = -RT_ERROR;
+            break;
+        }
+
+        break;
+    }
+
+    case AUDIO_TYPE_MIXER: /* report the Mixer Units */
+    {
+        switch (caps->sub_type)
+        {
+        case AUDIO_MIXER_QUERY:
+            caps->udata.mask = AUDIO_MIXER_VOLUME;
+            break;
+
+        case AUDIO_MIXER_VOLUME:
+            caps->udata.value = snd_dev->volume;
+            break;
+
+        default:
+            result = -RT_ERROR;
+            break;
+        }
+
+        break;
+    }
+
+    default:
+        result = -RT_ERROR;
+        break;
+    }
+
+    return result;
+}
+
+static rt_err_t sound_configure(struct rt_audio_device *audio, struct rt_audio_caps *caps)
+{
+    rt_err_t result = RT_EOK;
+    struct sound_device *snd_dev;
+    struct rt_audio_replay *replay;
+
+    RT_ASSERT(audio != RT_NULL);
+    snd_dev = (struct sound_device *)audio->parent.user_data;
+
+    switch (caps->main_type)
+    {
+    case AUDIO_TYPE_MIXER:
+    {
+        switch (caps->sub_type)
+        {
+        case AUDIO_MIXER_VOLUME:
+        {
+            rt_uint8_t volume = caps->udata.value;
+
+            snd_dev->volume = volume;
+            ac97_set_vol(volume);
+            LOG_I("set volume %d", volume);
+            break;
+        }
+
+        default:
+            result = -RT_ERROR;
+            break;
+        }
+
+        break;
+    }
+
+    case AUDIO_TYPE_OUTPUT:
+    {
+        switch (caps->sub_type)
+        {
+        case AUDIO_DSP_PARAM:
+        {
+            /* set samplerate */
+            ac97_set_rate(caps->udata.config.samplerate);
+
+            /* update buffer fifo informaition according samplerate */
+            replay = snd_dev->audio.replay;
+            replay->buf_info.total_size = caps->udata.config.samplerate / 50 * 4;
+            replay->buf_info.block_size = replay->buf_info.total_size / 2;
+
+            /* save configs */
+            snd_dev->replay_config.samplerate = caps->udata.config.samplerate;
+            snd_dev->replay_config.channels   = caps->udata.config.channels;
+            snd_dev->replay_config.samplebits = caps->udata.config.samplebits;
+            LOG_D("set samplerate %d", snd_dev->replay_config.samplerate);
+            break;
+        }
+
+        case AUDIO_DSP_SAMPLERATE:
+        {
+            ac97_set_rate(caps->udata.config.samplerate);
+
+            snd_dev->replay_config.samplerate = caps->udata.config.samplerate;
+            LOG_D("set samplerate %d", snd_dev->replay_config.samplerate);
+            break;
+        }
+
+        case AUDIO_DSP_CHANNELS:
+        {
+            /* not support */
+            snd_dev->replay_config.channels   = caps->udata.config.channels;
+            LOG_D("set channels %d", snd_dev->replay_config.channels);
+            break;
+        }
+
+        case AUDIO_DSP_SAMPLEBITS:
+        {
+            /* not support */
+            snd_dev->replay_config.samplebits = caps->udata.config.samplebits;
+            break;
+        }
+
+        default:
+            result = -RT_ERROR;
+            break;
+        }
+
+        break;
+    }
+
+    default:
+        break;
+    }
+
+    return result;
+}
+
+static rt_err_t sound_init(struct rt_audio_device *audio)
+{
+    rt_err_t result = RT_EOK;
+    struct sound_device *snd_dev;
+    struct pl041_cfg _cfg;
+
+    RT_ASSERT(audio != RT_NULL);
+    snd_dev = (struct sound_device *)audio->parent.user_data;
+
+    aaci_pl041_init();
+
+    _cfg.itype = PL041_CHANNLE_LEFT_ADC | PL041_CHANNLE_RIGHT_ADC;
+    _cfg.otype = PL041_CHANNLE_LEFT_DAC | PL041_CHANNLE_RIGHT_DAC;
+    _cfg.vol   = snd_dev->volume;
+    _cfg.rate  = snd_dev->replay_config.samplerate;
+
+    ac97_reset();
+    aaci_pl041_channle_cfg(0, &_cfg);
+    aaci_pl041_irq_register(0, rt_hw_aaci_isr, RT_NULL);
+
+    return result;
+}
+
+static rt_err_t sound_start(struct rt_audio_device *audio, int stream)
+{
+    RT_ASSERT(audio != RT_NULL);
+
+    if (stream == AUDIO_STREAM_REPLAY)
+    {
+        LOG_D("open sound device");
+        aaci_pl041_channle_enable(0);
+        aaci_pl041_irq_enable(0, AACI_IE_UR | AACI_IE_TX | AACI_IE_TXC);
+    }
+
+    return RT_EOK;
+}
+
+static rt_err_t sound_stop(struct rt_audio_device *audio, int stream)
+{
+    RT_ASSERT(audio != RT_NULL);
+
+    if (stream == AUDIO_STREAM_REPLAY)
+    {
+        /* wait codec free */
+        rt_thread_mdelay(100);
+        /* disable irq and channels 0 */
+        aaci_pl041_irq_disable(0, AACI_IE_UR | AACI_IE_TX | AACI_IE_TXC);
+        aaci_pl041_channle_disable(0);
+        LOG_D("close sound device");
+    }
+
+    return RT_EOK;
+}
+
+static void sound_buffer_info(struct rt_audio_device *audio, struct rt_audio_buf_info *info)
+{
+    struct sound_device *snd_dev;
+
+    RT_ASSERT(audio != RT_NULL);
+    snd_dev = (struct sound_device *)audio->parent.user_data;
+
+    /**
+     *               TX_FIFO
+     * +----------------+----------------+
+     * |     block1     |     block2     |
+     * +----------------+----------------+
+     *  \  block_size  /
+     */
+    info->buffer      = snd_dev->tx_fifo;
+    info->total_size  = TX_FIFO_SIZE;
+    info->block_size  = TX_FIFO_SIZE/2;
+    info->block_count = 2;
+}
+
+static rt_size_t sound_transmit(struct rt_audio_device *audio, const void *writeBuf, void *readBuf, rt_size_t size)
+{
+    RT_ASSERT(audio != RT_NULL);
+
+    /* write data to channel_0 fifo */
+    aaci_pl041_channle_write(0, (rt_uint16_t *)writeBuf, size >> 1);
+
+    return size;
+}
+
+static struct rt_audio_ops snd_ops =
+{
+    .getcaps     = sound_getcaps,
+    .configure   = sound_configure,
+    .init        = sound_init,
+    .start       = sound_start,
+    .stop        = sound_stop,
+    .transmit    = sound_transmit,
+    .buffer_info = sound_buffer_info,
+};
+
+int rt_hw_audio_init(void)
+{
+    rt_uint8_t *tx_fifo;
+
+    if (snd_dev.tx_fifo)
+        return RT_EOK;
+
+    tx_fifo = rt_malloc(TX_FIFO_SIZE);
+    if (tx_fifo == RT_NULL)
+        return -RT_ENOMEM;
+    rt_memset(tx_fifo, 0, TX_FIFO_SIZE);
+    snd_dev.tx_fifo = tx_fifo;
+
+    /* init default configuration */
+    {
+        snd_dev.replay_config.samplerate = 44100;
+        snd_dev.replay_config.channels   = 2;
+        snd_dev.replay_config.samplebits = 16;
+        snd_dev.volume                   = 55;
+    }
+
+    /* register sound device */
+    snd_dev.audio.ops = &snd_ops;
+    rt_audio_register(&snd_dev.audio, "sound0", RT_DEVICE_FLAG_WRONLY, &snd_dev);
+
+    return RT_EOK;
+}
+
+INIT_DEVICE_EXPORT(rt_hw_audio_init);

+ 15 - 0
bsp/qemu-vexpress-a9/drivers/audio/drv_sound.h

@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ * 
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Date           Author       Notes
+ * 2019-07-23     Zero-Free    first implementation
+ */
+
+#ifndef __DRV_SOUND_H__
+#define __DRV_SOUND_H__
+
+int rt_hw_audio_init(void);
+
+#endif

+ 57 - 0
bsp/qemu-vexpress-a9/drivers/board.c

@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2012-11-20     Bernard    the first version
+ * 2018-11-22     Jesven     add rt_hw_spin_lock
+ *                           add rt_hw_spin_unlock
+ *                           add smp ipi init
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#include "board.h"
+#include "drv_timer.h"
+
+#include <mmu.h>
+
+struct mem_desc platform_mem_desc[] = {
+    {0x10000000, 0x50000000, 0x10000000, DEVICE_MEM},
+    {0x60000000, 0xe0000000, 0x60000000, NORMAL_MEM}
+};
+
+const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc)/sizeof(platform_mem_desc[0]);
+
+#define SYS_CTRL                        __REG32(REALVIEW_SCTL_BASE)
+
+extern void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler);
+
+void idle_wfi(void)
+{
+    asm volatile ("wfi");
+}
+
+/**
+ * This function will initialize beaglebone board
+ */
+void rt_hw_board_init(void)
+{
+    /* initialize hardware interrupt */
+    rt_hw_interrupt_init();
+    /* initialize system heap */
+    rt_system_heap_init(HEAP_BEGIN, HEAP_END);
+
+    rt_components_board_init();
+    rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
+
+    rt_thread_idle_sethook(idle_wfi);
+
+#ifdef RT_USING_SMP
+    /* install IPI handle */
+    rt_hw_ipi_handler_install(RT_SCHEDULE_IPI, rt_scheduler_ipi_handler);
+#endif
+}

+ 33 - 0
bsp/qemu-vexpress-a9/drivers/board.h

@@ -0,0 +1,33 @@
+/*
+ * File      : board.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2013, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2013-07-06     Bernard    the first version
+ */
+
+#ifndef __BOARD_H__
+#define __BOARD_H__
+
+#include <realview.h>
+#include "vexpress_a9.h"
+
+#if defined(__CC_ARM)
+extern int Image$$RW_IRAM1$$ZI$$Limit;
+#define HEAP_BEGIN      ((void*)&Image$$RW_IRAM1$$ZI$$Limit)
+#elif defined(__GNUC__)
+extern int __bss_end;
+#define HEAP_BEGIN      ((void*)&__bss_end)
+#endif
+
+#define HEAP_END        (void*)(0x60000000 + 8 * 1024 * 1024)
+
+void rt_hw_board_init(void);
+
+#endif

+ 133 - 0
bsp/qemu-vexpress-a9/drivers/drv_clcd.c

@@ -0,0 +1,133 @@
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <rtthread.h>
+#include "drv_clcd.h"
+
+#define CLCD_WIDTH  (BSP_LCD_WIDTH)
+#define CLCD_HEIGHT (BSP_LCD_HEIGHT)
+
+#define CLCD_DEVICE(dev)    (struct drv_clcd_device*)(dev)
+
+#define PL111_CR_EN         0x001
+#define PL111_CR_PWR        0x800
+#define PL111_IOBASE        0x10020000
+#define PL111_PALBASE       (PL111_IOBASE + 0x200)
+
+typedef struct _PL111MMIO
+{
+    uint32_t      volatile tim0;      //0
+    uint32_t      volatile tim1;      //4
+    uint32_t      volatile tim2;      //8
+    uint32_t      volatile tim3;      //c
+    uint32_t      volatile upbase;    //10
+    uint32_t      volatile f;         //14
+    uint32_t      volatile control;   //18
+    uint32_t      volatile g;         //1c
+} PL111MMIO;
+
+struct drv_clcd_device
+{
+    struct rt_device parent;
+
+    int width;
+    int height;
+
+    uint8_t *fb;
+};
+struct drv_clcd_device _lcd;
+
+static rt_err_t drv_clcd_init(struct rt_device *device)
+{
+    struct drv_clcd_device *lcd = CLCD_DEVICE(device);
+
+    lcd = lcd; /* nothing, right now */
+    return RT_EOK;
+}
+
+static rt_err_t drv_clcd_control(struct rt_device *device, int cmd, void *args)
+{
+    struct drv_clcd_device *lcd = CLCD_DEVICE(device);
+
+    switch (cmd)
+    {
+    case RTGRAPHIC_CTRL_RECT_UPDATE:
+        {
+            struct rt_device_rect_info *info = (struct rt_device_rect_info*)args;
+
+            info = info; /* nothing, right now */
+        }
+        break;
+
+    case RTGRAPHIC_CTRL_GET_INFO:
+        {
+            struct rt_device_graphic_info* info = (struct rt_device_graphic_info*)args;
+
+            RT_ASSERT(info != RT_NULL);
+            info->pixel_format  = RTGRAPHIC_PIXEL_FORMAT_RGB565;
+            // info->pixel_format  = RTGRAPHIC_PIXEL_FORMAT_ARGB888;
+            info->bits_per_pixel= 16;
+            info->width         = lcd->width;
+            info->height        = lcd->height;
+            info->framebuffer   = lcd->fb;
+        }
+        break;
+    }
+
+    return RT_EOK;
+}
+
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops clcd_ops = 
+{
+    drv_clcd_init,
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    drv_clcd_control
+};
+#endif
+
+int drv_clcd_hw_init(void)
+{
+    PL111MMIO   *plio;
+    struct rt_device *device = &_lcd.parent;
+
+    /* memset _lcd to zero */
+    memset(&_lcd, 0x0, sizeof(_lcd));
+
+    _lcd.width  = CLCD_WIDTH;
+    _lcd.height = CLCD_HEIGHT;
+    _lcd.fb     = rt_malloc (_lcd.width * _lcd.height * 2);
+    if (_lcd.fb == NULL)
+    {
+        rt_kprintf("initialize frame buffer failed!\n");
+        return -1;
+    }
+
+    memset(_lcd.fb, 0xff, _lcd.width * _lcd.height * 2);
+
+    plio = (PL111MMIO*)PL111_IOBASE;
+
+    plio->tim0 = 0x3F1F3C00 | ((CLCD_WIDTH/16 - 1) << 2);
+    plio->tim1 = 0x080B6000 | (CLCD_HEIGHT - 1);
+
+    plio->upbase = (uint32_t)_lcd.fb;
+    /* 16-bit 565 color */
+    plio->control = 0x1921 | (0x6 << 1);
+
+    device->type    = RT_Device_Class_Graphic;
+#ifdef RT_USING_DEVICE_OPS
+    device->ops     = &clcd_ops;
+#else
+    device->init    = drv_clcd_init;
+    device->control = drv_clcd_control;
+#endif
+
+    rt_device_register(device, "lcd", RT_DEVICE_FLAG_RDWR);
+
+    return 0;
+}
+INIT_DEVICE_EXPORT(drv_clcd_hw_init);

+ 16 - 0
bsp/qemu-vexpress-a9/drivers/drv_clcd.h

@@ -0,0 +1,16 @@
+#ifndef DRV_CLCD_H__
+#define DRV_CLCD_H__
+
+#include <rtthread.h>
+
+#ifndef BSP_LCD_WIDTH
+#define BSP_LCD_WIDTH   640
+#endif
+
+#ifndef BSP_LCD_HEIGHT
+#define BSP_LCD_HEIGHT  480
+#endif
+
+int drv_clcd_hw_init(void);
+
+#endif

+ 471 - 0
bsp/qemu-vexpress-a9/drivers/drv_keyboard.c

@@ -0,0 +1,471 @@
+#include <rthw.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#include "board.h"
+#include "interrupt.h"
+#include "drv_keyboard.h"
+
+#define DBG_LVL DBG_INFO
+#include "rtdbg.h"
+
+#define KEYBOARD_ADDRESS    (0x10006000)
+#define KEYBOARD_IRQ_NUM    (IRQ_VEXPRESS_A9_KBD)
+
+#ifdef PKG_USING_GUIENGINE
+
+#include <rtgui/event.h>
+#include <rtgui/rtgui_server.h>
+
+typedef rt_uint32_t virtual_addr_t;
+
+enum{
+    KEYBOARD_CR     = 0x00,
+    KEYBOARD_STAT   = 0x04,
+    KEYBOARD_DATA   = 0x08,
+    KEYBOARD_CLKDIV = 0x0c,
+    KEYBOARD_IIR    = 0x10,
+};
+
+struct keyboard_pl050_pdata_t
+{
+    virtual_addr_t virt;
+    int irq;
+};
+
+enum decode_state {
+    DECODE_STATE_MAKE_CODE,
+    DECODE_STATE_BREAK_CODE,
+    DECODE_STATE_LONG_MAKE_CODE,
+    DECODE_STATE_LONG_BREAK_CODE
+};
+
+struct keymap {
+    rt_uint8_t data;
+    rt_uint32_t key;
+    rt_uint32_t unicode;
+    char *normal_key;
+};
+
+enum key_value_t {
+    KEY_BUTTON_UP,
+    KEY_BUTTON_DOWN,
+};
+
+enum {
+    KBD_LEFT_SHIFT  = (0x1 << 0),
+    KBD_RIGHT_SHIFT = (0x1 << 1),
+    KBD_LEFT_CTRL   = (0x1 << 2),
+    KBD_RIGHT_CTRL  = (0x1 << 3),
+    KBD_CAPS_LOCK   = (0x1 << 6),
+    KBD_NUM_LOCK    = (0x1 << 7),
+    KBD_SCROLL_LOCK = (0x1 << 8),
+};
+
+static const struct keymap map[] = {
+    {0x1c,  RTGUIK_a, 0, "a",          },
+    {0x32,  RTGUIK_b, 0, "b",          },
+    {0x21,  RTGUIK_c, 0, "c",          },
+    {0x23,  RTGUIK_d, 0, "d",          },
+    {0x24,  RTGUIK_e, 0, "e",          },
+    {0x2b,  RTGUIK_f, 0, "f",          },
+    {0x34,  RTGUIK_g, 0, "g",          },
+    {0x33,  RTGUIK_h, 0, "h",          },
+    {0x43,  RTGUIK_i, 0, "i",          },
+    {0x3b,  RTGUIK_j, 0, "j",          },
+    {0x42,  RTGUIK_k, 0, "k",          },
+    {0x4b,  RTGUIK_l, 0, "l",          },
+    {0x3a,  RTGUIK_m, 0, "m",          },
+    {0x31,  RTGUIK_n, 0, "n",          },
+    {0x44,  RTGUIK_o, 0, "o",          },
+    {0x4d,  RTGUIK_p, 0, "p",          },
+    {0x15,  RTGUIK_q, 0, "q",          },
+    {0x2d,  RTGUIK_r, 0, "r",          },
+    {0x1b,  RTGUIK_s, 0, "s",          },
+    {0x2c,  RTGUIK_k, 0, "k",          },
+    {0x3c,  RTGUIK_u, 0, "u",          },
+    {0x2a,  RTGUIK_v, 0, "v",          },
+    {0x1d,  RTGUIK_w, 0, "w",          },
+    {0x22,  RTGUIK_x, 0, "x",          },
+    {0x35,  RTGUIK_y, 0, "y",          },
+    {0x1a,  RTGUIK_z, 0, "z",          },
+
+    {0x45,  RTGUIK_0, 0, "0",          },
+    {0x16,  RTGUIK_1, 0, "1",          },
+    {0x1e,  RTGUIK_2, 0, "2",          },
+    {0x26,  RTGUIK_3, 0, "3",          },
+    {0x25,  RTGUIK_4, 0, "4",          },
+    {0x2e,  RTGUIK_5, 0, "5",          },
+    {0x36,  RTGUIK_6, 0, "6",          },
+    {0x3d,  RTGUIK_7, 0, "7",          },
+    {0x3e,  RTGUIK_8, 0, "8",          },
+    {0x46,  RTGUIK_9, 0, "9",          },
+
+    {0x05,  RTGUIK_F1,  0, "F1",       },
+    {0x06,  RTGUIK_F2,  0, "F2",       },
+    {0x04,  RTGUIK_F3,  0, "F3",       },
+    {0x0c,  RTGUIK_F4,  0, "F4",       },
+    {0x03,  RTGUIK_F5,  0, "F5",       },
+    {0x0b,  RTGUIK_F6,  0, "F6",       },
+    {0x83,  RTGUIK_F7,  0, "F7",       },
+    {0x0a,  RTGUIK_F8,  0, "F8",       },
+    {0x01,  RTGUIK_F9,  0, "F9",       },
+    {0x09,  RTGUIK_F10, 0, "F10",      },
+    {0x78,  RTGUIK_F11, 0, "F11",      },
+    {0x07,  RTGUIK_F12, 0, "F12",      },
+
+    {0x29,  RTGUIK_SPACE,  0, "SPACE"  },
+    {0x71,  RTGUIK_DELETE, 0, "DELETE" },
+    {0x52,  RTGUIK_QUOTE,  0, "'"      },
+    {0x55,  RTGUIK_EQUALS, 0, "="      },
+    {0x41,  RTGUIK_COMMA,  0, ","      },
+    {0x4e,  RTGUIK_MINUS,  0, "-"      },
+    // {0x49,  RTGUIK_,    0, "."         },
+    {0x4a,  RTGUIK_SLASH,  0, "/"      },
+    {0x4c,  RTGUIK_SEMICOLON, 0, ";"   },
+    {0x54,  RTGUIK_LEFTBRACKET, 0, "[" },
+    {0x5d,  RTGUIK_BACKSLASH, 0, "\\"  },
+    {0x5b,  RTGUIK_RIGHTBRACKET, 0, "]"},
+    {0x75,  RTGUIK_UP,    0, "UP"      },
+    {0x72,  RTGUIK_DOWN,  0, "DOWN"    },
+    {0x6b,  RTGUIK_LEFT,  0, "LEFT"    },
+    {0x74,  RTGUIK_RIGHT, 0, "RIGHT"   },
+    {0x0d,  RTGUIK_TAB,   0, "TAB"     },
+    {0x76,  RTGUIK_ESCAPE, 0, "ESC"    },
+    {0x37,  RTGUIK_POWER,  0, "POWER"  }, 
+    {0x5a,  RTGUIK_KP_ENTER, 0, "ENTER"},
+    {0x66,  RTGUIK_BACKSPACE, 0, "BACKSPACE"},
+};
+
+rt_inline rt_uint8_t read8(uint32_t addr)
+{
+    return (*((volatile rt_uint8_t *)(addr)));
+}
+
+rt_inline void write8(uint32_t addr, rt_uint8_t value)
+{
+    *((volatile rt_uint8_t *)(addr)) = value;
+}
+
+rt_inline rt_uint32_t read32(uint32_t addr)
+{
+    return (*((volatile rt_uint32_t *)(addr)));
+}
+
+rt_inline void write32(uint32_t addr, rt_uint32_t value)
+{
+    *((volatile rt_uint32_t *)(addr)) = value;
+}
+
+rt_inline int kmi_write(struct keyboard_pl050_pdata_t * pdat, rt_uint8_t value)
+{
+    int timeout = 1000;
+
+    while((read8(pdat->virt + KEYBOARD_STAT) & (1 << 6)) == 0 && timeout--);
+
+    if(timeout)
+    {
+        write8(pdat->virt + KEYBOARD_DATA, value);
+        while((read8(pdat->virt + KEYBOARD_STAT) & (1 << 4)) == 0);
+
+        if(read8(pdat->virt + KEYBOARD_DATA) == 0xfa)
+            return RT_TRUE;
+    }
+    return RT_FALSE;
+}
+
+rt_inline int kmi_read(struct keyboard_pl050_pdata_t * pdat, rt_uint8_t * value)
+{
+    if((read8(pdat->virt + KEYBOARD_STAT) & (1 << 4)))
+    {
+        *value = read8(pdat->virt + KEYBOARD_DATA);
+        return RT_TRUE;
+    }
+    return RT_FALSE;
+}
+
+static void keyboard_report_event(void * device, rt_uint32_t flag, rt_uint8_t data, enum key_value_t press)
+{
+    struct rtgui_event_kbd key_event;
+    rt_uint16_t i = 0, mod = 0, find_key = 0;
+
+    for(i = 0; i < sizeof(map)/sizeof(map[0]); i++)
+    {
+        if (map[i].data == data)
+        {
+            LOG_D("KEY info:");
+            if (flag & KBD_CAPS_LOCK)
+            {
+                LOG_D("CAPS:LOCK");
+            }
+            else
+            {
+                LOG_D("CAPS:UNLOCK");
+            }
+
+            if (flag & KBD_LEFT_SHIFT)
+            {
+                mod |= RTGUI_KMOD_LSHIFT;
+                LOG_D("SHIFT:LEFT");
+            }
+            else if (flag & KBD_RIGHT_SHIFT)
+            {
+                mod |= RTGUI_KMOD_RSHIFT;
+                LOG_D("SHIFT:RIGHT");
+            }
+            else
+            {
+                LOG_D("SHIFT:NULL");
+            }
+
+            if (flag & KBD_LEFT_CTRL)
+            {
+                mod |= RTGUI_KMOD_LCTRL;
+                LOG_D("CTRL:LEFT");
+            }
+            else if (flag & KBD_RIGHT_CTRL)
+            {
+                mod |= RTGUI_KMOD_RCTRL;
+                LOG_D("CTRL:RIGHT");
+            }
+            else
+            {
+                LOG_D("CTRL:NULL");
+            }
+
+            LOG_D("flag:0x%08x value:0x%x key:%s status:%s", \
+                flag, data, map[i].normal_key, press ==0 ? "UP" : "DOWN");
+            find_key = 1;
+            break;
+        }
+    }
+    if (find_key == 0)
+    {
+        LOG_D("flag:0x%08x value:0x%x key:%s status:%s", \
+            flag, data, "UNKNOWN", press ==0 ? "UP" : "DOWN");
+        return;
+    }
+
+    key_event.parent.sender = RT_NULL;
+    key_event.parent.type = RTGUI_EVENT_KBD;
+    key_event.type = (press == 0 ? RTGUI_KEYUP : RTGUI_KEYDOWN);
+    key_event.key = map[i].key;
+    key_event.mod = mod;
+    key_event.unicode = map[i].unicode;
+    rtgui_server_post_event(&key_event.parent, sizeof(key_event));
+}
+
+static void keyboard_pl050_interrupt(int irq, void *data)
+{
+    struct keyboard_pl050_pdata_t * pdat = (struct keyboard_pl050_pdata_t *)data;
+    static enum decode_state ds = DECODE_STATE_MAKE_CODE;
+    static rt_uint32_t kbd_flag = KBD_NUM_LOCK;
+    rt_uint8_t status, value;
+
+    status = read8(pdat->virt + KEYBOARD_IIR);
+
+    while(status & (1 << 0))
+    {
+        value = read8(pdat->virt + KEYBOARD_DATA);
+
+        switch(ds)
+        {
+        case DECODE_STATE_MAKE_CODE:
+            /* break code */
+            if(value == 0xf0)
+            {
+                ds = DECODE_STATE_BREAK_CODE;
+            }
+            /* long make code */
+            else if(value == 0xe0)
+            {
+                ds = DECODE_STATE_LONG_MAKE_CODE;
+            }
+            else
+            {
+                ds = DECODE_STATE_MAKE_CODE;
+
+                /* left shift */
+                if(value == 0x12)
+                {
+                    kbd_flag |= KBD_LEFT_SHIFT;
+                }
+                /* right shift */
+                else if(value == 0x59)
+                {
+                    kbd_flag |= KBD_RIGHT_SHIFT;
+                }
+                /* left ctrl */
+                else if(value == 0x14)
+                {
+                    kbd_flag |= KBD_LEFT_CTRL;
+                }
+                /* caps lock */
+                else if(value == 0x58)
+                {
+                    if(kbd_flag & KBD_CAPS_LOCK)
+                        kbd_flag &= ~KBD_CAPS_LOCK;
+                    else
+                        kbd_flag |= KBD_CAPS_LOCK;
+                }
+                /* scroll lock */
+                else if(value == 0x7e)
+                {
+                    if(kbd_flag & KBD_SCROLL_LOCK)
+                        kbd_flag &= ~KBD_SCROLL_LOCK;
+                    else
+                        kbd_flag |= KBD_SCROLL_LOCK;
+                }
+                /* num lock */
+                else if(value == 0x77)
+                {
+                    if(kbd_flag & KBD_NUM_LOCK)
+                        kbd_flag &= ~KBD_NUM_LOCK;
+                    else
+                        kbd_flag |= KBD_NUM_LOCK;
+                }
+                /* others */
+                else
+                {
+                    keyboard_report_event(data, kbd_flag, value, KEY_BUTTON_DOWN);
+                }
+            }
+            break;
+
+        case DECODE_STATE_BREAK_CODE:
+            if( (value != 0xf0) && (value != 0xe0))
+            {
+                ds = DECODE_STATE_MAKE_CODE;
+
+                /* left shift */
+                if(value == 0x12)
+                {
+                    kbd_flag &= ~KBD_LEFT_SHIFT;
+                }
+                /* right shift */
+                else if(value == 0x59)
+                {
+                    kbd_flag &= ~KBD_RIGHT_SHIFT;
+                }
+                /* left ctrl */
+                else if(value == 0x14)
+                {
+                    kbd_flag &= ~KBD_LEFT_CTRL;
+                }
+                /* others */
+                else
+                {
+                    keyboard_report_event(data, kbd_flag, value, KEY_BUTTON_UP);
+                }
+            }
+            else
+            {
+                ds = DECODE_STATE_BREAK_CODE;
+            }
+            break;
+
+        case DECODE_STATE_LONG_MAKE_CODE:
+            if( value != 0xf0 && value!= 0xe0)
+            {
+                ds = DECODE_STATE_MAKE_CODE;
+
+                /* left ctrl */
+                if(value == 0x14)
+                {
+                    kbd_flag |= KBD_RIGHT_CTRL;
+                }
+                /* others */
+                else
+                {
+                    keyboard_report_event(data, kbd_flag, value, KEY_BUTTON_DOWN);
+                }
+            }
+            else
+            {
+                ds = DECODE_STATE_LONG_BREAK_CODE;
+            }
+            break;
+
+        case DECODE_STATE_LONG_BREAK_CODE:
+            if( (value != 0xf0) && (value != 0xe0))
+            {
+                ds = DECODE_STATE_MAKE_CODE;
+
+                /* left ctrl */
+                if(value == 0x14)
+                {
+                    kbd_flag &= ~KBD_RIGHT_CTRL;
+                }
+                /* others */
+                else
+                {
+                    keyboard_report_event(data, kbd_flag, value, KEY_BUTTON_UP);
+                }
+            }
+            else
+            {
+                ds = DECODE_STATE_LONG_BREAK_CODE;
+            }
+            break;
+
+        default:
+            ds = DECODE_STATE_MAKE_CODE;
+            break;
+        }
+
+        status = read8(pdat->virt + KEYBOARD_IIR);
+    }
+}
+
+int rt_hw_keyboard_init(void)
+{
+    rt_uint8_t value;
+    rt_uint32_t id;
+    struct keyboard_pl050_pdata_t *pdat;
+    virtual_addr_t virt = (virtual_addr_t)KEYBOARD_ADDRESS;
+    int irq = KEYBOARD_IRQ_NUM;
+    
+    id = (((read32(virt + 0xfec) & 0xff) << 24) |
+                ((read32(virt + 0xfe8) & 0xff) << 16) |
+                ((read32(virt + 0xfe4) & 0xff) <<  8) |
+                ((read32(virt + 0xfe0) & 0xff) <<  0));
+    
+    if(((id >> 12) & 0xff) != 0x41 || (id & 0xfff) != 0x050)
+    {
+        LOG_E("read id fail id:0x%08x", id);
+        return RT_ERROR;
+    }
+
+    pdat = rt_malloc(sizeof(struct keyboard_pl050_pdata_t));
+    if(!pdat)
+    {
+        LOG_E("malloc memory failed");
+        return RT_ERROR;
+    }
+    rt_memset(pdat, 0, sizeof(struct keyboard_pl050_pdata_t));
+
+    pdat->virt = virt;
+    pdat->irq = irq;
+
+    write8(pdat->virt + KEYBOARD_CLKDIV, 0);
+    write8(pdat->virt + KEYBOARD_CR, (1 << 2));
+    kmi_read(pdat, &value);
+    kmi_write(pdat, 0xff);
+    kmi_read(pdat, &value);
+    kmi_write(pdat, 0xf3);
+    kmi_write(pdat, 0x2b);
+    kmi_write(pdat, 0xf0);
+    kmi_write(pdat, 0x02);
+    kmi_write(pdat, 0xfa);
+    kmi_write(pdat, 0xed);
+    kmi_write(pdat, 0x02);
+    write8(pdat->virt + KEYBOARD_CR, (1 << 2) | (1 << 4));
+
+    rt_hw_interrupt_install(irq, keyboard_pl050_interrupt, (void *)pdat, "keyboard");
+    rt_hw_interrupt_umask(irq);
+
+    return RT_EOK;
+}
+INIT_DEVICE_EXPORT(rt_hw_keyboard_init);
+
+#endif

+ 6 - 0
bsp/qemu-vexpress-a9/drivers/drv_keyboard.h

@@ -0,0 +1,6 @@
+#ifndef __DEV_KEYBOARD_H__
+#define __DEV_KEYBOARD_H__
+
+int rt_hw_keyboard_init(void);
+
+#endif

+ 297 - 0
bsp/qemu-vexpress-a9/drivers/drv_mouse.c

@@ -0,0 +1,297 @@
+#include <rthw.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#include "board.h"
+#include "interrupt.h"
+#include "drv_mouse.h"
+#include "drv_clcd.h"
+
+#define DBG_TAG "drv.mouse"
+#define DBG_LVL DBG_INFO
+#include "rtdbg.h"
+
+#define MOUSE_ADDRESS    (0x10007000)
+#define MOUSE_IRQ_NUM    (IRQ_VEXPRESS_A9_MOUSE)
+#define MOUSE_XMAX       (BSP_LCD_WIDTH)
+#define MOUSE_YMAX       (BSP_LCD_HEIGHT)
+
+#define MOUSE_BUTTON_LEFT    (0x01)
+#define MOUSE_BUTTON_RIGHT   (0x02)
+#define MOUSE_BUTTON_MIDDLE  (0x04)
+#define MOUSE_BUTTON_DOWN    (0x10)
+#define MOUSE_BUTTON_UP      (0x20)
+#define MOUSE_BUTTON_MOVE    (0x40)
+#define MOUSE_BUTTON_WHELL   (0x80)
+
+#ifdef PKG_USING_GUIENGINE
+
+#include <rtgui/event.h>
+#include <rtgui/rtgui_server.h>
+
+typedef rt_uint32_t virtual_addr_t;
+
+enum {
+    MOUSE_CR        = 0x00,
+    MOUSE_STAT      = 0x04,
+    MOUSE_DATA      = 0x08,
+    MOUSE_CLKDIV    = 0x0c,
+    MOUSE_IIR       = 0x10,
+};
+
+struct mouse_pl050_pdata_t {
+    virtual_addr_t virt;
+    int irq;
+    int xmax, ymax;
+    int xpos, ypos;
+    unsigned char packet[4];
+    int index;
+    int obtn;
+    int type;
+};
+
+rt_inline rt_uint8_t read8(uint32_t addr)
+{
+    return (*((volatile rt_uint8_t *)(addr)));
+}
+
+rt_inline void write8(uint32_t addr, rt_uint8_t value)
+{
+    *((volatile rt_uint8_t *)(addr)) = value;
+}
+
+rt_inline rt_uint32_t read32(uint32_t addr)
+{
+    return (*((volatile rt_uint32_t *)(addr)));
+}
+
+rt_inline void write32(uint32_t addr, rt_uint32_t value)
+{
+    *((volatile rt_uint32_t *)(addr)) = value;
+}
+
+rt_inline int kmi_write(struct mouse_pl050_pdata_t * pdat, rt_uint8_t value)
+{
+    int timeout = 1000;
+
+    while((read8(pdat->virt + MOUSE_STAT) & (1 << 6)) == 0 && timeout--);
+
+    if(timeout)
+    {
+        write8(pdat->virt + MOUSE_DATA, value);
+        while((read8(pdat->virt + MOUSE_STAT) & (1 << 4)) == 0);
+
+        if(read8(pdat->virt + MOUSE_DATA) == 0xfa)
+            return RT_TRUE;
+    }
+    return RT_FALSE;
+}
+
+rt_inline int kmi_read(struct mouse_pl050_pdata_t * pdat, rt_uint8_t * value)
+{
+    if((read8(pdat->virt + MOUSE_STAT) & (1 << 4)))
+    {
+        *value = read8(pdat->virt + MOUSE_DATA);
+        return RT_TRUE;
+    }
+    return RT_FALSE;
+}
+
+static rt_uint32_t emouse_id;
+
+void push_event_touch_move(int x, int y)
+{
+    struct rtgui_event_mouse emouse;
+
+    emouse.parent.sender = RT_NULL;
+    emouse.wid = RT_NULL;
+
+    emouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN;
+    emouse.parent.type = RTGUI_EVENT_MOUSE_MOTION;
+    emouse.x = x;
+    emouse.y = y;
+    emouse.ts = rt_tick_get();
+    emouse.id = emouse_id;
+
+    LOG_D("[line]:%d motion event id:%d x:%d y:%d", __LINE__, emouse.id, x, y);
+    rtgui_server_post_event(&emouse.parent, sizeof(emouse));
+}
+
+void push_event_touch_begin(int x, int y)
+{
+    struct rtgui_event_mouse emouse;
+
+    emouse_id = rt_tick_get();
+
+    emouse.parent.sender = RT_NULL;
+    emouse.wid = RT_NULL;
+
+    emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON;
+    emouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN;
+    emouse.x = x;
+    emouse.y = y;
+    emouse.ts = rt_tick_get();
+    emouse.id = emouse_id;
+    LOG_D("[line]:%d down event id:%d x:%d y:%d", __LINE__, emouse.id, x, y);
+    rtgui_server_post_event(&emouse.parent, sizeof(emouse));
+}
+
+void push_event_touch_end(int x, int y)
+{
+    struct rtgui_event_mouse emouse;
+
+    emouse.parent.sender = RT_NULL;
+    emouse.wid = RT_NULL;
+
+    emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON;
+    emouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_UP;
+    emouse.x = x;
+    emouse.y = y;
+    emouse.ts = rt_tick_get();
+    emouse.id = emouse_id;
+    
+    LOG_D("[line]:%d up event id:%d x:%d y:%d", __LINE__, emouse.id, x, y);
+    rtgui_server_post_event(&emouse.parent, sizeof(emouse));
+}
+
+static void mouse_pl050_interrupt(int irq, void * data)
+{
+    struct mouse_pl050_pdata_t * pdat = (struct mouse_pl050_pdata_t *)data;
+    int x, y, relx, rely, delta;
+    int btndown, btnup, btn;
+    int status = 0;
+
+    status = read8(pdat->virt + MOUSE_IIR);
+    while(status & (1 << 0))
+    {
+        pdat->packet[pdat->index] = read8(pdat->virt + MOUSE_DATA);
+        pdat->index = (pdat->index + 1) & 0x3;
+
+        if(pdat->index == 0)
+        {
+            btn = pdat->packet[0] & 0x7;
+            btndown = (btn ^ pdat->obtn) & btn;
+            btnup = (btn ^ pdat->obtn) & pdat->obtn;
+            pdat->obtn = btn;
+
+            if(pdat->packet[0] & 0x10)
+                relx = 0xffffff00 | pdat->packet[1];
+            else
+                relx = pdat->packet[1];
+
+            if(pdat->packet[0] & 0x20)
+                rely = 0xffffff00 | pdat->packet[2];
+            else
+                rely = pdat->packet[2];
+            rely = -rely;
+
+            delta = pdat->packet[3] & 0xf;
+            if(delta == 0xf)
+                delta = -1;
+
+            if(relx != 0)
+            {
+                pdat->xpos = pdat->xpos + relx;
+                if(pdat->xpos < 0)
+                    pdat->xpos = 0;
+                if(pdat->xpos > pdat->xmax - 1)
+                    pdat->xpos = pdat->xmax - 1;
+            }
+            if(rely != 0)
+            {
+                pdat->ypos = pdat->ypos + rely;
+                if(pdat->ypos < 0)
+                    pdat->ypos = 0;
+                if(pdat->ypos > pdat->ymax - 1)
+                    pdat->ypos = pdat->ymax - 1;
+            }
+            x = pdat->xpos;
+            y = pdat->ypos;
+
+            if((btn & (0x01 << 0)) && ((relx != 0) || (rely != 0)))
+                push_event_touch_move(x, y);
+
+            if(btndown & (0x01 << 0))
+                push_event_touch_begin(x, y);
+
+            if(btnup & (0x01 << 0))
+                push_event_touch_end(x, y);
+        }
+
+        status = read8(pdat->virt + MOUSE_IIR);
+    }
+}
+
+int rt_hw_mouse_init(void)
+{
+    rt_uint8_t value;
+    rt_uint32_t id;
+    struct mouse_pl050_pdata_t *pdat;
+    virtual_addr_t virt = MOUSE_ADDRESS;
+    int irq = MOUSE_IRQ_NUM;
+
+    id = (((read32(virt + 0xfec) & 0xff) << 24) |
+                ((read32(virt + 0xfe8) & 0xff) << 16) |
+                ((read32(virt + 0xfe4) & 0xff) <<  8) |
+                ((read32(virt + 0xfe0) & 0xff) <<  0));
+    
+    if(((id >> 12) & 0xff) != 0x41 || (id & 0xfff) != 0x050)
+    {
+        LOG_E("read id fail id:0x%08x", id);
+        return RT_ERROR;
+    }
+
+    pdat = rt_malloc(sizeof(struct mouse_pl050_pdata_t));
+    if(!pdat)
+    {
+        LOG_E("malloc memory failed");
+        return RT_ERROR;
+    }
+    rt_memset(pdat, 0, sizeof(struct mouse_pl050_pdata_t));
+
+    pdat->virt = virt;
+    pdat->irq = irq;
+    pdat->xmax = MOUSE_XMAX;
+    pdat->ymax = MOUSE_YMAX;
+    pdat->xpos = pdat->xmax / 2;
+    pdat->ypos = pdat->ymax / 2;
+    pdat->packet[0] = 0;
+    pdat->packet[1] = 0;
+    pdat->packet[2] = 0;
+    pdat->packet[3] = 0;
+    pdat->index = 0;
+    pdat->obtn = 0;
+
+    write8(pdat->virt + MOUSE_CLKDIV, 0);
+    write8(pdat->virt + MOUSE_CR, (1 << 2));
+    kmi_write(pdat, 0xff);
+    kmi_read(pdat, &value);
+    kmi_write(pdat, 0xf3);
+    kmi_write(pdat, 200);
+    kmi_write(pdat, 0xf3);
+    kmi_write(pdat, 100);
+    kmi_write(pdat, 0xf3);
+    kmi_write(pdat, 80);
+    kmi_write(pdat, 0xf2);
+    kmi_read(pdat, &value);
+    kmi_read(pdat, &value);
+    kmi_write(pdat, 0xf3);
+    kmi_write(pdat, 100);
+    kmi_write(pdat, 0xe8);
+    kmi_write(pdat, 0x02);
+    kmi_write(pdat, 0xe6);
+    kmi_write(pdat, 0xf4);
+    kmi_read(pdat, &value);
+    kmi_read(pdat, &value);
+    kmi_read(pdat, &value);
+    kmi_read(pdat, &value);
+    write8(pdat->virt + MOUSE_CR, (1 << 2) | (1 << 4));
+
+    rt_hw_interrupt_install(pdat->irq, mouse_pl050_interrupt, (void *)pdat, "mouse");
+    rt_hw_interrupt_umask(pdat->irq);
+
+    return RT_EOK;
+}
+INIT_DEVICE_EXPORT(rt_hw_mouse_init);
+
+#endif

+ 6 - 0
bsp/qemu-vexpress-a9/drivers/drv_mouse.h

@@ -0,0 +1,6 @@
+#ifndef __DRV_MOUSE_H__
+#define __DRV_MOUSE_H__
+
+int rt_hw_mouse_init(void);
+
+#endif

+ 467 - 0
bsp/qemu-vexpress-a9/drivers/drv_sdio.c

@@ -0,0 +1,467 @@
+#include <rthw.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <drivers/mmcsd_core.h>
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include "drv_sdio.h"
+
+#ifdef RT_USING_SDIO
+
+#define MMC_BASE_ADDR    (0x10005000)
+
+#define PL180_POWER             (0x00)
+#define PL180_CLOCK             (0x04)
+#define PL180_ARGUMENT          (0x08)
+#define PL180_COMMAND           (0x0c)
+#define PL180_RESPCMD           (0x10)
+#define PL180_RESP0             (0x14)
+#define PL180_RESP1             (0x18)
+#define PL180_RESP2             (0x1c)
+#define PL180_RESP3             (0x20)
+#define PL180_DATA_TIMER        (0x24)
+#define PL180_DATA_LENGTH       (0x28)
+#define PL180_DATA_CTRL         (0x2c)
+#define PL180_DATA_CNT          (0x30)
+#define PL180_STATUS            (0x34)
+#define PL180_CLEAR             (0x38)
+#define PL180_MASK0             (0x3c)
+#define PL180_MASK1             (0x40)
+#define PL180_SELECT            (0x44)
+#define PL180_FIFO_CNT          (0x48)
+#define PL180_FIFO              (0x80)
+
+#define PL180_RSP_NONE          (0 << 0)
+#define PL180_RSP_PRESENT       (1 << 0)
+#define PL180_RSP_136BIT        (1 << 1)
+#define PL180_RSP_CRC           (1 << 2)
+
+#define PL180_CMD_WAITRESP      (1 << 6)
+#define PL180_CMD_LONGRSP       (1 << 7)
+#define PL180_CMD_WAITINT       (1 << 8)
+#define PL180_CMD_WAITPEND      (1 << 9)
+#define PL180_CMD_ENABLE        (1 << 10)
+
+#define PL180_STAT_CMD_CRC_FAIL (1 << 0)
+#define PL180_STAT_DAT_CRC_FAIL (1 << 1)
+#define PL180_STAT_CMD_TIME_OUT (1 << 2)
+#define PL180_STAT_DAT_TIME_OUT (1 << 3)
+#define PL180_STAT_TX_UNDERRUN  (1 << 4)
+#define PL180_STAT_RX_OVERRUN   (1 << 5)
+#define PL180_STAT_CMD_RESP_END (1 << 6)
+#define PL180_STAT_CMD_SENT     (1 << 7)
+#define PL180_STAT_DAT_END      (1 << 8)
+#define PL180_STAT_DAT_BLK_END  (1 << 10)
+#define PL180_STAT_CMD_ACT      (1 << 11)
+#define PL180_STAT_TX_ACT       (1 << 12)
+#define PL180_STAT_RX_ACT       (1 << 13)
+#define PL180_STAT_TX_FIFO_HALF (1 << 14)
+#define PL180_STAT_RX_FIFO_HALF (1 << 15)
+#define PL180_STAT_TX_FIFO_FULL (1 << 16)
+#define PL180_STAT_RX_FIFO_FULL (1 << 17)
+#define PL180_STAT_TX_FIFO_ZERO (1 << 18)
+#define PL180_STAT_RX_DAT_ZERO  (1 << 19)
+#define PL180_STAT_TX_DAT_AVL   (1 << 20)
+#define PL180_STAT_RX_FIFO_AVL  (1 << 21)
+
+#define PL180_CLR_CMD_CRC_FAIL  (1 << 0)
+#define PL180_CLR_DAT_CRC_FAIL  (1 << 1)
+#define PL180_CLR_CMD_TIMEOUT   (1 << 2)
+#define PL180_CLR_DAT_TIMEOUT   (1 << 3)
+#define PL180_CLR_TX_UNDERRUN   (1 << 4)
+#define PL180_CLR_RX_OVERRUN    (1 << 5)
+#define PL180_CLR_CMD_RESP_END  (1 << 6)
+#define PL180_CLR_CMD_SENT      (1 << 7)
+#define PL180_CLR_DAT_END       (1 << 8)
+#define PL180_CLR_DAT_BLK_END   (1 << 10)
+
+#define DBG_TAG "drv.sdio"
+#define DBG_LVL DBG_INFO
+#include "rtdbg.h"
+
+struct sdhci_pl180_pdata_t
+{
+    rt_uint32_t virt;
+};
+
+static inline rt_uint32_t read32(uint32_t addr)
+{
+    return( *((volatile rt_uint32_t *)(addr)) );
+}
+
+static inline void write32(uint32_t addr, rt_uint32_t value)
+{
+    *((volatile rt_uint32_t *)(addr)) = value;
+}
+
+static rt_err_t pl180_transfer_command(struct sdhci_pl180_pdata_t * pdat, struct sdhci_cmd_t * cmd)
+{
+    rt_uint32_t cmdidx;
+    rt_uint32_t status;
+    rt_err_t ret = RT_EOK;
+
+    if(read32(pdat->virt + PL180_COMMAND) & PL180_CMD_ENABLE)
+        write32(pdat->virt + PL180_COMMAND, 0x0);
+
+    cmdidx = (cmd->cmdidx & 0xff) | PL180_CMD_ENABLE;
+    if(cmd->resptype)
+    {
+        cmdidx |= PL180_CMD_WAITRESP;
+        if(cmd->resptype & PL180_RSP_136BIT)
+            cmdidx |= PL180_CMD_LONGRSP;
+    }
+
+    write32(pdat->virt + PL180_ARGUMENT, cmd->cmdarg);
+    write32(pdat->virt + PL180_COMMAND, cmdidx);
+
+    do {
+        status = read32(pdat->virt + PL180_STATUS);
+    } while(!(status & (PL180_STAT_CMD_SENT | PL180_STAT_CMD_RESP_END | PL180_STAT_CMD_TIME_OUT | PL180_STAT_CMD_CRC_FAIL)));
+    LOG_D("mmc status done!");
+
+    if(cmd->resptype & PL180_RSP_PRESENT)
+    {
+        cmd->response[0] = read32(pdat->virt + PL180_RESP0);
+        if(cmd->resptype & PL180_RSP_136BIT)
+        {
+            LOG_D("136bit response");
+            cmd->response[1] = read32(pdat->virt + PL180_RESP1);
+            cmd->response[2] = read32(pdat->virt + PL180_RESP2);
+            cmd->response[3] = read32(pdat->virt + PL180_RESP3);
+        }
+    }
+
+    if(status & PL180_STAT_CMD_TIME_OUT)
+    {
+        ret = -RT_ETIMEOUT;
+    }
+    else if ((status & PL180_STAT_CMD_CRC_FAIL) && (cmd->resptype & PL180_RSP_CRC))
+    {
+        ret = -RT_ERROR;
+    }
+
+    write32(pdat->virt + PL180_CLEAR, (PL180_CLR_CMD_SENT | PL180_CLR_CMD_RESP_END | PL180_CLR_CMD_TIMEOUT | PL180_CLR_CMD_CRC_FAIL));
+    return ret;
+}
+
+static rt_err_t read_bytes(struct sdhci_pl180_pdata_t * pdat, rt_uint32_t * buf, rt_uint32_t blkcount, rt_uint32_t blksize)
+{
+    rt_uint32_t * tmp = buf;
+    rt_uint32_t count = blkcount * blksize;
+    rt_uint32_t status, err;
+
+    status = read32(pdat->virt + PL180_STATUS);
+    err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_RX_OVERRUN);
+    while((!err) && (count >= sizeof(rt_uint32_t)))
+    {
+        if(status & PL180_STAT_RX_FIFO_AVL)
+        {
+            *(tmp) = read32(pdat->virt + PL180_FIFO);
+            tmp++;
+            count -= sizeof(rt_uint32_t);
+        }
+        status = read32(pdat->virt + PL180_STATUS);
+        err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_RX_OVERRUN);
+    }
+
+    err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_DAT_BLK_END | PL180_STAT_RX_OVERRUN);
+    while(!err)
+    {
+        status = read32(pdat->virt + PL180_STATUS);
+        err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_DAT_BLK_END | PL180_STAT_RX_OVERRUN);
+    }
+
+    if(status & PL180_STAT_DAT_TIME_OUT)
+        return -RT_ERROR;
+    else if (status & PL180_STAT_DAT_CRC_FAIL)
+        return -RT_ERROR;
+    else if (status & PL180_STAT_RX_OVERRUN)
+        return -RT_ERROR;
+    write32(pdat->virt + PL180_CLEAR, 0x1DC007FF);
+
+    if(count)
+        return -RT_ERROR;
+
+    return RT_EOK;
+}
+
+static rt_err_t write_bytes(struct sdhci_pl180_pdata_t * pdat, rt_uint32_t * buf, rt_uint32_t blkcount, rt_uint32_t blksize)
+{
+    rt_uint32_t * tmp = buf;
+    rt_uint32_t count = blkcount * blksize;
+    rt_uint32_t status, err;
+    int i;
+
+    status = read32(pdat->virt + PL180_STATUS);
+    err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT);
+    while(!err && count)
+    {
+        if(status & PL180_STAT_TX_FIFO_HALF)
+        {
+            if(count >= 8 * sizeof(rt_uint32_t))
+            {
+                for(i = 0; i < 8; i++)
+                    write32(pdat->virt + PL180_FIFO, *(tmp + i));
+                tmp += 8;
+                count -= 8 * sizeof(rt_uint32_t);
+            }
+            else
+            {
+                while(count >= sizeof(rt_uint32_t))
+                {
+                    write32(pdat->virt + PL180_FIFO, *tmp);
+                    tmp++;
+                    count -= sizeof(rt_uint32_t);
+                }
+            }
+        }
+        status = read32(pdat->virt + PL180_STATUS);
+        err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT);
+    }
+
+    err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_DAT_BLK_END);
+    while(!err)
+    {
+        status = read32(pdat->virt + PL180_STATUS);
+        err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_DAT_BLK_END);
+    }
+
+    if(status & PL180_STAT_DAT_TIME_OUT)
+        return -RT_ERROR;
+    else if (status & PL180_STAT_DAT_CRC_FAIL)
+        return -RT_ERROR;
+    write32(pdat->virt + PL180_CLEAR, 0x1DC007FF);
+
+    if(count)
+        return -RT_ERROR;
+    return RT_EOK;
+}
+
+static rt_err_t pl180_transfer_data(struct sdhci_pl180_pdata_t * pdat, struct sdhci_cmd_t * cmd, struct sdhci_data_t * dat)
+{
+    rt_uint32_t dlen = (rt_uint32_t)(dat->blkcnt * dat->blksz);
+    rt_uint32_t blksz_bits = dat->blksz - 1;
+    rt_uint32_t dctrl = (blksz_bits << 4) | (0x1 << 0) | (0x1 << 14);
+    rt_err_t ret = -RT_ERROR;
+
+    write32(pdat->virt + PL180_DATA_TIMER, 0xffff);
+    write32(pdat->virt + PL180_DATA_LENGTH, dlen);
+
+    if(dat->flag & DATA_DIR_READ)
+    {
+        dctrl |= (0x1 << 1);
+        write32(pdat->virt + PL180_DATA_CTRL, dctrl);
+        ret = pl180_transfer_command(pdat, cmd);
+        if (ret < 0) return ret;
+        ret = read_bytes(pdat, (rt_uint32_t *)dat->buf, dat->blkcnt, dat->blksz);
+    }
+    else if(dat->flag & DATA_DIR_WRITE)
+    {
+        ret = pl180_transfer_command(pdat, cmd);
+        if (ret < 0) return ret;
+        write32(pdat->virt + PL180_DATA_CTRL, dctrl);
+        ret = write_bytes(pdat, (rt_uint32_t *)dat->buf, dat->blkcnt, dat->blksz);
+    }
+
+    return ret;
+}
+
+static rt_err_t sdhci_pl180_detect(struct sdhci_t * sdhci)
+{
+    return RT_EOK;
+}
+
+static rt_err_t sdhci_pl180_setwidth(struct sdhci_t * sdhci, rt_uint32_t width)
+{
+    return RT_EOK;
+}
+
+static rt_err_t sdhci_pl180_setclock(struct sdhci_t * sdhci, rt_uint32_t clock)
+{
+    rt_uint32_t temp = 0;
+    struct sdhci_pl180_pdata_t * pdat = (struct sdhci_pl180_pdata_t *)sdhci->priv;
+
+    if(clock)
+    {
+        temp = read32(pdat->virt + PL180_CLOCK) | (0x1<<8);
+        temp = temp; // skip warning 
+        write32(pdat->virt + PL180_CLOCK, 0x100);
+    }
+    else
+    {
+        //write32(pdat->virt + PL180_CLOCK, read32(pdat->virt + PL180_CLOCK) & (~(0x1<<8)));
+    }
+    return RT_EOK;
+}
+
+static rt_err_t sdhci_pl180_transfer(struct sdhci_t * sdhci, struct sdhci_cmd_t * cmd, struct sdhci_data_t * dat)
+{
+    struct sdhci_pl180_pdata_t * pdat = (struct sdhci_pl180_pdata_t *)sdhci->priv;
+
+    if(!dat)
+        return pl180_transfer_command(pdat, cmd);
+
+    return pl180_transfer_data(pdat, cmd, dat);
+}
+
+static void mmc_request_send(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req)
+{
+    struct sdhci_t *sdhci = (struct sdhci_t *)host->private_data;
+    struct sdhci_cmd_t cmd;
+    struct sdhci_cmd_t stop;
+    struct sdhci_data_t dat;
+
+    rt_memset(&cmd, 0, sizeof(struct sdhci_cmd_t));
+    rt_memset(&stop, 0, sizeof(struct sdhci_cmd_t));
+    rt_memset(&dat, 0, sizeof(struct sdhci_data_t));
+
+    cmd.cmdidx = req->cmd->cmd_code;
+    cmd.cmdarg = req->cmd->arg;
+    if (req->cmd->flags & RESP_MASK)
+    {
+        cmd.resptype = PL180_RSP_PRESENT;
+        if (resp_type(req->cmd) == RESP_R2)
+            cmd.resptype |= PL180_RSP_136BIT;
+    }
+    else
+        cmd.resptype = 0;
+
+    if(req->data)
+    {
+        dat.buf = (rt_uint8_t *)req->data->buf;
+        dat.flag = req->data->flags;
+        dat.blksz = req->data->blksize;
+        dat.blkcnt = req->data->blks;
+
+        req->cmd->err = sdhci_pl180_transfer(sdhci, &cmd, &dat);
+    }
+    else
+    {
+        req->cmd->err = sdhci_pl180_transfer(sdhci, &cmd, RT_NULL);
+    }
+
+    LOG_D("cmdarg:%d", cmd.cmdarg);
+    LOG_D("cmdidx:%d", cmd.cmdidx);
+
+    LOG_D("[0]:0x%08x [1]:0x%08x [2]:0x%08x [3]:0x%08x", cmd.response[0], cmd.response[1], cmd.response[2], cmd.response[3]);
+    req->cmd->resp[3] = cmd.response[3];
+    req->cmd->resp[2] = cmd.response[2];
+    req->cmd->resp[1] = cmd.response[1];
+    req->cmd->resp[0] = cmd.response[0];
+
+    if (req->stop)
+    {
+        stop.cmdidx = req->stop->cmd_code;
+        stop.cmdarg = req->stop->arg;
+        if (req->stop->flags & RESP_MASK)
+        {
+            stop.resptype = PL180_RSP_PRESENT;
+            if (resp_type(req->stop) == RESP_R2)
+                stop.resptype |= PL180_RSP_136BIT;
+        }
+        else
+            stop.resptype = 0;
+
+        req->stop->err = sdhci_pl180_transfer(sdhci, &stop, RT_NULL);
+    }
+
+    mmcsd_req_complete(host);
+}
+
+static void mmc_set_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *io_cfg)
+{
+    struct sdhci_t * sdhci = (struct sdhci_t *)host->private_data;
+
+    sdhci_pl180_setclock(sdhci, io_cfg->clock);
+    sdhci_pl180_setwidth(sdhci, io_cfg->bus_width);
+    LOG_D("clock:%d bus_width:%d", io_cfg->clock, io_cfg->bus_width);
+}
+
+static const struct rt_mmcsd_host_ops ops = 
+{
+    mmc_request_send,
+    mmc_set_iocfg,
+    RT_NULL,
+    RT_NULL,
+};
+
+int pl180_init(void)
+{
+    rt_uint32_t virt;
+    rt_uint32_t id;
+    struct rt_mmcsd_host * host = RT_NULL;
+    struct sdhci_pl180_pdata_t * pdat = RT_NULL;
+    struct sdhci_t * sdhci = RT_NULL;
+
+    host = mmcsd_alloc_host();
+    if (!host)
+    {
+        LOG_E("alloc host failed");
+        goto err;
+    }
+
+    sdhci = rt_malloc(sizeof(struct sdhci_t));
+    if (!sdhci)
+    {
+        LOG_E("alloc sdhci failed");
+        goto err;
+    }
+    rt_memset(sdhci, 0, sizeof(struct sdhci_t));
+
+    virt = MMC_BASE_ADDR;
+    id = (((read32((virt + 0xfec)) & 0xff) << 24) |
+                ((read32((virt + 0xfe8)) & 0xff) << 16) |
+                ((read32((virt + 0xfe4)) & 0xff) <<  8) |
+                ((read32((virt + 0xfe0)) & 0xff) <<  0));
+
+    LOG_D("id=0x%08x", id);
+    if(((id >> 12) & 0xff) != 0x41 || (id & 0xfff) != 0x181)
+    {
+        LOG_E("check id  failed");
+        goto err;
+    }
+
+    pdat = (struct sdhci_pl180_pdata_t *)rt_malloc(sizeof(struct sdhci_pl180_pdata_t));
+    RT_ASSERT(pdat != RT_NULL);
+
+    pdat->virt = (uint32_t)virt;
+
+    sdhci->name = "sd0";
+    sdhci->voltages = VDD_33_34;
+    sdhci->width = MMCSD_BUSWIDTH_4;
+    sdhci->clock = 26 * 1000 * 1000;
+    sdhci->removeable = RT_TRUE;
+    sdhci->detect = sdhci_pl180_detect;
+    sdhci->setwidth = sdhci_pl180_setwidth;
+    sdhci->setclock = sdhci_pl180_setclock;
+    sdhci->transfer = sdhci_pl180_transfer;
+    sdhci->priv = pdat;
+    write32(pdat->virt + PL180_POWER, 0xbf);
+
+    host->ops = &ops;
+    host->freq_min = 400000;
+    host->freq_max = 50000000;
+    host->valid_ocr = VDD_32_33 | VDD_33_34;
+    host->flags = MMCSD_MUTBLKWRITE | MMCSD_SUP_HIGHSPEED | MMCSD_SUP_SDIO_IRQ | MMCSD_BUSWIDTH_4;
+    host->max_seg_size = 2048;
+    host->max_dma_segs = 10;
+    host->max_blk_size = 512;
+    host->max_blk_count = 4096;
+
+    host->private_data = sdhci;
+
+    mmcsd_change(host);
+
+    return RT_EOK;
+
+err:
+    if(host)  rt_free(host);
+    if(sdhci) rt_free(sdhci);
+
+    return -RT_EIO;
+}
+INIT_DEVICE_EXPORT(pl180_init);
+
+#endif

+ 47 - 0
bsp/qemu-vexpress-a9/drivers/drv_sdio.h

@@ -0,0 +1,47 @@
+#ifndef __DRV_SDIO_H__
+#define __DRV_SDIO_H__
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtthread.h>
+
+struct sdhci_cmd_t
+{
+    rt_uint32_t cmdidx;
+    rt_uint32_t cmdarg;
+    rt_uint32_t resptype;
+    rt_uint32_t response[4];
+};
+
+struct sdhci_data_t
+{
+    rt_uint8_t * buf;
+    rt_uint32_t flag;
+    rt_uint32_t blksz;
+    rt_uint32_t blkcnt;
+};
+
+struct sdhci_t
+{
+    char * name;
+    rt_uint32_t voltages;
+    rt_uint32_t width;
+    rt_uint32_t clock;
+    rt_err_t removeable;
+    void * sdcard;
+
+    rt_err_t (*detect)(struct sdhci_t * sdhci);
+    rt_err_t (*setwidth)(struct sdhci_t * sdhci, rt_uint32_t width);
+    rt_err_t (*setclock)(struct sdhci_t * sdhci, rt_uint32_t clock);
+    rt_err_t (*transfer)(struct sdhci_t * sdhci, struct sdhci_cmd_t * cmd, struct sdhci_data_t * dat);
+    void * priv;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 559 - 0
bsp/qemu-vexpress-a9/drivers/drv_smc911x.c

@@ -0,0 +1,559 @@
+#include <board.h>
+#include <rtthread.h>
+#include <netif/ethernetif.h>
+#include <lwipopts.h>
+#include <automac.h>
+
+#define MAX_ADDR_LEN                6
+#define SMC911X_EMAC_DEVICE(eth)    (struct eth_device_smc911x*)(eth)
+
+#include "drv_smc911x.h"
+
+#define DRIVERNAME "EMAC"
+
+struct eth_device_smc911x
+{
+    /* inherit from Ethernet device */
+    struct eth_device parent;
+    /* interface address info. */
+    rt_uint8_t enetaddr[MAX_ADDR_LEN];         /* MAC address  */
+
+    uint32_t iobase;
+    uint32_t irqno;
+};
+static struct eth_device_smc911x _emac;
+
+int udelay(int value)
+{
+    return 0;
+}
+
+int mdelay(int value)
+{
+    return 0;
+}
+
+#if defined (CONFIG_SMC911X_32_BIT)
+rt_inline uint32_t smc911x_reg_read(struct eth_device_smc911x *dev, uint32_t offset)
+{
+    return *(volatile uint32_t*)(dev->iobase + offset);
+}
+
+rt_inline void smc911x_reg_write(struct eth_device_smc911x *dev, uint32_t offset, uint32_t val)
+{
+    *(volatile uint32_t*)(dev->iobase + offset) = val;
+}
+
+#elif defined (CONFIG_SMC911X_16_BIT)
+rt_inline uint32_t smc911x_reg_read(struct eth_device_smc911x *dev, uint32_t offset)
+{
+    volatile uint16_t *addr_16 = (uint16_t *)(dev->iobase + offset);
+    return ((*addr_16 & 0x0000ffff) | (*(addr_16 + 1) << 16));
+}
+
+rt_inline void smc911x_reg_write(struct eth_device_smc911x *dev, uint32_t offset, uint32_t val)
+{
+    *(volatile uint16_t *)(dev->iobase + offset) = (uint16_t)val;
+    *(volatile uint16_t *)(dev->iobase + offset + 2) = (uint16_t)(val >> 16);
+}
+#else
+#error "SMC911X: undefined bus width"
+#endif /* CONFIG_SMC911X_16_BIT */
+
+struct chip_id
+{
+    uint16_t id;
+    char *name;
+};
+
+static const struct chip_id chip_ids[] =
+{
+    { CHIP_89218,"LAN89218" },
+    { CHIP_9115, "LAN9115" },
+    { CHIP_9116, "LAN9116" },
+    { CHIP_9117, "LAN9117" },
+    { CHIP_9118, "LAN9118" },
+    { CHIP_9211, "LAN9211" },
+    { CHIP_9215, "LAN9215" },
+    { CHIP_9216, "LAN9216" },
+    { CHIP_9217, "LAN9217" },
+    { CHIP_9218, "LAN9218" },
+    { CHIP_9220, "LAN9220" },
+    { CHIP_9221, "LAN9221" },
+    { 0, RT_NULL },
+};
+
+static uint32_t smc911x_get_mac_csr(struct eth_device_smc911x *dev, uint8_t reg)
+{
+    while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) ;
+
+    smc911x_reg_write(dev, MAC_CSR_CMD, MAC_CSR_CMD_CSR_BUSY | MAC_CSR_CMD_R_NOT_W | reg);
+
+    while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) ;
+
+    return smc911x_reg_read(dev, MAC_CSR_DATA);
+}
+
+static void smc911x_set_mac_csr(struct eth_device_smc911x *dev, uint8_t reg, uint32_t data)
+{
+    while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) ;
+
+    smc911x_reg_write(dev, MAC_CSR_DATA, data);
+    smc911x_reg_write(dev, MAC_CSR_CMD, MAC_CSR_CMD_CSR_BUSY | reg);
+
+    while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY) ;
+}
+
+static int smc911x_detect_chip(struct eth_device_smc911x *dev)
+{
+    unsigned long val, i;
+
+    val = smc911x_reg_read(dev, BYTE_TEST);
+    if (val == 0xffffffff)
+    {
+        /* Special case -- no chip present */
+        return -1;
+    }
+    else if (val != 0x87654321)
+    {
+        rt_kprintf(DRIVERNAME ": Invalid chip endian 0x%08lx\n", val);
+        return -1;
+    }
+
+    val = smc911x_reg_read(dev, ID_REV) >> 16;
+    for (i = 0; chip_ids[i].id != 0; i++)
+    {
+        if (chip_ids[i].id == val) break;
+    }
+
+    if (!chip_ids[i].id)
+    {
+        rt_kprintf(DRIVERNAME ": Unknown chip ID %04lx\n", val);
+        return -1;
+    }
+
+    return 0;
+}
+
+static void smc911x_reset(struct eth_device_smc911x *dev)
+{
+    int timeout;
+
+    /*
+    *  Take out of PM setting first
+    *  Device is already wake up if PMT_CTRL_READY bit is set
+    */
+    if ((smc911x_reg_read(dev, PMT_CTRL) & PMT_CTRL_READY) == 0)
+    {
+        /* Write to the bytetest will take out of powerdown */
+        smc911x_reg_write(dev, BYTE_TEST, 0x0);
+
+        timeout = 10;
+
+        while (timeout-- && !(smc911x_reg_read(dev, PMT_CTRL) & PMT_CTRL_READY))
+            udelay(10);
+
+        if (timeout < 0)
+        {
+            rt_kprintf(DRIVERNAME
+                       ": timeout waiting for PM restore\n");
+            return;
+        }
+    }
+
+    /* Disable interrupts */
+    smc911x_reg_write(dev, INT_EN, 0);
+    smc911x_reg_write(dev, HW_CFG, HW_CFG_SRST);
+
+    timeout = 1000;
+    while (timeout-- && smc911x_reg_read(dev, E2P_CMD) & E2P_CMD_EPC_BUSY)
+        udelay(10);
+
+    if (timeout < 0)
+    {
+        rt_kprintf(DRIVERNAME ": reset timeout\n");
+        return;
+    }
+
+    /* Reset the FIFO level and flow control settings */
+    smc911x_set_mac_csr(dev, FLOW, FLOW_FCPT | FLOW_FCEN);
+    smc911x_reg_write(dev, AFC_CFG, 0x0050287F);
+
+    /* Set to LED outputs */
+    smc911x_reg_write(dev, GPIO_CFG, 0x70070000);
+}
+
+static void smc911x_handle_mac_address(struct eth_device_smc911x *dev)
+{
+    unsigned long addrh, addrl;
+    uint8_t *m = dev->enetaddr;
+
+    addrl = m[0] | (m[1] << 8) | (m[2] << 16) | (m[3] << 24);
+    addrh = m[4] | (m[5] << 8);
+
+    smc911x_set_mac_csr(dev, ADDRL, addrl);
+    smc911x_set_mac_csr(dev, ADDRH, addrh);
+}
+
+static int smc911x_eth_phy_read(struct eth_device_smc911x *dev,
+                                uint8_t phy, uint8_t reg, uint16_t *val)
+{
+    while (smc911x_get_mac_csr(dev, MII_ACC) & MII_ACC_MII_BUSY) ;
+
+    smc911x_set_mac_csr(dev, MII_ACC, phy << 11 | reg << 6 | MII_ACC_MII_BUSY);
+
+    while (smc911x_get_mac_csr(dev, MII_ACC) & MII_ACC_MII_BUSY) ;
+
+    *val = smc911x_get_mac_csr(dev, MII_DATA);
+
+    return 0;
+}
+
+static int smc911x_eth_phy_write(struct eth_device_smc911x *dev,
+                                 uint8_t phy, uint8_t reg, uint16_t  val)
+{
+    while (smc911x_get_mac_csr(dev, MII_ACC) & MII_ACC_MII_BUSY)
+        ;
+
+    smc911x_set_mac_csr(dev, MII_DATA, val);
+    smc911x_set_mac_csr(dev, MII_ACC,
+                        phy << 11 | reg << 6 | MII_ACC_MII_BUSY | MII_ACC_MII_WRITE);
+
+    while (smc911x_get_mac_csr(dev, MII_ACC) & MII_ACC_MII_BUSY)
+        ;
+    return 0;
+}
+
+static int smc911x_phy_reset(struct eth_device_smc911x *dev)
+{
+    uint32_t reg;
+
+    reg = smc911x_reg_read(dev, PMT_CTRL);
+    reg &= ~0xfffff030;
+    reg |= PMT_CTRL_PHY_RST;
+    smc911x_reg_write(dev, PMT_CTRL, reg);
+
+    mdelay(100);
+
+    return 0;
+}
+
+static void smc911x_phy_configure(struct eth_device_smc911x *dev)
+{
+    int timeout;
+    uint16_t status;
+
+    smc911x_phy_reset(dev);
+
+    smc911x_eth_phy_write(dev, 1, MII_BMCR, BMCR_RESET);
+    mdelay(1);
+    smc911x_eth_phy_write(dev, 1, MII_ADVERTISE, 0x01e1);
+    smc911x_eth_phy_write(dev, 1, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART);
+
+    timeout = 5000;
+    do
+    {
+        mdelay(1);
+        if ((timeout--) == 0)
+            goto err_out;
+
+        if (smc911x_eth_phy_read(dev, 1, MII_BMSR, &status) != 0)
+            goto err_out;
+    }
+    while (!(status & BMSR_LSTATUS));
+
+    return;
+
+err_out:
+    rt_kprintf(DRIVERNAME ": autonegotiation timed out\n");
+}
+
+static void smc911x_enable(struct eth_device_smc911x *dev)
+{
+    /* Enable TX */
+    smc911x_reg_write(dev, HW_CFG, 8 << 16 | HW_CFG_SF);
+
+    smc911x_reg_write(dev, GPT_CFG, GPT_CFG_TIMER_EN | 10000);
+
+    smc911x_reg_write(dev, TX_CFG, TX_CFG_TX_ON);
+
+    /* no padding to start of packets */
+    smc911x_reg_write(dev, RX_CFG, 0);
+
+    smc911x_set_mac_csr(dev, MAC_CR, MAC_CR_TXEN | MAC_CR_RXEN |
+                        MAC_CR_HBDIS);
+}
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+/* wrapper for smc911x_eth_phy_read */
+static int smc911x_miiphy_read(struct mii_dev *bus, int phy, int devad,
+                               int reg)
+{
+    uint16_t val = 0;
+    struct eth_device_smc911x *dev = eth_get_dev_by_name(bus->name);
+    if (dev)
+    {
+        int retval = smc911x_eth_phy_read(dev, phy, reg, &val);
+        if (retval < 0)
+            return retval;
+        return val;
+    }
+    return -ENODEV;
+}
+
+/* wrapper for smc911x_eth_phy_write */
+static int smc911x_miiphy_write(struct mii_dev *bus, int phy, int devad,
+                                int reg, uint16_t val)
+{
+    struct eth_device_smc911x *dev = eth_get_dev_by_name(bus->name);
+    if (dev)
+        return smc911x_eth_phy_write(dev, phy, reg, val);
+    return -ENODEV;
+}
+#endif
+
+static void smc911x_isr(int vector, void *param)
+{
+    uint32_t status;
+    struct eth_device_smc911x *emac;
+
+    emac = SMC911X_EMAC_DEVICE(param);
+
+    status = smc911x_reg_read(emac, INT_STS);
+    
+    if (status & INT_STS_RSFL)
+    {
+        eth_device_ready(&emac->parent);
+    }
+    smc911x_reg_write(emac, INT_STS, status);
+
+    return ;
+}
+
+static rt_err_t smc911x_emac_init(rt_device_t dev)
+{
+    // uint32_t value;
+    struct eth_device_smc911x *emac;
+
+    emac = SMC911X_EMAC_DEVICE(dev);
+    RT_ASSERT(emac != RT_NULL);
+
+    smc911x_reset(emac);
+
+    /* Configure the PHY, initialize the link state */
+    smc911x_phy_configure(emac);
+    smc911x_handle_mac_address(emac);
+
+    /* Turn on Tx + Rx */
+    smc911x_enable(emac);
+
+#if 1
+    /* Interrupt on every received packet */
+    smc911x_reg_write(emac, FIFO_INT, 0x01 << 8);
+    smc911x_reg_write(emac, INT_EN, INT_EN_RDFL_EN | INT_EN_RSFL_EN);
+
+    /* enable interrupt */
+    smc911x_reg_write(emac, INT_CFG, INT_CFG_IRQ_EN | INT_CFG_IRQ_POL | INT_CFG_IRQ_TYPE);
+#else
+
+    /* disable interrupt */
+    smc911x_reg_write(emac, INT_EN, 0);
+    value = smc911x_reg_read(emac, INT_CFG);
+    value &= ~INT_CFG_IRQ_EN;
+    smc911x_reg_write(emac, INT_CFG, value);
+#endif
+
+    rt_hw_interrupt_install(emac->irqno, smc911x_isr, emac, "smc911x");
+    rt_hw_interrupt_umask(emac->irqno);
+
+    return RT_EOK;
+}
+
+static rt_err_t smc911x_emac_control(rt_device_t dev, int cmd, void *args)
+{
+    struct eth_device_smc911x *emac;
+
+    emac = SMC911X_EMAC_DEVICE(dev);
+    RT_ASSERT(emac != RT_NULL);
+
+    switch(cmd)
+    {
+    case NIOCTL_GADDR:
+        /* get MAC address */
+        if(args) rt_memcpy(args, emac->enetaddr, 6);
+        else return -RT_ERROR;
+        break;
+    default :
+        break;
+    }
+    return RT_EOK;
+}
+
+/* Ethernet device interface */
+/* transmit packet. */
+static uint8_t tx_buf[2048];
+rt_err_t smc911x_emac_tx(rt_device_t dev, struct pbuf* p)
+{
+    struct eth_device_smc911x *emac;
+
+    uint32_t *data;
+    uint32_t tmplen;
+    uint32_t status;
+    uint32_t length;
+
+    emac = SMC911X_EMAC_DEVICE(dev);
+    RT_ASSERT(emac != RT_NULL);
+
+    /* copy pbuf to a whole ETH frame */
+    pbuf_copy_partial(p, tx_buf, p->tot_len, 0);
+
+    /* send it out */
+    data = (uint32_t*)tx_buf;
+    length = p->tot_len;
+
+    smc911x_reg_write(emac, TX_DATA_FIFO, TX_CMD_A_INT_FIRST_SEG | TX_CMD_A_INT_LAST_SEG | length);
+    smc911x_reg_write(emac, TX_DATA_FIFO, length);
+
+    tmplen = (length + 3) / 4;
+    while (tmplen--)
+    {
+        smc911x_reg_write(emac, TX_DATA_FIFO, *data++);
+    }
+
+    /* wait for transmission */
+    while (!((smc911x_reg_read(emac, TX_FIFO_INF) & TX_FIFO_INF_TSUSED) >> 16));
+
+    /* get status. Ignore 'no carrier' error, it has no meaning for
+     * full duplex operation
+     */
+    status = smc911x_reg_read(emac, TX_STATUS_FIFO) &
+             (TX_STS_LOC | TX_STS_LATE_COLL | TX_STS_MANY_COLL |
+              TX_STS_MANY_DEFER | TX_STS_UNDERRUN);
+
+    if (!status) return 0;
+
+    rt_kprintf(DRIVERNAME ": failed to send packet: %s%s%s%s%s\n",
+               status & TX_STS_LOC ? "TX_STS_LOC " : "",
+               status & TX_STS_LATE_COLL ? "TX_STS_LATE_COLL " : "",
+               status & TX_STS_MANY_COLL ? "TX_STS_MANY_COLL " : "",
+               status & TX_STS_MANY_DEFER ? "TX_STS_MANY_DEFER " : "",
+               status & TX_STS_UNDERRUN ? "TX_STS_UNDERRUN" : "");
+
+    return -RT_EIO;
+}
+
+/* reception packet. */
+struct pbuf *smc911x_emac_rx(rt_device_t dev)
+{
+    struct pbuf* p = RT_NULL;
+    struct eth_device_smc911x *emac;
+
+    emac = SMC911X_EMAC_DEVICE(dev);
+    RT_ASSERT(emac != RT_NULL);
+
+    /* take the emac buffer to the pbuf */
+    if ((smc911x_reg_read(emac, RX_FIFO_INF) & RX_FIFO_INF_RXSUSED) >> 16)
+    {
+        uint32_t status;
+        uint32_t pktlen, tmplen;
+
+        status = smc911x_reg_read(emac, RX_STATUS_FIFO);
+
+        /* get frame length */
+        pktlen = (status & RX_STS_PKT_LEN) >> 16;
+
+        smc911x_reg_write(emac, RX_CFG, 0);
+
+        tmplen = (pktlen + 3) / 4;
+
+        /* allocate pbuf */
+        p = pbuf_alloc(PBUF_RAW, tmplen * 4, PBUF_RAM);
+        if (p)
+        {
+            uint32_t *data = (uint32_t *)p->payload;
+            while (tmplen--)
+            {
+                *data++ = smc911x_reg_read(emac, RX_DATA_FIFO);
+            }
+        }
+
+        if (status & RX_STS_ES)
+        {
+            rt_kprintf(DRIVERNAME ": dropped bad packet. Status: 0x%08x\n", status);
+        }
+    }
+
+    return p;
+}
+
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops smc911x_emac_ops = 
+{
+    smc911x_emac_init,
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    smc911x_emac_control
+};
+#endif
+
+int smc911x_emac_hw_init(void)
+{
+    _emac.iobase = VEXPRESS_ETH_BASE;
+    _emac.irqno  = IRQ_VEXPRESS_A9_ETH;
+
+    if (smc911x_detect_chip(&_emac))
+    {
+        rt_kprintf("no smc911x network interface found!\n");
+        return -1;
+    }
+
+    /* set INT CFG */
+    smc911x_reg_write(&_emac, INT_CFG, INT_CFG_IRQ_POL | INT_CFG_IRQ_TYPE);
+
+    /* test MAC address */
+    _emac.enetaddr[0] = AUTOMAC0;
+    _emac.enetaddr[1] = AUTOMAC1;
+    _emac.enetaddr[2] = AUTOMAC2;
+    _emac.enetaddr[3] = AUTOMAC3;
+    _emac.enetaddr[4] = AUTOMAC4;
+    _emac.enetaddr[5] = AUTOMAC5;
+
+#ifdef RT_USING_DEVICE_OPS
+    _emac.parent.parent.ops        = &smc911x_emac_ops;
+#else
+    _emac.parent.parent.init       = smc911x_emac_init;
+    _emac.parent.parent.open       = RT_NULL;
+    _emac.parent.parent.close      = RT_NULL;
+    _emac.parent.parent.read       = RT_NULL;
+    _emac.parent.parent.write      = RT_NULL;
+    _emac.parent.parent.control    = smc911x_emac_control;
+#endif
+    _emac.parent.parent.user_data  = RT_NULL;
+    _emac.parent.eth_rx     = smc911x_emac_rx;
+    _emac.parent.eth_tx     = smc911x_emac_tx;
+
+    /* register ETH device */
+    eth_device_init(&(_emac.parent), "e0");
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+    {
+        int retval;
+        struct mii_dev *mdiodev = mdio_alloc();
+        if (!mdiodev)
+            return -ENOMEM;
+        strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
+        mdiodev->read = smc911x_miiphy_read;
+        mdiodev->write = smc911x_miiphy_write;
+
+        retval = mdio_register(mdiodev);
+        if (retval < 0)
+            return retval;
+    }
+#endif
+
+    eth_device_linkchange(&_emac.parent, RT_TRUE);
+    return 0;
+}
+INIT_APP_EXPORT(smc911x_emac_hw_init);

+ 402 - 0
bsp/qemu-vexpress-a9/drivers/drv_smc911x.h

@@ -0,0 +1,402 @@
+/*
+ * SMSC LAN9[12]1[567] Network driver
+ *
+ * (c) 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _SMC911X_H_
+#define _SMC911X_H_
+
+#include <stdint.h>
+
+#define CONFIG_SMC911X_32_BIT
+
+/* Below are the register offsets and bit definitions
+ * of the Lan911x memory space
+ */
+#define RX_DATA_FIFO                    0x00
+
+#define TX_DATA_FIFO                    0x20
+#define TX_CMD_A_INT_ON_COMP            0x80000000
+#define TX_CMD_A_INT_BUF_END_ALGN       0x03000000
+#define TX_CMD_A_INT_4_BYTE_ALGN        0x00000000
+#define TX_CMD_A_INT_16_BYTE_ALGN       0x01000000
+#define TX_CMD_A_INT_32_BYTE_ALGN       0x02000000
+#define TX_CMD_A_INT_DATA_OFFSET        0x001F0000
+#define TX_CMD_A_INT_FIRST_SEG          0x00002000
+#define TX_CMD_A_INT_LAST_SEG           0x00001000
+#define TX_CMD_A_BUF_SIZE               0x000007FF
+#define TX_CMD_B_PKT_TAG                0xFFFF0000
+#define TX_CMD_B_ADD_CRC_DISABLE        0x00002000
+#define TX_CMD_B_DISABLE_PADDING        0x00001000
+#define TX_CMD_B_PKT_BYTE_LENGTH        0x000007FF
+
+#define RX_STATUS_FIFO              0x40
+#define RX_STS_PKT_LEN              0x3FFF0000
+#define RX_STS_ES                   0x00008000
+#define RX_STS_BCST                 0x00002000
+#define RX_STS_LEN_ERR              0x00001000
+#define RX_STS_RUNT_ERR             0x00000800
+#define RX_STS_MCAST                0x00000400
+#define RX_STS_TOO_LONG             0x00000080
+#define RX_STS_COLL                 0x00000040
+#define RX_STS_ETH_TYPE             0x00000020
+#define RX_STS_WDOG_TMT             0x00000010
+#define RX_STS_MII_ERR              0x00000008
+#define RX_STS_DRIBBLING            0x00000004
+#define RX_STS_CRC_ERR              0x00000002
+#define RX_STATUS_FIFO_PEEK         0x44
+#define TX_STATUS_FIFO              0x48
+#define TX_STS_TAG                  0xFFFF0000
+#define TX_STS_ES                   0x00008000
+#define TX_STS_LOC                  0x00000800
+#define TX_STS_NO_CARR              0x00000400
+#define TX_STS_LATE_COLL            0x00000200
+#define TX_STS_MANY_COLL            0x00000100
+#define TX_STS_COLL_CNT             0x00000078
+#define TX_STS_MANY_DEFER           0x00000004
+#define TX_STS_UNDERRUN             0x00000002
+#define TX_STS_DEFERRED             0x00000001
+#define TX_STATUS_FIFO_PEEK         0x4C
+#define ID_REV                      0x50
+#define ID_REV_CHIP_ID              0xFFFF0000  /* RO */
+#define ID_REV_REV_ID               0x0000FFFF  /* RO */
+
+#define INT_CFG                     0x54
+#define INT_CFG_INT_DEAS            0xFF000000  /* R/W */
+#define INT_CFG_INT_DEAS_CLR        0x00004000
+#define INT_CFG_INT_DEAS_STS        0x00002000
+#define INT_CFG_IRQ_INT             0x00001000  /* RO */
+#define INT_CFG_IRQ_EN              0x00000100  /* R/W */
+/* R/W Not Affected by SW Reset */
+#define INT_CFG_IRQ_POL             0x00000010
+/* R/W Not Affected by SW Reset */
+#define INT_CFG_IRQ_TYPE            0x00000001
+
+#define INT_STS                     0x58
+#define INT_STS_SW_INT              0x80000000  /* R/WC */
+#define INT_STS_TXSTOP_INT          0x02000000  /* R/WC */
+#define INT_STS_RXSTOP_INT          0x01000000  /* R/WC */
+#define INT_STS_RXDFH_INT           0x00800000  /* R/WC */
+#define INT_STS_RXDF_INT            0x00400000  /* R/WC */
+#define INT_STS_TX_IOC              0x00200000  /* R/WC */
+#define INT_STS_RXD_INT             0x00100000  /* R/WC */
+#define INT_STS_GPT_INT             0x00080000  /* R/WC */
+#define INT_STS_PHY_INT             0x00040000  /* RO */
+#define INT_STS_PME_INT             0x00020000  /* R/WC */
+#define INT_STS_TXSO                0x00010000  /* R/WC */
+#define INT_STS_RWT                 0x00008000  /* R/WC */
+#define INT_STS_RXE                 0x00004000  /* R/WC */
+#define INT_STS_TXE                 0x00002000  /* R/WC */
+/*#define   INT_STS_ERX     0x00001000*/  /* R/WC */
+#define INT_STS_TDFU                0x00000800  /* R/WC */
+#define INT_STS_TDFO                0x00000400  /* R/WC */
+#define INT_STS_TDFA                0x00000200  /* R/WC */
+#define INT_STS_TSFF                0x00000100  /* R/WC */
+#define INT_STS_TSFL                0x00000080  /* R/WC */
+/*#define   INT_STS_RXDF        0x00000040*/  /* R/WC */
+#define INT_STS_RDFO                0x00000040  /* R/WC */
+#define INT_STS_RDFL                0x00000020  /* R/WC */
+#define INT_STS_RSFF                0x00000010  /* R/WC */
+#define INT_STS_RSFL                0x00000008  /* R/WC */
+#define INT_STS_GPIO2_INT           0x00000004  /* R/WC */
+#define INT_STS_GPIO1_INT           0x00000002  /* R/WC */
+#define INT_STS_GPIO0_INT           0x00000001  /* R/WC */
+#define INT_EN                      0x5C
+#define INT_EN_SW_INT_EN            0x80000000  /* R/W */
+#define INT_EN_TXSTOP_INT_EN        0x02000000  /* R/W */
+#define INT_EN_RXSTOP_INT_EN        0x01000000  /* R/W */
+#define INT_EN_RXDFH_INT_EN         0x00800000  /* R/W */
+/*#define   INT_EN_RXDF_INT_EN      0x00400000*/  /* R/W */
+#define INT_EN_TIOC_INT_EN          0x00200000  /* R/W */
+#define INT_EN_RXD_INT_EN           0x00100000  /* R/W */
+#define INT_EN_GPT_INT_EN           0x00080000  /* R/W */
+#define INT_EN_PHY_INT_EN           0x00040000  /* R/W */
+#define INT_EN_PME_INT_EN           0x00020000  /* R/W */
+#define INT_EN_TXSO_EN              0x00010000  /* R/W */
+#define INT_EN_RWT_EN               0x00008000  /* R/W */
+#define INT_EN_RXE_EN               0x00004000  /* R/W */
+#define INT_EN_TXE_EN               0x00002000  /* R/W */
+/*#define   INT_EN_ERX_EN           0x00001000*/  /* R/W */
+#define INT_EN_TDFU_EN              0x00000800  /* R/W */
+#define INT_EN_TDFO_EN              0x00000400  /* R/W */
+#define INT_EN_TDFA_EN              0x00000200  /* R/W */
+#define INT_EN_TSFF_EN              0x00000100  /* R/W */
+#define INT_EN_TSFL_EN              0x00000080  /* R/W */
+/*#define   INT_EN_RXDF_EN          0x00000040*/  /* R/W */
+#define INT_EN_RDFO_EN              0x00000040  /* R/W */
+#define INT_EN_RDFL_EN              0x00000020  /* R/W */
+#define INT_EN_RSFF_EN              0x00000010  /* R/W */
+#define INT_EN_RSFL_EN              0x00000008  /* R/W */
+#define INT_EN_GPIO2_INT            0x00000004  /* R/W */
+#define INT_EN_GPIO1_INT            0x00000002  /* R/W */
+#define INT_EN_GPIO0_INT            0x00000001  /* R/W */
+
+#define BYTE_TEST                   0x64
+#define FIFO_INT                    0x68
+#define FIFO_INT_TX_AVAIL_LEVEL     0xFF000000  /* R/W */
+#define FIFO_INT_TX_STS_LEVEL       0x00FF0000  /* R/W */
+#define FIFO_INT_RX_AVAIL_LEVEL     0x0000FF00  /* R/W */
+#define FIFO_INT_RX_STS_LEVEL       0x000000FF  /* R/W */
+
+#define RX_CFG                      0x6C
+#define RX_CFG_RX_END_ALGN          0xC0000000  /* R/W */
+#define     RX_CFG_RX_END_ALGN4     0x00000000  /* R/W */
+#define     RX_CFG_RX_END_ALGN16    0x40000000  /* R/W */
+#define     RX_CFG_RX_END_ALGN32    0x80000000  /* R/W */
+#define RX_CFG_RX_DMA_CNT           0x0FFF0000  /* R/W */
+#define RX_CFG_RX_DUMP              0x00008000  /* R/W */
+#define RX_CFG_RXDOFF               0x00001F00  /* R/W */
+/*#define   RX_CFG_RXBAD            0x00000001*/  /* R/W */
+
+#define TX_CFG                      0x70
+/*#define   TX_CFG_TX_DMA_LVL       0xE0000000*/     /* R/W */
+/* R/W Self Clearing */
+/*#define   TX_CFG_TX_DMA_CNT       0x0FFF0000*/
+#define TX_CFG_TXS_DUMP             0x00008000  /* Self Clearing */
+#define TX_CFG_TXD_DUMP             0x00004000  /* Self Clearing */
+#define TX_CFG_TXSAO                0x00000004  /* R/W */
+#define TX_CFG_TX_ON                0x00000002  /* R/W */
+#define TX_CFG_STOP_TX              0x00000001  /* Self Clearing */
+
+#define HW_CFG                      0x74
+#define HW_CFG_TTM                  0x00200000  /* R/W */
+#define HW_CFG_SF                   0x00100000  /* R/W */
+#define HW_CFG_TX_FIF_SZ            0x000F0000  /* R/W */
+#define HW_CFG_TR                   0x00003000  /* R/W */
+#define HW_CFG_PHY_CLK_SEL          0x00000060  /* R/W */
+#define HW_CFG_PHY_CLK_SEL_INT_PHY  0x00000000 /* R/W */
+#define HW_CFG_PHY_CLK_SEL_EXT_PHY  0x00000020 /* R/W */
+#define HW_CFG_PHY_CLK_SEL_CLK_DIS  0x00000040 /* R/W */
+#define HW_CFG_SMI_SEL              0x00000010  /* R/W */
+#define HW_CFG_EXT_PHY_DET          0x00000008  /* RO */
+#define HW_CFG_EXT_PHY_EN           0x00000004  /* R/W */
+#define HW_CFG_32_16_BIT_MODE       0x00000004  /* RO */
+#define HW_CFG_SRST_TO              0x00000002  /* RO */
+#define HW_CFG_SRST                 0x00000001  /* Self Clearing */
+
+#define RX_DP_CTRL                  0x78
+#define RX_DP_CTRL_RX_FFWD          0x80000000  /* R/W */
+#define RX_DP_CTRL_FFWD_BUSY        0x80000000  /* RO */
+
+#define RX_FIFO_INF                 0x7C
+#define  RX_FIFO_INF_RXSUSED        0x00FF0000  /* RO */
+#define  RX_FIFO_INF_RXDUSED        0x0000FFFF  /* RO */
+
+#define TX_FIFO_INF                 0x80
+#define TX_FIFO_INF_TSUSED          0x00FF0000  /* RO */
+#define TX_FIFO_INF_TDFREE          0x0000FFFF  /* RO */
+
+#define PMT_CTRL                    0x84
+#define PMT_CTRL_PM_MODE            0x00003000  /* Self Clearing */
+#define PMT_CTRL_PHY_RST            0x00000400  /* Self Clearing */
+#define PMT_CTRL_WOL_EN             0x00000200  /* R/W */
+#define PMT_CTRL_ED_EN              0x00000100  /* R/W */
+/* R/W Not Affected by SW Reset */
+#define PMT_CTRL_PME_TYPE           0x00000040
+#define PMT_CTRL_WUPS               0x00000030  /* R/WC */
+#define PMT_CTRL_WUPS_NOWAKE        0x00000000  /* R/WC */
+#define PMT_CTRL_WUPS_ED            0x00000010  /* R/WC */
+#define PMT_CTRL_WUPS_WOL           0x00000020  /* R/WC */
+#define PMT_CTRL_WUPS_MULTI         0x00000030  /* R/WC */
+#define PMT_CTRL_PME_IND            0x00000008  /* R/W */
+#define PMT_CTRL_PME_POL            0x00000004  /* R/W */
+/* R/W Not Affected by SW Reset */
+#define PMT_CTRL_PME_EN             0x00000002
+#define PMT_CTRL_READY              0x00000001  /* RO */
+
+#define GPIO_CFG                    0x88
+#define GPIO_CFG_LED3_EN            0x40000000  /* R/W */
+#define GPIO_CFG_LED2_EN            0x20000000  /* R/W */
+#define GPIO_CFG_LED1_EN            0x10000000  /* R/W */
+#define GPIO_CFG_GPIO2_INT_POL      0x04000000  /* R/W */
+#define GPIO_CFG_GPIO1_INT_POL      0x02000000  /* R/W */
+#define GPIO_CFG_GPIO0_INT_POL      0x01000000  /* R/W */
+#define GPIO_CFG_EEPR_EN            0x00700000  /* R/W */
+#define GPIO_CFG_GPIOBUF2           0x00040000  /* R/W */
+#define GPIO_CFG_GPIOBUF1           0x00020000  /* R/W */
+#define GPIO_CFG_GPIOBUF0           0x00010000  /* R/W */
+#define GPIO_CFG_GPIODIR2           0x00000400  /* R/W */
+#define GPIO_CFG_GPIODIR1           0x00000200  /* R/W */
+#define GPIO_CFG_GPIODIR0           0x00000100  /* R/W */
+#define GPIO_CFG_GPIOD4             0x00000010  /* R/W */
+#define GPIO_CFG_GPIOD3             0x00000008  /* R/W */
+#define GPIO_CFG_GPIOD2             0x00000004  /* R/W */
+#define GPIO_CFG_GPIOD1             0x00000002  /* R/W */
+#define GPIO_CFG_GPIOD0             0x00000001  /* R/W */
+
+#define GPT_CFG                     0x8C
+#define GPT_CFG_TIMER_EN            0x20000000  /* R/W */
+#define GPT_CFG_GPT_LOAD            0x0000FFFF  /* R/W */
+
+#define GPT_CNT                     0x90
+#define GPT_CNT_GPT_CNT             0x0000FFFF  /* RO */
+
+#define ENDIAN                      0x98
+#define FREE_RUN                    0x9C
+#define RX_DROP                     0xA0
+#define MAC_CSR_CMD                 0xA4
+#define  MAC_CSR_CMD_CSR_BUSY       0x80000000  /* Self Clearing */
+#define  MAC_CSR_CMD_R_NOT_W        0x40000000  /* R/W */
+#define  MAC_CSR_CMD_CSR_ADDR       0x000000FF  /* R/W */
+
+#define MAC_CSR_DATA                0xA8
+#define AFC_CFG                     0xAC
+#define     AFC_CFG_AFC_HI          0x00FF0000  /* R/W */
+#define     AFC_CFG_AFC_LO          0x0000FF00  /* R/W */
+#define     AFC_CFG_BACK_DUR        0x000000F0  /* R/W */
+#define     AFC_CFG_FCMULT          0x00000008  /* R/W */
+#define     AFC_CFG_FCBRD           0x00000004  /* R/W */
+#define     AFC_CFG_FCADD           0x00000002  /* R/W */
+#define     AFC_CFG_FCANY           0x00000001  /* R/W */
+
+#define E2P_CMD                     0xB0
+#define     E2P_CMD_EPC_BUSY        0x80000000  /* Self Clearing */
+#define     E2P_CMD_EPC_CMD         0x70000000  /* R/W */
+#define     E2P_CMD_EPC_CMD_READ    0x00000000  /* R/W */
+#define     E2P_CMD_EPC_CMD_EWDS    0x10000000  /* R/W */
+#define     E2P_CMD_EPC_CMD_EWEN    0x20000000  /* R/W */
+#define     E2P_CMD_EPC_CMD_WRITE   0x30000000  /* R/W */
+#define     E2P_CMD_EPC_CMD_WRAL    0x40000000  /* R/W */
+#define     E2P_CMD_EPC_CMD_ERASE   0x50000000  /* R/W */
+#define     E2P_CMD_EPC_CMD_ERAL    0x60000000  /* R/W */
+#define     E2P_CMD_EPC_CMD_RELOAD  0x70000000  /* R/W */
+#define     E2P_CMD_EPC_TIMEOUT     0x00000200  /* RO */
+#define     E2P_CMD_MAC_ADDR_LOADED 0x00000100  /* RO */
+#define     E2P_CMD_EPC_ADDR        0x000000FF  /* R/W */
+
+#define E2P_DATA                0xB4
+#define E2P_DATA_EEPROM_DATA    0x000000FF  /* R/W */
+/* end of LAN register offsets and bit definitions */
+
+/* MAC Control and Status registers */
+#define MAC_CR                  0x01  /* R/W */
+
+/* MAC_CR - MAC Control Register */
+#define MAC_CR_RXALL            0x80000000
+/* TODO: delete this bit? It is not described in the data sheet. */
+#define MAC_CR_HBDIS            0x10000000
+#define MAC_CR_RCVOWN           0x00800000
+#define MAC_CR_LOOPBK           0x00200000
+#define MAC_CR_FDPX             0x00100000
+#define MAC_CR_MCPAS            0x00080000
+#define MAC_CR_PRMS             0x00040000
+#define MAC_CR_INVFILT          0x00020000
+#define MAC_CR_PASSBAD          0x00010000
+#define MAC_CR_HFILT            0x00008000
+#define MAC_CR_HPFILT           0x00002000
+#define MAC_CR_LCOLL            0x00001000
+#define MAC_CR_BCAST            0x00000800
+#define MAC_CR_DISRTY           0x00000400
+#define MAC_CR_PADSTR           0x00000100
+#define MAC_CR_BOLMT_MASK       0x000000C0
+#define MAC_CR_DFCHK            0x00000020
+#define MAC_CR_TXEN             0x00000008
+#define MAC_CR_RXEN             0x00000004
+
+#define ADDRH                   0x02      /* R/W mask 0x0000FFFFUL */
+#define ADDRL                   0x03      /* R/W mask 0xFFFFFFFFUL */
+#define HASHH                   0x04      /* R/W */
+#define HASHL                   0x05      /* R/W */
+
+#define MII_ACC                 0x06      /* R/W */
+#define MII_ACC_PHY_ADDR        0x0000F800
+#define MII_ACC_MIIRINDA        0x000007C0
+#define MII_ACC_MII_WRITE       0x00000002
+#define MII_ACC_MII_BUSY        0x00000001
+
+#define MII_DATA            0x07      /* R/W mask 0x0000FFFFUL */
+
+#define FLOW                0x08      /* R/W */
+#define FLOW_FCPT           0xFFFF0000
+#define FLOW_FCPASS         0x00000004
+#define FLOW_FCEN           0x00000002
+#define FLOW_FCBSY          0x00000001
+
+#define VLAN1               0x09      /* R/W mask 0x0000FFFFUL */
+#define VLAN1_VTI1          0x0000ffff
+
+#define VLAN2               0x0A      /* R/W mask 0x0000FFFFUL */
+#define VLAN2_VTI2          0x0000ffff
+
+#define WUFF                0x0B      /* WO */
+
+#define WUCSR               0x0C      /* R/W */
+#define WUCSR_GUE           0x00000200
+#define WUCSR_WUFR          0x00000040
+#define WUCSR_MPR           0x00000020
+#define WUCSR_WAKE_EN       0x00000004
+#define WUCSR_MPEN          0x00000002
+
+/* Chip ID values */
+#define CHIP_89218  0x218a
+#define CHIP_9115   0x115
+#define CHIP_9116   0x116
+#define CHIP_9117   0x117
+#define CHIP_9118   0x118
+#define CHIP_9211   0x9211
+#define CHIP_9215   0x115a
+#define CHIP_9216   0x116a
+#define CHIP_9217   0x117a
+#define CHIP_9218   0x118a
+#define CHIP_9220   0x9220
+#define CHIP_9221   0x9221
+
+
+/* Generic MII registers. */
+
+#define MII_BMCR        0x00    /* Basic mode control register */
+#define MII_BMSR        0x01    /* Basic mode status register  */
+#define MII_PHYSID1     0x02    /* PHYS ID 1               */
+#define MII_PHYSID2     0x03    /* PHYS ID 2               */
+#define MII_ADVERTISE   0x04    /* Advertisement control reg   */
+#define MII_LPA         0x05    /* Link partner ability reg    */
+#define MII_EXPANSION   0x06    /* Expansion register          */
+#define MII_CTRL1000    0x09    /* 1000BASE-T control          */
+#define MII_STAT1000    0x0a    /* 1000BASE-T status           */
+#define MII_ESTATUS     0x0f    /* Extended Status */
+#define MII_DCOUNTER    0x12    /* Disconnect counter          */
+#define MII_FCSCOUNTER  0x13    /* False carrier counter       */
+#define MII_NWAYTEST    0x14    /* N-way auto-neg test reg     */
+#define MII_RERRCOUNTER 0x15    /* Receive error counter       */
+#define MII_SREVISION   0x16    /* Silicon revision        */
+#define MII_RESV1       0x17    /* Reserved...             */
+#define MII_LBRERROR    0x18    /* Lpback, rx, bypass error    */
+#define MII_PHYADDR     0x19    /* PHY address             */
+#define MII_RESV2       0x1a    /* Reserved...             */
+#define MII_TPISTATUS   0x1b    /* TPI status for 10mbps       */
+#define MII_NCONFIG     0x1c    /* Network interface config    */
+
+/* Basic mode control register. */
+#define BMCR_RESV       0x003f  /* Unused...               */
+#define BMCR_SPEED1000  0x0040  /* MSB of Speed (1000)         */
+#define BMCR_CTST       0x0080  /* Collision test          */
+#define BMCR_FULLDPLX   0x0100  /* Full duplex             */
+#define BMCR_ANRESTART  0x0200  /* Auto negotiation restart    */
+#define BMCR_ISOLATE    0x0400  /* Disconnect DP83840 from MII */
+#define BMCR_PDOWN      0x0800  /* Powerdown the DP83840       */
+#define BMCR_ANENABLE   0x1000  /* Enable auto negotiation     */
+#define BMCR_SPEED100   0x2000  /* Select 100Mbps          */
+#define BMCR_LOOPBACK   0x4000  /* TXD loopback bits           */
+#define BMCR_RESET      0x8000  /* Reset the DP83840           */
+
+/* Basic mode status register. */
+#define BMSR_ERCAP      0x0001  /* Ext-reg capability          */
+#define BMSR_JCD        0x0002  /* Jabber detected         */
+#define BMSR_LSTATUS    0x0004  /* Link status             */
+#define BMSR_ANEGCAPABLE    0x0008  /* Able to do auto-negotiation */
+#define BMSR_RFAULT     0x0010  /* Remote fault detected       */
+#define BMSR_ANEGCOMPLETE   0x0020  /* Auto-negotiation complete   */
+#define BMSR_RESV       0x00c0  /* Unused...               */
+#define BMSR_ESTATEN    0x0100  /* Extended Status in R15 */
+#define BMSR_100HALF2   0x0200  /* Can do 100BASE-T2 HDX */
+#define BMSR_100FULL2   0x0400  /* Can do 100BASE-T2 FDX */
+#define BMSR_10HALF     0x0800  /* Can do 10mbps, half-duplex  */
+#define BMSR_10FULL     0x1000  /* Can do 10mbps, full-duplex  */
+#define BMSR_100HALF    0x2000  /* Can do 100mbps, half-duplex */
+#define BMSR_100FULL    0x4000  /* Can do 100mbps, full-duplex */
+#define BMSR_100BASE4   0x8000  /* Can do 100mbps, 4k packets  */
+
+#endif

+ 130 - 0
bsp/qemu-vexpress-a9/drivers/drv_timer.c

@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-11-22     Jesven       first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <stdint.h>
+
+#include "board.h"
+
+#define TIMER01_HW_BASE                 0x10011000
+#define TIMER23_HW_BASE                 0x10012000
+
+#define TIMER_LOAD(hw_base)             __REG32(hw_base + 0x00)
+#define TIMER_VALUE(hw_base)            __REG32(hw_base + 0x04)
+#define TIMER_CTRL(hw_base)             __REG32(hw_base + 0x08)
+#define TIMER_CTRL_ONESHOT              (1 << 0)
+#define TIMER_CTRL_32BIT                (1 << 1)
+#define TIMER_CTRL_DIV1                 (0 << 2)
+#define TIMER_CTRL_DIV16                (1 << 2)
+#define TIMER_CTRL_DIV256               (2 << 2)
+#define TIMER_CTRL_IE                   (1 << 5)        /* Interrupt Enable (versatile only) */
+#define TIMER_CTRL_PERIODIC             (1 << 6)
+#define TIMER_CTRL_ENABLE               (1 << 7)
+
+#define TIMER_INTCLR(hw_base)           __REG32(hw_base + 0x0c)
+#define TIMER_RIS(hw_base)              __REG32(hw_base + 0x10)
+#define TIMER_MIS(hw_base)              __REG32(hw_base + 0x14)
+#define TIMER_BGLOAD(hw_base)           __REG32(hw_base + 0x18)
+
+#define TIMER_LOAD(hw_base)             __REG32(hw_base + 0x00)
+#define TIMER_VALUE(hw_base)            __REG32(hw_base + 0x04)
+#define TIMER_CTRL(hw_base)             __REG32(hw_base + 0x08)
+#define TIMER_CTRL_ONESHOT              (1 << 0)
+#define TIMER_CTRL_32BIT                (1 << 1)
+#define TIMER_CTRL_DIV1                 (0 << 2)
+#define TIMER_CTRL_DIV16                (1 << 2)
+#define TIMER_CTRL_DIV256               (2 << 2)
+#define TIMER_CTRL_IE                   (1 << 5)        /* Interrupt Enable (versatile only) */
+#define TIMER_CTRL_PERIODIC             (1 << 6)
+#define TIMER_CTRL_ENABLE               (1 << 7)
+
+#define TIMER_INTCLR(hw_base)           __REG32(hw_base + 0x0c)
+#define TIMER_RIS(hw_base)              __REG32(hw_base + 0x10)
+#define TIMER_MIS(hw_base)              __REG32(hw_base + 0x14)
+#define TIMER_BGLOAD(hw_base)           __REG32(hw_base + 0x18)
+
+#define SYS_CTRL                        __REG32(REALVIEW_SCTL_BASE)
+#define TIMER_HW_BASE                   REALVIEW_TIMER2_3_BASE
+
+static void rt_hw_timer_isr(int vector, void *param)
+{
+    rt_tick_increase();
+    /* clear interrupt */
+    TIMER_INTCLR(TIMER_HW_BASE) = 0x01;
+}
+
+int rt_hw_timer_init(void)
+{
+    rt_uint32_t val;
+
+    SYS_CTRL |= REALVIEW_REFCLK;
+
+    /* Setup Timer0 for generating irq */
+    val = TIMER_CTRL(TIMER_HW_BASE);
+    val &= ~TIMER_CTRL_ENABLE;
+    val |= (TIMER_CTRL_32BIT | TIMER_CTRL_PERIODIC | TIMER_CTRL_IE);
+    TIMER_CTRL(TIMER_HW_BASE) = val;
+
+    TIMER_LOAD(TIMER_HW_BASE) = 1000000/RT_TICK_PER_SECOND;
+
+    /* enable timer */
+    TIMER_CTRL(TIMER_HW_BASE) |= TIMER_CTRL_ENABLE;
+
+    rt_hw_interrupt_install(IRQ_PBA8_TIMER2_3, rt_hw_timer_isr, RT_NULL, "tick");
+    rt_hw_interrupt_umask(IRQ_PBA8_TIMER2_3);
+
+    return 0;
+}
+INIT_BOARD_EXPORT(rt_hw_timer_init);
+
+void timer_init(int timer, unsigned int preload)
+{
+    uint32_t val;
+
+    if (timer == 0) 
+    {
+        /* Setup Timer0 for generating irq */
+        val = TIMER_CTRL(TIMER01_HW_BASE);
+        val &= ~TIMER_CTRL_ENABLE;
+        val |= (TIMER_CTRL_32BIT | TIMER_CTRL_PERIODIC | TIMER_CTRL_IE);
+        TIMER_CTRL(TIMER01_HW_BASE) = val;
+
+        TIMER_LOAD(TIMER01_HW_BASE) = preload;
+
+        /* enable timer */
+        TIMER_CTRL(TIMER01_HW_BASE) |= TIMER_CTRL_ENABLE;
+    } 
+    else 
+    {
+        /* Setup Timer1 for generating irq */
+        val = TIMER_CTRL(TIMER23_HW_BASE);
+        val &= ~TIMER_CTRL_ENABLE;
+        val |= (TIMER_CTRL_32BIT | TIMER_CTRL_PERIODIC | TIMER_CTRL_IE);
+        TIMER_CTRL(TIMER23_HW_BASE) = val;
+
+        TIMER_LOAD(TIMER23_HW_BASE) = preload;
+
+        /* enable timer */
+        TIMER_CTRL(TIMER23_HW_BASE) |= TIMER_CTRL_ENABLE;
+    }
+}
+
+void timer_clear_pending(int timer)
+{
+    if (timer == 0)
+    {
+        TIMER_INTCLR(TIMER01_HW_BASE) = 0x01;
+    } 
+    else
+    {
+        TIMER_INTCLR(TIMER23_HW_BASE) = 0x01;
+    }
+}

+ 17 - 0
bsp/qemu-vexpress-a9/drivers/drv_timer.h

@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-11-22     Jesven       first version
+ */
+
+#ifndef DRV_TIMER_H__
+#define DRV_TIMER_H__
+
+void timer_init(int timer, unsigned int preload);
+void timer_clear_pending(int timer);
+
+#endif

+ 330 - 0
bsp/qemu-vexpress-a9/drivers/realview.h

@@ -0,0 +1,330 @@
+#ifndef __AM33XX_H__
+#define __AM33XX_H__
+
+#define __REG32(x)  (*((volatile unsigned int *)(x)))
+#define __REG16(x)  (*((volatile unsigned short *)(x)))
+
+/*
+ * Peripheral addresses
+ */
+#define REALVIEW_UART0_BASE         0x10009000  /* UART 0 */
+#define REALVIEW_UART1_BASE         0x1000A000  /* UART 1 */
+#define REALVIEW_UART2_BASE         0x1000B000  /* UART 2 */
+#define REALVIEW_UART3_BASE         0x1000C000  /* UART 3 */
+#define REALVIEW_SSP_BASE           0x1000D000  /* Synchronous Serial Port */
+#define REALVIEW_WATCHDOG0_BASE     0x1000F000  /* Watchdog 0 */
+#define REALVIEW_WATCHDOG_BASE      0x10010000  /* watchdog interface */
+#define REALVIEW_TIMER0_1_BASE      0x10011000  /* Timer 0 and 1 */
+#define REALVIEW_TIMER2_3_BASE      0x10012000  /* Timer 2 and 3 */
+#define REALVIEW_GPIO0_BASE         0x10013000  /* GPIO port 0 */
+#define REALVIEW_RTC_BASE           0x10017000  /* Real Time Clock */
+#define REALVIEW_TIMER4_5_BASE      0x10018000  /* Timer 4/5 */
+#define REALVIEW_TIMER6_7_BASE      0x10019000  /* Timer 6/7 */
+#define REALVIEW_SCTL_BASE          0x10001000  /* System Controller */
+#define REALVIEW_CLCD_BASE          0x10020000  /* CLCD */
+#define REALVIEW_ONB_SRAM_BASE      0x10060000  /* On-board SRAM */
+#define REALVIEW_DMC_BASE           0x100E0000  /* DMC configuration */
+#define REALVIEW_SMC_BASE           0x100E1000  /* SMC configuration */
+#define REALVIEW_CAN_BASE           0x100E2000  /* CAN bus */
+#define REALVIEW_GIC_CPU_BASE       0x1E000100  /* Generic interrupt controller CPU interface */
+#define REALVIEW_FLASH0_BASE        0x40000000
+#define REALVIEW_FLASH0_SIZE        SZ_64M
+#define REALVIEW_FLASH1_BASE        0x44000000
+#define REALVIEW_FLASH1_SIZE        SZ_64M
+
+#define VEXPRESS_SRAM_BASE          0x48000000
+
+#define REALVIEW_ETH_BASE           0x4E000000  /* Ethernet */
+#define VEXPRESS_ETH_BASE           0x4E000000  /* Ethernet */
+
+#define REALVIEW_USB_BASE           0x4F000000  /* USB */
+#define REALVIEW_GIC_DIST_BASE      0x1E001000  /* Generic interrupt controller distributor */
+#define REALVIEW_LT_BASE            0xC0000000  /* Logic Tile expansion */
+#define REALVIEW_SDRAM6_BASE        0x70000000  /* SDRAM bank 6 256MB */
+#define REALVIEW_SDRAM7_BASE        0x80000000  /* SDRAM bank 7 256MB */
+
+#define REALVIEW_SYS_PLD_CTRL1      0x74
+
+/*
+ * PCI regions
+ */
+#define REALVIEW_PCI_BASE           0x90040000  /* PCI-X Unit base */
+#define REALVIEW_PCI_IO_BASE        0x90050000  /* IO Region on AHB */
+#define REALVIEW_PCI_MEM_BASE       0xA0000000  /* MEM Region on AHB */
+
+#define REALVIEW_PCI_BASE_SIZE      0x10000     /* 16 Kb */
+#define REALVIEW_PCI_IO_SIZE        0x1000      /* 4 Kb */
+#define REALVIEW_PCI_MEM_SIZE       0x20000000  /* 512 MB */
+
+/*
+ * Memory definitions
+ */
+#define REALVIEW_BOOT_ROM_LO          0x30000000    /* DoC Base (64Mb)... */
+#define REALVIEW_BOOT_ROM_HI          0x30000000
+#define REALVIEW_BOOT_ROM_BASE        REALVIEW_BOOT_ROM_HI  /*  Normal position */
+#define REALVIEW_BOOT_ROM_SIZE        SZ_64M
+
+#define REALVIEW_SSRAM_BASE /* REALVIEW_SSMC_BASE ? */
+#define REALVIEW_SSRAM_SIZE           SZ_2M
+
+/*
+ *  SDRAM
+ */
+#define REALVIEW_SDRAM_BASE           0x00000000
+
+/*
+ *  Logic expansion modules
+ *
+ */
+#define IRQ_PBA8_GIC_START          32
+
+/*
+ * PB-A8 on-board gic irq sources
+ */
+#define IRQ_PBA8_WATCHDOG   (IRQ_PBA8_GIC_START + 0)    /* Watchdog timer */
+#define IRQ_PBA8_SOFT       (IRQ_PBA8_GIC_START + 1)    /* Software interrupt */
+#define IRQ_PBA8_TIMER0_1   (IRQ_PBA8_GIC_START + 2)    /* Timer 0/1 (default timer) */
+#define IRQ_PBA8_TIMER2_3   (IRQ_PBA8_GIC_START + 3)    /* Timer 2/3 */
+#define IRQ_PBA8_RTC        (IRQ_PBA8_GIC_START + 4)    /* Timer 2/3 */
+#define IRQ_VEXPRESS_A9_RTC (IRQ_PBA8_GIC_START + 4)
+
+#define IRQ_PBA8_UART0      (IRQ_PBA8_GIC_START + 5)    /* UART 0 on development chip */
+#define IRQ_PBA8_UART1      (IRQ_PBA8_GIC_START + 6)    /* UART 1 on development chip */
+#define IRQ_PBA8_UART2      (IRQ_PBA8_GIC_START + 7)    /* UART 2 on development chip */
+#define IRQ_PBA8_UART3      (IRQ_PBA8_GIC_START + 8)    /* UART 3 on development chip */
+
+#define IRQ_VEXPRESS_A9_KBD     (IRQ_PBA8_GIC_START + 12)
+#define IRQ_VEXPRESS_A9_MOUSE   (IRQ_PBA8_GIC_START + 13)
+#define IRQ_VEXPRESS_A9_CLCD    (IRQ_PBA8_GIC_START + 14)
+#define IRQ_VEXPRESS_A9_ETH     (IRQ_PBA8_GIC_START + 15)
+
+/* 9 reserved */
+#define IRQ_PBA8_SSP        (IRQ_PBA8_GIC_START + 11)   /* Synchronous Serial Port */
+#define IRQ_PBA8_SCI        (IRQ_PBA8_GIC_START + 16)   /* Smart Card Interface */
+#define IRQ_PBA8_MMCI0A     (IRQ_PBA8_GIC_START + 17)   /* Multimedia Card 0A */
+#define IRQ_PBA8_MMCI0B     (IRQ_PBA8_GIC_START + 18)   /* Multimedia Card 0B */
+#define IRQ_PBA8_AACI       (IRQ_PBA8_GIC_START + 19)   /* Audio Codec */
+#define IRQ_PBA8_KMI0       (IRQ_PBA8_GIC_START + 20)   /* Keyboard/Mouse port 0 */
+#define IRQ_PBA8_KMI1       (IRQ_PBA8_GIC_START + 21)   /* Keyboard/Mouse port 1 */
+#define IRQ_PBA8_CHARLCD    (IRQ_PBA8_GIC_START + 22)   /* Character LCD */
+#define IRQ_PBA8_CLCD       (IRQ_PBA8_GIC_START + 23)   /* CLCD controller */
+#define IRQ_PBA8_DMAC       (IRQ_PBA8_GIC_START + 24)   /* DMA controller */
+#define IRQ_PBA8_PWRFAIL    (IRQ_PBA8_GIC_START + 25)   /* Power failure */
+#define IRQ_PBA8_PISMO      (IRQ_PBA8_GIC_START + 26)   /* PISMO interface */
+#define IRQ_PBA8_DoC        (IRQ_PBA8_GIC_START + 27)   /* Disk on Chip memory controller */
+#define IRQ_PBA8_ETH        (IRQ_PBA8_GIC_START + 28)   /* Ethernet controller */
+#define IRQ_PBA8_USB        (IRQ_PBA8_GIC_START + 29)   /* USB controller */
+#define IRQ_PBA8_TSPEN      (IRQ_PBA8_GIC_START + 30)   /* Touchscreen pen */
+#define IRQ_PBA8_TSKPAD     (IRQ_PBA8_GIC_START + 31)   /* Touchscreen keypad */
+
+#define IRQ_PBA8_PMU        (IRQ_PBA8_GIC_START + 47)   /* Cortex-A8 PMU */
+
+/* ... */
+#define IRQ_PBA8_PCI0       (IRQ_PBA8_GIC_START + 50)
+#define IRQ_PBA8_PCI1       (IRQ_PBA8_GIC_START + 51)
+#define IRQ_PBA8_PCI2       (IRQ_PBA8_GIC_START + 52)
+#define IRQ_PBA8_PCI3       (IRQ_PBA8_GIC_START + 53)
+
+#define IRQ_PBA8_SMC        -1
+#define IRQ_PBA8_SCTL       -1
+
+#define NR_GIC_PBA8     1
+
+/*
+ * Only define NR_IRQS if less than NR_IRQS_PBA8
+ */
+#define NR_IRQS_PBA8        (IRQ_PBA8_GIC_START + 64)
+
+/* ------------------------------------------------------------------------
+ *  RealView Registers
+ * ------------------------------------------------------------------------
+ *
+ */
+#define REALVIEW_SYS_ID_OFFSET               0x00
+#define REALVIEW_SYS_SW_OFFSET               0x04
+#define REALVIEW_SYS_LED_OFFSET              0x08
+#define REALVIEW_SYS_OSC0_OFFSET             0x0C
+
+#define REALVIEW_SYS_OSC1_OFFSET             0x10
+#define REALVIEW_SYS_OSC2_OFFSET             0x14
+#define REALVIEW_SYS_OSC3_OFFSET             0x18
+#define REALVIEW_SYS_OSC4_OFFSET             0x1C   /* OSC1 for RealView/AB */
+
+#define REALVIEW_SYS_LOCK_OFFSET             0x20
+#define REALVIEW_SYS_100HZ_OFFSET            0x24
+#define REALVIEW_SYS_CFGDATA1_OFFSET         0x28
+#define REALVIEW_SYS_CFGDATA2_OFFSET         0x2C
+#define REALVIEW_SYS_FLAGS_OFFSET            0x30
+#define REALVIEW_SYS_FLAGSSET_OFFSET         0x30
+#define REALVIEW_SYS_FLAGSCLR_OFFSET         0x34
+#define REALVIEW_SYS_NVFLAGS_OFFSET          0x38
+#define REALVIEW_SYS_NVFLAGSSET_OFFSET       0x38
+#define REALVIEW_SYS_NVFLAGSCLR_OFFSET       0x3C
+#define REALVIEW_SYS_RESETCTL_OFFSET         0x40
+#define REALVIEW_SYS_PCICTL_OFFSET           0x44
+#define REALVIEW_SYS_MCI_OFFSET              0x48
+#define REALVIEW_SYS_FLASH_OFFSET            0x4C
+#define REALVIEW_SYS_CLCD_OFFSET             0x50
+#define REALVIEW_SYS_CLCDSER_OFFSET          0x54
+#define REALVIEW_SYS_BOOTCS_OFFSET           0x58
+#define REALVIEW_SYS_24MHz_OFFSET            0x5C
+#define REALVIEW_SYS_MISC_OFFSET             0x60
+#define REALVIEW_SYS_IOSEL_OFFSET            0x70
+#define REALVIEW_SYS_PROCID_OFFSET           0x84
+#define REALVIEW_SYS_TEST_OSC0_OFFSET        0xC0
+#define REALVIEW_SYS_TEST_OSC1_OFFSET        0xC4
+#define REALVIEW_SYS_TEST_OSC2_OFFSET        0xC8
+#define REALVIEW_SYS_TEST_OSC3_OFFSET        0xCC
+#define REALVIEW_SYS_TEST_OSC4_OFFSET        0xD0
+
+#define REALVIEW_SYS_BASE                    0x10000000
+#define REALVIEW_SYS_ID                      (REALVIEW_SYS_BASE + REALVIEW_SYS_ID_OFFSET)
+#define REALVIEW_SYS_SW                      (REALVIEW_SYS_BASE + REALVIEW_SYS_SW_OFFSET)
+#define REALVIEW_SYS_LED                     (REALVIEW_SYS_BASE + REALVIEW_SYS_LED_OFFSET)
+#define REALVIEW_SYS_OSC0                    (REALVIEW_SYS_BASE + REALVIEW_SYS_OSC0_OFFSET)
+#define REALVIEW_SYS_OSC1                    (REALVIEW_SYS_BASE + REALVIEW_SYS_OSC1_OFFSET)
+
+#define REALVIEW_SYS_LOCK                    (REALVIEW_SYS_BASE + REALVIEW_SYS_LOCK_OFFSET)
+#define REALVIEW_SYS_100HZ                   (REALVIEW_SYS_BASE + REALVIEW_SYS_100HZ_OFFSET)
+#define REALVIEW_SYS_CFGDATA1                (REALVIEW_SYS_BASE + REALVIEW_SYS_CFGDATA1_OFFSET)
+#define REALVIEW_SYS_CFGDATA2                (REALVIEW_SYS_BASE + REALVIEW_SYS_CFGDATA2_OFFSET)
+#define REALVIEW_SYS_FLAGS                   (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGS_OFFSET)
+#define REALVIEW_SYS_FLAGSSET                (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGSSET_OFFSET)
+#define REALVIEW_SYS_FLAGSCLR                (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGSCLR_OFFSET)
+#define REALVIEW_SYS_NVFLAGS                 (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGS_OFFSET)
+#define REALVIEW_SYS_NVFLAGSSET              (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGSSET_OFFSET)
+#define REALVIEW_SYS_NVFLAGSCLR              (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGSCLR_OFFSET)
+#define REALVIEW_SYS_RESETCTL                (REALVIEW_SYS_BASE + REALVIEW_SYS_RESETCTL_OFFSET)
+#define REALVIEW_SYS_PCICTL                  (REALVIEW_SYS_BASE + REALVIEW_SYS_PCICTL_OFFSET)
+#define REALVIEW_SYS_MCI                     (REALVIEW_SYS_BASE + REALVIEW_SYS_MCI_OFFSET)
+#define REALVIEW_SYS_FLASH                   (REALVIEW_SYS_BASE + REALVIEW_SYS_FLASH_OFFSET)
+#define REALVIEW_SYS_CLCD                    (REALVIEW_SYS_BASE + REALVIEW_SYS_CLCD_OFFSET)
+#define REALVIEW_SYS_CLCDSER                 (REALVIEW_SYS_BASE + REALVIEW_SYS_CLCDSER_OFFSET)
+#define REALVIEW_SYS_BOOTCS                  (REALVIEW_SYS_BASE + REALVIEW_SYS_BOOTCS_OFFSET)
+#define REALVIEW_SYS_24MHz                   (REALVIEW_SYS_BASE + REALVIEW_SYS_24MHz_OFFSET)
+#define REALVIEW_SYS_MISC                    (REALVIEW_SYS_BASE + REALVIEW_SYS_MISC_OFFSET)
+#define REALVIEW_SYS_IOSEL                   (REALVIEW_SYS_BASE + REALVIEW_SYS_IOSEL_OFFSET)
+#define REALVIEW_SYS_PROCID                  (REALVIEW_SYS_BASE + REALVIEW_SYS_PROCID_OFFSET)
+#define REALVIEW_SYS_TEST_OSC0               (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC0_OFFSET)
+#define REALVIEW_SYS_TEST_OSC1               (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC1_OFFSET)
+#define REALVIEW_SYS_TEST_OSC2               (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC2_OFFSET)
+#define REALVIEW_SYS_TEST_OSC3               (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC3_OFFSET)
+#define REALVIEW_SYS_TEST_OSC4               (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC4_OFFSET)
+
+#define REALVIEW_SYS_CTRL_LED         (1 << 0)
+
+/* ------------------------------------------------------------------------
+ *  RealView control registers
+ * ------------------------------------------------------------------------
+ */
+
+/*
+ * REALVIEW_IDFIELD
+ *
+ * 31:24 = manufacturer (0x41 = ARM)
+ * 23:16 = architecture (0x08 = AHB system bus, ASB processor bus)
+ * 15:12 = FPGA (0x3 = XVC600 or XVC600E)
+ * 11:4  = build value
+ * 3:0   = revision number (0x1 = rev B (AHB))
+ */
+
+/*
+ * REALVIEW_SYS_LOCK
+ *     control access to SYS_OSCx, SYS_CFGDATAx, SYS_RESETCTL,
+ *     SYS_CLD, SYS_BOOTCS
+ */
+#define REALVIEW_SYS_LOCK_LOCKED    (1 << 16)
+#define REALVIEW_SYS_LOCKVAL        0xA05F
+#define REALVIEW_SYS_LOCKVAL_MASK   0xFFFF  /* write 0xA05F to enable write access */
+
+/*
+ * REALVIEW_SYS_FLASH
+ */
+#define REALVIEW_FLASHPROG_FLVPPEN  (1 << 0)    /* Enable writing to flash */
+
+/*
+ * REALVIEW_INTREG
+ *     - used to acknowledge and control MMCI and UART interrupts
+ */
+#define REALVIEW_INTREG_WPROT        0x00   /* MMC protection status (no interrupt generated) */
+#define REALVIEW_INTREG_RI0          0x01   /* Ring indicator UART0 is asserted,              */
+#define REALVIEW_INTREG_CARDIN       0x08   /* MMCI card in detect                            */
+/* write 1 to acknowledge and clear               */
+#define REALVIEW_INTREG_RI1          0x02   /* Ring indicator UART1 is asserted,              */
+#define REALVIEW_INTREG_CARDINSERT   0x03   /* Signal insertion of MMC card                   */
+
+/*
+ *  LED settings, bits [7:0]
+ */
+#define REALVIEW_SYS_LED0             (1 << 0)
+#define REALVIEW_SYS_LED1             (1 << 1)
+#define REALVIEW_SYS_LED2             (1 << 2)
+#define REALVIEW_SYS_LED3             (1 << 3)
+#define REALVIEW_SYS_LED4             (1 << 4)
+#define REALVIEW_SYS_LED5             (1 << 5)
+#define REALVIEW_SYS_LED6             (1 << 6)
+#define REALVIEW_SYS_LED7             (1 << 7)
+
+#define ALL_LEDS                  0xFF
+
+#define LED_BANK                  REALVIEW_SYS_LED
+
+/*
+ * Control registers
+ */
+#define REALVIEW_IDFIELD_OFFSET 0x0 /* RealView build information */
+#define REALVIEW_FLASHPROG_OFFSET   0x4 /* Flash devices */
+#define REALVIEW_INTREG_OFFSET      0x8 /* Interrupt control */
+#define REALVIEW_DECODE_OFFSET      0xC /* Fitted logic modules */
+
+/*
+ *  Clean base - dummy
+ *
+ */
+#define CLEAN_BASE                      REALVIEW_BOOT_ROM_HI
+
+/*
+ * System controller bit assignment
+ */
+#define REALVIEW_REFCLK 0
+#define REALVIEW_TIMCLK 1
+
+#define REALVIEW_TIMER1_EnSel   15
+#define REALVIEW_TIMER2_EnSel   17
+#define REALVIEW_TIMER3_EnSel   19
+#define REALVIEW_TIMER4_EnSel   21
+
+struct rt_hw_register
+{
+    unsigned long r0;
+    unsigned long r1;
+    unsigned long r2;
+    unsigned long r3;
+    unsigned long r4;
+    unsigned long r5;
+    unsigned long r6;
+    unsigned long r7;
+    unsigned long r8;
+    unsigned long r9;
+    unsigned long r10;
+    unsigned long fp;
+    unsigned long ip;
+    unsigned long sp;
+    unsigned long lr;
+    unsigned long pc;
+    unsigned long cpsr;
+    unsigned long ORIG_r0;
+};
+
+#include <armv7.h>
+
+/* Interrupt Control Interface */
+#define ARM_GIC_CPU_BASE    0x1E000000
+
+/* number of interrupts on board */
+#define ARM_GIC_NR_IRQS     96
+/* only one GIC available */
+#define ARM_GIC_MAX_NR      1
+
+#endif
+

+ 59 - 0
bsp/qemu-vexpress-a9/drivers/secondary_cpu.c

@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-11-22     Jesven       first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <stdint.h>
+
+#include "board.h"
+#include "gic.h"
+#include "drv_timer.h"
+
+#ifdef RT_USING_SMP
+#include <interrupt.h>
+
+static void rt_hw_timer2_isr(int vector, void *param)
+{
+    rt_tick_increase();
+    /* clear interrupt */
+    timer_clear_pending(0);
+}
+
+void rt_hw_secondary_cpu_up(void)
+{
+    extern void set_secondary_cpu_boot_address(void);
+
+    set_secondary_cpu_boot_address();
+    __asm__ volatile ("dsb":::"memory");
+    rt_hw_ipi_send(0, 1 << 1);
+}
+
+void secondary_cpu_c_start(void)
+{
+    rt_hw_vector_init();
+
+    rt_hw_spin_lock(&_cpus_lock);
+
+    arm_gic_cpu_init(0, REALVIEW_GIC_CPU_BASE);
+    arm_gic_set_cpu(0, IRQ_PBA8_TIMER0_1, 0x2);
+
+    timer_init(0, 10000);
+    rt_hw_interrupt_install(IRQ_PBA8_TIMER0_1, rt_hw_timer2_isr, RT_NULL, "tick");
+    rt_hw_interrupt_umask(IRQ_PBA8_TIMER0_1);
+
+    rt_system_scheduler_start();
+}
+
+void rt_hw_secondary_cpu_idle_exec(void)
+{
+     asm volatile ("wfe":::"memory", "cc");
+}
+
+#endif

+ 183 - 0
bsp/qemu-vexpress-a9/drivers/serial.c

@@ -0,0 +1,183 @@
+/*
+ *  serial.c UART driver
+ *
+ * COPYRIGHT (C) 2013, Shanghai Real-Thread Technology Co., Ltd
+ *
+ *  This file is part of RT-Thread (http://www.rt-thread.org)
+ *  Maintainer: bernard.xiong <bernard.xiong at gmail.com>
+ *
+ *  All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2013-03-30     Bernard      the first verion
+ */
+
+#include <rthw.h>
+#include <rtdevice.h>
+
+#include "serial.h"
+
+struct hw_uart_device
+{
+    rt_uint32_t hw_base;
+    rt_uint32_t irqno;
+};
+
+#define UART_DR(base)   __REG32(base + 0x00)
+#define UART_FR(base)   __REG32(base + 0x18)
+#define UART_CR(base)   __REG32(base + 0x30)
+#define UART_IMSC(base) __REG32(base + 0x38)
+#define UART_ICR(base)  __REG32(base + 0x44)
+
+#define UARTFR_RXFE     0x10
+#define UARTFR_TXFF     0x20
+#define UARTIMSC_RXIM   0x10
+#define UARTIMSC_TXIM   0x20
+#define UARTICR_RXIC    0x10
+#define UARTICR_TXIC    0x20
+
+static void rt_hw_uart_isr(int irqno, void *param)
+{
+    struct rt_serial_device *serial = (struct rt_serial_device *)param;
+
+    rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
+}
+
+static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
+{
+    return RT_EOK;
+}
+
+static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg)
+{
+    struct hw_uart_device *uart;
+
+    RT_ASSERT(serial != RT_NULL);
+    uart = (struct hw_uart_device *)serial->parent.user_data;
+
+    switch (cmd)
+    {
+    case RT_DEVICE_CTRL_CLR_INT:
+        /* disable rx irq */
+        UART_IMSC(uart->hw_base) &= ~UARTIMSC_RXIM;
+        break;
+
+    case RT_DEVICE_CTRL_SET_INT:
+        /* enable rx irq */
+        UART_IMSC(uart->hw_base) |= UARTIMSC_RXIM;
+        rt_hw_interrupt_umask(uart->irqno);
+        break;
+    }
+
+    return RT_EOK;
+}
+
+static int uart_putc(struct rt_serial_device *serial, char c)
+{
+    struct hw_uart_device *uart;
+
+    RT_ASSERT(serial != RT_NULL);
+    uart = (struct hw_uart_device *)serial->parent.user_data;
+
+    while (UART_FR(uart->hw_base) & UARTFR_TXFF);
+    UART_DR(uart->hw_base) = c;
+
+    return 1;
+}
+
+static int uart_getc(struct rt_serial_device *serial)
+{
+    int ch;
+    struct hw_uart_device *uart;
+
+    RT_ASSERT(serial != RT_NULL);
+    uart = (struct hw_uart_device *)serial->parent.user_data;
+
+    ch = -1;
+    if (!(UART_FR(uart->hw_base) & UARTFR_RXFE))
+    {
+        ch = UART_DR(uart->hw_base) & 0xff;
+    }
+
+    return ch;
+}
+
+static const struct rt_uart_ops _uart_ops =
+{
+    uart_configure,
+    uart_control,
+    uart_putc,
+    uart_getc,
+};
+
+#ifdef RT_USING_UART0
+/* UART device driver structure */
+static struct hw_uart_device _uart0_device =
+{
+    REALVIEW_UART0_BASE,
+    IRQ_PBA8_UART0,
+};
+static struct rt_serial_device _serial0;
+#endif
+
+#ifdef RT_USING_UART1
+/* UART1 device driver structure */
+static struct hw_uart_device _uart1_device =
+{
+    REALVIEW_UART1_BASE,
+    IRQ_PBA8_UART1,
+};
+static struct rt_serial_device _serial1;
+#endif
+
+int rt_hw_uart_init(void)
+{
+    struct hw_uart_device *uart;
+    struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
+
+#ifdef RT_USING_UART0
+    uart = &_uart0_device;
+
+    _serial0.ops    = &_uart_ops;
+    _serial0.config = config;
+
+    /* register UART1 device */
+    rt_hw_serial_register(&_serial0, "uart0",
+                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
+                          uart);
+    rt_hw_interrupt_install(uart->irqno, rt_hw_uart_isr, &_serial0, "uart0");
+    /* enable Rx and Tx of UART */
+    UART_CR(uart->hw_base) = (1 << 0) | (1 << 8) | (1 << 9);
+#endif
+
+#ifdef RT_USING_UART1
+    uart = &_uart1_device;
+    _serial1.ops = &_uart_ops;
+    _serial1.config = config;
+
+    /* register UART1 device */
+    rt_hw_serial_register(&_serial1, "uart1",
+                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart);
+    /* enable Rx and Tx of UART */
+    UART_CR(uart->hw_base) = (1 << 0) | (1 << 8) | (1 << 9);
+    rt_hw_interrupt_install(uart->irqno, rt_hw_uart_isr, &_serial1, "uart1");
+#endif
+
+    return 0;
+}
+INIT_BOARD_EXPORT(rt_hw_uart_init);

+ 39 - 0
bsp/qemu-vexpress-a9/drivers/serial.h

@@ -0,0 +1,39 @@
+/*
+ *  UART driver
+ *
+ * COPYRIGHT (C) 2013, Shanghai Real-Thread Technology Co., Ltd
+ *
+ *  This file is part of RT-Thread (http://www.rt-thread.org)
+ *  Maintainer: bernard.xiong <bernard.xiong at gmail.com>
+ *
+ *  All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2013-03-30     Bernard      the first verion
+ */
+
+#ifndef __UART_H__
+#define __UART_H__
+
+#include <board.h>
+
+int rt_hw_uart_init(void);
+
+#endif
+
+

+ 37 - 0
bsp/qemu-vexpress-a9/drivers/vexpress_a9.h

@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018-03-22     quanzhao     first version
+ */
+
+#ifndef __VEXPRESS_A9_H__
+#define __VEXPRESS_A9_H__
+
+/* for 'rt_inline' */
+#include <rtdef.h>
+/* SOC-relative definitions */
+#include "realview.h"
+
+/* the maximum entries of the exception table */
+#define MAX_HANDLERS    NR_IRQS_PBA8
+
+/* the basic constants and interfaces needed by gic */
+rt_inline rt_uint32_t platform_get_gic_dist_base(void)
+{
+    return REALVIEW_GIC_DIST_BASE;
+}
+
+rt_inline rt_uint32_t platform_get_gic_cpu_base(void)
+{
+    return REALVIEW_GIC_CPU_BASE;
+}
+
+#define GIC_IRQ_START   0
+
+#define GIC_ACK_INTID_MASK  0x000003ff
+
+#endif  /* __VEXPRESS_A9_H__ */

+ 101 - 0
bsp/qemu-vexpress-a9/link.lds

@@ -0,0 +1,101 @@
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+SECTIONS
+{
+    . = 0x60010000;
+
+    __text_start = .;
+    .text :
+    {
+        *(.vectors)
+        *(.text)
+        *(.text.*)
+
+        /* section information for utest */
+        . = ALIGN(4);
+        __rt_utest_tc_tab_start = .;
+        KEEP(*(UtestTcTab))
+        __rt_utest_tc_tab_end = .;
+        
+        /* section information for finsh shell */
+        . = ALIGN(4);
+        __fsymtab_start = .;
+        KEEP(*(FSymTab))
+        __fsymtab_end = .;
+        . = ALIGN(4);
+        __vsymtab_start = .;
+        KEEP(*(VSymTab))
+        __vsymtab_end = .;
+        . = ALIGN(4);
+
+        /* section information for modules */
+        . = ALIGN(4);
+        __rtmsymtab_start = .;
+        KEEP(*(RTMSymTab))
+        __rtmsymtab_end = .;
+
+        /* section information for initialization */
+        . = ALIGN(4);
+        __rt_init_start = .;
+        KEEP(*(SORT(.rti_fn*)))
+        __rt_init_end = .;
+    } =0
+    __text_end = .;
+
+    __exidx_start = .;
+    .ARM.exidx   : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) }
+    __exidx_end = .;
+
+    __rodata_start = .;
+    .rodata   : { *(.rodata) *(.rodata.*) }
+    __rodata_end = .;
+
+    . = ALIGN(4);
+    .ctors :
+    {
+        PROVIDE(__ctors_start__ = .);
+        KEEP(*(SORT(.ctors.*)))
+        KEEP(*(.ctors))
+        PROVIDE(__ctors_end__ = .);
+    }
+
+    .dtors :
+    {
+        PROVIDE(__dtors_start__ = .);
+        KEEP(*(SORT(.dtors.*)))
+        KEEP(*(.dtors))
+        PROVIDE(__dtors_end__ = .);
+    }
+
+    . = ALIGN(8);
+    __data_start = .;
+    .data :
+    {
+        *(.data)
+        *(.data.*)
+    }
+    __data_end = .;
+
+    . = ALIGN(8);
+    __bss_start = .;
+    .bss       :
+    {
+    *(.bss)
+    *(.bss.*)
+    *(COMMON)
+    . = ALIGN(4);
+    }
+    . = ALIGN(4);
+    __bss_end = .;
+
+    /* Stabs debugging sections.  */
+    .stab 0 : { *(.stab) }
+    .stabstr 0 : { *(.stabstr) }
+    .stab.excl 0 : { *(.stab.excl) }
+    .stab.exclstr 0 : { *(.stab.exclstr) }
+    .stab.index 0 : { *(.stab.index) }
+    .stab.indexstr 0 : { *(.stab.indexstr) }
+    .comment 0 : { *(.comment) }
+
+    _end = .;
+}

+ 4 - 0
bsp/qemu-vexpress-a9/makefile.targets

@@ -0,0 +1,4 @@
+clean2:
+	-$(RM) $(CC_DEPS)$(C++_DEPS)$(C_UPPER_DEPS)$(CXX_DEPS)$(SECONDARY_FLASH)$(SECONDARY_SIZE)$(ASM_DEPS)$(S_UPPER_DEPS)$(C_DEPS)$(CPP_DEPS)
+	-$(RM) $(OBJS) *.elf
+	-@echo ' '

+ 6 - 0
bsp/qemu-vexpress-a9/qemu-dbg.bat

@@ -0,0 +1,6 @@
+@echo off
+if exist sd.bin goto run
+qemu-img create -f raw sd.bin 64M
+
+:run
+qemu-system-arm -M vexpress-a9 -kernel rtthread.elf -serial stdio -sd sd.bin -S -s

+ 6 - 0
bsp/qemu-vexpress-a9/qemu-dbg.sh

@@ -0,0 +1,6 @@
+if [ ! -f "sd.bin" ]; then
+dd if=/dev/zero of=sd.bin bs=1024 count=65536
+fi
+
+
+qemu-system-arm -M vexpress-a9 -kernel rtthread.elf -serial vc -serial vc -sd sd.bin -S -s

+ 6 - 0
bsp/qemu-vexpress-a9/qemu-nographic.bat

@@ -0,0 +1,6 @@
+@echo off
+if exist sd.bin goto run
+qemu-img create -f raw sd.bin 64M
+
+:run
+qemu-system-arm -M vexpress-a9 -kernel rtthread.elf -nographic -sd sd.bin

+ 6 - 0
bsp/qemu-vexpress-a9/qemu-nographic.sh

@@ -0,0 +1,6 @@
+if [ ! -f "sd.bin" ]; then
+dd if=/dev/zero of=sd.bin bs=1024 count=65536
+fi
+
+qemu-system-arm -M vexpress-a9 -smp cpus=2 -kernel rtthread.bin -nographic -sd sd.bin -net nic -net tap
+

+ 6 - 0
bsp/qemu-vexpress-a9/qemu.bat

@@ -0,0 +1,6 @@
+@echo off
+if exist sd.bin goto run
+qemu-img create -f raw sd.bin 64M
+
+:run
+qemu-system-arm -M vexpress-a9 -smp cpus=2 -kernel rtthread.bin -serial stdio -sd sd.bin

+ 5 - 0
bsp/qemu-vexpress-a9/qemu.sh

@@ -0,0 +1,5 @@
+if [ ! -f "sd.bin" ]; then
+dd if=/dev/zero of=sd.bin bs=1024 count=65536
+fi
+
+qemu-system-arm -M vexpress-a9 -smp cpus=2 -kernel rtthread.bin -serial stdio -sd sd.bin

+ 275 - 0
bsp/qemu-vexpress-a9/rtconfig.h

@@ -0,0 +1,275 @@
+#ifndef RT_CONFIG_H__
+#define RT_CONFIG_H__
+
+/* Automatically generated file; DO NOT EDIT. */
+/* RT-Thread Project Configuration */
+
+/* RT-Thread Kernel */
+
+#define RT_NAME_MAX 8
+#define RT_USING_SMP
+#define RT_CPUS_NR 2
+#define RT_ALIGN_SIZE 4
+#define RT_THREAD_PRIORITY_32
+#define RT_THREAD_PRIORITY_MAX 32
+#define RT_TICK_PER_SECOND 100
+#define RT_USING_OVERFLOW_CHECK
+#define RT_USING_HOOK
+#define RT_USING_IDLE_HOOK
+#define RT_IDLE_HOOK_LIST_SIZE 4
+#define IDLE_THREAD_STACK_SIZE 1024
+#define RT_USING_TIMER_SOFT
+#define RT_TIMER_THREAD_PRIO 4
+#define RT_TIMER_THREAD_STACK_SIZE 1024
+#define RT_DEBUG
+#define RT_DEBUG_COLOR
+
+/* Inter-Thread communication */
+
+#define RT_USING_SEMAPHORE
+#define RT_USING_MUTEX
+#define RT_USING_EVENT
+#define RT_USING_MAILBOX
+#define RT_USING_MESSAGEQUEUE
+#define RT_USING_SIGNALS
+
+/* Memory Management */
+
+#define RT_USING_MEMPOOL
+#define RT_USING_MEMHEAP
+#define RT_USING_SMALL_MEM
+#define RT_USING_MEMTRACE
+#define RT_USING_HEAP
+
+/* Kernel Device Object */
+
+#define RT_USING_DEVICE
+#define RT_USING_DEVICE_OPS
+#define RT_USING_INTERRUPT_INFO
+#define RT_USING_CONSOLE
+#define RT_CONSOLEBUF_SIZE 256
+#define RT_CONSOLE_DEVICE_NAME "uart0"
+#define RT_VER_NUM 0x40002
+#define ARCH_ARM
+#define ARCH_ARM_CORTEX_A
+#define ARCH_ARM_CORTEX_A9
+
+/* RT-Thread Components */
+
+#define RT_USING_COMPONENTS_INIT
+#define RT_USING_USER_MAIN
+#define RT_MAIN_THREAD_STACK_SIZE 2048
+#define RT_MAIN_THREAD_PRIORITY 10
+
+/* C++ features */
+
+#define RT_USING_CPLUSPLUS
+
+/* Command shell */
+
+#define RT_USING_FINSH
+#define FINSH_THREAD_NAME "tshell"
+#define FINSH_USING_HISTORY
+#define FINSH_HISTORY_LINES 5
+#define FINSH_USING_SYMTAB
+#define FINSH_USING_DESCRIPTION
+#define FINSH_THREAD_PRIORITY 20
+#define FINSH_THREAD_STACK_SIZE 4096
+#define FINSH_CMD_SIZE 80
+#define FINSH_USING_MSH
+#define FINSH_USING_MSH_DEFAULT
+#define FINSH_ARG_MAX 10
+
+/* Device virtual file system */
+
+#define RT_USING_DFS
+#define DFS_USING_WORKDIR
+#define DFS_FILESYSTEMS_MAX 2
+#define DFS_FILESYSTEM_TYPES_MAX 8
+#define DFS_FD_MAX 16
+#define RT_USING_DFS_ELMFAT
+
+/* elm-chan's FatFs, Generic FAT Filesystem Module */
+
+#define RT_DFS_ELM_CODE_PAGE 437
+#define RT_DFS_ELM_WORD_ACCESS
+#define RT_DFS_ELM_USE_LFN_3
+#define RT_DFS_ELM_USE_LFN 3
+#define RT_DFS_ELM_MAX_LFN 255
+#define RT_DFS_ELM_DRIVES 2
+#define RT_DFS_ELM_MAX_SECTOR_SIZE 4096
+#define RT_DFS_ELM_REENTRANT
+#define RT_USING_DFS_DEVFS
+#define RT_USING_DFS_ROMFS
+#define RT_USING_DFS_RAMFS
+
+/* Device Drivers */
+
+#define RT_USING_DEVICE_IPC
+#define RT_PIPE_BUFSZ 512
+#define RT_USING_SYSTEM_WORKQUEUE
+#define RT_SYSTEM_WORKQUEUE_STACKSIZE 2048
+#define RT_SYSTEM_WORKQUEUE_PRIORITY 23
+#define RT_USING_SERIAL
+#define RT_SERIAL_USING_DMA
+#define RT_SERIAL_RB_BUFSZ 64
+#define RT_USING_I2C
+#define RT_USING_I2C_BITOPS
+#define RT_USING_PIN
+#define RT_USING_MTD_NOR
+#define RT_USING_MTD_NAND
+#define RT_MTD_NAND_DEBUG
+#define RT_USING_RTC
+#define RT_USING_SOFT_RTC
+#define RT_USING_SDIO
+#define RT_SDIO_STACK_SIZE 512
+#define RT_SDIO_THREAD_PRIORITY 15
+#define RT_MMCSD_STACK_SIZE 1024
+#define RT_MMCSD_THREAD_PREORITY 22
+#define RT_MMCSD_MAX_PARTITION 16
+#define RT_USING_SPI
+#define RT_USING_SPI_MSD
+#define RT_USING_SFUD
+#define RT_SFUD_USING_SFDP
+#define RT_SFUD_USING_FLASH_INFO_TABLE
+#define RT_USING_WDT
+
+/* Using Hardware Crypto drivers */
+
+
+/* Using WiFi */
+
+
+/* Using USB */
+
+
+/* POSIX layer and C standard library */
+
+#define RT_USING_LIBC
+#define RT_USING_PTHREADS
+#define PTHREAD_NUM_MAX 8
+#define RT_USING_POSIX
+#define RT_USING_POSIX_MMAP
+#define RT_USING_POSIX_TERMIOS
+#define RT_USING_POSIX_AIO
+
+/* Network */
+
+/* Socket abstraction layer */
+
+#define RT_USING_SAL
+
+/* protocol stack implement */
+
+#define SAL_USING_LWIP
+#define SAL_USING_POSIX
+
+/* Network interface device */
+
+#define RT_USING_NETDEV
+#define NETDEV_USING_IFCONFIG
+#define NETDEV_USING_PING
+#define NETDEV_USING_NETSTAT
+#define NETDEV_USING_AUTO_DEFAULT
+#define NETDEV_IPV4 1
+#define NETDEV_IPV6 0
+
+/* light weight TCP/IP stack */
+
+#define RT_USING_LWIP
+#define RT_USING_LWIP202
+#define RT_LWIP_ICMP
+#define RT_LWIP_DNS
+#define RT_LWIP_DHCP
+#define IP_SOF_BROADCAST 1
+#define IP_SOF_BROADCAST_RECV 1
+
+/* Static IPv4 Address */
+
+#define RT_LWIP_IPADDR "192.168.1.30"
+#define RT_LWIP_GWADDR "192.168.1.1"
+#define RT_LWIP_MSKADDR "255.255.255.0"
+#define RT_LWIP_UDP
+#define RT_LWIP_TCP
+#define RT_LWIP_RAW
+#define RT_MEMP_NUM_NETCONN 8
+#define RT_LWIP_PBUF_NUM 16
+#define RT_LWIP_RAW_PCB_NUM 4
+#define RT_LWIP_UDP_PCB_NUM 4
+#define RT_LWIP_TCP_PCB_NUM 4
+#define RT_LWIP_TCP_SEG_NUM 40
+#define RT_LWIP_TCP_SND_BUF 8196
+#define RT_LWIP_TCP_WND 8196
+#define RT_LWIP_TCPTHREAD_PRIORITY 10
+#define RT_LWIP_TCPTHREAD_MBOX_SIZE 8
+#define RT_LWIP_TCPTHREAD_STACKSIZE 1024
+#define RT_LWIP_ETHTHREAD_PRIORITY 12
+#define RT_LWIP_ETHTHREAD_STACKSIZE 1024
+#define RT_LWIP_ETHTHREAD_MBOX_SIZE 8
+#define RT_LWIP_REASSEMBLY_FRAG
+#define LWIP_NETIF_STATUS_CALLBACK 1
+#define LWIP_NETIF_LINK_CALLBACK 1
+#define SO_REUSE 1
+#define LWIP_SO_RCVTIMEO 1
+#define LWIP_SO_SNDTIMEO 1
+#define LWIP_SO_RCVBUF 1
+#define LWIP_NETIF_LOOPBACK 0
+#define RT_LWIP_USING_PING
+
+/* Modbus master and slave stack */
+
+
+/* AT commands */
+
+
+/* VBUS(Virtual Software BUS) */
+
+
+/* Utilities */
+#define RT_USING_LWP
+
+/* RT-Thread online packages */
+
+/* IoT - internet of things */
+
+
+/* Wi-Fi */
+
+/* Marvell WiFi */
+
+
+/* Wiced WiFi */
+
+
+/* IoT Cloud */
+
+
+/* security packages */
+
+
+/* language packages */
+
+
+/* multimedia packages */
+
+
+/* tools packages */
+
+
+/* system packages */
+
+
+/* peripheral libraries and drivers */
+
+
+/* miscellaneous packages */
+
+
+/* samples: kernel and components samples */
+
+#define SOC_VEXPRESS_A9
+#define RT_USING_UART0
+#define RT_USING_UART1
+#define BSP_DRV_EMAC
+
+#endif

+ 87 - 0
bsp/qemu-vexpress-a9/rtconfig.py

@@ -0,0 +1,87 @@
+import os
+
+import uuid
+def get_mac_address(): 
+    mac=uuid.UUID(int = uuid.getnode()).hex[-12:] 
+    return "#define AUTOMAC".join([str(int(e/2) + 1) + '  0x' + mac[e:e+2] + '\n' for e in range(5,11,2)])
+
+header = '''
+#ifndef __MAC_AUTO_GENERATE_H__
+#define __MAC_AUTO_GENERATE_H__
+
+/* Automatically generated file; DO NOT EDIT. */
+/* mac configure file for RT-Thread qemu */
+
+#define AUTOMAC0  0x52
+#define AUTOMAC1  0x54
+#define AUTOMAC2  0x00
+#define AUTOMAC'''
+
+end = '''
+#endif
+'''
+
+automac_h_fn = os.path.join(os.path.dirname(__file__), 'drivers', 'automac.h')
+with open(automac_h_fn, 'w') as f:
+    f.write(header + get_mac_address() + end)
+
+# toolchains options
+ARCH='arm'
+CPU='cortex-a'
+CROSS_TOOL='gcc'
+
+if os.getenv('RTT_CC'):
+    CROSS_TOOL = os.getenv('RTT_CC')
+
+# only support GNU GCC compiler.
+PLATFORM    = 'gcc'
+EXEC_PATH   = '/usr/bin'
+
+if os.getenv('RTT_EXEC_PATH'):
+    EXEC_PATH = os.getenv('RTT_EXEC_PATH')
+
+BUILD = 'debug'
+
+if PLATFORM == 'gcc':
+    # toolchains
+    PREFIX = 'arm-none-eabi-'
+    CC = PREFIX + 'gcc'
+    CXX = PREFIX + 'g++'
+    AS = PREFIX + 'gcc'
+    AR = PREFIX + 'ar'
+    LINK = PREFIX + 'gcc'
+    TARGET_EXT = 'elf'
+    SIZE = PREFIX + 'size'
+    OBJDUMP = PREFIX + 'objdump'
+    OBJCPY = PREFIX + 'objcopy'
+    STRIP = PREFIX + 'strip'
+
+    DEVICE = ' -march=armv7-a -marm -msoft-float'
+    CFLAGS = DEVICE + ' -Wall'
+    AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -D__ASSEMBLY__ -I.'
+    LINK_SCRIPT = 'link.lds'
+    LFLAGS = DEVICE + ' -nostartfiles -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,system_vectors'+\
+                      ' -T %s' % LINK_SCRIPT
+
+    CPATH = ''
+    LPATH = ''
+
+    # generate debug info in all cases
+    AFLAGS += ' -gdwarf-2'
+    CFLAGS += ' -g -gdwarf-2'
+
+    if BUILD == 'debug':
+        CFLAGS += ' -O0'
+    else:
+        CFLAGS += ' -O2'
+
+    CXXFLAGS = CFLAGS + ' -Woverloaded-virtual -fno-exceptions -fno-rtti'
+
+    M_CFLAGS = CFLAGS + ' -mlong-calls -fPIC '
+    M_CXXFLAGS = CXXFLAGS + ' -mlong-calls -fPIC'
+    M_LFLAGS = DEVICE + CXXFLAGS + ' -Wl,--gc-sections,-z,max-page-size=0x4' +\
+                                    ' -shared -fPIC -nostartfiles -nostdlib -static-libgcc'
+    M_POST_ACTION = STRIP + ' -R .hash $TARGET\n' + SIZE + ' $TARGET \n'
+
+    POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' +\
+                  SIZE + ' $TARGET \n'

+ 62 - 0
bsp/stm32/README.md

@@ -0,0 +1,62 @@
+# STM32 BSP 说明
+
+STM32 系列 BSP 目前支持情况如下表所示:
+
+| **BSP 文件夹名称**       | **开发板名称**                 |
+|:------------------------- |:-------------------------- |
+| **F0 系列** |  |
+| [stm32f091-st-nucleo](stm32f091-st-nucleo) | ST 官方 STM32F091-nucleo 开发板 |
+| **F1 系列** |  |
+| [stm32f103-atk-nano](stm32f103-atk-nano)        | 正点原子 F103 NANO 开发板  |
+| [stm32f103-atk-warshipv3](stm32f103-atk-warshipv3)  | 正点原子 F103 战舰V3 开发板  |
+| [stm32f103-dofly-lyc8](stm32f103-dofly-lyc8) | 德飞莱 STM32F103 开发板 |
+| [stm32f103-dofly-M3S](stm32f103-dofly-M3S) | 德飞莱 STM32F103 开发板 |
+| [stm32f103-fire-arbitrary](stm32f103-fire-arbitrary/)  | 野火 F103 霸道开发板     |
+| [stm32f103-hw100k-ibox](stm32f103-hw100k-ibox) |  硬件十万个为什么 STM32F103 iBox 开发板 |
+| [stm32f103-mini-system](stm32f103-mini-system)        | STM32F103C8T6最小系统板  |
+| [stm32f107-uc-eval](stm32f107-uc-eval) | 麦克泰 STM32F107 评估板(中国版) |
+| **F4 系列** |  |
+| [stm32f401-st-nucleo](stm32f401-st-nucleo) | ST 官方 STM32F401 Nucleo-64 开发板 |
+| [stm32f405-smdz-breadfruit](stm32f405-smdz-breadfruit) | 三木电子 SM1432F405 开发板 |
+| [stm32f407-st-discovery](stm32f407-st-discovery) | ST 官方 STM32F407-discovery 开发板 |
+| [stm32f407-atk-explorer](stm32f407-atk-explorer) | 正点原子 F407 探索者开发板 |
+| [stm32f411-st-nucleo](stm32f411-st-nucleo/) | ST 官方 STM32F411-Nucleo-64 开发板 |
+| [stm32f427-robomaster-a](stm32f427-robomaster-a/) |大疆公司 RoboMaster A型开发板|
+| [stm32f429-st-disco](stm32f429-st-disco) | ST 官方 STM32F429-discovery 开发板 |
+| [stm32f429-atk-apollo](stm32f429-atk-apollo)      | 正点原子 F429 阿波罗开发板 |
+| [stm32f429-fire-challenger](stm32f429-fire-challenger/) | 野火 F429 挑战者开发板 |
+| [stm32f429-armfly-v6](stm32f429-armfly-v6) | 安富莱 F429-v6 开发板 |
+| [stm32f446-st-nucleo](stm32f446-st-nucleo) | ST 官方 STM32F446-nucleo 开发板 |
+| [stm32f469-st-disco](stm32f469-st-disco) | ST 官方 STM32F469-discovery 开发板 |
+| **F7 系列** |  |
+| [stm32f746-st-disco](stm32f746-st-disco) | ST 官方 STM32F746-discovery 开发板 |
+| [stm32f767-atk-apollo](stm32f767-atk-apollo) | 正点原子 F767 阿波罗开发板 |
+| [stm32f767-fire-challenger](stm32f767-fire-challenger/) | 野火 F767 挑战者开发板 |
+| [stm32f767-st-nucleo](stm32f767-st-nucleo) | ST 官方 STM32F767-nucleo 开发板 |
+| [stm32f769-st-disco](stm32f769-st-disco) | ST 官方 STM32f769-discovery 开发板 |
+| **G0 系列** |  |
+| [stm32g071-st-nucleo](stm32g071-st-nucleo) | ST 官方 STM32G071-nucleo 开发板 |
+| **G4 系列** |  |
+| [stm32g431-st-nucleo](stm32g431-st-nucleo) | ST 官方 STM32G431-nucleo 开发板 |
+| **H7 系列** |  |
+| [stm32h743-atk-apollo](stm32h743-atk-apollo) | 正点原子 h743 阿波罗开发板 |
+| [stm32h743-st-nucleo](stm32h743-st-nucleo) | ST 官方 STM32H743-nucleo 开发板 |
+| **L0 系列** |  |
+| [stm32l053-st-nucleo](stm32l053-st-nucleo) | ST 官方 STM32L053-nucleo 开发板 |
+| **L4 系列** |  |
+| [stm32l4r9-st-eval](stm32l4r9-st-eval) | ST 官方 STM32L4R9I-EVAL 开发板 |
+| [stm32l432-st-nucleo](stm32l432-st-nucleo) | ST 官方 STM32L432-nucleo 开发板 |
+| [stm32l475-atk-pandora](stm32l475-atk-pandora) | 正点原子 L475 潘多拉 IoT 开发板 |
+| [stm32l475-st-discovery](stm32l475-st-discovery) | ST 官方 stm32l475-discovery 开发板 |
+| [stm32l476-st-nucleo](stm32l476-st-nucleo) | ST 官方 STM32L476-nucleo 开发板 |
+| [stm32l496-ali-developer](stm32l496-ali-developer) | 诺行 STM32L496 Ali Developer Kit 开发板 |
+
+可以通过阅读相应 BSP 下的 README 来快速上手,如果想要使用 BSP 更多功能可参考 docs 文件夹下提供的说明文档,如下表所示:
+
+| **BSP 使用教程** | **简介**                                          |
+|:-------------------- |:------------------------------------------------- |
+| [外设驱动使用教程](docs/STM32系列BSP外设驱动使用教程.md) | 讲解 BSP 上更多外设驱动的使用方法 |
+| [外设驱动介绍与应用](docs/STM32系列驱动介绍.md) | 讲解 STM32 系列 BSP 驱动的支持情况,以及如何利用驱动框架开发应用程序 |
+| **BSP 制作与提交** | **简介**                                     |
+| [BSP 制作教程](docs/STM32系列BSP制作教程.md) | 讲解 STM32 系列 BSP 的制作方法,以及在制作 BSP 和提交 BSP 时应当遵守的规范,视频教程请观看 :[《RT-Thread STM32 系列 BSP 制作视频教程》](https://url.cn/5qqxJMU?sf=uri) |
+| [外设驱动添加指南](docs/STM32系列外设驱动添加指南.md) | 讲解 BSP 添加更多设备驱动的方法 |

+ 87 - 0
bsp/stm32/docs/STM32绯诲垪BSP澶栬椹卞姩浣跨敤鏁欑▼.md

@@ -0,0 +1,87 @@
+# BSP 外设驱动使用教程
+
+## 简介
+
+本文档是为需要在 RT-Thread 操作系统上使用更多开发板资源的开发者准备的。通过使用 ENV 工具对 BSP 进行配置,可以开启更多板载资源,实现更多高级功能。
+
+主要包括以下内容:
+
+1. 如何使用开发板上更多的板载资源
+2. 如何使用更多的片上资源
+3. 如何添加更多片上资源选项
+
+## 前提要求
+
+- 学会如何使用 ENV 工具,参考:[RT-Thread env 工具用户手册](https://www.rt-thread.org/document/site/rtthread-development-guide/rtthread-tool-manual/env/env-user-manual/)
+
+## 如何使用更多的板载资源
+
+开发板上一般有很多板载资源,如 Flash、SD卡、以太网等,但是 BSP 工程默认没有开启这些外设驱动。RT-Thread 提供了 ENV 工具来开启或关闭 BSP 的外设驱动。下面以在正点原子阿波罗 F429 开发板上开启 SPI Flash 驱动为例,一步步的展示如何使用 ENV 工具对 BSP 进行配置。
+
+### 1)打开配置工具
+
+在目录 `rt-thread\bsp\stm32\stm32f429-atk-apollo` 下打开 menuconfig 配置界面。
+
+![打开 menuconfig](figures/menuconfig_apolo.png)
+
+打开的配置工具界面如下所示:
+
+![RT-Thread 配置菜单](figures/config1.png)
+
+通过键盘上的上下键移动光标,选中 `Hardware Drivers Config`然后按回车键进入硬件驱动配置菜单。
+
+### 2)进入硬件驱动配置菜单
+
+在硬件配置菜单里有三个选项,分别是 **板载外设配置菜单**、**片上外设配置菜单**和**扩展模块配置菜单**,按回车键进入板载外设配置菜单。
+
+![硬件驱动 配置菜单](figures/config2.png)
+
+### 3)在板载外设配置菜单里开启 SPI Flash 选项
+
+![板载外设 配置菜单](figures/spi_flash.png)
+
+### 4)保存退出
+
+然后右移光标选中 Save 按回车键保存,然后按 Esc 键退出配置工具。
+
+![保存退出](figures/save.png)
+
+### 5)更新软件包
+
+输入命令 `pkgs --update` 使软件包配置生效。
+
+![1543477036034](figures/update.png)
+
+### 6)生成 MDK5 工程
+
+输入命令 `scons --target=mdk5 -s` 重新生成 MDK5 的工程。
+
+![1543477194829](figures/scons_mdk5.png)
+
+### 7)编译下载
+
+打开生成的 MDK5 工程文件,编译并下载。
+
+![1543478492157](figures/complise.png)
+
+### 8)查看运行结果
+
+程序运行后,输入命令 `list_device` 可以看到名为 W25Q256 的块设备,此时 `SPI Flash` 设备已经可以使用了。
+
+![1543478742034](figures/run_flash.png)
+
+## 如何使用更多的片上资源
+
+如果想要使用除了当前支持的片上资源(GPIO 和 UART1),又不想开启板载资源的支持,可以通过直接配置 **片上外设配置菜单** 的方式,使用更多片上资源。
+
+配置方法和上一章节介绍的 **如何使用更多的板载资源的配置方法** 一样,只是本次需要进入 `片上外设配置菜单`。
+
+![1543481275711](figures/on_chip_config.png)
+
+配置完成后重新生成工程,编译下载,在 FinSH 控制台输入 `list_device` 命令,可以看到 I2C1 总线已经启用。
+
+![i2c_device](figures/i2c_device.png)
+
+## 总结
+
+当开发者需要使用未开启的外设时,只要在 ENV 工具中使能相关的外设即可,重新生成的工程中就会添加对应的驱动文件。开发者就可以利用 RT-Thread 提供的驱动开快速开发应用了。

+ 288 - 0
bsp/stm32/docs/STM32绯诲垪BSP鍒朵綔鏁欑▼.md

@@ -0,0 +1,288 @@
+# STM32 系列 BSP 制作教程
+
+为了让广大开发者更好、更方便地使用 BSP 进行开发,RT-Thread 开发团队重新整理了现有的 STM32 系列的 BSP,推出了新的 BSP 框架。新的 BSP 框架在易用性、移植便利性、驱动完整性、代码规范性等方面都有较大提升,在新的 BSP 框架下进行开发,可以大大提高应用的开发效率。
+
+和 RT-Thread 以往提供的 BSP 不同,在新的 BSP 文件夹中将不会包含固件库、外设驱动等可以被多个 BSP 引用的代码文件。而是将这些通用的文件统一存放在 Library 文件夹中,通过在特定 BSP 中引用这些文件的方式,来包含 BSP 中所需的库文件或者驱动文件。这种方式不仅大大提高了代码复用率,降低了 BSP 的维护成本,而且可以更方便地给开发者提供更丰富的驱动文件,让开发者可以更容易地找到自己需要的资源。
+
+新的 BSP 框架还引入了 CubeMX 工具,可以使用该工具来对 BSP 中使用的外设引脚进行配置。CubeMX 工具提供了图形化的配置界面,这种图形化的配置方式对开发者来说更加直观,不仅可以让开发者灵活地配置 BSP 中使用的资源,并且可以让开发者对资源的使用情况一目了然。
+
+新 BSP 框架的主要特性如下:
+
+- 提供多系列 BSP 模板,大大降低新 BSP 的添加难度;
+- 每个 BSP 都配有齐全的驱动文件,开发者可以方便地使用所有驱动;
+- 开发者可以使用 CubeMX 工具对 BSP 进行图形化配置;
+
+## 1. BSP 框架介绍 
+
+BSP 框架结构如下图所示:
+
+![BSP 框架图](./figures/frame.png)
+
+每一个 STM32 系列的 BSP 由三部分组成,分别是通用库、BSP 模板和特定开发板 BSP,下面的表格以 F1 系列 BSP 为例介绍这三个部分:
+
+|项目|文件夹|说明|
+| - | - | :-- |
+| 通用库 | stm32/libraries | 用于存放 HAL 库以及基于 HAL 库的多系列通用外设驱动文件 |
+| F1 系列 BSP 工程模板 | stm32/libraries/templates/stm32f10x | F1系列 BSP 模板,可以通过修改该模板制作更多 F1系列 BSP |
+| 特定开发板 BSP | stm32/stm32f103-atk-nano | 在 BSP 模板的基础上修改而成 |
+
+## 2. 知识准备
+
+制作一个 BSP 的过程就是构建一个新系统的过程,因此想要制作出好用的 BSP,要对 RT-Thread 系统的构建过程有一定了解,需要的知识准备如下所示:
+
+- 掌握  stm32 系列 BSP 的使用方法
+
+  了解 BSP 的使用方法,可以阅读 [BSP 说明文档](../README.md) 中使用教程表格内的文档。了解外设驱动的添加方法可以参考《外设驱动添加指南》。
+
+- 了解 scons 工程构建方法
+
+  RT-Thread 使用 scons 作为系统的构建工具,因此了解 scons 的常用命令对制作新 BSP 是基本要求。
+
+- 了解设备驱动框架
+
+  在 RT-Thread 系统中,应用程序通过设备驱动框架来操作硬件,因此了解设备驱动框架,对添加 BSP 驱动是很重要的。
+
+- 了解 kconfig 语法
+
+  RT-Thread 系统通过 menuconfig 的方式进行配置,而 menuconfig 中的选项是由 kconfig 文件决定的,因此想要对 RT-Thread 系统进行配置,需要对 kconfig 语法有一定了解。
+
+- 熟悉 CubeMX 工具的使用
+
+  在新的 stm32 系列 BSP 中利用了 CubeMX 工具对底层硬件进行配置,因此需要了解 CubeMX 工具的使用方法。
+
+## 3. BSP 制作方法
+
+本节以制作正点原子 `stm32f103-atk-nano` 开发板的 BSP 为例,讲解如何为一个新的开发板添加 BSP。
+
+BSP 的制作过程分为如下五个步骤:
+
+1. 复制通用模板
+2. 使用 CubeMX 工具配置工程
+3. 修改 BSP 中的 Kconfig 文件
+4. 修改构建工程相关文件
+5. 重新生成工程
+
+在接下来的章节中将会详细介绍这五个步骤,帮助开发者快速创建所需要的 BSP。
+
+### 3.1 复制通用模板
+制作新 BSP 的第一步是复制一份同系列的 BSP 模板作为基础,通过对 BSP 模板的修改来获得新 BSP。目前提供的 BSP 模板系列如下表所示:
+
+| 工程模板 | 说明 |
+| ------- | ---- |
+| libraries/templates/stm32f0xx | F0 系列 BSP 模板 |
+| libraries/templates/stm32f10x | F1 系列 BSP 模板 |
+| libraries/templates/stm32f4xx | F4 系列 BSP 模板 |
+| libraries/templates/stm32f7xx | F7 系列 BSP 模板 |
+| libraries/templates/stm32l4xx | L4 系列 BSP 模板 |
+
+本次示例所用的 F1 系列 BSP 模板文件夹结构如下所示:
+
+![F1 系列 BSP 模板文件夹内容](figures/bsp_template_dir.png)
+
+本次制作的 BSP 为 F1 系列,因此拷贝模板文件夹下的 `stm32f10x` 文件夹,并将该文件夹的名称改为 `stm32f103-atk-nano` ,如下图所示:
+
+![复制通用模板](./figures/copy.png)
+
+在接下来的 BSP 的制作过程中,将会修改 board 文件夹内的配置文件,将 F1 系列的 BSP 模板变成一个适用于正点原子 `stm32f103-atk-nano` 开发板的 BSP ,下表总结了 board 文件夹中需要修改的内容:
+
+| 项目 | 需要修改的内容说明 |
+|-------------|-------------------------------------------------------|
+| CubeMX_Config (文件夹)| CubeMX 工程 |
+| linker_scripts (文件夹)| BSP 特定的链接脚本 |
+|board.c/h | 系统时钟、GPIO 初始化函数、芯片存储器大小 |
+| Kconfig | 芯片型号、系列、外设资源 |
+| SConscript | 芯片启动文件、目标芯片型号 |
+
+### 3.2 使用 CubeMX 配置工程
+
+在制作 BSP 的第二步,需要创建一个基于目标芯片的 CubeMX 工程。默认的 CubeMX 工程在 **CubeMX_Config** 文件夹中,双击打开 `CubeMX_Config.ioc` 工程,如下图所示:
+
+![open_cubemx](figures/open_cubemx.png)
+
+在 CubeMX 工程中将芯片型号为修改芯片型号为 STM32F103RBTx 。
+
+#### 3.2.1 生成 CubeMX 工程
+
+配置系统时钟、外设引脚等,步骤如下图所示:
+
+1. 打开外部时钟、设置下载方式、打开串口外设(注意只需要选择串口外设引脚即可,无需配置其他参数):
+
+![配置芯片引脚](./figures/CubeMX_1.png)
+
+2. 配置系统时钟:
+
+![配置系统时钟](./figures/CubeMX_2.png)
+
+3. 设置项目名称,并在指定地址重新生成 CubeMX 工程:
+
+![生成对应的配置代码](./figures/CubeMX_4.png)
+
+最终 CubeMX 生成的工程目录结构如下图所示:
+
+![CubeMX 图7](./figures/CubeMX_5.png)
+
+#### 3.2.2 拷贝初始化函数
+
+在 **board.c** 文件中存放了函数 `SystemClock_Config()` ,该函数负责初始化系统时钟。当使用 CubeMX 工具对系统时钟重新配置的时候,需要更新这个函数。
+
+该函数由 CubeMX 工具生成,默认存放在`board/CubeMX_Config/Src/main.c` 文件中。但是该文件并没有被包含到我们的工程中,因此需要将这个函数从 main.c 中拷贝到 board.c 文件中。在整个 BSP 的制作过程中,这个函数是唯一要要拷贝的函数,该函数内容如下所示:
+
+![board_1](./figures/board_1.png)
+
+在 **board.h** 文件中配置了 FLASH 和 RAM 的相关参数,这个文件中需要修改的是 `STM32_FLASH_SIZE` 和 `STM32_SRAM_SIZE` 这两个宏控制的参数。本次制作的 BSP 所用的 STM32F103RBTx 芯片的 flash 大小为 128k,ram 的大小为 20k,因此对该文件作出如下的修改:
+
+![修改 board.h](./figures/board_h.png)
+
+#### 3.2.3 堆内存配置讲解
+
+通常情况下,系统 RAM 中的一部分内存空间会被用作堆内存。下面代码的作用是,在不同编译器下规定堆内存的起始地址 **HEAP_BEGIN** 和结束地址 **HEAP_END**。这里 **HEAP_BEGIN** 和 **HEAP_END** 的值需要和后面 [3.4.1 修改链接脚本](# 3.4.1 修改链接脚本) 章节所修改的配置相一致。
+
+在某些系列的芯片中,芯片 RAM 可能分布在不连续的多块内存区域上。此时堆内存的位置可以和系统内存在同一片连续的内存区域,也可以存放在一片独立的内存区域中。例如在 L4 系列的芯片上,就可以将堆内存配置在起始地址为 `0x20000000` 的大小为 96k 的内存空间,而将 `0x10000000` 开始的 32k 内存空间用作系统运行内存。
+
+![heap_config](figures/heap_config.png)
+
+### 3.3 修改 Kconfig 选项
+
+在本小节中修改 `board/Kconfig` 文件的内容有如下两点:
+
+- 芯片型号和系列
+- BSP 上的外设支持选项
+
+芯片型号和系列的修改如下表所示:
+
+| 宏定义             | 意义     | 格式               |
+| ------------------ | -------- | ------------------ |
+| SOC_STM32F103RB    | 芯片型号 | SOC_STM32xxx       |
+| SOC_SERIES_STM32F1 | 芯片系列 | SOC_SERIES_STM32xx |
+
+关于 BSP 上的外设支持选项,一个初次提交的 BSP 仅仅需要支持 GPIO 驱动和串口驱动即可,因此在配置选项中只需保留这两个驱动配置项,如下图所示:
+
+![修改 Kconfig](./figures/Kconfig.png)
+
+### 3.4 修改工程构建相关文件
+接下来需要修改用于构建工程相关的文件。
+
+#### 3.4.1 修改链接脚本
+**linker_scripts** 链接文件如下图所示:
+
+![需要修改的链接脚本](./figures/linker_scripts.png)
+
+下面以 MDK 使用的链接脚本 link.sct 为例,演示如何修改链接脚本:
+
+![linkscripts_change](figures/linkscripts_change.png)
+
+本次制作 BSP 使用的芯片为 STM32F103RB,FLASH 为 128k,因此修改 LR_IROM1 和 ER_IROM1 的参数为 0x00020000。RAM 的大小为20k, 因此修改 RW_IRAM1 的参数为 0x00005000。这样的修改方式在一般的应用下就够用了,后续如果有特殊要求,则需要按照链接脚本的语法来根据需求修改。修改链接脚本时,可以参考 [**3.2.3 堆内存配置讲解**](# 3.2.3 堆内存配置讲解) 章节来确定 BSP 的内存分配。
+
+其他两个链接脚本的文件分别为 iar 使用的 link.icf 和 gcc 编译器使用的 link.lds,修改的方式也是类似的,如下图所示:
+
+- link.icf 修改内容
+
+  ![link_icf](figures/link_icf.png)
+
+- link.lds 修改内容
+
+  ![link_lds](figures/link_lds.png)
+
+
+####  3.4.2 修改构建脚本
+
+**SConscript** 脚本决定 MDK/IAR 工程的生成以及编译过程中要添加文件。
+
+在这一步中需要修改芯片型号以及芯片启动文件的地址,修改内容如下图所示:
+
+![修改启动文件和芯片型号](./figures/SConscript.png)
+
+注意:如果在文件夹中找不到相应系列的 .s 文件,可能是多个系列的芯片重用了相同的启动文件,此时可以在 CubeMX 中生成目标芯片的工程,查看使用了哪个启动文件,然后再修改启动文件名。
+
+#### 3.4.3 修改工程模板
+
+**template** 文件是生成 MDK/IAR 工程的模板文件,通过修改该文件可以设置工程中使用的芯片型号以及下载方式。MDK4/MDK5/IAR 的工程模板文件,如下图所示:
+
+![MDK/IAR 工程模板](./figures/template_1.png)
+
+下面以 MDK5 模板的修改为例,介绍如何修改模板配置:
+
+![选择芯片型号](./figures/template_2.png)
+
+修改程序下载方式:
+
+![配置下载方式](./figures/template_3.png)
+
+### 3.5 重新生成工程
+
+重新生成工程需要使用 env 工具。
+
+#### 3.5.1 重新生成 rtconfig.h 文件
+
+在 env 界面输入命令 menuconfig 对工程进行配置,并生成新的 rtconfig.h 文件。如下图所示:
+
+![输入menuconfig进入配置界面](./figures/menuconfig_1.png)
+
+![选择要打开的外设](./figures/menuconfig_2.png)
+
+#### 3.5.2 重新 MDK/IAR 工程
+下面以重新生成 MDK 工程为例,介绍如何重新生成 BSP 工程。
+
+使用 env 工具输入命令 `scons --target=mdk5` 重新生成工程,如下图所示:
+
+![重新生成 BSP 工程](./figures/menuconfig_3.png)
+
+重新生成工程成功:
+
+![重新生成 BSP 工程](./figures/menuconfig_4.png)
+
+到这一步为止,新的 BSP 就可以使用了。
+
+接下来我们可以分别使用命令 `scons --target=mdk4` 和 `scons --target=iar`,来更新 mdk4 和 iar 的工程,使得该 BSP 变成一个完整的,可以提交到 GitHub 的 BSP。
+
+感谢每一位贡献代码的开发者,RT-Thread 将与你一同成长。
+
+## 4. 规范
+
+本章节介绍 RT-Thread STM32 系列 BSP 制作与提交时应当遵守的规范 。开发人员在 BSP 制作完成后,可以根据本规范提出的检查点对制作的 BSP 进行检查,确保 BSP 在提交前有较高的质量 。
+
+### 1. BSP 制作规范
+
+STM32 BSP 的制作规范主要分为 3 个方面:工程配置,ENV 配置和 IDE 配置。在已有的 STM32 系列 BSP 的模板中,已经根据下列规范对模板进行配置。在制作新 BSP 的过程中,拷贝模板进行修改时,需要注意的是不要修改这些默认的配置。BSP 制作完成后,需要对新制作的 BSP 进行功能测试,功能正常后再进行代码提交。
+
+下面将详细介绍 BSP 的制作规范。
+
+#### 工程配置
+
+- 遵从RT-Thread 编码规范,代码注释风格统一
+- main 函数功能保持一致
+  - 如果有 LED 的话,main 函数里**只放一个**  LED 1HZ 闪烁的程序
+- 在 `rt_hw_board_init` 中需要完成堆的初始化:调用 `rt_system_heap_init`
+- 默认只初始化 GPIO 驱动和 FinSH 对应的串口驱动,不使用 DMA
+- 当使能板载外设驱动时,应做到不需要修改代码就能编译下载使用
+- 提交前应检查 gcc/mdk/iar 三种编译器直接编译或者重新生成后编译是否成功
+- 使用 dist 功能对 BSP 进行发布,检查使用 dist 命令生成的工程是否可以正常使用
+
+#### ENV 配置
+
+- 系统心跳统一设置为 1000(宏:RT_TICK_PER_SECOND)
+- BSP 中需要打开调试选项中的断言(宏:RT_DEBUG)
+- 系统空闲线程栈大小统一设置为 256(宏:IDLE_THREAD_STACK_SIZE)
+- 开启组件自动初始化(宏:RT_USING_COMPONENTS_INIT)
+- 需要开启 user main 选项(宏:RT_USING_USER_MAIN)
+- 默认关闭 libc(宏:RT_USING_LIBC)
+- FinSH 默认只使用 MSH 模式(宏:FINSH_USING_MSH_ONLY)
+
+#### IDE 配置
+
+- 使能下载代码后自动运行
+- 使能 C99 支持
+- 使能 One ELF Setion per Function(MDK)
+- keil/iar 生成的临时文件分别放到build下的 keil/iar 文件夹下
+- mdk/gcc/iar 生成 bin 文件名字统一成 rtthread.bin
+
+### 2. BSP 提交规范
+
+- 提交前请认真修改 BSP 的 README.md 文件,README.md 文件的外设支持表单只填写 BSP 支持的外设,可参考其他 BSP 填写。查看文档[《STM32系列驱动介绍》](./STM32系列驱动介绍.md)了解驱动分类。
+- 提交 BSP 分为 2 个阶段提交:
+  - 第一阶段:基础 BSP 包括串口驱动和 GPIO 驱动,能运行 FinSH 控制台。完成 MDK4、MDK5 、IAR 和 GCC 编译器支持,如果芯片不支持某款编译器(比如MDK4)可以不用做。 BSP 的 README.md 文件需要填写第二阶段要完成的驱动。
+  - 第二阶段:完成板载外设驱动支持,所有板载外设使用 menuconfig 配置后就能直接使用。若开发板没有板载外设,则此阶段可以不用完成。不同的驱动也要分开提交,方便 review 和合并。
+- 只提交 BSP 必要的文件,删除无关的中间文件,能够提交的文件请对照其他 BSP。
+- 提交 stm32 不同系列的 Library 库时,请参考 f1/f4 系列的 HAL 库,删除多余库文件
+- 提交前要对 BSP 进行编译测试,确保在不同编译器下编译正常
+- 提交前要对 BSP 进行功能测试,确保 BSP 的在提交前符合工程配置章节中的要求

+ 63 - 0
bsp/stm32/docs/STM32绯诲垪椹卞姩浠嬬粛.md

@@ -0,0 +1,63 @@
+#  外设驱动介绍与应用
+
+在 RT-Thread 实时操作系统中,各种各样的设备驱动是通过一套  I/O 设备管理框架来管理的。设备管理框架给上层应用提供了一套标准的设备操作 API,开发者通过调用这些标准设备操作 API,可以高效地完成和底层硬件外设的交互。设备管理框架的结构如下图所示:
+
+![rt_device](figures/rt_device.png)
+
+使用 I/O 设备管理框架开发应用程序,有如下优点:
+
+- 使用同一套标准的 API 开发应用程序,使应用程序具有更好的移植性
+- 底层驱动的升级和修改不会影响到上层代码
+- 驱动和应用程序相互独立,方便多个开发者协同开发
+
+## 1. 驱动分类介绍
+
+本小节介绍 BSP 提供的不同类别驱动的概念,对一个 BSP 而言,有如下三类驱动:
+
+- **板载外设驱动**:指 MCU 之外,开发板上外设,例如 TF 卡、以太网和 LCD 等
+- **片上外设驱动**:指 MCU 芯片上的外设,例如硬件定时器、ADC 和看门狗等
+- **扩展模块驱动**:指可以通过扩展接口或者杜邦线连接的开发板的模块,例如 ESP8266 模块
+
+这三种外设的示意图如下所示:
+
+![Peripheral](figures/Peripheral.png)
+
+## 2. 外设驱动的使用方法
+
+当前 RT-Thread 提供的驱动库已经支持 STM32 多个系列的 BSP。点击下表中的驱动名称,即可跳转到对应驱动框架的介绍文档。开发者可以通过阅读相关资料,了解如何在应用开发中通过设备驱动框架来使用这些外设驱动。
+
+### 2.1 片上外设
+
+| 序号 | 驱动                                                         | 简介                                             |
+| ---- | ------------------------------------------------------------ | ------------------------------------------------ |
+| 1    | [GPIO](https://www.rt-thread.org/document/site/programming-manual/device/pin/pin/) | 操作 GPIO 管脚                                   |
+| 2    | [UART](https://www.rt-thread.org/document/site/programming-manual/device/uart/uart/) | 通过串口收发数据                                 |
+| 3    | [soft I2C](https://www.rt-thread.org/document/site/programming-manual/device/i2c/i2c/) | 通过软件 I2C 收发数据                            |
+| 4    | [SPI](https://www.rt-thread.org/document/site/programming-manual/device/spi/spi/) | 通过 SPI 收发数据                                |
+| 5    | [ADC](https://www.rt-thread.org/document/site/programming-manual/device/adc/adc/) | 测量管脚上的模拟量                               |
+| 6    | SDIO                                                         | 通过 SDIO 读写数据                               |
+| 7    | [TIMER](https://www.rt-thread.org/document/site/programming-manual/device/hwtimer/hwtimer/) | 使用硬件定时器实现测量时间和定时执行回调函数功能 |
+| 8    | [PWM](https://www.rt-thread.org/document/site/programming-manual/device/pwm/pwm/) | 在特定的管脚输出 PWM 波形                        |
+| 9    | [RTC](https://www.rt-thread.org/document/site/programming-manual/device/rtc/rtc/) | 设置和读取时间                                   |
+| 10   | [WDT](https://www.rt-thread.org/document/site/programming-manual/device/watchdog/watchdog/) | 看门狗驱动                                       |
+| 11   | [QSPI](https://www.rt-thread.org/document/site/programming-manual/device/spi/spi/#qspi_1) | 通过 SPI(1、2、4线) 收发数据                   |
+
+### 2.2 板载外设
+
+| 序号 | 驱动    | 简介                                    |
+| ---- | ------- | --------------------------------------- |
+| 1    | SD      | 适用于 SPI 接口或 SDIO 接口的 SD(TF) 卡 |
+| 2    | ETH PHY | 以太网                                  |
+| 3    | USB PHY | USB                                     |
+| 4    | LCD     | 显示屏                                  |
+
+### 2.3 扩展模块
+
+| 序号 | 驱动     | 简介                   |
+| ---- | -------- | ---------------------- |
+| 1    | ESP8266  | 串口转 WIFI 模块       |
+| 2    | ENC28J60 | SPI 接口的以太网控制器 |
+
+### 2.4 驱动示例代码
+
+在 RT-Thread 的 `examples\test` 目录下,有 RT-Thread 提供的基于不同外设驱动的示例代码。在 env 工具中开启 BSP 中要测试的驱动,并将 `examples\test` 中对应的驱动框架测试文件加入工程,即可快速测试 BSP 中提供的驱动。

+ 162 - 0
bsp/stm32/docs/STM32绯诲垪澶栬椹卞姩娣诲姞鎸囧崡.md

@@ -0,0 +1,162 @@
+# STM32 系列外设驱动添加指南
+
+## 1. 简介
+
+本文档是为需要给现有的 STM32 BSP 添加更多外设驱动的开发者准备的。通过阅读本文,开发者可以按照自己的实际情况给现有 BSP 添加自己需要的驱动。
+
+## 2. 前提要求
+
+- 熟练使用 ENV 工具,参考:[RT-Thread env 工具用户手册](https://www.rt-thread.org/document/site/rtthread-development-guide/rtthread-tool-manual/env/env-user-manual/)
+- 熟悉 Kconfig 语法
+- 熟悉 STM32CubeMX 工具
+- 对 RT-Thread 设备驱动框架有一定了解
+
+## 3. 如何添加更多的外设驱动选项
+
+本章节以添加片上外设驱动为例,讲解如何为 BSP 添加更多可用驱动。如果想使用的片上外设是 `片上外设配置菜单` 里没有的,就需要开发者自己添加了。下面我们将演示如何为 stm32f429-atk-apollo BSP 添加 SPI3 驱动。
+
+> 没有安装 stm32cubemx 软件的可以访问 STM32cube中文网:<http://www.stm32cube.com/> ,在 `资源下载` 里下载 stm32cubemx 软件。
+
+阿波罗 BSP 默认只支持 SPI1、SPI2 和 SPI5,是不支持 SPI3 的。开发者如果需要使用 SPI3,则需要自己添加。
+
+![spi_config](figures/spi_config.png)
+
+添加 SPI3 的外设支持需要以下几步:
+
+### 1)打开 STM32CubeMX 工程
+
+打开 BSP 的 STM32CubeMX 配置文件。
+
+![1543486779576](figures/cubemx.png)
+
+### 2)按原理图配置 SPI3 的引脚,并生成代码
+
+按图示顺序配置 SPI3,并生成代码。
+
+![1543487684698](figures/cube_spi3.png)
+
+> 为 BSP 添加驱动时,STM32CubeMX 工具可以快速的完成**使能外设**和**配置管脚**的工作。而外设初始化,中断配置,DMA配置等等则由 RT-Thread 提供的驱动文件来完成。也就是说,虽然 STM32CubeMX 生成了多个文件用来初始化外设,但 RT-Thread 只使用了 STM32CubeMX  生成的 `stm32fxx_hal_msp.c` 文件和 `stm32fxx_hal_conf.h` 文件。
+>
+> 对于不同的外设驱动,通过 STM32CubeMX 工具配置的内容也不一样。开发者可以参考本文档的附录 CubeMX 配置说明章节来了解不同外设的配置方法。
+
+### 3)修改 Kconfig 文件
+
+打开 board 文件夹下的 Konfig 文件,拷贝 SPI2 的配置项,并重命名 SPI2 为 SPI3。
+
+![1543542657074](figures/Kconfig2.png)
+
+### 4)重新配置工程
+
+经过上一步的修改,此时重新打开 ENV 工具,在 menuconfig 中就会出现添加的 SPI3 的配置项。
+
+![1543543081284](figures/config5.png)
+
+### 5)生成工程,检查驱动文件
+
+使用 ENV 重新生成工程并打开,检查原有驱动文件是否支持新添加的驱动(查看是否有新驱动的配置文件,中断函数,DMA配置和中断函数等等),如不支持,需参考现有驱动添加相关的代码。
+
+![spi_code](figures/spi_code.png)
+
+### 6)编译下载
+
+检查完工程后,编译下载到开发板,程序会自动开始运行。输入 `list_device` 命令,可以看到 spi3 总线已经注册到内核,说明驱动已经添加成功。
+
+![1543543446786](figures/run_spi3.png)
+
+
+## 4. 注意事项
+
+- 部分驱动如果没有适配 BSP 所属的 STM32 系列,请等待 RT-Thread 团队更新。
+  - 驱动文件对 STM32 系列的支持情况可以查看 [STM32系列驱动介绍文档](STM32系列驱动介绍文档.md)。
+- 对于驱动文件或文档说明,有任何建议或者意见,欢迎反馈到 [RT_Thread GitHub](https://github.com/RT-Thread/rt-thread) 网站或 [RT-Thread 官方论坛](https://www.rt-thread.org/qa/forum.php)。
+
+## 5. 附录
+
+### 5.1 CubeMX配置说明
+
+本小节介绍 stm32 系列的 BSP 是如何利用 CubeMX 工具对 BSP 进行配置的。
+
+就像文档中提到的那样,stm32 系列的 BSP 只利用了  CubeMX 工具生成的  `stm32XXxx_hal_conf.h` 和 `stm32XXxx_hal_msp.c` 文件。在 HAL 库中, `stm32XXxx_hal_conf.h` 文件里提供的宏开关会决定 HAL 库将哪些外设驱动添加到工程中。 而`stm32XXxx_hal_msp.c` 文件中则存放了在 CubeMX 工具中开启的外设驱动的配置代码。
+
+### 5.2 外设配置总结
+
+当开发者想要在 BSP 中添加更多驱动时,需要使用 CubeMX 工具来配置这些外设。对于绝大多数驱动的配置,只需要在工具中使能相应的外设即可。但是对于一些复杂的外设,则需要更多的配置内容。下表展示了不同驱动在 CubeMX 工具配置步骤的总结:
+
+| 序号 | 驱动     | CubeMx 工程中的配置情况(**加粗部分为必做步骤**)            |
+| :--: | :------- | :----------------------------------------------------------- |
+|  1   | GPIO     | 无需任何操作                                                 |
+|  2   | UART     | **开启该外设** ,然后配置所需要的引脚(或者使用默认引脚)    |
+|  3   | SPI      | **开启该外设** ,然后配置所需要的引脚(或者使用默认引脚)    |
+|  4   | I2C      | 依赖于PIN 驱动,无需任何操作                                |
+|  5   | TIMER    | **使能 internal Clock 时钟** ,详细内容可参考5.3章节      |
+|  7   | PWM      | **首先使能 internal Clock 时钟,然后为 channelx 选项选择PWM Generation CHx,** 最后配置所需要的引脚(或者使用默认引脚) ,详细内容可参考5.3章节 |
+|  8   | ADC      | **开启该外设,然后选择使用的通道** ,详细内容可参考5.3章节  |
+|  9   | RTC      | **开启该外设,然后在时钟树状图里将 RTC 选择为 LSE 时钟**     |
+|  10  | Watchdog | **开启该外设**                                             |
+|  11  | EMAC     | **配置 ETH 外设的工作模式(一般为 RMII 模式)**              |
+|  12  | SDRAM    | **需要根据板载的 SDRAM 型号配置片选脚,地址线,数据线等**    |
+|  13  | SDIO     | **开启该外设,配置引脚(或者使用默认引脚),SDIO会改变时钟结构,故需重新配置时钟并修改board.c** |
+
+### 5.3 复杂外设配置说明
+
+本章节着重介绍配置步骤较为复杂的驱动。
+
+#### 5.3.1 TIMER 外设驱动添加说明
+
+ 1. 打开 STM32CubeMX 工程,设置 timer 在 Cube 里的选项,如下图所示:
+
+ ![timer CubeMX 配置](figures/timer_config1.png)
+
+ 2. 打开 stm32/stm32f429-atk-apollo/board/Kconfig ,添加 Kconfig 选项。选中自己添加的选项后,生成一遍工程,如下图所示:
+
+ ![timer Kconfig 配置](figures/timer_config2.png)
+
+  3. 打开工程进行编译,工程会提示 TIM11_CONFIG 未定义。 可以在 stm32/libraries/HAL_Drivers/config/f4/tim_config.h 中进行定义,如下图所示:
+
+ ![timer 编译](figures/timer_config3.png)
+ ![timer 编译](figures/timer_config4.png)
+
+#### 5.3.2 PWM 外设驱动添加说明
+
+ 1. 打开 STM32CubeMX 工程,设置 PWM 在 Cube 里的选项,如下图所示:
+
+ ![pwm CubeMX 配置](figures/pwm_config1.png)
+
+ 2. 打开 stm32/stm32f429-atk-apollo/board/Kconfig ,添加 Kconfig 选项。选中自己添加的选项后,生成一遍工程,如下图所示:
+
+ ![pwm Kconfig 配置](figures/pwm_config2.png)
+
+ 3. 打开工程进行编译,工程会提示 PWM2_CONFIG 未定义。 可以在 stm32/libraries/HAL_Drivers/config/f4/pwm_config.h 中进行定义,如下图所示:
+
+ ![pwm 编译](figures/pwm_config3.png)
+ ![pwm 编译](figures/pwm_config4.png)
+
+#### 5.3.3 ADC 外设驱动添加说明
+
+ 1. 打开 STM32CubeMX 工程,设置 ADC 在 Cube 里的选项,如下图所示:
+
+ ![adc CubeMX 配置](figures/adc_config1.png)
+
+ 2. 打开 stm32/stm32f429-atk-apollo/board/Kconfig ,添加 Kconfig 选项。选中自己添加的选项后,生成一遍工程,如下图所示:
+
+ ![adc Kconfig 配置](figures/adc_config2.png)
+
+ 3. 打开工程进行编译,工程会提示 ADC1_CONFIG 未定义。 可以在 stm32/libraries/HAL_Drivers/config/f4/adc_config.h 中进行定义,如下图所示:
+
+ ![adc 编译](figures/adc_config3.png)
+ ![adc 编译](figures/adc_config4.png)
+
+#### 5.3.4 编码器外设驱动添加说明
+
+ 1. 打开 STM32CubeMX 工程,设置 TIMER 在 Cube 里的选项,如下图所示:
+
+ ![pulse_encoder CubeMX 配置](figures/pulse_encoder_config1.png)
+
+ 2. 打开 stm32/stm32f407-atk-explorer/board/Kconfig ,添加 Kconfig 选项。选中自己添加的选项后,生成一遍工程,如下图所示:
+
+ ![pulse_encoder Kconfig 配置](figures/pulse_encoder_config2.png)
+
+ 3. 打开工程进行编译,工程会提示 PULSE_ENCODER4_CONFIG 未定义。 可以在 stm32/libraries/HAL_Drivers/config/f4/pulse_encoder_config.h 中进行定义,如下图所示:
+
+ ![pulse_encoder 编译](figures/pulse_encoder_config3.png)
+ ![pulse_encoder 编译](figures/pulse_encoder_config4.png)

BIN
bsp/stm32/docs/figures/CubeMX_1.png


BIN
bsp/stm32/docs/figures/CubeMX_2.png


BIN
bsp/stm32/docs/figures/CubeMX_3.png


BIN
bsp/stm32/docs/figures/CubeMX_4.png


BIN
bsp/stm32/docs/figures/CubeMX_5.png


BIN
bsp/stm32/docs/figures/Kconfig.png


BIN
bsp/stm32/docs/figures/Kconfig2.png


BIN
bsp/stm32/docs/figures/Peripheral.png


BIN
bsp/stm32/docs/figures/SConscript.png


BIN
bsp/stm32/docs/figures/adc_config1.png


BIN
bsp/stm32/docs/figures/adc_config2.png


BIN
bsp/stm32/docs/figures/adc_config3.png


BIN
bsp/stm32/docs/figures/adc_config4.png


BIN
bsp/stm32/docs/figures/board_1.png


BIN
bsp/stm32/docs/figures/board_2.png


BIN
bsp/stm32/docs/figures/board_h.png


BIN
bsp/stm32/docs/figures/bsp_template_dir.png


BIN
bsp/stm32/docs/figures/complise.png


BIN
bsp/stm32/docs/figures/config.png


BIN
bsp/stm32/docs/figures/config1.png


BIN
bsp/stm32/docs/figures/config2.png


BIN
bsp/stm32/docs/figures/config3.png


BIN
bsp/stm32/docs/figures/config4.png


BIN
bsp/stm32/docs/figures/config5.png


BIN
bsp/stm32/docs/figures/copy.png


BIN
bsp/stm32/docs/figures/cube_spi3.png


BIN
bsp/stm32/docs/figures/cubemx.png


BIN
bsp/stm32/docs/figures/exit.png


BIN
bsp/stm32/docs/figures/frame.png


BIN
bsp/stm32/docs/figures/heap_config.png


BIN
bsp/stm32/docs/figures/i2c_device.png


BIN
bsp/stm32/docs/figures/link_icf.png


BIN
bsp/stm32/docs/figures/link_lds.png


BIN
bsp/stm32/docs/figures/linker_scripts.png


BIN
bsp/stm32/docs/figures/linkscripts_change.png


Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff