const VIEW_ID = 'storageProtocolImplementation' const TITLE = '协议实现' const SOURCES = { STORAGE_ACCESS_C: '', STORAGE_ACCESS_H: '', STRUCT_H: '' } const GUIDE = { kicker: '存储访问协议', title: '协议说明与实现规划', text: '存储访问协议普通读写使用 CMD + ADDR + LEN + DATA + CRC16-CCITT-FALSE 帧格式,不带从机地址。当前先固定上位机协议模型,从机源码参考暂不提供,后续再单独规划实现细节。', points: [ { id: 'frame', text: 'CMD bit7 为故障位,仅回帧出现;bit6 为特殊指令位;普通读写中 bit3 为读写位,bit4/bit5 保留,bit0~bit2 表示区域。' }, { id: 'addr', text: '普通区域 0x00 为 codeinfo 只读描述符;0x01/0x02/0x03/0x04 为 DATA、IDATA、XDATA、CODE 的 16 位地址;0x07 为 ADDR32 的 32 位地址;0x05~0x06 保留。' }, { id: 'info', text: 'bit6=1 时 bit0~bit5 表示特殊指令码;当前仅定义 0x01 复位,因此复位帧 CMD=0x41。' }, { id: 'control', text: 'CodeInfo 同步先发送 00+CRC 读取 area=0x00 描述符,数据区返回 TLV 起始 addr32、len16、地址位宽和最大包长。' }, { id: 'struct', text: 'CodeInfo 使用 TYPE + LEN8 + VALUE 的纯 TLV 信息块;0x01~0x08 为固定内存入口,VALUE 为 addr(2/4)+len16+name_len8+name;单独变量由 TLV 给长度,UI 或 enum 导入配置解释类型。' }, { id: 'source', text: '协议实现源码已暂时移除,设置页仅保留文件占位与说明,避免给出过期从机实现。' } ] } const FILES = [ { badge: '从机', details: [ '源码暂未提供。', '后续需要按新 CMD 位定义重新规划从机头文件。', '当前页面仅保留文件占位。' ], location: 'User/function/storage_access.h', name: 'storage_access.h', role: '从机协议头文件', sourceKey: 'STORAGE_ACCESS_H', summary: '源码暂时移除,等待协议实现方案确认。' }, { badge: '从机', details: [ '源码暂未提供。', '后续需要重新设计普通读写、特殊指令、异常响应和 CodeInfo 描述符读取。', '当前页面仅保留文件占位。' ], location: 'User/function/storage_access.c', name: 'storage_access.c', role: '从机协议实现', sourceKey: 'STORAGE_ACCESS_C', summary: '源码暂时移除,等待协议实现方案确认。' }, { badge: '定义', details: [ '源码暂未提供。', '后续再决定是否在此提供 struct.h 示例。', '当前页面仅保留文件占位。' ], location: 'struct.h', name: 'struct.h', role: '结构体定义参考', sourceKey: 'STRUCT_H', summary: '结构体定义参考暂时移除,等待后续实现规划。' } ] function getSourceText(file) { return String(SOURCES[file && file.sourceKey] || '') } function getLineCount(text) { if (!text) return 0 return text.split(/\r?\n/).length } function formatSourceMeta(text) { const chars = text.length const lines = getLineCount(text) return `${lines} 行 / ${chars} 字符` } function getSourceMetaText(text) { return text ? formatSourceMeta(text) : '暂未提供' } function normalizeIndex(index) { const numberValue = Number(index) if (!Number.isFinite(numberValue)) return 0 return Math.max(0, Math.min(FILES.length - 1, Math.round(numberValue))) } function getFiles(activeIndex = 0) { const normalizedIndex = normalizeIndex(activeIndex) return FILES.map((file, index) => ({ ...file, active: index === normalizedIndex, id: file.name, sourceAvailable: !!getSourceText(file), sourceMeta: getSourceMetaText(getSourceText(file)) })) } function getState(activeIndex = 0) { const normalizedIndex = normalizeIndex(activeIndex) const activeFile = FILES[normalizedIndex] const sourceText = getSourceText(activeFile) return { storageProtocolImplementationActiveFile: { ...activeFile, sourceAvailable: !!sourceText, sourceMeta: getSourceMetaText(sourceText) }, storageProtocolImplementationActiveIndex: normalizedIndex, storageProtocolImplementationFiles: getFiles(normalizedIndex), storageProtocolImplementationGuide: { ...GUIDE, points: GUIDE.points.map((point) => ({ ...point })) } } } module.exports = { TITLE, VIEW_ID, getSourceText(index = 0) { return getSourceText(FILES[normalizeIndex(index)]) }, getState }