Aladdin-Wang 3 ani în urmă
comite
ffc7b93a34
75 a modificat fișierele cu 1592 adăugiri și 0 ștergeri
  1. 201 0
      LICENSE
  2. 16 0
      SConscript
  3. 683 0
      docs/readme.md
  4. 63 0
      inc/flash_blob.h
  5. 114 0
      readme.md
  6. 9 0
      src/SConscript
  7. 55 0
      src/STM32F4xx_1024.FLM.c
  8. 140 0
      src/flash_blob.c
  9. 0 0
      tools/release/.dev
  10. BIN
      tools/release/ControlCAN.dll
  11. 262 0
      tools/release/ControlCAN.h
  12. BIN
      tools/release/ControlCAN.lib
  13. BIN
      tools/release/D3Dcompiler_47.dll
  14. BIN
      tools/release/Qt5Core.dll
  15. BIN
      tools/release/Qt5Gui.dll
  16. BIN
      tools/release/Qt5SerialPort.dll
  17. BIN
      tools/release/Qt5Svg.dll
  18. BIN
      tools/release/Qt5Widgets.dll
  19. BIN
      tools/release/UpdataTool.exe
  20. BIN
      tools/release/iconengines/qsvgicon.dll
  21. BIN
      tools/release/imageformats/qgif.dll
  22. BIN
      tools/release/imageformats/qicns.dll
  23. BIN
      tools/release/imageformats/qico.dll
  24. BIN
      tools/release/imageformats/qjpeg.dll
  25. BIN
      tools/release/imageformats/qsvg.dll
  26. BIN
      tools/release/imageformats/qtga.dll
  27. BIN
      tools/release/imageformats/qtiff.dll
  28. BIN
      tools/release/imageformats/qwbmp.dll
  29. BIN
      tools/release/imageformats/qwebp.dll
  30. BIN
      tools/release/kerneldlls/CANDTU_NET.dll
  31. BIN
      tools/release/kerneldlls/CANDTU_NET_400.dll
  32. BIN
      tools/release/kerneldlls/CANETE.dll
  33. BIN
      tools/release/kerneldlls/CANET_TCP.dll
  34. BIN
      tools/release/kerneldlls/CANWIFI_TCP.dll
  35. BIN
      tools/release/kerneldlls/CANWIFI_UDP.dll
  36. BIN
      tools/release/kerneldlls/USBCAN.dll
  37. BIN
      tools/release/kerneldlls/USBCAN_8E_U_x64.dll
  38. 49 0
      tools/release/kerneldlls/kerneldll.ini
  39. BIN
      tools/release/kerneldlls/pci9810b.dll
  40. BIN
      tools/release/kerneldlls/pci9820b.dll
  41. BIN
      tools/release/kerneldlls/pci9820i.dll
  42. BIN
      tools/release/kerneldlls/pci9840b.dll
  43. BIN
      tools/release/kerneldlls/pcie9140_x64.dll
  44. BIN
      tools/release/kerneldlls/pec9920.dll
  45. BIN
      tools/release/libEGL.dll
  46. BIN
      tools/release/libGLESv2.dll
  47. BIN
      tools/release/libgcc_s_dw2-1.dll
  48. BIN
      tools/release/libstdc++-6.dll
  49. BIN
      tools/release/libwinpthread-1.dll
  50. BIN
      tools/release/opengl32sw.dll
  51. BIN
      tools/release/platforms/qwindows.dll
  52. BIN
      tools/release/styles/qwindowsvistastyle.dll
  53. BIN
      tools/release/translations/qt_ar.qm
  54. BIN
      tools/release/translations/qt_bg.qm
  55. BIN
      tools/release/translations/qt_ca.qm
  56. BIN
      tools/release/translations/qt_cs.qm
  57. BIN
      tools/release/translations/qt_da.qm
  58. BIN
      tools/release/translations/qt_de.qm
  59. BIN
      tools/release/translations/qt_en.qm
  60. BIN
      tools/release/translations/qt_es.qm
  61. BIN
      tools/release/translations/qt_fi.qm
  62. BIN
      tools/release/translations/qt_fr.qm
  63. BIN
      tools/release/translations/qt_gd.qm
  64. BIN
      tools/release/translations/qt_he.qm
  65. BIN
      tools/release/translations/qt_hu.qm
  66. BIN
      tools/release/translations/qt_it.qm
  67. BIN
      tools/release/translations/qt_ja.qm
  68. BIN
      tools/release/translations/qt_ko.qm
  69. BIN
      tools/release/translations/qt_lv.qm
  70. BIN
      tools/release/translations/qt_pl.qm
  71. BIN
      tools/release/translations/qt_ru.qm
  72. BIN
      tools/release/translations/qt_sk.qm
  73. BIN
      tools/release/translations/qt_tr.qm
  74. BIN
      tools/release/translations/qt_uk.qm
  75. BIN
      tools/release/translations/qt_zh_TW.qm

+ 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.

+ 16 - 0
SConscript

@@ -0,0 +1,16 @@
+# RT-Thread building script for bridge
+
+import os
+from building import *
+
+cwd = GetCurrentDir()
+objs = []
+list = os.listdir(cwd)
+
+if GetDepend('PKG_USING_FLASH_BLOB'):
+    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')

+ 683 - 0
docs/readme.md

