Опубликовал | Дата 21 мая, 2012
Как проверить НЕХ-файл
Многие радиолюбители, пытаясь повторить то или иное устройство на микроконтроллере, нередко сталкиваются с необъяснимыми, на первый взгляд, трудностями. И микроконтроллер в порядке, и программатор исправен, и схема рабочая, но работать, как следует, устройство не хочет. На самом деле в подавляющем большинстве случаев виноваты ошибки, допущенные при ручном вводе в компьютер НЕХ-файла программы. Значительно реже бывают сбои при копировании файлов с дисков или «скачивании» их из Интернета.
Любая опечатка в НЕХ-файле ведет к выполнению микроконтроллером неверной команды. Ни один программист в этой ситуации не сможет по внешним признакам точно указать место ошибки. Остается очень тщательно сверять НЕХ-файл. Очень муторное занятие. К счастью для проверки Hex- файлов существует программа CheckHEX, которой была посвящена статья А. Долгого «Как проверить HEX-файл» («Радио», 2003, № 8, с. 27, 28) и которую можно скачать здесь.
Дополнение
Для проверки HEX- файлов есть еще одна программа, разработанная П. Высочанским. Ее можно скачать с FTP-сервера журнаоа «Радио» . Описание этой программы опубликовано в «Радио» за 2009г №10 стр.26
Просмотров:4 710
Текст главного модуля управляющей программы высокого уровня на языке Delphi приведен ниже.
В начале своей работы программа пытается последовательно открыть первые четыре COM-порта компьютера. Через каждый порт, дескриптор которого удалось получить, устройству посылается запрос на передачу строки подтверждения “ATmega8”. Если строка была получена, то программа продолжает свое продолжение. В противном случае приложение закрывается.

