| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- const storageAccessProtocol = require('../../protocols/storage-access/index.js')
- const transport = require('../../transport/ble-core.js')
- const {
- createGroupsFromCodeInfo,
- parseCodeInfo
- } = require('../../domain/storage-access/code-info-parser.js')
- const {
- cloneImportedGroup,
- normalizeGroup
- } = require('../../domain/parameter-groups/model.js')
- const protocolIo = require('./protocol-io.js')
- function formatDwordHex(value) {
- const numberValue = Math.max(0, Math.floor(Number(value) || 0))
- return numberValue.toString(16).toUpperCase().padStart(8, '0')
- }
- function showCodeInfoError(label, message, options = {}) {
- if (options.showModal === false) return
- transport.showCommandAlert(label, message)
- }
- async function readCodeInfoBlock(label = '同步CodeInfo', kind = 'storage-code-info-read', options = {}) {
- const protocolIoOptions = protocolIo.normalizeProtocolIoOptions({
- ...options,
- useDeviceCaps: false
- })
- const descriptorBytes = await protocolIo.readMemory(
- storageAccessProtocol.AREA.CODEINFO,
- storageAccessProtocol.CODE_INFO_DESCRIPTOR_ADDRESS,
- storageAccessProtocol.CODE_INFO_DESCRIPTOR_BYTE_LENGTH,
- label,
- `${kind}-descriptor`,
- {
- ...protocolIoOptions,
- showModal: false,
- useDeviceCaps: false
- }
- )
- if (!descriptorBytes) {
- showCodeInfoError(label, 'CodeInfo 描述符读取失败或超时', protocolIoOptions)
- return null
- }
- let descriptor
- try {
- descriptor = storageAccessProtocol.parseCodeInfoDescriptorBytes(descriptorBytes)
- } catch (error) {
- showCodeInfoError(label, error.message || 'CodeInfo 描述符长度无效', protocolIoOptions)
- return null
- }
- let codeInfoAddressWidth
- try {
- codeInfoAddressWidth = storageAccessProtocol.normalizeDescriptorAddressWidth(
- descriptor.codeInfoAddressWidth
- )
- } catch (error) {
- showCodeInfoError(label, error.message || 'CodeInfo 描述符地址长度无效', protocolIoOptions)
- return null
- }
- const codeInfoAddress = Number(descriptor.codeInfoAddress || 0)
- const codeInfoByteLength = Number(descriptor.codeInfoByteLength || 0)
- const codeInfoMaxPacketLength = Number(descriptor.codeInfoMaxPacketLength || 0) & 0xFFFF
- const codeInfoMemoryEndian = String(descriptor.codeInfoMemoryEndian || 'big').trim()
- const codeInfoMemoryType = codeInfoAddressWidth === 32
- ? storageAccessProtocol.AREA.ADDR32
- : storageAccessProtocol.AREA.CODE
- const codeInfoReadAddress = codeInfoAddressWidth === 32 ? codeInfoAddress : (codeInfoAddress & 0xFFFF)
- const codeInfoMaxFrameBytes = storageAccessProtocol.resolveDescriptorMaxFrameBytes(
- protocolIoOptions.maxFrameBytes,
- codeInfoMaxPacketLength
- )
- if (!codeInfoByteLength || codeInfoByteLength > 0xFFFF) {
- showCodeInfoError(label, 'CodeInfo 信息块长度无效', protocolIoOptions)
- return null
- }
- const codeInfoBytes = await protocolIo.readMemory(
- codeInfoMemoryType,
- codeInfoReadAddress,
- codeInfoByteLength,
- label,
- kind,
- {
- ...protocolIoOptions,
- maxFrameBytes: codeInfoMaxFrameBytes,
- useDeviceCaps: false
- }
- )
- if (!codeInfoBytes) return null
- return {
- codeInfoAddress,
- codeInfoAddressWidth,
- codeInfoByteLength,
- codeInfoBytes,
- codeInfoDescriptorBytes: descriptorBytes,
- codeInfoMaxPacketLength,
- codeInfoMemoryEndian,
- codeInfoMemoryEndianMark: Number(descriptor.codeInfoMemoryEndianMark || 0) & 0xFFFF,
- codeInfoMemoryType
- }
- }
- async function syncCodeInfo(options = {}) {
- const result = await readCodeInfoBlock(
- options.label || '同步CodeInfo',
- options.kind || 'storage-code-info-read',
- {
- maxPacketLength: options.maxPacketLength,
- showModal: options.showModal !== false
- }
- )
- if (!result) {
- return {
- ok: false
- }
- }
- const descriptorCaps = {
- addressWidth: result.codeInfoAddressWidth,
- codeInfoByteLength: result.codeInfoByteLength,
- maxPacketLength: result.codeInfoMaxPacketLength,
- memoryEndian: result.codeInfoMemoryEndian,
- memoryEndianMark: result.codeInfoMemoryEndianMark
- }
- let codeInfo
- let importedGroups
- try {
- codeInfo = parseCodeInfo(result.codeInfoBytes, descriptorCaps)
- importedGroups = createGroupsFromCodeInfo(codeInfo, options)
- .map(cloneImportedGroup)
- .map(normalizeGroup)
- } catch (error) {
- const errorText = error.message || 'CodeInfo 解析失败'
- showCodeInfoError(options.label || '同步CodeInfo', errorText, options)
- return {
- errorText,
- ok: false
- }
- }
- protocolIo.updateSyncedDeviceCaps(descriptorCaps)
- return {
- codeInfoAddress: result.codeInfoAddress,
- codeInfoAddressText: formatDwordHex(result.codeInfoAddress),
- codeInfoAddressWidth: result.codeInfoAddressWidth,
- codeInfoByteLength: result.codeInfoByteLength,
- codeInfoByteLengthText: formatDwordHex(result.codeInfoByteLength),
- codeInfoBytes: result.codeInfoBytes,
- codeInfo,
- codeInfoDescriptorBytes: result.codeInfoDescriptorBytes,
- codeInfoMaxPacketLength: result.codeInfoMaxPacketLength,
- codeInfoMemoryEndian: result.codeInfoMemoryEndian,
- codeInfoMemoryEndianMark: result.codeInfoMemoryEndianMark,
- codeInfoMemoryType: result.codeInfoMemoryType,
- groupCount: importedGroups.length,
- importedGroups,
- ok: true,
- structCount: codeInfo.structCount
- }
- }
- module.exports = {
- readCodeInfoBlock,
- syncCodeInfo
- }
|