@@ -0,0 +1,683 @@
+---
+
+# 前言
+在进行Flash操作时,一般我们需要设计一套Flash抽象层,至少要包括flash的init,read、write、erase这些操作。但每更换一个单片机或者flash器件就要额外去编写flash驱动去适配init,read、write、erase。尽管有会者不难的属性加持,但适配所有的单片机或者flash器件,工作量也可想而知。
+
+本文为大家提供一个适配几乎任意单片机型号的flash驱动,之所以说是几乎,是因为我们这次要借东风,而这个东风就是Keil的FLM文件。
+
+项目开源地址:[https://gitee.com/Aladdin-Wang/flash_blob](https://gitee.com/Aladdin-Wang/flash_blob)
+
+---
+
+# 一、FLM文件是什么?
+熟悉Keil的朋友们都知道,当我们要下载编译好的镜像到Flash时,首先要做的一步就是选择合适的Flash下载算法,而这个算法本身就是一个FLM文件:
+![](https://img-blog.csdnimg.cn/5a44095e41044d1fb0aa4b2860c7bb36.png)
+所谓Flash下载算法,是负责擦除,下载应用数据到flash的一个软件。而Keil往往会集成不少FLM文件以支持大多数的flash型号。
+当然,这些算法也是根据不同型号的flash所编写的。只不过,前人们已经为我们种好了大树,我们可以直接在树下乘凉了。
+
+# 二、FLM文件结构
+Keil规定了FLM文件的构成,它是一成不变的,我们才可以放心的对文件本身进行解析,并为自己所用。
+
+生成FLM文件的程序中,有两个非常重要的文件,分别是
+- FlashPrg.c中包含编程算法。
+- FlashDev.c中包含设备参数。
+## 1.FlashPrg.c
+FlashPrg.c文件包含强制性flash编程函数Init、UnInit、EraseSector和ProgramPage。可选地,根据设备特性,可以实现函数EraseChip、BlankCheck和Verify 。
+| Function Name | Indication | Description                                                  |
+| ------------- | ---------- | ------------------------------------------------------------ |
+| BlankCheck    | optional   | Check and compare patterns.                                  |
+| EraseChip     | optional   | Delete entire Flash memory content.                          |
+| EraseSector   | mandatory  | Delete Flash memory content of a specific sector.            |
+| Init          | mandatory  | Initialize and prepare device for Flash programming.         |
+| ProgramPage   | mandatory  | Write the application into the Flash memory.                 |
+| UnInit        | mandatory  | De-initialize the microcontroller after one of the Flash programming steps. |
+| Verify        | optional   | Compare Flash memory content with the program code.          |
+
+其中有4个是必须要有的,我们来逐一说明:
+1. Init
+函数Init为 Flash 编程初始化微控制器。每当尝试将程序下载到 Flash 时都会调用它。
+```c
+int Init (unsigned long adr, unsigned long clk, unsigned long fnc);
+```
+
+
+参数adr指定设备的基址。
+
+参数clk指定用于编程设备的时钟频率。
+
+参数fnc是一个数字:
+
+1 代表擦除。
+2代表程序。
+3代表验证。
+
+Code Example:
+
+```c
+int Init (unsigned long adr, unsigned long clk, unsigned long fnc) {
+ 
+  // Zero Wait State
+  FLASH->ACR  = 0x00000000;
+ 
+  // Unlock Flash
+  FLASH->KEYR = FLASH_KEY1;
+  FLASH->KEYR = FLASH_KEY2;
+ 
+  // Test if IWDG is running (IWDG in HW mode)
+  if ((FLASH->OBR & 0x04) == 0x00) {
+    // Set IWDG time out to ~32.768 second
+    IWDG->KR  = 0x5555; // Enable write access to IWDG_PR and IWDG_RLR
+    IWDG->PR  = 0x06;   // Set prescaler to 256
+    IWDG->RLR = 4095;   // Set reload value to 4095
+  }
+ 
+  return (0);
+}
+```
+2. ProgramPage
+函数ProgramPage用于将代码写入闪存。它被调用以将程序下载到 Flash。由于flash通常以块或页的形式组织,因此函数ProgramPage的参数不得跨越这些闪存页的对齐边界。页面大小在结构 FlashDevice 中指定,值为Program Page Size。
+
+```c
+int ProgramPage ( unsigned  long adr, unsigned  long sz, unsigned  char *buf);
+```
+
+参数adr指定要编程的页面的起始地址。它由主机编程系统与flash页面的起始地址对齐。
+
+参数sz指定数据缓冲区中的数据大小。主机编程系统确保不跨越页面边界。
+
+参数buf指向包含要编程的数据的数据缓冲区。
+
+Code Example:
+
+```c
+int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf) {
+ 
+  sz = (sz + 1) & ~1;                           // Adjust size for Half Words
+ 
+  while (sz) {
+ 
+    FLASH->CR |=  FLASH_PG;                     // Programming Enabled
+ 
+    M16(adr) = *((unsigned short *)buf);        // Program Half Word
+    while (FLASH->SR & FLASH_BSY);
+ 
+    FLASH->CR &= ~FLASH_PG;                     // Programming Disabled
+ 
+    // Check for Errors
+    if (FLASH->SR & (FLASH_PGERR | FLASH_WRPRTERR)) {
+      FLASH->SR |= FLASH_PGERR | FLASH_WRPRTERR;
+      return (1);                               // Failed
+    }
+ 
+    // Go to next Half Word
+    adr += 2;
+    buf += 2;
+    sz  -= 2;
+  }
+ 
+  return (0);                                   // Done
+}
+```
+3. EraseSector
+函数EraseSector删除从参数adr指定的地址开始的扇区内容。
+
+```c
+int EraseSector (unsigned long adr);
+```
+
+参数adr扇区地址
+
+Code Example:
+```c
+int EraseSector (unsigned long adr) {
+ 
+  FLASH->CR |=  FLASH_PER;                      // Page Erase Enabled
+  FLASH->AR  =  adr;                            // Page Address
+  FLASH->CR |=  FLASH_STRT;                     // Start Erase
+ 
+  while (FLASH->SR & FLASH_BSY) {
+    IWDG->KR = 0xAAAA;                          // Reload IWDG
+  }
+ 
+  FLASH->CR &= ~FLASH_PER;                      // Page Erase Disabled
+ 
+  return (0);                                   // Done
+}
+```
+4. UnInit
+函数UnInit取消初始化微控制器,并在擦除、编程或验证步骤结束时调用。
+```c
+int UnInit (unsigned long fnc);
+```
+
+Code Example
+
+```c
+int UnInit (unsigned long fnc) {
+ 
+  // Lock Flash
+  FLASH->CR |=  FLASH_LOCK;
+ 
+  return (0);
+}
+```
+## 2.FlashPrg.c
+文件FlashDev.c包含以下参数定义:
+1. Flash编程功能。
+2. FlashDevice结构:
+```c
+struct FlashDevice const FlashDevice  =  {
+   FLASH_DRV_VERS,              // 驱动版本,请勿修改!
+   "New Device 256kB Flash" ,    // 设备名称
+   ONCHIP,                      // 设备类型
+   0x00000000,                  // 设备起始地址
+   0x00040000,                  // 以字节为单位的设备大小 (256kB)
+   1024,                        // 编程页面大小
+   0,                           // 保留,必须为0
+   0xFF,                        // 已擦除内存的初始内容
+   100,                         // 程序页面超时 100 毫秒
+   3000,                        // 擦除扇区超时 3000 毫秒
+ 
+// 指定扇区的大小和地址
+   0x002000, 0x000000,          // 扇区大小 8kB(8 个扇区)
+   0x010000, 0x010000,          // 扇区大小 64kB(2 个扇区)
+   0x002000, 0x030000,          // 扇区大小 8kB(8 个扇区)
+   SECTOR_END
+};
+```
+Device Name通常显示在工具中,用于识别 Flash 算法。确保此名称反映设备名称。
+编程页面大小指定使用函数ProgramPage进行编程 的块大小。对于块大小较小的设备,最好指定物理块大小的倍数,因为这可以减少与目标的通信开销。快速编程的最佳块大小为 1024 字节,但系统本身并不限制此大小值。
+# 三、解析FLM文件
+## 1.解析flm文件
+下面让我们解析一下现有的FLM文件,以STM32F4xx_1024.FLM为例:
+将ARM:CMSIS Pack文件夹(通常在D:\Users\Administrator\AppData\Local\Arm\Packs\Keil\STM32F4xx_DFP\2.15.0\CMSIS\Flash)中的内容复制到一个新文件夹中。
+
+打开命令行工具,输入arm-none-eabi-readelf -a STM32F4xx_1024.FLM:
+
+```c
+$ arm-none-eabi-readelf -a STM32F4xx_1024.FLM
+ELF Header:
+  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
+  Class:                             ELF32
+  Data:                              2's complement, little endian
+  Version:                           1 (current)
+  OS/ABI:                            UNIX - System V
+  ABI Version:                       0
+  Type:                              EXEC (Executable file)
+  Machine:                           ARM
+  Version:                           0x1
+  Entry point address:               0x0
+  Start of program headers:          12172 (bytes into file)
+  Start of section headers:          12236 (bytes into file)
+  Flags:                             0x5000000, Version5 EABI
+  Size of this header:               52 (bytes)
+  Size of program headers:           32 (bytes)
+  Number of program headers:         2
+  Size of section headers:           40 (bytes)
+  Number of section headers:         16
+  Section header string table index: 15
+
+Section Headers:
+  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
+  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
+  [ 1] PrgCode           PROGBITS        00000000 000034 000144 00  AX  0   0  4
+  [ 2] PrgData           PROGBITS        00000144 000178 000004 00  WA  0   0  4
+  [ 3] DevDscr           PROGBITS        00000148 00017c 0010a0 00   A  0   0  4
+  [ 4] .debug_abbrev     PROGBITS        00000000 00121c 0005a4 00      0   0  1
+  [ 5] .debug_frame      PROGBITS        00000000 0017c0 000104 00      0   0  1
+  [ 6] .debug_info       PROGBITS        00000000 0018c4 00064c 00      0   0  1
+  [ 7] .debug_line       PROGBITS        00000000 001f10 000218 00      0   0  1
+  [ 8] .debug_loc        PROGBITS        00000000 002128 0001b8 00      0   0  1
+  [ 9] .debug_macinfo    PROGBITS        00000000 0022e0 000614 00      0   0  1
+  [10] .debug_pubnames   PROGBITS        00000000 0028f4 000096 00      0   0  1
+  [11] .symtab           SYMTAB          00000000 00298c 000110 10     12   9  4
+  [12] .strtab           STRTAB          00000000 002a9c 000100 00      0   0  1
+  [13] .note             NOTE            00000000 002b9c 00001c 00      0   0  4
+  [14] .comment          PROGBITS        00000000 002bb8 000334 00      0   0  1
+  [15] .shstrtab         STRTAB          00000000 002eec 0000a0 00      0   0  1
+Key to Flags:
+  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
+  L (link order), O (extra OS processing required), G (group), T (TLS),
+  C (compressed), x (unknown), o (OS specific), E (exclude),
+  y (purecode), p (processor specific)
+
+There are no section groups in this file.
+
+Program Headers:
+  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
+  LOAD           0x000034 0x00000000 0x00000000 0x00148 0x00148 RWE 0x4
+  LOAD           0x00017c 0x00000148 0x00000148 0x010a0 0x010a0 R   0x4
+
+ Section to Segment mapping:
+  Segment Sections...
+   00     PrgCode PrgData
+   01     DevDscr
+
+There is no dynamic section in this file.
+
+There are no relocations in this file.
+
+There are no unwind sections in this file.
+
+Symbol table '.symtab' contains 17 entries:
+   Num:    Value  Size Type    Bind   Vis      Ndx Name
+     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
+     1: 00000000     0 NOTYPE  LOCAL  DEFAULT    1 $t
+     2: 00000122     0 NOTYPE  LOCAL  DEFAULT    1 $d
+     3: 00000144     0 NOTYPE  LOCAL  DEFAULT    2 $d.realdata
+     4: 00000148     0 NOTYPE  LOCAL  DEFAULT    3 $d.realdata
+     5: 00000000     0 FILE    LOCAL  DEFAULT  ABS FlashPrg.c
+     6: 00000000     0 SECTION LOCAL  DEFAULT    1 .text
+     7: 00000000     0 FILE    LOCAL  DEFAULT  ABS FlashDev.c
+     8: 00000148  4256 SECTION LOCAL  DEFAULT    3 .constdata
+     9: 00000000     0 NOTYPE  GLOBAL HIDDEN   ABS BuildAttributes$$THM_ISAv
+    10: 00000001    28 FUNC    GLOBAL HIDDEN     1 GetSecNum
+    11: 0000001d    46 FUNC    GLOBAL HIDDEN     1 Init
+    12: 0000004b    14 FUNC    GLOBAL HIDDEN     1 UnInit
+    13: 00000059    44 FUNC    GLOBAL HIDDEN     1 EraseChip
+    14: 00000085    76 FUNC    GLOBAL HIDDEN     1 EraseSector
+    15: 000000d1    82 FUNC    GLOBAL HIDDEN     1 ProgramPage
+    16: 00000148  4256 OBJECT  GLOBAL HIDDEN     3 FlashDevice
+
+No version information found in this file.
+
+Displaying notes found at file offset 0x00002b9c with length 0x0000001c:
+  Owner                 Data size       Description
+  ARM                  0x0000000c       Unknown note type: (0x40000000)
+```
+通过Symbol table信息我们可以找到Init、UnInit、EraseSector和ProgramPage函数所在的位置。
+
+我们还需要根据Section Headers所描述的位置提取出Prgcode(代码),PrgData(数据),DevDscr(设备描述)的信息。
+
+在命令行中输入arm-none-eabi-objdum -s -d STM32F4xx_1024.FLM:-s参数可以将所有段的内容一十六进制方式打印出来,-d参数可以将所有包含指令的段反汇编。
+
+```c
+$ arm-none-eabi-objdump -s -d STM32F4xx_1024.FLM
+
+STM32F4xx_1024.FLM:     file format elf32-littlearm
+
+Contents of section PrgCode:
+ 0000 0003000e 202802d3 4009001d 70471028  .... (..@...pG.(
+ 0010 02d30009 c01c7047 80087047 42484149  ......pG..pGBHAI
+ 0020 41604249 41600021 0160c168 f0221143  A`BIA`.!.`.h.".C
+ 0030 c1604069 800606d4 3e483d49 01600621  .`@i....>H=I.`.!
+ 0040 41603d49 81600020 70473748 01694205  A`=I.`. pG7H.iB.
+ 0050 11430161 00207047 10b53348 01690424  .C.a. pG..3H.i.$
+ 0060 21430161 0169a203 11430161 3349314a  !C.a.i...C.a3I1J
+ 0070 00e01160 c368db03 fbd40169 a1430161  ...`.h.....i.C.a
+ 0080 002010bd 30b5fff7 bbff2749 ca68f023  . ..0.....'I.h.#
+ 0090 1a43ca60 02240c61 0a690007 400e0243  .C.`.$.a.i..@..C
+ 00a0 0a610869 e2031043 08612448 214a00e0  .a.i...C.a$H!J..
+ 00b0 1060cd68 ed03fbd4 0869a043 0861c868  .`.h.....i.C.a.h
+ 00c0 0006000f 03d0c868 1843c860 012030bd  .......h.C.`. 0.
+ 00d0 70b5154d c91c8908 eb688900 f0263343  p..M.....h...&3C
+ 00e0 eb600023 2b61164b 17e02c69 1c432c61  .`.#+a.K..,i.C,a
+ 00f0 14680460 ec68e403 fcd42c69 64086400  .h.`.h....,id.d.
+ 0100 2c61ec68 2406240f 04d0e868 3043e860  ,a.h$.$....h0C.`
+ 0110 012070bd 001d121d 091f0029 e5d10020  . p........)...
+ 0120 70bd0000 23016745 003c0240 ab89efcd  p...#.gE.<.@....
+ 0130 55550000 00300040 ff0f0000 aaaa0000  UU...0.@........
+ 0140 01020000                             ....
+Contents of section PrgData:
+ 0144 00000000                             ....
+Contents of section DevDscr:
+ 0148 01015354 4d333246 34787820 466c6173  ..STM32F4xx Flas
+ 0158 68000000 00000000 00000000 00000000  h...............
+ 0168 00000000 00000000 00000000 00000000  ................
+ 0178 00000000 00000000 00000000 00000000  ................
+ 0188 00000000 00000000 00000000 00000000  ................
+ 0198 00000000 00000000 00000000 00000000  ................
+ 01a8 00000000 00000000 00000000 00000000  ................
+ 01b8 00000000 00000000 00000000 00000000  ................
+ 01c8 00000100 00000008 00001000 00040000  ................
+ 01d8 00000000 ff000000 64000000 70170000  ........d...p...
+ 01e8 00400000 00000000 00000100 00000100  .@..............
+ 01f8 00000200 00000200 ffffffff ffffffff  ................
+```
+我们所需要的正是以上信息,接下来的任务只需要写一个上位机,将以上文件提取出来即可,这个工具我已经写好,如图:
+![](https://img-blog.csdnimg.cn/e6c2d314ec024033bcf64015220e3f17.png)
+
+选择STM32F4xx_1024.FLM,生成STM32F4xx_1024.FLM.c文件,然后直接添加到我们的工程中即可,生成的代码如下:
+
+```c
+#include "flash_blob.h" 
+
+#define OPS_OFFSET ((uint32_t)&flash_code)
+
+#define DEV_OFFSET ((uint32_t)&flash_dev)
+
+#define RAM_OFFSET ((uint32_t)&rw_data)
+
+static const uint32_t flash_code[] = 
+{
+    0X0E000300,0XD3022820,0X1D000940,0X28104770,0X0900D302,0X47701CC0,0X47700880,0X49414842,
+    0X49426041,0X21036041,0X68C16001,0X431122F0,0X694060C1,0XD4060680,0X493D483E,0X21066001,
+    0X493D6041,0X20006081,0X48374770,0X05426901,0X61014311,0X47702000,0X4833B510,0X24046901,
+    0X61014321,0X03A26901,0X61014311,0X4A314933,0X6011E000,0X03DB68C3,0X6901D4FB,0X610143A1,
+    0XBD102000,0XF7FFB530,0X4927FFBB,0X23F068CA,0X60CA431A,0X610C2402,0X0700690A,0X43020E40,
+    0X6908610A,0X431003E2,0X48246108,0XE0004A21,0X68CD6010,0XD4FB03ED,0X43A06908,0X68C86108,
+    0X0F000600,0X68C8D003,0X60C84318,0XBD302001,0X4D15B570,0X08891CC9,0X008968EB,0X433326F0,
+    0X230060EB,0X4B16612B,0X692CE017,0X612C431C,0X60046814,0X03E468EC,0X692CD4FC,0X00640864,
+    0X68EC612C,0X0F240624,0X68E8D004,0X60E84330,0XBD702001,0X1D121D00,0X29001F09,0X2000D1E5,
+    0X0000BD70,0X45670123,0X40023C00,0XCDEF89AB,0X00005555,0X40003000,0X00000FFF,0X0000AAAA,
+    0X00000201,0X00000000,
+};
+
+static const uint32_t flash_dev[] = 
+{
+    0X54530101,0X4632334D,0X20787834,0X73616C46,0X00000068,0X00000000,0X00000000,0X00000000,
+    0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
+    0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
+    0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
+    0X00010000,0X08000000,0X00100000,0X00000400,0X00000000,0X000000FF,0X00000064,0X00001770,
+    0X00004000,0X00000000,0X00010000,0X00010000,0X00020000,0X00020000,0XFFFFFFFF,0XFFFFFFFF,
+};
+
+static uint32_t rw_data[] = 
+{
+    0X00000000,
+};
+
+static flash_blob_device_t  flash_device =
+{
+    (void*)(OPS_OFFSET + 0X001D),  // Init
+    (void*)(OPS_OFFSET + 0X004B),  // UnInit
+    (void*)(OPS_OFFSET + 0X0059),  // EraseChip
+    (void*)(OPS_OFFSET + 0X0085),  // EraseSector
+    (void*)(OPS_OFFSET + 0X00D1),  // ProgramPage
+    (void*)(DEV_OFFSET),
+    (void*)(RAM_OFFSET),
+};
+static int flash_blob_device_register(void) 
+{                                            
+    flash_dev_register(&flash_device);       
+    return 0 ;                                
+}                                               
+INIT_BOARD_EXPORT(flash_blob_device_register);
+
+```
+
+# 四、设计flash驱动抽象层
+接下来,为了方便后续使用,需要设计一个flash驱动抽象层,代码如下:
+flash_blob.h
+```c
+#ifndef FLASH_BLOB_H
+#define FLASH_BLOB_H
+#include "rtthread.h"
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+#define VERS       1           // Interface Version 1.01
+
+#define UNKNOWN    0           // Unknown
+#define ONCHIP     1           // On-chip Flash Memory
+#define EXT8BIT    2           // External Flash Device on 8-bit  Bus
+#define EXT16BIT   3           // External Flash Device on 16-bit Bus
+#define EXT32BIT   4           // External Flash Device on 32-bit Bus
+#define EXTSPI     5           // External Flash Device on SPI
+
+#define SECTOR_NUM 16         // Max Number of Sector Items
+
+struct FlashSectors  {
+  unsigned long   szSector;    // Sector Size in Bytes
+  unsigned long AddrSector;    // Address of Sector
+};
+
+typedef struct FlashDevice  {
+   unsigned short     Vers;    // Version Number and Architecture
+   char       DevName[128];    // Device Name and Description
+   unsigned short  DevType;    // Device Type: ONCHIP, EXT8BIT, EXT16BIT, ...
+   unsigned long    DevAdr;    // Default Device Start Address
+   unsigned long     szDev;    // Total Size of Device
+   unsigned long    szPage;    // Programming Page Size
+   unsigned long       Res;    // Reserved for future Extension
+   unsigned char  valEmpty;    // Content of Erased Memory
+
+   unsigned long    toProg;    // Time Out of Program Page Function
+   unsigned long   toErase;    // Time Out of Erase Sector Function
+
+   struct FlashSectors sectors[SECTOR_NUM];
+}flash_dev_t;
+
+typedef struct {
+	int (*Init)(uint32_t adr, uint32_t clk, uint32_t fnc);
+	int (*UnInit)(uint32_t fnc);
+    int (*EraseChip)(void);
+	int (*EraseSector)(uint32_t adr);
+	int (*ProgramPage)(uint32_t adr, uint32_t sz, uint8_t* buf);  
+}flash_ops_t;
+
+typedef struct
+{
+    flash_ops_t tFlashops;
+    flash_dev_t *ptFlashDev;
+    int *pPrgData;
+    rt_slist_t slist;      
+}flash_blob_t;
+
+extern void flash_dev_register(flash_blob_t *ptFlashDevice);
+extern bool target_flash_init(uint32_t flash_start, int32_t size);
+extern bool target_flash_uninit(uint32_t flash_start);
+extern int32_t target_flash_write(uint32_t addr, const uint8_t *buf, int32_t size);
+extern int32_t target_flash_erase(uint32_t addr, int32_t size);
+extern int32_t target_flash_read(uint32_t addr, const uint8_t *buf, int32_t size);
+#endif
+
+```
+flash_blob.c
+
+```c
+#include "flash_blob.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+
+static bool s_bIsInit = false;
+static rt_slist_t _slist_head = RT_SLIST_OBJECT_INIT(_slist_head);
+register int *pPrgDataBase __asm("r9");
+
+void flash_dev_register(flash_blob_t *ptFlashDevice)
+{
+    rt_slist_init(&(ptFlashDevice->slist));
+    rt_slist_append(&_slist_head, &(ptFlashDevice->slist));
+}
+
+static flash_blob_t * flash_dev_find(uint32_t flash_start)
+{
+    rt_slist_t *node;
+    rt_slist_for_each(node, &_slist_head) {
+        flash_blob_t *ptFlashDevice = rt_slist_entry(node, flash_blob_t, slist);
+
+        if(flash_start >= ptFlashDevice->ptFlashDev->DevAdr &&
+           flash_start < ptFlashDevice->ptFlashDev->DevAdr + ptFlashDevice->ptFlashDev->szDev) {
+            return ptFlashDevice;
+        }
+    }
+    return NULL;
+}
+
+bool target_flash_init(uint32_t flash_start, int32_t size)
+{
+    if (flash_start % 4 != 0) {
+        LOG_E("flash addr must be 4-byte alignment");
+        return NULL;
+    }
+
+    flash_blob_t *ptFlashDevice = flash_dev_find(flash_start);
+
+    if(ptFlashDevice != NULL) {
+        pPrgDataBase = ptFlashDevice->pPrgData;
+        ptFlashDevice->tFlashops.Init(flash_start, 0, 0);
+        return true;
+    }
+
+    return false;
+}
+
+bool target_flash_uninit(uint32_t flash_start)
+{
+    flash_blob_t *ptFlashDevice = flash_dev_find(flash_start);
+
+    if(ptFlashDevice != NULL) {
+        pPrgDataBase = ptFlashDevice->pPrgData;
+        ptFlashDevice->tFlashops.UnInit(flash_start);
+        return true;
+    }
+
+    return true;
+}
+
+int target_flash_write(uint32_t addr, const uint8_t *buf, int32_t size)
+{
+    flash_blob_t *ptFlashDevice = flash_dev_find(addr);
+
+    if(ptFlashDevice != NULL) {
+        pPrgDataBase = ptFlashDevice->pPrgData;
+
+        while(size > 0) {
+            uint32_t write_size = size > ptFlashDevice->ptFlashDev->szPage ? ptFlashDevice->ptFlashDev->szPage : size;
+
+            if( 0 != ptFlashDevice->tFlashops.ProgramPage(addr, write_size, (uint8_t *)buf)) {
+                LOG_E("Programming Failed");
+                return -1;
+            }
+
+            addr += write_size;
+            buf  += write_size;
+            size -= write_size;
+        }
+
+        return size;
+    }
+
+    return -1;
+}
+
+int32_t target_flash_read(uint32_t addr, const uint8_t *buf, int32_t size)
+{
+    flash_blob_t *ptFlashDevice;
+    pPrgDataBase = ptFlashDevice->pPrgData;
+    return size;
+}
+
+int32_t target_flash_erase(uint32_t addr, int32_t size)
+{
+    int32_t wSector, wRemainLen;
+    flash_blob_t *ptFlashDevice = flash_dev_find(addr);
+
+    if(ptFlashDevice != NULL) {
+        if (size > ptFlashDevice->ptFlashDev->szDev) {
+            LOG_E("erase outrange flash size! addr is (0x%p)\n", (void *)(addr + size));
+            return -1;
+        }
+
+        pPrgDataBase = ptFlashDevice->pPrgData;
+        wRemainLen = size;
+        while(wRemainLen > 0) {
+            if(0 != ptFlashDevice->tFlashops.EraseSector(addr)) {
+                LOG_E("erase Failed! addr is (0x%p)\n", (void *)addr);
+                return -1;
+            }
+
+            for(wSector = 0; wSector < SECTOR_NUM; wSector++) {
+                if(ptFlashDevice->ptFlashDev->sectors[wSector + 1].szSector == 0XFFFFFFFF )
+                    break;
+
+                if(((addr - ptFlashDevice->ptFlashDev->DevAdr) < ptFlashDevice->ptFlashDev->sectors[wSector + 1].AddrSector) &&
+                   ((addr - ptFlashDevice->ptFlashDev->DevAdr) >= ptFlashDevice->ptFlashDev->sectors[wSector].AddrSector) )
+                    break;
+            }
+
+            addr += ptFlashDevice->ptFlashDev->sectors[wSector].szSector;
+            wRemainLen -= ptFlashDevice->ptFlashDev->sectors[wSector].szSector;
+        }
+
+        return size;
+    }
+
+    return -1;
+}
+
+int32_t target_flash_verify (uint32_t addr, uint8_t *buf, int32_t size)
+{
+
+    return size;
+}
+```
+
+# 五、快速使用
+本项目借用了rtthread的自动初始化机制和链表,所以最快的使用方式是直接作为rtthread的软件包使用,使用方法如下:
+
+1.在rtthread软件包中找到flash_blob,然后添加进工程。
+2. 通过tools文件下的工具,生成对应的xxx.FLM.c文件,将xxx.FLM.c添加进工程,如果有多个flash器件,可以连续添加。
+ 注意:多个设备的话每个flash的FlashDevice 的设备起始地址不可重叠,flash抽象层根据地址,自动选择相应的驱动。
+  3.由于flash驱动需要占用“r9”寄存器,所以需要在编译选项中添加`-ffixed-r9`
+
+![在这里插入图片描述](https://img-blog.csdnimg.cn/78a368cc80b4459c84549da58569a496.png)
+
+ 以上步骤完成后,就可以快速使用了,例如将YMODEM接收到的数据,写到flash中,代码如下:
+
+
+```c
+uint8_t *ymodem_call_back_receive(uint8_t *pchBuffer, uint16_t hwSize)
+{
+    static char *s_pchFileName = NULL, *s_pchFileSize = NULL;
+    static uint32_t s_wFileSize = 0, s_wRemainLen = 0, s_wOffSet = 0;
+
+    static enum  {
+        START = 0,
+        RECEIVE,
+        END,
+    } s_tState = {START};
+
+    switch(s_tState) {
+        case START:
+            s_wOffSet = 0;
+            s_pchFileName = (char *)&pchBuffer[0];
+            s_pchFileSize = (char *)&pchBuffer[strlen(s_pchFileName) + 1];
+            s_wFileSize = atol(s_pchFileSize);
+
+            LOG_D("Ymodem file_name:%s", s_pchFileName);
+            LOG_D("Ymodem file_size:%d", s_wFileSize);
+
+			if(target_flash_init(APP_PART_ADDR, s_wFileSize) == false) {
+				LOG_E("target flash uninit.");
+				return NULL;
+			}
+
+			if(target_flash_erase(APP_PART_ADDR, s_wFileSize) < 0) {
+				LOG_E("target flash erase error.");
+				return NULL;
+			}            
+
+            s_tState = RECEIVE;
+            break;
+
+        case RECEIVE:
+            s_wRemainLen = s_wFileSize - s_wOffSet;
+
+            if(hwSize > s_wRemainLen) {
+                hwSize = s_wRemainLen;
+                s_tState = END;
+            }
+
+			if(target_flash_write(APP_PART_ADDR + s_wOffSet, pchBuffer, hwSize) < 0) {
+				LOG_E("target flash write data error.");
+				return NULL;
+			}
+			s_wOffSet += hwSize;
+            
+            break;
+
+        case END:
+            target_flash_uninit(APP_PART_ADDR);                        
+            s_tState = START;
+            break;
+    }
+
+    return s_chBuffer;
+}
+```
+
+ 

+ 63 - 0
inc/flash_blob.h

@@ -0,0 +1,63 @@
+#ifndef FLASH_BLOB_H
+#define FLASH_BLOB_H
+#include "rtthread.h"
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+#define VERS       1           // Interface Version 1.01
+
+#define UNKNOWN    0           // Unknown
+#define ONCHIP     1           // On-chip Flash Memory
+#define EXT8BIT    2           // External Flash Device on 8-bit  Bus
+#define EXT16BIT   3           // External Flash Device on 16-bit Bus
+#define EXT32BIT   4           // External Flash Device on 32-bit Bus
+#define EXTSPI     5           // External Flash Device on SPI
+
+#define SECTOR_NUM 16         // Max Number of Sector Items
+
+struct FlashSectors  {
+  unsigned long   szSector;    // Sector Size in Bytes
+  unsigned long AddrSector;    // Address of Sector
+};
+
+typedef struct FlashDevice  {
+   unsigned short     Vers;    // Version Number and Architecture
+   char       DevName[128];    // Device Name and Description
+   unsigned short  DevType;    // Device Type: ONCHIP, EXT8BIT, EXT16BIT, ...
+   unsigned long    DevAdr;    // Default Device Start Address
+   unsigned long     szDev;    // Total Size of Device
+   unsigned long    szPage;    // Programming Page Size
+   unsigned long       Res;    // Reserved for future Extension
+   unsigned char  valEmpty;    // Content of Erased Memory
+
+   unsigned long    toProg;    // Time Out of Program Page Function
+   unsigned long   toErase;    // Time Out of Erase Sector Function
+
+   struct FlashSectors sectors[SECTOR_NUM];
+}flash_dev_t;
+
+typedef struct {
+	int (*Init)(uint32_t adr, uint32_t clk, uint32_t fnc);
+	int (*UnInit)(uint32_t fnc);
+    int (*EraseChip)(void);
+	int (*EraseSector)(uint32_t adr);
+	int (*ProgramPage)(uint32_t adr, uint32_t sz, uint8_t* buf);  
+}flash_ops_t;
+
+typedef struct
+{
+    flash_ops_t tFlashops;
+    flash_dev_t *ptFlashDev;
+    int *pPrgData;
+    rt_slist_t slist;      
+}flash_blob_t;
+
+
+extern void flash_dev_register(flash_blob_t *ptFlashDevice);
+extern bool target_flash_init(uint32_t flash_start, int32_t size);
+extern bool target_flash_uninit(uint32_t flash_start);
+extern int32_t target_flash_write(uint32_t addr, const uint8_t *buf, int32_t size);
+extern int32_t target_flash_erase(uint32_t addr, int32_t size);
+extern int32_t target_flash_read(uint32_t addr, const uint8_t *buf, int32_t size);
+#endif

+ 114 - 0
readme.md

@@ -0,0 +1,114 @@
+# flash_blob
+
+## 1、介绍
+
+利用MDK的FLM文件快速生成通用flash驱动。
+- 同时支持多个flash芯片级联,根据地址自动选择flash驱动。
+- 可以作为直接操作 `片内 Flash` 和 `SPI Flash` 的后端实现。
+
+### 1.1、API接口
+```c
+extern bool target_flash_init(uint32_t flash_start, int32_t size);
+extern bool target_flash_uninit(uint32_t flash_start);
+extern int32_t target_flash_write(uint32_t addr, const uint8_t *buf, int32_t size);
+extern int32_t target_flash_erase(uint32_t addr, int32_t size);
+extern int32_t target_flash_read(uint32_t addr, const uint8_t *buf, int32_t size);
+```
+
+### 1.2、目录结构
+
+| doc   | 文档         |
+| ----- | ------------ |
+| src   | 源代码       |
+| inc   | 头文件       |
+| tools | 驱动生成工具 |
+
+### 1.3、许可证
+
+Agile Upgrade 遵循 `Apache-2.0` 许可,详见 `LICENSE` 文件。
+
+
+
+## 2、使用 flash_blob
+1. 在rtthread软件包中找到flash_blob,然后添加进工程。
+
+2. 通过tools文件下的工具,生成对应的xxx.FLM.c文件,将xxx.FLM.c添加进工程,如果有多个flash器件,可以连续添加。
+
+
+![](https://img-blog.csdnimg.cn/e6c2d314ec024033bcf64015220e3f17.png)
+
+
+
+注意:多个设备的话每个flash的FlashDevice 的设备起始地址不可重叠,flash抽象层根据地址,自动选择相应的驱动。
+
+
+
+3.  由于flash驱动需要占用“r9”寄存器,所以需要在编译选项中添加`-ffixed-r9`
+
+![在这里插入图片描述](https://img-blog.csdnimg.cn/78a368cc80b4459c84549da58569a496.png)
+
+ 以上步骤完成后,就可以快速使用了,例如将YMODEM接收到的数据,写到flash中,代码如下:
+
+
+```c
+uint8_t *ymodem_call_back_receive(uint8_t *pchBuffer, uint16_t hwSize)
+{
+    static char *s_pchFileName = NULL, *s_pchFileSize = NULL;
+    static uint32_t s_wFileSize = 0, s_wRemainLen = 0, s_wOffSet = 0;
+
+    static enum  {
+        START = 0,
+        RECEIVE,
+        END,
+    } s_tState = {START};
+
+    switch(s_tState) {
+        case START:
+            s_wOffSet = 0;
+            s_pchFileName = (char *)&pchBuffer[0];
+            s_pchFileSize = (char *)&pchBuffer[strlen(s_pchFileName) + 1];
+            s_wFileSize = atol(s_pchFileSize);
+
+            LOG_D("Ymodem file_name:%s", s_pchFileName);
+            LOG_D("Ymodem file_size:%d", s_wFileSize);
+
+			if(target_flash_init(APP_PART_ADDR, s_wFileSize) == false) {
+				LOG_E("target flash uninit.");
+				return NULL;
+			}
+
+			if(target_flash_erase(APP_PART_ADDR, s_wFileSize) < 0) {
+				LOG_E("target flash erase error.");
+				return NULL;
+			}            
+
+            s_tState = RECEIVE;
+            break;
+
+        case RECEIVE:
+            s_wRemainLen = s_wFileSize - s_wOffSet;
+
+            if(hwSize > s_wRemainLen) {
+                hwSize = s_wRemainLen;
+                s_tState = END;
+            }
+
+			if(target_flash_write(APP_PART_ADDR + s_wOffSet, pchBuffer, hwSize) < 0) {
+				LOG_E("target flash write data error.");
+				return NULL;
+			}
+			s_wOffSet += hwSize;
+            
+            break;
+
+        case END:
+            target_flash_uninit(APP_PART_ADDR);                        
+            s_tState = START;
+            break;
+    }
+
+    return s_chBuffer;
+}
+```
+
+ 

+ 9 - 0
src/SConscript

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

+ 55 - 0
src/STM32F4xx_1024.FLM.c

@@ -0,0 +1,55 @@
+#include "flash_blob.h" 
+
+#define OPS_OFFSET ((uint32_t)&flash_code)
+
+#define DEV_OFFSET ((uint32_t)&flash_dev)
+
+#define RAM_OFFSET ((uint32_t)&rw_data)
+
+static const uint32_t flash_code[] = 
+{
+    0X0E000300,0XD3022820,0X1D000940,0X28104770,0X0900D302,0X47701CC0,0X47700880,0X49414842,
+    0X49426041,0X21036041,0X68C16001,0X431122F0,0X694060C1,0XD4060680,0X493D483E,0X21066001,
+    0X493D6041,0X20006081,0X48374770,0X05426901,0X61014311,0X47702000,0X4833B510,0X24046901,
+    0X61014321,0X03A26901,0X61014311,0X4A314933,0X6011E000,0X03DB68C3,0X6901D4FB,0X610143A1,
+    0XBD102000,0XF7FFB530,0X4927FFBB,0X23F068CA,0X60CA431A,0X610C2402,0X0700690A,0X43020E40,
+    0X6908610A,0X431003E2,0X48246108,0XE0004A21,0X68CD6010,0XD4FB03ED,0X43A06908,0X68C86108,
+    0X0F000600,0X68C8D003,0X60C84318,0XBD302001,0X4D15B570,0X08891CC9,0X008968EB,0X433326F0,
+    0X230060EB,0X4B16612B,0X692CE017,0X612C431C,0X60046814,0X03E468EC,0X692CD4FC,0X00640864,
+    0X68EC612C,0X0F240624,0X68E8D004,0X60E84330,0XBD702001,0X1D121D00,0X29001F09,0X2000D1E5,
+    0X0000BD70,0X45670123,0X40023C00,0XCDEF89AB,0X00005555,0X40003000,0X00000FFF,0X0000AAAA,
+    0X00000201,0X00000000,
+};
+
+static const uint32_t flash_dev[] = 
+{
+    0X54530101,0X4632334D,0X20787834,0X73616C46,0X00000068,0X00000000,0X00000000,0X00000000,
+    0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
+    0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
+    0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,0X00000000,
+    0X00010000,0X08000000,0X00100000,0X00000400,0X00000000,0X000000FF,0X00000064,0X00001770,
+    0X00004000,0X00000000,0X00010000,0X00010000,0X00020000,0X00020000,0XFFFFFFFF,0XFFFFFFFF,
+};
+
+static uint32_t rw_data[] = 
+{
+    0X00000000,
+};
+
+static flash_blob_t  flash_blob =
+{
+    (void*)(OPS_OFFSET + 0X001D),  // Init
+    (void*)(OPS_OFFSET + 0X004B),  // UnInit
+    (void*)(OPS_OFFSET + 0X0059),  // EraseChip
+    (void*)(OPS_OFFSET + 0X0085),  // EraseSector
+    (void*)(OPS_OFFSET + 0X00D1),  // ProgramPage
+    (void*)(DEV_OFFSET),
+    (void*)(RAM_OFFSET),
+};
+
+static int flash_blob_device_register(void) 
+{                                            
+    flash_dev_register(&flash_blob);       
+    return 0 ;                                
+}                                               
+INIT_BOARD_EXPORT(flash_blob_device_register);

+ 140 - 0
src/flash_blob.c

@@ -0,0 +1,140 @@
+#include "flash_blob.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+
+//#define DRV_DEBUG
+#define LOG_TAG             "flash"
+#include <drv_log.h>
+
+static bool s_bIsInit = false;
+static rt_slist_t _slist_head = RT_SLIST_OBJECT_INIT(_slist_head);
+register int *pPrgDataBase __asm("r9");
+
+void flash_dev_register(flash_blob_t *ptFlashDevice)
+{
+    rt_slist_init(&(ptFlashDevice->slist));
+    rt_slist_append(&_slist_head, &(ptFlashDevice->slist));
+}
+
+static flash_blob_t * flash_dev_find(uint32_t flash_start)
+{
+    rt_slist_t *node;
+    rt_slist_for_each(node, &_slist_head) {
+        flash_blob_t *ptFlashDevice = rt_slist_entry(node, flash_blob_t, slist);
+
+        if(flash_start >= ptFlashDevice->ptFlashDev->DevAdr &&
+           flash_start < ptFlashDevice->ptFlashDev->DevAdr + ptFlashDevice->ptFlashDev->szDev) {
+            return ptFlashDevice;
+        }
+    }
+    return NULL;
+}
+
+bool target_flash_init(uint32_t flash_start, int32_t size)
+{
+    if (flash_start % 4 != 0) {
+        LOG_E("flash addr must be 4-byte alignment");
+        return NULL;
+    }
+
+    flash_blob_t *ptFlashDevice = flash_dev_find(flash_start);
+
+    if(ptFlashDevice != NULL) {
+        pPrgDataBase = ptFlashDevice->pPrgData;
+        ptFlashDevice->tFlashops.Init(flash_start, 0, 0);
+        return true;
+    }
+
+    return false;
+}
+
+bool target_flash_uninit(uint32_t flash_start)
+{
+    flash_blob_t *ptFlashDevice = flash_dev_find(flash_start);
+
+    if(ptFlashDevice != NULL) {
+        pPrgDataBase = ptFlashDevice->pPrgData;
+        ptFlashDevice->tFlashops.UnInit(flash_start);
+        return true;
+    }
+
+    return true;
+}
+
+int target_flash_write(uint32_t addr, const uint8_t *buf, int32_t size)
+{
+    flash_blob_t *ptFlashDevice = flash_dev_find(addr);
+
+    if(ptFlashDevice != NULL) {
+        pPrgDataBase = ptFlashDevice->pPrgData;
+
+        while(size > 0) {
+            uint32_t write_size = size > ptFlashDevice->ptFlashDev->szPage ? ptFlashDevice->ptFlashDev->szPage : size;
+
+            if( 0 != ptFlashDevice->tFlashops.ProgramPage(addr, write_size, (uint8_t *)buf)) {
+                LOG_E("Programming Failed");
+                return -1;
+            }
+
+            addr += write_size;
+            buf  += write_size;
+            size -= write_size;
+        }
+
+        return size;
+    }
+
+    return -1;
+}
+
+int32_t target_flash_read(uint32_t addr, const uint8_t *buf, int32_t size)
+{
+    flash_blob_t *ptFlashDevice;
+    pPrgDataBase = ptFlashDevice->pPrgData;
+    return size;
+}
+
+int32_t target_flash_erase(uint32_t addr, int32_t size)
+{
+    int32_t wSector, wRemainLen;
+    flash_blob_t *ptFlashDevice = flash_dev_find(addr);
+
+    if(ptFlashDevice != NULL) {
+        if (size > ptFlashDevice->ptFlashDev->szDev) {
+            LOG_E("erase outrange flash size! addr is (0x%p)\n", (void *)(addr + size));
+            return -1;
+        }
+
+        pPrgDataBase = ptFlashDevice->pPrgData;
+        wRemainLen = size;
+        while(wRemainLen > 0) {
+            if(0 != ptFlashDevice->tFlashops.EraseSector(addr)) {
+                LOG_E("erase Failed! addr is (0x%p)\n", (void *)addr);
+                return -1;
+            }
+
+            for(wSector = 0; wSector < SECTOR_NUM; wSector++) {
+                if(ptFlashDevice->ptFlashDev->sectors[wSector + 1].szSector == 0XFFFFFFFF )
+                    break;
+
+                if(((addr - ptFlashDevice->ptFlashDev->DevAdr) < ptFlashDevice->ptFlashDev->sectors[wSector + 1].AddrSector) &&
+                   ((addr - ptFlashDevice->ptFlashDev->DevAdr) >= ptFlashDevice->ptFlashDev->sectors[wSector].AddrSector) )
+                    break;
+            }
+
+            addr += ptFlashDevice->ptFlashDev->sectors[wSector].szSector;
+            wRemainLen -= ptFlashDevice->ptFlashDev->sectors[wSector].szSector;
+        }
+
+        return size;
+    }
+
+    return -1;
+}
+
+int32_t target_flash_verify (uint32_t addr, uint8_t *buf, int32_t size)
+{
+
+    return size;
+}

+ 0 - 0
tools/release/.dev


BIN
tools/release/ControlCAN.dll


+ 262 - 0
tools/release/ControlCAN.h

@@ -0,0 +1,262 @@
+#ifndef CONTROLCAN_H
+#define CONTROLCAN_H
+
+//接口卡类型定义
+#define VCI_PCI5121         1
+#define VCI_PCI9810         2
+#define VCI_USBCAN1         3
+#define VCI_USBCAN2         4
+#define VCI_USBCAN2A        4
+#define VCI_PCI9820         5
+#define VCI_CAN232          6
+#define VCI_PCI5110         7
+#define VCI_CANLITE         8
+#define VCI_ISA9620         9
+#define VCI_ISA5420         10
+#define VCI_PC104CAN        11
+#define VCI_CANETUDP        12
+#define VCI_CANETE          12
+#define VCI_DNP9810         13
+#define VCI_PCI9840         14
+#define VCI_PC104CAN2       15
+#define VCI_PCI9820I        16
+#define VCI_CANETTCP        17
+#define VCI_PEC9920         18
+#define VCI_PCIE_9220       18
+#define VCI_PCI5010U        19
+#define VCI_USBCAN_E_U      20
+#define VCI_USBCAN_2E_U     21
+#define VCI_PCI5020U        22
+#define VCI_EG20T_CAN       23
+#define VCI_PCIE9221        24
+#define VCI_WIFICAN_TCP     25
+#define VCI_WIFICAN_UDP     26
+#define VCI_PCIe9120        27
+#define VCI_PCIe9110        28
+#define VCI_PCIe9140        29
+#define VCI_USBCAN_4E_U     31
+#define VCI_CANDTU_200UR    32
+#define VCI_CANDTU_MINI     33
+#define VCI_USBCAN_8E_U     34
+#define VCI_CANREPLAY       35
+#define VCI_CANDTU_NET      36
+#define VCI_CANDTU_100UR    37
+
+//CAN错误码
+#define ERR_CAN_OVERFLOW            0x0001  //CAN控制器内部FIFO溢出
+#define ERR_CAN_ERRALARM            0x0002  //CAN控制器错误报警
+#define ERR_CAN_PASSIVE             0x0004  //CAN控制器消极错误
+#define ERR_CAN_LOSE                0x0008  //CAN控制器仲裁丢失
+#define ERR_CAN_BUSERR              0x0010  //CAN控制器总线错误
+#define ERR_CAN_BUSOFF              0x0020  //总线关闭错误
+#define ERR_CAN_BUFFER_OVERFLOW     0x0040  //CAN控制器内部BUFFER溢出
+//通用错误码
+#define ERR_DEVICEOPENED            0x0100  //设备已经打开
+#define ERR_DEVICEOPEN              0x0200  //打开设备错误
+#define ERR_DEVICENOTOPEN           0x0400  //设备没有打开
+#define ERR_BUFFEROVERFLOW          0x0800  //缓冲区溢出
+#define ERR_DEVICENOTEXIST          0x1000  //此设备不存在
+#define ERR_LOADKERNELDLL           0x2000  //装载动态库失败
+#define ERR_CMDFAILED               0x4000  //执行命令失败错误码
+#define ERR_BUFFERCREATE            0x8000  //内存不足
+
+//CANET错误码
+#define ERR_CANETE_PORTOPENED       0x00010000  //端口已经被打开
+#define ERR_CANETE_INDEXUSED        0x00020000  //设备索引号已经被占用
+#define ERR_REF_TYPE_ID             0x00030000  //SetReference或GetReference传递的RefType不存在
+#define ERR_CREATE_SOCKET           0x00030002  //创建Socket失败
+#define ERR_OPEN_CONNECT            0x00030003  //打开Socket的连接时失败,可能设备连接已经存在
+#define ERR_NO_STARTUP              0x00030004  //设备没启动
+#define ERR_NO_CONNECTED            0x00030005  //设备无连接
+#define ERR_SEND_PARTIAL            0x00030006  //只发送了部分的CAN帧
+#define ERR_SEND_TOO_FAST           0x00030007  //数据发得太快,Socket缓冲区满了
+
+//函数调用返回状态值
+#define STATUS_OK                   1
+#define STATUS_ERR                  0
+
+#define CMD_DESIP                   0
+#define CMD_DESPORT                 1
+#define CMD_CHGDESIPANDPORT         2
+#define CMD_SRCPORT                 2
+#define CMD_TCP_TYPE                4  //tcp 工作方式,服务器:1 或是客户端:0
+#define TCP_CLIENT                  0
+#define TCP_SERVER                  1
+//服务器方式下有效
+#define CMD_CLIENT_COUNT            5  //连接上的客户端计数
+#define CMD_CLIENT                  6  //连接上的客户端
+#define CMD_DISCONN_CLINET          7  //断开一个连接
+#define CMD_SET_RECONNECT_TIME      8  //使能自动重连
+//CANDTU_NET支持GPS
+#define CMD_GET_GPS                 9
+#define CMD_GET_GPS_NUM             10 //获取GPS信息的数目
+
+typedef unsigned long       DWORD, ULONG;
+typedef int                 INT;
+typedef void*				HANDLE;
+typedef unsigned char       BYTE;
+typedef unsigned short      USHORT;
+typedef char				CHAR;
+typedef unsigned int        UINT;
+typedef unsigned char		UCHAR;
+typedef unsigned short      UINT16;
+typedef void*				PVOID;
+
+typedef struct tagRemoteClient{
+    int     iIndex;
+    DWORD   port;
+    HANDLE  hClient;
+    char    szip[32];
+}REMOTE_CLIENT;
+
+typedef struct _tagChgDesIPAndPort
+{
+    char    szpwd[10];
+    char    szdesip[20];
+    int     desport;
+    BYTE    blistenonly;
+}CHGDESIPANDPORT;
+
+//1.ZLGCAN系列接口卡信息的数据类型。
+typedef  struct  _VCI_BOARD_INFO{
+    USHORT  hw_Version;
+    USHORT  fw_Version;
+    USHORT  dr_Version;
+    USHORT  in_Version;
+    USHORT  irq_Num;
+    BYTE    can_Num;
+    CHAR    str_Serial_Num[20];
+    CHAR    str_hw_Type[40];
+    USHORT  Reserved[4];
+} VCI_BOARD_INFO,*PVCI_BOARD_INFO;
+
+//2.定义CAN信息帧的数据类型。
+typedef  struct  _VCI_CAN_OBJ{
+    UINT    ID;
+    UINT    TimeStamp;
+    BYTE    TimeFlag;
+    BYTE    SendType;
+    BYTE    RemoteFlag;//是否是远程帧
+    BYTE    ExternFlag;//是否是扩展帧
+    BYTE    DataLen;
+    BYTE    Data[8];
+    BYTE    Reserved[3];    //Reserved[0] 第0位表示特殊的空行或者高亮帧
+}VCI_CAN_OBJ,*PVCI_CAN_OBJ;
+
+//3.定义CAN控制器状态的数据类型。
+typedef struct _VCI_CAN_STATUS{
+    UCHAR   ErrInterrupt;
+    UCHAR   regMode;
+    UCHAR   regStatus;
+    UCHAR   regALCapture;
+    UCHAR   regECCapture; 
+    UCHAR   regEWLimit;
+    UCHAR   regRECounter; 
+    UCHAR   regTECounter;
+    DWORD   Reserved;
+}VCI_CAN_STATUS,*PVCI_CAN_STATUS;
+
+//4.定义错误信息的数据类型。
+typedef struct _VCI_ERR_INFO{
+    UINT    ErrCode;
+    BYTE    Passive_ErrData[3];
+    BYTE    ArLost_ErrData;
+} VCI_ERR_INFO,*PVCI_ERR_INFO;
+
+//5.定义初始化CAN的数据类型
+typedef struct _VCI_INIT_CONFIG{
+    DWORD    AccCode;
+    DWORD    AccMask;
+    DWORD    Reserved;
+    UCHAR    Filter;
+    UCHAR    Timing0;
+    UCHAR    Timing1;
+    UCHAR    Mode;
+}VCI_INIT_CONFIG,*PVCI_INIT_CONFIG;
+
+///////// new add struct for filter /////////
+typedef struct _VCI_FILTER_RECORD{
+    DWORD   ExtFrame;   //是否为扩展帧
+    DWORD   Start;
+    DWORD   End;
+}VCI_FILTER_RECORD,*PVCI_FILTER_RECORD;
+
+//定时自动发送帧结构
+typedef struct _VCI_AUTO_SEND_OBJ{
+    BYTE    Enable;     //使能本条报文 0:禁能 1:使能
+    BYTE    Index;      //报文编号     最大支持32条报文
+    DWORD   Interval;   //定时发送时间 1ms为单位
+    VCI_CAN_OBJ obj;    //报文
+}VCI_AUTO_SEND_OBJ,*PVCI_AUTO_SEND_OBJ;
+
+//设置指示灯状态结构
+typedef struct _VCI_INDICATE_LIGHT{
+    BYTE    Indicate;             //指示灯编号
+    BYTE    AttribRedMode:2;      //Red LED灭/亮/闪烁/自控
+    BYTE    AttribGreenMode:2;    //Green LED灭/亮/闪烁/自控
+    BYTE    AttribReserved:4;     //保留暂时不用
+    BYTE    FrequenceRed:2;       //Red LED闪烁频率
+    BYTE    FrequenceGreen:2;     //Green LED闪烁频率
+    BYTE    FrequenceReserved:4;  //保留暂时不用
+} VCI_INDICATE_LIGHT,*PVCI_INDICATE_LIGHT;
+
+//设置转发结构
+typedef struct _VCI_CAN_OBJ_REDIRECT{
+    BYTE    Action;                //标识开启或停止转发
+    BYTE    DestCanIndex;          //CAN目标通道
+} VCI_CAN_OBJ_REDIRECT,*PVCI_CAN_OBJ_REDIRECT;
+
+typedef struct _CANDTUTIME {
+    UINT16 wYear;
+    UINT16 wMonth;
+    UINT16 wDay;
+    UINT16 wHour;
+    UINT16 wMinute;
+    UINT16 wSecond;
+} CANDTUTIME;
+
+//GPS数据结构
+typedef struct _tagCANDTUGPSData
+{
+    float       fLatitude;  //纬度
+    float       fLongitude; //经度
+    float       fSpeed;     //速度
+    CANDTUTIME  candtuTime;
+}CANDTUGPSData, *PCANDTUGPSData;
+
+//获取GPS结构
+typedef struct _VCI_CANDTU_GPS_DATA
+{
+    PCANDTUGPSData pGPSData;    //用户提供接收GPS数据的缓冲区地址
+    ULONG          nGPSDataCnt; //可以容纳的GPS数据个数
+}VCI_CANDTU_GPS_DATA, *PVCI_CANDTU_GPS_DATA;
+
+#ifdef __cplusplus
+#define EXTERNC extern "C"
+#define DEF(a) = a
+#else
+#define EXTERNC
+#define DEF(a)
+#endif
+
+EXTERNC DWORD __stdcall VCI_OpenDevice(DWORD DeviceType,DWORD DeviceInd,DWORD Reserved);
+EXTERNC DWORD __stdcall VCI_CloseDevice(DWORD DeviceType,DWORD DeviceInd);
+EXTERNC DWORD __stdcall VCI_InitCAN(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd, PVCI_INIT_CONFIG pInitConfig);
+
+EXTERNC DWORD __stdcall VCI_ReadBoardInfo(DWORD DeviceType,DWORD DeviceInd,PVCI_BOARD_INFO pInfo);
+EXTERNC DWORD __stdcall VCI_ReadErrInfo(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,PVCI_ERR_INFO pErrInfo);
+EXTERNC DWORD __stdcall VCI_ReadCANStatus(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,PVCI_CAN_STATUS pCANStatus);
+
+EXTERNC DWORD __stdcall VCI_GetReference(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,DWORD RefType,PVOID pData);
+EXTERNC DWORD __stdcall VCI_SetReference(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,DWORD RefType,PVOID pData);
+
+EXTERNC ULONG __stdcall VCI_GetReceiveNum(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd);
+EXTERNC DWORD __stdcall VCI_ClearBuffer(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd);
+
+EXTERNC DWORD __stdcall VCI_StartCAN(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd);
+EXTERNC DWORD __stdcall VCI_ResetCAN(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd);
+
+EXTERNC ULONG __stdcall VCI_Transmit(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,PVCI_CAN_OBJ pSend,ULONG Len);
+EXTERNC ULONG __stdcall VCI_Receive(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,PVCI_CAN_OBJ pReceive,ULONG Len,INT WaitTime DEF(-1));
+
+#endif

BIN
tools/release/ControlCAN.lib


BIN
tools/release/D3Dcompiler_47.dll


BIN
tools/release/Qt5Core.dll


BIN
tools/release/Qt5Gui.dll


BIN
tools/release/Qt5SerialPort.dll


BIN
tools/release/Qt5Svg.dll


BIN
tools/release/Qt5Widgets.dll


BIN
tools/release/UpdataTool.exe


BIN
tools/release/iconengines/qsvgicon.dll


BIN
tools/release/imageformats/qgif.dll


BIN
tools/release/imageformats/qicns.dll


BIN
tools/release/imageformats/qico.dll


BIN
tools/release/imageformats/qjpeg.dll


BIN
tools/release/imageformats/qsvg.dll


BIN
tools/release/imageformats/qtga.dll


BIN
tools/release/imageformats/qtiff.dll


BIN
tools/release/imageformats/qwbmp.dll


BIN
tools/release/imageformats/qwebp.dll


BIN
tools/release/kerneldlls/CANDTU_NET.dll


BIN
tools/release/kerneldlls/CANDTU_NET_400.dll


BIN
tools/release/kerneldlls/CANETE.dll


BIN
tools/release/kerneldlls/CANET_TCP.dll


BIN
tools/release/kerneldlls/CANWIFI_TCP.dll


BIN
tools/release/kerneldlls/CANWIFI_UDP.dll


BIN
tools/release/kerneldlls/USBCAN.dll


BIN
tools/release/kerneldlls/USBCAN_8E_U_x64.dll


+ 49 - 0
tools/release/kerneldlls/kerneldll.ini

@@ -0,0 +1,49 @@
+[KERNELDLL]
+COUNT=47
+1=PCI51XXE.dll
+2=PCI9810.dll
+3=USBCAN.dll
+4=USBCAN.dll
+5=PCI9820.dll
+6=CAN232.dll
+7=PCI51XXE.dll
+8=CANLite.dll
+9=ISA9620B.dll
+10=ISA5420.dll
+11=PC104CAN.dll
+12=CANETE.dll
+13=DNP9810B.dll
+14=PCI9840B.dll
+15=PC104C2.dll
+16=PCI9820I.dll
+17=CANET_TCP.dll
+18=pec9920.dll
+19=pci50xx_u.dll
+20=USBCAN_E.dll
+21=USBCAN_E.dll
+22=pci50xx_u.dll
+23=topcliff_can.dll 
+24=pcie9221.dll
+25=CANWIFI_TCP.dll
+26=CANWIFI_UDP.dll
+27=pcie9120.dll
+28=pcie9110.dll
+29=pcie9140.dll
+30=pci5010p.dll
+31=USBCAN_4E_U.dll
+32=CANDTU.DLL
+33=CANDTU_MINI.dll
+34=USBCAN_8E_U.dll
+35=CAN_REPLAY.dll
+36=CANDTU_NET.dll
+37=CANDTU.dll
+38=zpcfd_x86.dll
+39=zpcfd_x86.dll
+40=zpcfd_x86.dll
+41=usbcanfd.dll
+42=usbcanfd.dll
+43=usbcanfd.dll
+44=canfdcom100ie.dll
+45=canscope.dll
+46=zlgcould.dll
+47=CANDTU_NET_400.dll

BIN
tools/release/kerneldlls/pci9810b.dll


BIN
tools/release/kerneldlls/pci9820b.dll


BIN
tools/release/kerneldlls/pci9820i.dll


BIN
tools/release/kerneldlls/pci9840b.dll


BIN
tools/release/kerneldlls/pcie9140_x64.dll


BIN
tools/release/kerneldlls/pec9920.dll


BIN
tools/release/libEGL.dll


BIN
tools/release/libGLESv2.dll


BIN
tools/release/libgcc_s_dw2-1.dll


BIN
tools/release/libstdc++-6.dll


BIN
tools/release/libwinpthread-1.dll


BIN
tools/release/opengl32sw.dll


BIN
tools/release/platforms/qwindows.dll


BIN
tools/release/styles/qwindowsvistastyle.dll


BIN
tools/release/translations/qt_ar.qm


BIN
tools/release/translations/qt_bg.qm


BIN
tools/release/translations/qt_ca.qm


BIN
tools/release/translations/qt_cs.qm


BIN
tools/release/translations/qt_da.qm


BIN
tools/release/translations/qt_de.qm


BIN
tools/release/translations/qt_en.qm


BIN
tools/release/translations/qt_es.qm


BIN
tools/release/translations/qt_fi.qm


BIN
tools/release/translations/qt_fr.qm


BIN
tools/release/translations/qt_gd.qm


BIN
tools/release/translations/qt_he.qm


BIN
tools/release/translations/qt_hu.qm


BIN
tools/release/translations/qt_it.qm


BIN
tools/release/translations/qt_ja.qm


BIN
tools/release/translations/qt_ko.qm


BIN
tools/release/translations/qt_lv.qm


BIN
tools/release/translations/qt_pl.qm


BIN
tools/release/translations/qt_ru.qm


BIN
tools/release/translations/qt_sk.qm


BIN
tools/release/translations/qt_tr.qm


BIN
tools/release/translations/qt_uk.qm


BIN
tools/release/translations/qt_zh_TW.qm