Когда связь успешно установлена, появляется окно основной формы, вид которой изображен выше. Пользователю доступно два действия: стирание и программирование FLAS-памяти. В последнем случае данные из HEX-файла переносятся в буфер для записи и по страницам передаются в микроконтроллер. После завершения записи производится верификация памяти программ. При этом данные считываются из устройства в буфер для чтения. Результатом удачной операции программирования будет являться равенство содержимого обоих буферов.
Размер файла не должен превышать 4096–128=3968 слов, иначе во время записи произойдет повреждение загрузчика. По этой же причине стиранию подлежат только первые 124 из 128 страниц памяти программ. Перед записью HEX-файла ведется проверки диапазона адресов и контрольной суммы каждой из строк. Файл должен быть 8-ричным файлом формата Intel Hex и, кроме этого, не должен содержать команд смещения адресов. Присутствие, например строки :020000020100FB (смещение начального адреса записи на 0x0100 б) приведет к ошибки.
unit MainUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, ComCtrls, ExtCtrls, AppEvnts, CheckLst;
type
TMainForm = class(TForm)
PbProgressBar: TProgressBar;
LbInfo: TLabel;
CbLowFuse: TCheckListBox;
CbHighFuse: TCheckListBox;
CbLockBits: TCheckListBox;
BtFilePath: TButton;
EdFilePath: TEdit;
BtProgramFlash: TBitBtn;
BtEraseFlash: TBitBtn;
DlOpenDialog: TOpenDialog;
function StrToHex(const Sim: char): byte;
function CheckHexFile: boolean;
function PrepareFlashBuffer: boolean;
function ProgramFlash: boolean;
procedure ReadFuseBits;
function ReadFlash: boolean;
function EraseFlash: boolean;
procedure OnFormCreate(Sender: TObject);
procedure OnFormDestroy(Sender: TObject);
procedure BtFilePathClick(Sender: TObject);
procedure BtProgramFlashClick(Sender: TObject);
procedure BtEraseFlashClick(Sender: TObject);
end;
var
MainForm: TMainForm;
PortHandle: THandle; //дескриптор COM-порта
FlashWriteBuffer: array of word;//массивы данных для записи во FLASH-памяти
FlashReadBuffer: array of word;//массивы прочитанных из FLASH-памяти данных
const
FLASH_SIZE = 4096;//число слов FLASH-памяти программ (4096 слова для ATmega8)
PAGE_SIZE = 32;//число слов в странице (32 слова для ATmega8)
implementation
{$R *.dfm}
// Функция открытия COM-порта. В качестве параметра принимает номер порта
//ComNumber в интервале 0…9. В случае удачного завершения возвращает 0.
function OpenPort(const ComNumber: cardinal): boolean;
var ComName:string;
begin
ComName:=Format('\.COM%-d',[ComNumber]);
// API-функция CreateFile производит открытие COM-порта по имени, в режиме
//чтения/записи. Установка флага FILE_FLAG_OVERLAPPED позволяет использовать
//асинхронные операции чтения/записи. При удачном завершении функция
//возвращает дескриптор устройства; в случае ошибки - INVALID_HANDLE_VALUE.
PortHandle:=CreateFile(PChar(ComName),GENERIC_READ or GENERIC_WRITE,0,
nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED,0);
Result:=PortHandle<>INVALID_HANDLE_VALUE;
end;
// Процедура закрытия COM-порта.
procedure ClosePort;
begin
// API-функция CloseHandle закрывает дескриптор, полученный вызовом
//CreateFile.
CloseHandle(PortHandle);
end;
// Процедура задания настроек COM-порта. В качестве параметров принимает:
//скорость обмена BaudRate, тип контроля четность Parity, количество стоп-бит
//StopBits и разрядность данных ByteSize.
// Скорость обмена BaudRate в бит/с задается одной из констант:
//CBR_110 = 110, CBR_300 = 300, CBR_600 = 600, CBR_1200 = 1200,
//CBR_2400 = 2400, CBR_4800 = 4800, CBR_4800 = 9600, CBR_4800 = 14400,
//CBR_19200 = 19200, CBR_19200 = 19200, CBR_38400 = 38400, CBR_56000 = 56000,
//CBR_57600 = 57600, CBR_115200 = 115200.
// Контроль четности Parity задается одной из констант:
//NOPARITY = 0 – контроль четности отсутствует(бит четности отсутствует),
//ODDPARITY = 1 – проверка на нечетность(бит четности дополняет сумму
// единиц в слове данных до нечетного числа),
//EVENPARITY = 2 – проверка на четность(бит четности дополняет сумму
// единиц в слове данных до четного числа),
//MARKPARITY = 3 – проверка бита четности на 1,
//SPACEPARITY = 4 – проверка бита четности на 0.
// Количество стоп-бит StopBits задается одной из констант:
//ONESTOPBIT = 0 – 1 стоп-бит,
//ONE5STOPBITS = 1 – 1.5 стоп-бит,
//TWOSTOPBITS = 2 – 2 стоп-бит(только для 6…8-битовых данных).
// Разрядность данных ByteSize может быть 5…8 бит.
procedure SetComProperty (const BaudRate,Parity,StopBits,ByteSize: cardinal);
var DCB:TDCB;
begin
// Основные настройки COM-порта содержит структура DCB.
FillChar(DCB,SizeOf(DCB),0);
DCB.DCBLength:=SizeOf(DCB);
DCB.Flags:=1;
DCB.BaudRate:=BaudRate;
DCB.Parity:=Parity;
DCB.StopBits:=StopBits;
DCB.ByteSize:=ByteSize;
// API-функция SetCommState переписывает структуру DCB порта.
SetCommState(PortHandle,DCB);
end;
// Функция чтения буфера данных из COM-порта. В качестве параметров
//принимает: указатель на буфер памяти Buffer и размер буфера BufSize. В
//случае удачного завершения функция возвращает 0.
function ReadBuffer(var Buffer:Pointer;const BufSize:cardinal): boolean;
var BytesRead:cardinal;
ReadOL:TOverlapped;
ReadDone:cardinal;
begin
FillChar(ReadOL,SizeOf(ReadOL),0);
// API-функция Функция CreateEvent создает событие ReadOL.hEvent (дескриптор
//события ReadOL.hEvent размещен в структуре асинхронного доступа ReadOL типа
//TOverlapped), которое будет переведено в сигнальное состояние после
//завершения операции асинхронного чтения.
ReadOL.hEvent:=CreateEvent(nil,true,true,nil);
try
// API-функция Функция ReadFile производит чтение данных из COM-порта. В
//случае удачного завершения функция возвращает 0. В данном случае чтение
//происходит в асинхронном режиме. После вызова ReadFile поток не блокируется
//до окончания операции, а продолжает свое выполнение. О завершении операции
//чтения можно судить по состоянию объекта ReadOL.hEvent, который должен
//перейти в сигнальное состояние.
ReadFile(PortHandle,Buffer^,BufSize,BytesRead,@ReadOL);
// API-функция Функция WaitForSingleObject ожидает перевода в сигнальное
//состояние объекта синхронизации определенный период времени. В нашем случае
//объектом служит событие ReadOL.hEvent, интервал времени 100 мс. При
//успешном завершении (если объект перешел в сигнальное состояние раньше,
//чем истек период ожидания) функция возвратит код WAIT_OBJECT_0.
ReadDone:=WaitForSingleObject(ReadOL.hEvent,100);
finally
Result:= ReadDone = WAIT_OBJECT_0;
// API-функция Функция CloseHandle закрывает дескриптор события
//ReadOL.hEvent, полученный с помощью CreateEvent.
CloseHandle(ReadOL.hEvent);
end;
end;
// Функция записи буфера данных в COM-порт. В качестве параметров
//принимает: указатель на буфер памяти Buffer и размер буфера BufSize. В
//случае удачного завершения функция возвращает 0.
function WriteBuffer (var Buffer:Pointer; const BufSize:cardinal): boolean;
var BytesWritten:cardinal;
WriteOL:TOverlapped;
WriteDone:cardinal;
begin
FillChar(WriteOL,SizeOf(WriteOL),0);
// API-функция Функция CreateEvent создает событие WriteOL.hEvent (дескриптор
//события WriteOL.hEvent размещен в структуре асинхронного доступа WriteOL типа
//TOverlapped), которое будет переведено в сигнальное состояние после
//завершения операции асинхронной записи.
WriteOL.hEvent:=CreateEvent(nil,true,true,nil);
try
// API-функция Функция WriteFile производит запись данных в COM-порт. В
//случае удачного завершения функция возвращает 0. В данном случае запись
//происходит в асинхронном режиме. После вызова WriteFile поток не
//блокируется до окончания операции, а продолжает свое выполнение.
//О завершении операции чтения можно судить по состоянию объекта.
WriteFile(PortHandle,Buffer^,BufSize,BytesWritten,@WriteOL);
// API-функция Функция WaitForSingleObject ожидает перевода в сигнальное
//состояние объекта синхронизации определенный период времени. В нашем случае
//объектом служит событие WriteOL.hEvent, интервал времени 100 мс. При
//успешном завершении (если объект перешел в сигнальное состояние раньше,
//чем истек период ожидания) функция возвратит код WAIT_OBJECT_0.
WriteDone:=WaitForSingleObject(WriteOL.hEvent,100);
finally
Result:= WriteDone = WAIT_OBJECT_0;
// API-функция Функция CloseHandle закрывает дескриптор события
//WriteOL.hEvent, полученный с помощью CreateEvent.
CloseHandle(WriteOL.hEvent);
end;
end;
// Функция чтения байта данных из COM-порта. Возвращает прочитанный байт.
function ReadByte: byte;
var Ptr:Pointer;
begin
Ptr:=@Result;
ReadBuffer(Ptr,1);
end;
// Процедура записи байта данных в COM-порт. В качестве параметров принимает
//байт данных для записи.
procedure WriteByte(const TX:byte);
var Ptr:Pointer;
begin
Ptr:=@TX;
WriteBuffer(Ptr,1);
end;
// Функция преобразования символов ACSII (“0”…“9”, “A”…“F”) в число. В
//качестве параметров принимает символ, подлежащий преобразованию Sim.
//Возвращает преобразованное число.
function TMainForm.StrToHex(const Sim: char): byte;
begin
if ((Byte(Sim)>=$30) and (Byte(Sim)<=$39)) then Result:= Byte(Sim)-$30
else Result:= Byte(Sim)-$37;
end;
// Функция проверки HEX-файла на ошибки. В случае удачного завершения
//возвращает 0.
function TMainForm.CheckHexFile: boolean;
var F:TStringList;
Str: string;
Size,Sum: Byte;
I,J: integer;
begin
Result:= false;
F:= TStringList.Create;
F.LoadFromFile(EdFilePath.Text);
Str:= F.Strings[F.Count-1];
// Если 4 последних символа последней строки отличны от “01FF” (признак
//конца файла), то HEX-файл поврежден.
if Copy(Str,Length(Str)-3,4)<>'01FF' then begin
F.Free;
Exit;
end;
// Если в начале хотя бы одной из строк отсутствует символ “:” (признак
//начала строки), то HEX-файл поврежден.
for I:= 0 to F.Count-1 do begin
Str:= F.Strings[I];
if Str[1]<>':' then begin
F.Free;
Exit;
end;
Size:= 16*StrToHex(Str[2])+StrToHex(Str[3])+4;
Sum:=0;
// Если в хотя бы одной из строк не сходится контрольная сумма (сумма всех
//байтов в строке без учета переполнения должна равняться 0), то HEX-файл
//поврежден.
for J:= 0 to Size do Sum:= Byte(Sum+16*StrToHex(Str[2*J+2])+
StrToHex(Str[2*J+3]));
if Sum <> 0 then begin
F.Free;
Exit;
end;
end;
F.Free;
Result:=true;
end;
// Функция подготовки данных для записи. В случае удачного завершения
//возвращает 0.
function TMainForm.PrepareFlashBuffer: boolean;
var F: TStringList;
Str: string;
W,Size,MaxFlashSize,Offset: word;
I,J,K: integer;
begin
Result:= false;
F:=TStringList.Create;
F.LoadFromFile(EdFilePath.Text);
Str:=F.Strings[F.Count-2];
Size:=0;
for I:=0 to 3 do Size:= 16*Size+StrToHex(Str[4+I]);
MaxFlashSize:= (Size+16*StrToHex(Str[2])+StrToHex(Str[3])) div 2;
// Если максимальный размер HEX-файла превышает размер доступной памяти
//программ (загрузчик boot-loader размещен в Boot Loader Section размером 128
//слов), то запись не возможна.
if MaxFlashSize > (FLASH_SIZE-128) then begin
F.Free;
Exit;
end;
// Выделение под буфер памяти в MaxFlashSize 16-разрядных слов, чистка и
//заполнение его данными из HEX-файла.
SetLength(FlashWriteBuffer,MaxFlashSize);
SetLength(FlashReadBuffer,MaxFlashSize);
for I:=0 to MaxFlashSize-1 do FlashWriteBuffer[I]:= $FFFF;
for I:=0 to F.Count-2 do begin
Str:= F.Strings[I];
if Copy(Str,8,2)<>'00' then Continue;
Size:= (16*StrToHex(Str[2])+StrToHex(Str[3])) div 2;
Offset:= 0;
for J:=0 to 3 do Offset:=16*Offset+StrToHex(Str[4+J]);
for J:=0 to Size-1 do begin
W:=0;
for K:=0 to 3 do W:=16*W+StrToHex(Str[4*J+K+10]);
FlashWriteBuffer[Offset div 2 +J]:= W;
end;
end;
F.Free;
Result:= true;
end;
// Процедура чтения байтов конфигурации и содержимого ячеек защиты.
procedure TMainForm.ReadFuseBits;
var LowFuseBit,HighFuseBit,LockBits: byte;
I: integer;
begin
// Передача команды чтения (символ “F”).
WriteByte(Byte('F'));
// Чтение младшего байта конфигурации.
LowFuseBit:=ReadByte;
// Чтение ячеек защиты.
LockBits:=ReadByte;
// Чтение старшего байта конфигурации.
HighFuseBit:=ReadByte;
for I:=0 to 7 do CbLowFuse.Checked[I]:=((LowFuseBit shl I) and $80)<>$80;
for I:=0 to 7 do CbHighFuse.Checked[I]:=((HighFuseBit shl I) and $80)<>$80;
LockBits:=LockBits shl 2;
for I:=0 to 3 do CbLockBits.Checked[I]:=((LockBits shl I) and $80)<>$80;
end;
// Функция программирования FLASH-памяти. В случае удачного завершения
//возвращает 0.
function TMainForm.ProgramFlash: boolean;
var Adress,Data,Page: word;
I,J: integer;
begin
Result:= false;
PbProgressBar.Visible:= true;
PbProgressBar.Position:=0;
PbProgressBar.Min:=0;
PbProgressBar.Max:=Length(FlashWriteBuffer);
Page:= Length(FlashWriteBuffer) div PAGE_SIZE + 1;
Adress:=0;
// Программирование FLASH-памяти из буфера FlashWriteBuffer. Сначала
//передается команда программирования (символ “P”). Затем передаются номер
//страницы и 32 слова для записи.
for I:=0 to Page-1 do begin
WriteByte(Byte('P'));
WriteByte(Byte(Adress and $00FF));
WriteByte(Byte((Adress and $FF00) shr 8));
for J:=0 to PAGE_SIZE-1 do begin
if (PAGE_SIZE*I+J) >= Length(FlashReadBuffer) then Data:= $FFFF else
Data:= FlashWriteBuffer[PAGE_SIZE*I+J];
WriteByte(Byte((Data and $FF00) shr 8));
WriteByte(Byte(Data and $00FF));
// Небольшая задержка времени и принудительный запуск цикла обработки ообщений.
Sleep(10);
Application.ProcessMessages;
end;
// Если после завершения операции микроконтроллер не выдал символ
//подтверждения “!”, то произошла ошибка записи.
if ReadByte <> Byte('!') then begin
PbProgressBar.Visible:= false;
Exit;
end;
Adress:= Adress + 2*PAGE_SIZE;
PbProgressBar.Position:= PbProgressBar.Position+PAGE_SIZE;
end;
PbProgressBar.Visible:= false;
Result:= true;
end;
// Функция верификации данных FLASH-памяти. В случае удачного завершения
//возвращает 0.
function TMainForm.ReadFlash: boolean;
var Adress,Data,Page: word;
I,J: integer;
begin
Result:= false;
PbProgressBar.Visible:= true;
PbProgressBar.Position:=0;
PbProgressBar.Min:=0;
PbProgressBar.Max:=Length(FlashReadBuffer);
Page:= Length(FlashReadBuffer) div PAGE_SIZE + 1;
Adress:=0;
// Считывание FLASH-памяти в буфер FlashReadBuffer. Сначала передается
//команда верификации (символ “R”). Затем передается номер страницы и
//считываются 32 слова.
for I:=0 to Page-1 do begin
WriteByte(Byte('R'));
WriteByte(Byte(Adress and $00FF));
WriteByte(Byte((Adress and $FF00) shr 8));
for J:=0 to PAGE_SIZE-1 do begin
Data:=ReadByte;
Data:=(Data shl 8)+ReadByte;
if (PAGE_SIZE*I+J) < Length(FlashReadBuffer) then
FlashReadBuffer[PAGE_SIZE*I+J]:= Data;
Application.ProcessMessages;
end;
// Если после завершения операции микроконтроллер не выдал символ
//подтверждения “!”, то произошла ошибка чтения.
if ReadByte <> Byte('!') then begin
PbProgressBar.Visible:= false;
Exit;
end;
Adress:= Adress + 2*PAGE_SIZE;
PbProgressBar.Position:= PbProgressBar.Position+PAGE_SIZE;
end;
PbProgressBar.Visible:= false;
Result:= true;
end;
// Функция стирания данных FLASH-памяти. В случае удачного завершения
//возвращает 0.
function TMainForm.EraseFlash: boolean;
var Adress,Page: word;
I: integer;
begin
Result:= false;
PbProgressBar.Visible:=true;
PbProgressBar.Position:=0;
PbProgressBar.Min:=0;
PbProgressBar.Max:=FLASH_SIZE-128;
Page:=(FLASH_SIZE-128) div PAGE_SIZE;
Adress:=0;
// Стирание FLASH-памяти программ. Сначала передается команда стирания
//(символ “E”). Затем передается номер страницы.
for I:=0 to Page-1 do begin
WriteByte(Byte('E'));
WriteByte(Byte(Adress and $00FF));
WriteByte(Byte((Adress and $FF00) shr 8));
// Небольшая задержка времени и принудительный запуск цикла обработки
//сообщений.
Sleep(10);
Application.ProcessMessages;
// Если после завершения операции микроконтроллер не выдал символ
//подтверждения “!”, то произошла ошибка стирания.
if ReadByte <> Byte('!') then begin
PbProgressBar.Visible:= false;
Exit;
end;
Adress:= Adress + 2*PAGE_SIZE;
PbProgressBar.Position:= PbProgressBar.Position+PAGE_SIZE;
end;
PbProgressBar.Visible:= false;
Result:= true;
end;
// Обработчик события создания формы.
procedure TMainForm.OnFormCreate(Sender: TObject);
var Str: string;
Found: boolean;
I: integer;
begin
Found:= false;
SetLength(Str,7);
// Попытка последовательно открыть первые 4 COM-порта.
for I:=1 to 4 do begin
if not OpenPort(I) then Continue;
// Если порт успешно открыт, то устанавливаем параметры связи (в данном
//случае 115200, 8-N-2).
SetComProperty(CBR_115200,NOPARITY,TWOSTOPBITS,8);
// Посылка микроконтроллеру запроса (символ “D”) выдать информацию о
//присутствии на линии.
WriteByte(Byte('D'));
// Если не получена строка из семи символов, то устройство не найдено.
if not ReadBuffer(Pointer(Str),7) then begin
ClosePort;
Continue;
end;
// Если была получена строка подтверждения “ATmega8”, то устройство найдено
//и можно продолжать дальнейшую работу.
Found:= Str = 'ATmega8';
if Found then Break
else ClosePort;
end;
// Если микроконтроллер не обнаружен, то приложение прекращает свою работу.
if not Found then begin
ShowMessage('Не удалось связаться с устройством!');
Application.Terminate;
end;
LbInfo.Caption:= 'ATmega8 подключен к ' + Format('COM-%d.',[I]);
ReadFuseBits;
end;
// Обработчик события уничтожения формы.
procedure TMainForm.OnFormDestroy(Sender: TObject);
begin
// Посылка микроконтроллеру команды завершения связи (символ “O”).
WriteByte(Byte('O'));
if PortHandle <> INVALID_HANDLE_VALUE then ClosePort;
end;
// Обработчик нажатия кнопки выбора пути к HEX-файлу.
procedure TMainForm.BtFilePathClick(Sender: TObject);
begin
DlOpenDialog.Execute;
EdFilePath.Text:= DlOpenDialog.FileName;
end;
// Обработчик нажатия кнопки программирования FLASH-памяти.
procedure TMainForm.BtProgramFlashClick(Sender: TObject);
var Str: string;
I: integer;
Begin
// Если выбранный файл имеет расширение отличное от HEX, то
//программирование не возможно.
Str:= Copy(EdFilePath.Text,Length(EdFilePath.Text)-3,4);
if (Str <> '.hex') and (Str <> '.HEX') then begin
ShowMessage('Файл должен иметь расширение .hex !');
Exit;
end;
// Если путь, указанный к файлу не верный, то программирование не возможно.
if not FileExists(EdFilePath.Text) then begin
ShowMessage('Файл не найден !');
Exit;
end;
// Если в файле содержаться ошибки, то программирование не возможно.
if not CheckHexFile then begin
ShowMessage('Файл поврежден !');
Exit;
end;
// Если при подготовки данных оказалось, что размер HEX-файла превышает
//размер доступной памяти то программирование не возможно.
if not PrepareFlashBuffer then begin
ShowMessage('Слишком большой размер файла !');
Exit;
end;
BtProgramFlash.Enabled:= false;
BtEraseFlash.Enabled:= false;
LbInfo.Caption:= 'Программирование...';
// Запись данных из буфера FlashWriteBuffer.
if not ProgramFlash then begin
LbInfo.Caption:= 'Ошибка программирования !';
BtProgramFlash.Enabled:= true;
BtEraseFlash.Enabled:= true;
Exit;
end;
// Чтение данных в буфер FlashReadBuffer.
LbInfo.Caption:= 'Программирование... Верификация...';
if not ReadFlash then begin
LbInfo.Caption:= 'Ошибка чтения !';
BtProgramFlash.Enabled:= true;
BtEraseFlash.Enabled:= true;
Exit;
end;
// Сравнение записанных и считанных данных.
for I:= 0 to Length(FlashWriteBuffer)-1 do begin
if FlashReadBuffer[I] = FlashWriteBuffer[I] then Continue;
ShowMessage(Format('Ошибка записи по адресу 0x%x : 0x%x вместо 0x%x !',
[I,FlashReadBuffer[I],FlashWriteBuffer[I]]));
LbInfo.Caption:= 'Ошибка верификации !';
BtProgramFlash.Enabled:= true;
BtEraseFlash.Enabled:= true;
Exit;
end;
LbInfo.Caption:= 'Программирование успешно завершено.';
BtProgramFlash.Enabled:= true;
BtEraseFlash.Enabled:= true;
end;
// Обработчик нажатия кнопки стирания FLASH-памяти.
procedure TMainForm.BtEraseFlashClick(Sender: TObject);
begin
BtProgramFlash.Enabled:= false;
BtEraseFlash.Enabled:= false;
LbInfo.Caption:= 'Стирание...';
if not EraseFlash then LbInfo.Caption:= 'Ошибка при стирании !' else
LbInfo.Caption:= 'Стирание успешно завершено.';
BtProgramFlash.Enabled:= true;
BtEraseFlash.Enabled:= true;
end;
end.
Скачать исходник проекта
Перейти к следующей части: Самоуничтожение программы
Теги:
Поиск проблем в файле ›
HEX Файлы
Отобразить файлы HEX в алфавитном порядке:
#
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
Hexadecimal Исходный файл содержит настройки, информацию о конфигурации, или другие данные, сохраненные в шестнадцатеричном формате. Он может храниться в текстовом формате также. Он используется программируемыми логическими устройства, такие как микроконтроллеры в пультах дистанционного управления.
HEX
|
Поиск по имени файла HEX для получения инструкций по устранению ошибок: |
Найти мой файл HEX » |
25 наиболее популярных файлов HEX
| ИМЯ ФАЙЛА | РАЗРАБОТЧИК | СОФТ | ВЕРСИЯ |
| 1. usbdldv2.hex | Microsoft | Windows | Vista |
| 2. usbdload.hex | Microsoft | Windows | Vista |
Hex-редактор (англ. hex-editor ), шестнадцатеричный редактор — приложение для редактирования данных, в котором данные представлены в «сыром виде» — как последовательность байтов. Он может быть как отдельным самостоятельным приложением, так и компонентом другого, более сложного приложения, такого как дизассемблер, отладчик, интегрированная среда разработки и т. п.
Для представления значения байтов используется шестнадцатеричная (англ. hexadecimal ) система счисления, что и отражено в названии редактора. Выбор шестнадцатеричной системы счисления обусловлен следующими факторами:
- Наибольшую популярность получили платформы с 8-битным байтом. В таких платформах байт может принимать 2 8 =256 значений в диапазоне от 0 до 255. Число 25610, записанное в шестнадцатеричной системе, является круглым трёхзначным числом — 10016.
- То, что это число является трёхзначным, означает, что для представления любого числа в диапазоне 0—255 требуется не более 2 разрядов.
- То, что это число является круглым, означает, что для представления будут использованы все возможные комбинации цифр, и не останется неиспользованных (например, в случае использования десятичной системы, неиспользованными остаются комбинации, соответствующие числам от 256 до 999).
Очевидно, что, например, для платформ с 9-битовым байтом использовались бы трёхзначные восьмеричные числа, а аналогичное по функциональности приложение называлось бы Oct-редактором.
Данные, которые отображает и позволяет редактировать Hex-редактор, могут быть:
Содержание
Интерфейс [ править | править код ]

