protocol-implementation.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. const VIEW_ID = 'storageProtocolImplementation'
  2. const TITLE = '协议实现'
  3. const SOURCES = {
  4. STORAGE_ACCESS_C: '',
  5. STORAGE_ACCESS_H: '',
  6. STRUCT_H: ''
  7. }
  8. const GUIDE = {
  9. kicker: '存储访问协议',
  10. title: '协议说明与实现规划',
  11. text: '存储访问协议普通读写使用 CMD + ADDR + LEN + DATA + CRC16-CCITT-FALSE 帧格式,不带从机地址。当前先固定上位机协议模型,从机源码参考暂不提供,后续再单独规划实现细节。',
  12. points: [
  13. { id: 'frame', text: 'CMD bit7 为故障位,仅回帧出现;bit6 为特殊指令位;普通读写中 bit3 为读写位,bit4/bit5 保留,bit0~bit2 表示区域。' },
  14. { id: 'addr', text: '普通区域 0x00 为 codeinfo 只读描述符;0x01/0x02/0x03/0x04 为 DATA、IDATA、XDATA、CODE 的 16 位地址;0x07 为 ADDR32 的 32 位地址;0x05~0x06 保留。' },
  15. { id: 'info', text: 'bit6=1 时 bit0~bit5 表示特殊指令码;当前仅定义 0x01 复位,因此复位帧 CMD=0x41。' },
  16. { id: 'control', text: 'CodeInfo 同步先发送 00+CRC 读取 area=0x00 描述符,数据区返回小端序 TLV 起始 addr32、len16、地址位宽、最大包长和原始 ENDIAN_MARK(55AA/AA55)。' },
  17. { id: 'struct', text: 'CodeInfo 使用 TYPE + LEN8 + VALUE 的纯 TLV 信息块;0x01~0x08 为固定内存入口,VALUE 为小端序 addr(2/4)+len16+name_len8+name;单独变量由 TLV 给长度,UI 或 enum 导入配置解释类型。' },
  18. { id: 'bootloader', text: 'Bootloader 升级前先发送存储访问复位帧 CMD=0x41,再在 500ms 内每 50ms 发送一次 Bootloader 握手帧。' },
  19. { id: 'source', text: '协议实现源码已暂时移除,设置页仅保留文件占位与说明,避免给出过期从机实现。' }
  20. ]
  21. }
  22. const FILES = [
  23. {
  24. badge: '从机',
  25. details: [
  26. '源码暂未提供。',
  27. '后续需要按新 CMD 位定义重新规划从机头文件。',
  28. '当前页面仅保留文件占位。'
  29. ],
  30. location: 'User/function/storage_access.h',
  31. name: 'storage_access.h',
  32. role: '从机协议头文件',
  33. sourceKey: 'STORAGE_ACCESS_H',
  34. summary: '源码暂时移除,等待协议实现方案确认。'
  35. },
  36. {
  37. badge: '从机',
  38. details: [
  39. '源码暂未提供。',
  40. '后续需要重新设计普通读写、特殊指令、异常响应和 CodeInfo 描述符读取。',
  41. '当前页面仅保留文件占位。'
  42. ],
  43. location: 'User/function/storage_access.c',
  44. name: 'storage_access.c',
  45. role: '从机协议实现',
  46. sourceKey: 'STORAGE_ACCESS_C',
  47. summary: '源码暂时移除,等待协议实现方案确认。'
  48. },
  49. {
  50. badge: '定义',
  51. details: [
  52. '源码暂未提供。',
  53. '后续再决定是否在此提供 struct.h 示例。',
  54. '当前页面仅保留文件占位。'
  55. ],
  56. location: 'struct.h',
  57. name: 'struct.h',
  58. role: '结构体定义参考',
  59. sourceKey: 'STRUCT_H',
  60. summary: '结构体定义参考暂时移除,等待后续实现规划。'
  61. }
  62. ]
  63. function getSourceText(file) {
  64. return String(SOURCES[file && file.sourceKey] || '')
  65. }
  66. function getLineCount(text) {
  67. if (!text) return 0
  68. return text.split(/\r?\n/).length
  69. }
  70. function formatSourceMeta(text) {
  71. const chars = text.length
  72. const lines = getLineCount(text)
  73. return `${lines} 行 / ${chars} 字符`
  74. }
  75. function getSourceMetaText(text) {
  76. return text ? formatSourceMeta(text) : '暂未提供'
  77. }
  78. function normalizeIndex(index) {
  79. const numberValue = Number(index)
  80. if (!Number.isFinite(numberValue)) return 0
  81. return Math.max(0, Math.min(FILES.length - 1, Math.round(numberValue)))
  82. }
  83. function getFiles(activeIndex = 0) {
  84. const normalizedIndex = normalizeIndex(activeIndex)
  85. return FILES.map((file, index) => ({
  86. ...file,
  87. active: index === normalizedIndex,
  88. id: file.name,
  89. sourceAvailable: !!getSourceText(file),
  90. sourceMeta: getSourceMetaText(getSourceText(file))
  91. }))
  92. }
  93. function getState(activeIndex = 0) {
  94. const normalizedIndex = normalizeIndex(activeIndex)
  95. const activeFile = FILES[normalizedIndex]
  96. const sourceText = getSourceText(activeFile)
  97. return {
  98. storageProtocolImplementationActiveFile: {
  99. ...activeFile,
  100. sourceAvailable: !!sourceText,
  101. sourceMeta: getSourceMetaText(sourceText)
  102. },
  103. storageProtocolImplementationActiveIndex: normalizedIndex,
  104. storageProtocolImplementationFiles: getFiles(normalizedIndex),
  105. storageProtocolImplementationGuide: {
  106. ...GUIDE,
  107. points: GUIDE.points.map((point) => ({ ...point }))
  108. }
  109. }
  110. }
  111. module.exports = {
  112. TITLE,
  113. VIEW_ID,
  114. getSourceText(index = 0) {
  115. return getSourceText(FILES[normalizeIndex(index)])
  116. },
  117. getState
  118. }