2015-12-08 3 views
1

Для моего текущего приложения я пишу плагин, который позволит устройству разговаривать с ведомым устройством. Ведомое устройство имеет две контрольные суммы, заголовок и контрольную сумму данных. Контрольная сумма заголовка вызывала некоторые неустойчивые результаты, которые были точно настроены и исправлены членами здесь: Odd Checksum Result(s) - Not Receiving Expected ResultsФункция с контрольной суммой Функция nACK Ответы

Теперь я не уверен, что моя контрольная сумма данных верна. Я считаю, что это из-за потока, который я создал здесь, чтобы помочь понять и построить его, который я здесь сделал: Converting a C Checksum Function to Lua

Теперь я не думаю, что это функции контрольной суммы данных. Но я считаю, что я пытаюсь его реализовать. Я нахожусь в точке, где теперь я просто пытаюсь дублировать пример кода и отправлять его на мое подчиненное устройство в надежде, что я получу соответствующий ответ (ы). Проблема в том, что я получаю nACK в ответ. Я пробовал каждую перестановку и комбинацию, о которых я мог думать, и я не принимаю принятое значение. input представляет собой представление строки, которую мне нужно отправить в функцию function databuild(str) ниже.

input = "010032380000000000000000000000000000000000000000" -- title must be a specific length so it is filled with NUL's to meet that criteria 

function CRC(data, length) 
    sum = 65535 
    local d 
    for i = 1, length do 
     d = string.byte(data, i) 
     sum = ByteCRC(sum, d) 
    end 
    return sum 
end 

function ByteCRC(sum, data) 
    sum = sum ~ data 
    for i = 0, 7 do 
     if ((sum & 1) == 0) then 
      sum = sum >> 1 
     else 
      sum = (sum >> 1) ~ 0xA001 
     end 
    end 
    return sum 
end 

function databuild(str) -- I know I should not be doing what's inside here but don't fully understand why not to and better ways of approaching it. 
    local dataSum = "" 
    local dataSumReslt = "" 
    local dataConv = "" 
    for char in str:gmatch("..") do 
     dataConv = dataConv..string.char("0x"..char) 
    end 
    dataSum = string.format("%04X", CRC(dataConv, #dataConv)) 
    for char in dataSum:gmatch("..") do 
     dataSumReslt = dataSumReslt..string.char("0x"..char) 
    end 
    return dataConv..dataSumReslt 
end 

print(databuild(input)) 

Я должен получать контрольную сумму данных на основе этих значений байтов в своем заявлении на печать. Я посылаю всю строку в функцию function databuild(str). Оттуда я превращаю результат в шестнадцатеричный формат и затем объединяю этот результат (после поворота двухбайтового значения в шестнадцатеричном формате через string.char), а затем возвращаем всю шестую строку.

Прямо сейчас, так оно и есть, я получаю результат 170B. К сожалению, я недостаточно продвинутый в программировании, чтобы отлаживать или проверять, действительно ли то, что я получаю, истинно или нет.

  • Должен ли я поворачивать строку данных в шестнадцатеричном первый перед делать function CRC(data, length) или я должен оставить его десятичное представление первого, или это еще вопрос ???

  • Поскольку все 2-байтовые и 4-байтовые слова в моих файлах необходимы, чтобы быть малодушными, означает ли это, что моя контрольная сумма также должна быть малозначной? Или контрольные суммы остались нетронутыми? (функции контрольной суммы были предоставлены в руководстве по ведомому устройству C.

  • Наконец, что является лучшим способом приблизиться к function databuild(str), чтобы я не разбивал каждый байт, не переводил его, а затем конкатенировал его так много? Я очень ценю, когда мой код исправляется. Но кто-то может помочь мне понять, почему именно это просто не очень хорошая вещь, чтобы сделать?

Так как я довольно новыми для программирования в целом, большую часть времени Я не пытаюсь работать на этом низкоуровневом уровне (бит-манипуляция). Я не достиг этой точки ни в одном из моих классов, поскольку это было все более высокоуровневое программирование (Java и самообучение, что я знаю в Lua) Это моя первая работа oject, где это действительно «крещение огнем» относительно байтов, шестнадцатеричных преобразований и т. д. Излишне говорить, что я едва держу голову над водой здесь. Поэтому вся конструктивная критика, которую я получаю, НЕОБХОДИМО.

+0

В 'databuild', не должно быть' return dataConv .. dataSumReslt'? – lhf

+0

@lhf вы правы. Я понятия не имею, что я или не думал. Исправлено мое исходное сообщение – Pwrcdr87

+0

@lhf или любой другой член в этом отношении, я планирую включить код, который предоставил LHF ниже. Но я хотел бы получить больше информации по двум моим вопросам в моем первоначальном посте. A) Должен ли я перевернуть строку данных сначала от десятичной до шестнадцатеричной до отправки строки в 'function CRC (data, length)' или оставить ее десятичной после отправки? И B), так как все 2-байтовые и 4-байтовые слова являются малориентированными, следует ли изменить полученную контрольную сумму каким-либо образом или оставить конечный результат неизменным? – Pwrcdr87

ответ

2

Вы можете заменить

for char in str:gmatch("..") do 
    dataConv = dataConv..string.char("0x"..char) 
end 

с

dataConv = str:gsub("..",function (x) return string.char(tonumber(x,16)) end) 

Вы можете упростить это

dataConv = str:gsub("..",HEX) 

после выполнения

HEX={} 
for c=0,255 do 
    HEX[string.format("%02x",c)] = string.char(c) 
end 

Это позволит избежать конкатенаций.

+0

Можете ли вы или кто-нибудь объяснить мне, почему лучше избегать конкатенаций (я), которые я делаю? Просто потому, что он требует дополнительных ресурсов для поддержания всех манипуляций, выполняемых для создания каждого байта? Или это связано с бит-манипуляциями вообще? Я хочу лучше понять это. – Pwrcdr87

+1

@ Pwrcdr87 Каждая конкатенация строк требует выделения и копирования обеих частей в новую строку. Следовательно, повторное конкатенация приводит к значительным накладным расходам и большому количеству мусора, который должен быть освобожден сборщиком мусора. Использование 'table.concat' для конкатенации многих фрагментов сразу позволит избежать большей части этих накладных расходов, так же как и для использования' string.gsub' & co и для их замены деталей при перемещении. (Информация о низком уровне: они используют 'luaL_Buffer' (http://www.lua.org/manual/5.3/manual.html#luaL_Buffer), который растет инкрементально и избегает большей части копирования.) – nobody

+0

@nobody Awesome info. Я прочитаю больше в 'luaL_Buffer', который вы упомянули, чтобы получить лучшее понимание. – Pwrcdr87

Смежные вопросы