Hex-редактор отображает данные в виде матрицы, каждая ячейка которой соответствует одному байту, записанному в шестнадцатеричной системе счисления в виде двухзначного числа (с ведущим нулём, если он требуется). Количество столбцов матрицы является степенью двойки, чаще всего используются 16 или 8 колонок, иногда 4. Число строк зависит от количества байтов, которые требуется отобразить/отредактировать. В случае использования 16 колонок одна строка соответствует одному параграфу.
Кроме этого, часто используются дополнительные элементы:
- Слева от матрицы отображается линейка (на рисунке показана синим цветом) из чисел: каждой строчке соответствует число, означающее адрес/смещение первого байта этой строчки. Шаг адресов при этом равен количеству колонок.
- Сверху от матрицы отображается другая линейка (на рисунке показана зелёным цветом) из чисел: над каждой колонкой отображается смещение байта, стоящего в этой колонке, относительно первого байта соответствующей строчки. Сумма числа, соответствующего i -той строке, и числа, соответствующего j -той колонке является адресом/смещением байта (i;j) , стоящего на пересечении взятой строки и взятого столбца.
- Справа от матрицы могут отображаться те же данные, но в другой интерпретации. Наиболее часто используется альтернативное отображение данных как текста в кодировке ASCII (на рисунке показаны цветом фуксия), при этом байты, значения которых соответствуют непечатным символам, отображаются как точки ( · ). Многие редакторы позволяют выбрать произвольную кодировку для режима отображения текста. Вариант с отображением данных как текста встречается в Hex-редакторах общего назначения. В редакторах же, являющихся частью какой-либо специальной программы, например отладчика, обычно доступны другие режимы, такие как листинга дизассемблирования, подсказок об адресах, и другие специфичные для приложения режимы.
Большинство редакторов позволяют совершать редактирование как в левой половине, так и в правой (при её наличии). При этом совершаемые изменения когерентны [1] .
Простые редакторы позволяют только менять значение выбранных байтов по отдельности. Продвинутые — редактировать совокупности байтов как цельные блоки [2] , выполнять поиск по последовательностям или шаблонам последовательностей.
Hex-редакторы для редактирования образов дисков могут включать в себя функции по восстановлению повреждённой файловой системы или случайно удалённых файлов.
Использование [ править | править код ]
Hex-редакторы используются для редактирования не-текстовых данных, когда специализированной программы для редактирования имеющихся данных либо нет, либо её применение неоправданно или нежелательно. Примером может служить внесение изменений в скомпилированную программу без перекомпиляции последней. Так, с помощью Hex-редактора можно изменить значения жестко вшитых в код программы строковых и числовых констант, если правильно определить их расположение.
Если Hex-редактор имеет функции дизассемблера или дизассемблирование целевой программы уже было проведено с помощью другого инструмента заранее, и известно смещение, можно внести изменение непосредственно в код программы и изменить её поведение. Этим пользуются при исправлении ошибок, взломе, читерстве, ручном твикинге.
Поскольку Hex-редактор является достаточно универсальным инструментом, описать все варианты его применения не представляется возможным.
Галерея [ править | править код ]
![]()
Свободный hex-редактор KHexEdit входящий в состав KDE (kdeutils)
$ echo 1234567890ABCDEF > test.bin
Теперь посмотрим, что записалось внутрь файла:
$ hexdump -C test.bin
00000000 31 32 33 34 35 36 37 38 39 30 41 42 43 44 45 46 |1234567890ABCDEF|
00000010 0a |.|
00000011
$
Здесь три колонки: первая — смещения внутри файла, вторая — шестнадцатеричные коды символов, третья — сами символы (обычно непечатаемые символы в третьей колонке заменяются точками) .
В данной статье будет рассказано о работе в бесплатном hex-редакторе Free Hex Editor Neo, на примере правки файла BkEnd.dll из поставки 1С:Предприятие 7.7 для корректной работы этой системы с Microsoft SQL Server 2008 R2.
0. Оглавление
1. Немного о hex-редакторах и файлах
Как известно, любой файл, хранясь на жестком диске компьютера, представляет собой последовательность машинных слов — байтов. Байт, в свою очередь, состоит из 8 битов, каждый из которых может принимать значение «0» или «1» , а это означает, что один байт может принимать 2 8 =256 значений в диапазоне от 0 до 255. Число 25610, записанное в шестнадцатеричной системе, является круглым трёхзначным числом — 10016, т. е. для представления любого числа из диапазона 0—255 потребуется не более 2 разрядов. А это значит, что значение каждого байта очень удобно записать двузначным числом в шестнадцатеричной системе счисления.
Hex-редактор (англ. hex-editor) показывает нам файл, так, как его «видит» машина, а именно, последовательностью байтов. Например, открыв файл в редакторе, мы увидим матрицу, состоящую из 16 колонок и числа строк зависящего от размера файла. Каждое значение матрицы соответствует одному байту, записанному двузначным шестнадцатеричным числом. Изменяя значение нужного байта, мы можем, соответственно, изменить сам файл.
Кроме того, рядом с таблицей можем увидеть:
- Слева от матрицы отображается линейка из чисел: каждой строчке соответствует число, означающее адрес/смещение первого байта этой строчки. Шаг адресов при этом равен количеству колонок.
- Сверху от матрицы отображается другая линейка: над каждой колонкой отображается смещение байта, стоящего в этой колонке, относительно первого байта соответствующей строчки. Сумма числа, соответствующего i -той строке, и числа, соответствующего j -той колонке является адресом/смещением байта (i;j) , стоящего на пересечении взятой строки и взятого столбца.
- Справа от матрицы отображаются те же данные, но в другой интерпретации. Чаще всего используется альтернативное отображение данных как текста в кодировке ASCII , при этом байты, значения которых соответствуют непечатным символам, отображаются как точки ( · ). Редактировать значения можно и в этой области.

