To cut the long story short, it turned out that I have to send ISP-3 to Germany for an upgrade, so I have to use thinking instead of testing. Callback functions were ment to be very fast, almost like you have to do in interrupts. It's not your fault at all since I might have forgotten to put it in the documentation. You should just fire some flag or do a quick memory move in a callback procedure, and never write to a serial port like you do. Then other process can pick that flag (or for example a record with register number and value) and output it safely to serial. Callback procedures were not ment for something like this from your sample:
Code
procedure mb_BeforeRegisterRead (RegisterNumber: word);
begin
FlashLed;
Writeln (SerOut, 'Rd reg ' + IntToStr (RegisterNumber));
end;
procedure mb_AfterRegisterWrite (RegisterNumber: word);
begin
// FlashLed;
Writeln (SerOut, 'wr ' + IntToStr (RegisterNumber));
end;
You have put WriteLn and IntToStr in callback procedures, and that is too much. Just think about it. Your WriteLn might be longer then period between two MODBUS register read messages (callback is not finished until all characters are written to serial). If it is longer then it might be called again before previous callback has been finished, and BOOOOM!!! Let me show you how MODBUS callback procedures are called, and it might be more clear:
Code
function mb_ReadRegister(RegisterNumber: word): word; // return value of analog tag
var
ReturnValue: word;
begin
if BeforeRegisterRead <> NIL then
BeforeRegisterRead(RegisterNumber); // if event exists call it
endif;
ReturnValue := mb_tags[RegisterNumber];
if AfterRegisterRead <> NIL then
AfterRegisterRead(RegisterNumber); // if event exists call it
endif;
return(ReturnValue);
end;
Since I can not test yet, you can do it for me. Just replace procedures in your code with these:
Code
procedure mb_BeforeRegisterRead (RegisterNumber: word);
begin
LED := 1;
end;
procedure mb_AfterRegisterWrite (RegisterNumber: word);
begin
LED := 0;
end;
First register reading message should light a led on, and first register write message should light a led off. Of course, you must use both read and write register messages to see the effect. If this led light does not show as advertised, then we might really have a bug and I should investigate in another direction.