Подробнее о Hex-редакторах можно прочитать здесь.
2. Установка Free Hex Editor Neo
Скачиваем Free Hex Editor Neo с официального сайта. Программа бесплатна, на момент написания статьи последней была версия 5.14. Устанавливаем, следуя инструкциям инсталлятора, не меняя настроек по умолчанию. При первом запуске программа предложит выбрать режим интерфейса. Выбираем «Novice user» , этого более чем достаточно.

3. Работа с файлом hex-редакторе
Теперь откроем файл, который нам необходимо «подправить» выбрав «File» — «Open» — «Open File» в меню Free Hex Editor Neo. В моем случае это файл BkEnd.dll, находящийся в папке с установленной 1С:Предприятие 7.7 (По умолчанию «C:Program Files1Cv77BIN» ) для статьи Установка 1С:Предприятие 7.7 на Microsoft SQL Server 2008 R2.
Например, мне нужно в байт со смещением 000d9cca записать значение eb. Для этого я нахожу строку «000d9cco» и столбец «0a», кликаю два раза по нужной ячейке и забиваю новое значение.

Действуя аналогично, я вношу следующие изменения:
- Для исправления ошибки «Требуется MS SQL Server 6.5 + Service Pack 5a или более старшая версия!» изменяем поля:
по смещению 000d9cca значение 83 меняем на eb
по смещению 000d9ccb значение e8 меняем на 15
по смещению 000db130 значение 83 меняем на eb
по смещению 000db131 значение e8 меняем на 10 - Для исправления ошибки «Порядок сортировки, установленный для базы, отличается от системного!»:
по смещению 0018a79d значение 75 меняем на eb - Для исправления ошибки «Неправильный синтаксис около ключевого слова «TRANSACTION»
Фразу DUMP TRANSACTION %s WITH TRUNCATE_ONLY , которая находится по смещению 002856B0 заменяем на фразу ALTER DATABASE %s SET RECOVERY SIMPLE - Для исправления ошибки «База данных не может быть открыта в однопользовательском режиме», изменяем поля:
по смещению 0028549c значение 64 меняем на 6b
по смещению 0028549d значение 62 меняем на 70
После того, как все изменения сделаны, сохраним файл, нажав «File» — «Save» .
Смотрите также:
В данном вебинаре я расскажу о применяемых в нашей компании правилах и приемах доработки типовых конфигураций 1С для облегчения их дальнейшей поддержки и обновления. В видео использованы материалы…
Официально, платформа 1С:Предприятие 7.7 работает только с MS SQL Server 2000. Но с помощью небольших манипуляций можно организовать стабильную работу и с последней, на момент написания статьи, версий Microsoft SQL…
Небольшая зарисовка на тему, какие были бы сливные трубы, если бы их делали 1С-ники.
Free tool for analysis of hexadecimal codes. Can detect many file formats and encodings including: UTF-8, ASCII,
images files, sound files, video files and zip files. Just paste your binary data into the textbox below and click Analyze.
Text is empty.
Any other characters than hexadecimal digits (0-9, A-F or a-f) will be ignored.
Results
File format
- Find out about file formats at the code-breaking page.
Statistics
- Zeroes: %
- Ones: %
- Entropy:
- Byte length:
If both zeroes and ones are close to 50%, this is probably encrypted using a modern cipher. See more about modern cipher
at the code-breaking page.
For further statistical analysis, the frequency analysis tool is recommended.
Ensure to enable «Keep spaces & non-letters».