I'm attempting to write code for a buffer in NuSMV. The buffer has 6 wires. 4 input wires (reset, clock, read_enable, and write_enable) and 2 output wires(full and empty). Wires are modeled as boolean true|false (true being high voltage). The first
wire is an asynchronous (instant) reset. If there is a high voltage, the buffer
goes instantly to the empty configuration. Other wires are operated in the
synchronous mode triggered by a rising edge on the clock wire. The buffer is of Size 3. There are specific behaviors.
I created the following code but I cannot think of what the Main Module could be.
MODULE buffer (reset, clock, read_enable, write_enable, full, empty)
-- inputs
-- reset : boolean; -- asynchronous (instant) reset
-- clock : boolean; -- clock
-- read_enable : boolean; -- data read request = enqueue
-- write_enable : boolean; -- data write request = dequeue
-- outputs
-- full : boolean; -- is the buffer full?
-- empty : boolean; -- is the buffer empty?
-- use SIZE for the maximal buffer size
-- TODO ....
VAR
reset: {False, True};
clock: {False, True};
read_enable: {False, True};
write_enable: {False, True};
full: {False, True};
empty: {False, True};
ASSIGN
SIZE := 0;
init (reset) := True;
next (reset) := case
reset = True : empty = True;
esac;
next (clock) := case
write_enable = True : clock = True & empty = False;
esac;
next (write_enable):= case
write_enable = True : SIZE + 1 & SIZE <=3;
esac;
next (read_enable) := case
write_enable = True & read_enable = True : SIZE != SIZE +1;
esac;
next (full) := case
full = True & SIZE = 3 & write_enable = True : reset = True;
esac;
MODULE main
VAR
reset: boolean;
turn: boolean;
pro0: process buffer(reset, 0, clock, read_enable, write_enable);
pro1: process buffer(reset, 1, clock, read_enable, write_enable);
ASSIGN
init(turn) := 0;
FAIRNESS !(reset = True)
FAIRNESS !(reset = False)
MODULE prc(reset, turn, pro0, pro1)
ASSIGN
init(reset) := 0;
next (reset) := case
(reset = 0) : {0,1};
(reset = 1) : {0};
1 : reset;
esac;
Please assist
I've tried following basic NuSMV guides on how to write the code but I have no experience in this language.
My desire is to communicate with an Arduino Uno over an USB-port (COM3 - 9600,N,8,1).
I was going to manage the information with Autohotkey on a computer running Windows 10.
This test is only intended to read the information from the Arduino. But later I also want to be able to send information from the PC to the Arduino Uno.
The Arduino Uno has an extra card attached (Funduino JoyStick Shield V1.A) - only for the test.
This is the program I use on the Arduino .:
// Armuino --- Funduino Joystick Shield ---
// Playlist: https://www.youtube.com/playlist?list=PLRFnGJH1nJiKIpz_ZyaU-uAZOkMH8GAcw
//
// Part 1. Introduction - Basic Functions: https://www.youtube.com/watch?v=lZPZuBCFMH4
// Arduino digital pins associated with buttons
const byte PIN_BUTTON_A = 2;
const byte PIN_BUTTON_B = 3;
const byte PIN_BUTTON_C = 4;
const byte PIN_BUTTON_D = 5;
const byte PIN_BUTTON_E = 6;
const byte PIN_BUTTON_F = 7;
// Arduino analog pins associated with joystick
const byte PIN_ANALOG_X = 0;
const byte PIN_ANALOG_Y = 1;
void setup() {
Serial.begin(9600);
pinMode(PIN_BUTTON_B, INPUT);
digitalWrite(PIN_BUTTON_B, HIGH);
pinMode(PIN_BUTTON_E, INPUT);
digitalWrite(PIN_BUTTON_E, HIGH);
pinMode(PIN_BUTTON_C, INPUT);
digitalWrite(PIN_BUTTON_C, HIGH);
pinMode(PIN_BUTTON_D, INPUT);
digitalWrite(PIN_BUTTON_D, HIGH);
pinMode(PIN_BUTTON_A, INPUT);
digitalWrite(PIN_BUTTON_A, HIGH);
}
void loop() {
Serial.print("Buttons A:");
Serial.print(digitalRead(PIN_BUTTON_A));
Serial.print(" ");
Serial.print("B:");
Serial.print(digitalRead(PIN_BUTTON_B));
Serial.print(" ");
Serial.print("C:");
Serial.print(digitalRead(PIN_BUTTON_C));
Serial.print(" ");
Serial.print("D:");
Serial.print(digitalRead(PIN_BUTTON_D));
Serial.print(" ");
Serial.print("E:");
Serial.print(digitalRead(PIN_BUTTON_E));
Serial.print(" ");
Serial.print("F:");
Serial.print(digitalRead(PIN_BUTTON_F));
Serial.print(" -- ");
Serial.print("Position X:");
Serial.print(analogRead(PIN_ANALOG_X));
Serial.print(" ");
Serial.print("Y:");
Serial.print(analogRead(PIN_ANALOG_Y));
Serial.print(" ");
Serial.println();
delay(1000);
}
This program seems to work when I run the Arduino Serial Editor on the PC.
The values is coming row for row on the screen, like this .:
**00:58:44.434 -> Buttons A:1 B:1 C:1 D:1 E:1 F:1 -- Position X:334 Y:321**
(I can't see any wrong values in the Serial Editor. - maybe in higher speed)
But if I try to "do the same" with Autohotkey, characters may be missing - some times.
Like this .:
But:322
Buttons A:1 B:1 C:1 D:1 E:1 F:1 -- Position X:334 Y:322
334 Y:322
Buttons A:1 B:1 C:1 D:1 E:1 F:1 -- Position X:334 Y:322
I have no idea how the communication with USB should look like in Windows 10.
(I think it is not the same as eg. Windows XP)
I have looked on this solution .: Arduino + AutoHotKey > Serial Connection
- Not sure I found the right Arduino.ahk
- Maybe require Windows XP?
- It doesn't work for me!
This tip is better (but old) .: Arduino.ahk beta .01
The most of tests have been based on this link and I created the following AHK-program .:
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn ; Enable warnings to assist with detecting common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
#Singleinstance force
COM = 3
Num_Bytes = 500
Mode =
; Initialize COM-port
COM_Port = COM%COM%
COM_Baud = 9600
COM_Parity = N
COM_Data = 8
COM_Stop = 1
COM_DTR = Off
FilNamn := A_ScriptDir "/Test.txt"
IfExist %FilNamn%
FileDelete %FilNamn%
COM_Settings = %COM_Port%:baud=%COM_Baud% parity=%COM_Parity% data=%COM_Data% stop=%COM_Stop% dtr=%COM_DTR%
COM_FileHandle := Serial_Initialize(COM_Settings)
Loop 100
{ ; ReadResult := Serial_Read(COM_FileHandle, Num_Bytes, Mode)
ReadResult := Serial_Read_Raw(COM_FileHandle, Num_Bytes, Mode)
asciiString := Hex2ASCII(ReadResult)
sleep 20
FileAppend %asciiString%, %FilNamn%, UTF-8
; SplashTextOn 800, 100, Arduino Read, %asciiString%
; Sleep 1000
; MsgBox ,, Rad %A_LineNumber% -> %A_ScriptName%, % COM_Settings "`n`n" ReadResult "`n`n- " StrLen(ReadResult) "`n`n- " Bytes_Received "`n`n- " asciiString, 1
}
Serial_Close(COM_FileHandle)
; MsgBox ,, Rad %A_LineNumber% -> %A_ScriptName%, % COM_Settings "`n`n" ReadResult "`n`n- " StrLen(ReadResult) "`n`n- " Bytes_Received
; asciiString := Hex2ASCII(ReadResult)
; MsgBox ,, Rad %A_LineNumber% -> %A_ScriptName%, % ReadResult "`n`n"asciiString
MsgBox ,, Rad %A_LineNumber% -> %A_ScriptName%, Klart!
ExitApp
ESC::
SplashTextOff
Serial_Close(COM_FileHandle)
MsgBox ,,, Programmet avslutas!, 1
ExitApp
Return
Hex2ASCII(fHexString)
{ Loop Parse, fHexString
NewHexString .= A_LoopField (Mod(A_Index,2) ? "" : ",")
Loop Parse, NewHexString, `,
ConvString .= Chr("0x" A_LoopField)
Return ConvString
} ;http://www.autohotkey.com/forum/post-211769.html#211769
;########################################################################
;###### Initialize COM Subroutine #######################################
;########################################################################
Serial_Initialize(SERIAL_Settings){
;Global SERIAL_FileHandle ;uncomment this if there is a problem
;###### Build COM DCB ######
;Creates the structure that contains the COM Port number, baud rate,...
VarSetCapacity(DCB, 28)
BCD_Result := DllCall("BuildCommDCB"
,"str" , SERIAL_Settings ;lpDef
,"UInt", &DCB) ;lpDCB
If (BCD_Result <> 1){
error := DllCall("GetLastError")
MsgBox, There is a problem with Serial Port communication. `nFailed Dll BuildCommDCB, BCD_Result=%BCD_Result% `nLasterror=%error%`nThe Script Will Now Exit.
ExitApp
}
;###### Extract/Format the COM Port Number ######
StringSplit, SERIAL_Port_Temp, SERIAL_Settings, `:
SERIAL_Port_Temp1_Len := StrLen(SERIAL_Port_Temp1) ;For COM Ports > 9 \\.\ needs to prepended to the COM Port name.
If (SERIAL_Port_Temp1_Len > 4) ;So the valid names are
SERIAL_Port = \\.\%SERIAL_Port_Temp1% ; ... COM8 COM9 \\.\COM10 \\.\COM11 \\.\COM12 and so on...
Else ;
SERIAL_Port = %SERIAL_Port_Temp1%
;MsgBox, SERIAL_Port=%SERIAL_Port%
;###### Create COM File ######
;Creates the COM Port File Handle
;StringLeft, SERIAL_Port, SERIAL_Settings, 4 ; 7/23/08 This line is replaced by the "Extract/Format the COM Port Number" section above.
SERIAL_FileHandle := DllCall("CreateFile"
,"Str" , SERIAL_Port ;File Name
,"UInt", 0xC0000000 ;Desired Access
,"UInt", 3 ;Safe Mode
,"UInt", 0 ;Security Attributes
,"UInt", 3 ;Creation Disposition
,"UInt", 0 ;Flags And Attributes
,"UInt", 0 ;Template File
,"Cdecl Int")
If (SERIAL_FileHandle < 1){
error := DllCall("GetLastError")
MsgBox, There is a problem with Serial Port communication. `nFailed Dll CreateFile, SERIAL_FileHandle=%SERIAL_FileHandle% `nLasterror=%error%`nThe Script Will Now Exit.
ExitApp
}
;###### Set COM State ######
;Sets the COM Port number, baud rate,...
SCS_Result := DllCall("SetCommState"
,"UInt", SERIAL_FileHandle ;File Handle
,"UInt", &DCB) ;Pointer to DCB structure
If (SCS_Result <> 1){
error := DllCall("GetLastError")
MsgBox, There is a problem with Serial Port communication. `nFailed Dll SetCommState, SCS_Result=%SCS_Result% `nLasterror=%error%`nThe Script Will Now Exit.
Serial_Close(SERIAL_FileHandle)
ExitApp
}
;###### Create the SetCommTimeouts Structure ######
ReadIntervalTimeout = 0xffffffff
ReadTotalTimeoutMultiplier = 0x00000000
ReadTotalTimeoutConstant = 0x00000000
WriteTotalTimeoutMultiplier= 0x00000000
WriteTotalTimeoutConstant = 0x00000000
VarSetCapacity(Data, 20, 0) ; 5 * sizeof(DWORD)
NumPut(ReadIntervalTimeout, Data, 0, "UInt")
NumPut(ReadTotalTimeoutMultiplier, Data, 4, "UInt")
NumPut(ReadTotalTimeoutConstant, Data, 8, "UInt")
NumPut(WriteTotalTimeoutMultiplier, Data, 12, "UInt")
NumPut(WriteTotalTimeoutConstant, Data, 16, "UInt")
;###### Set the COM Timeouts ######
SCT_result := DllCall("SetCommTimeouts"
,"UInt", SERIAL_FileHandle ;File Handle
,"UInt", &Data) ;Pointer to the data structure
If (SCT_result <> 1){
error := DllCall("GetLastError")
MsgBox, There is a problem with Serial Port communication. `nFailed Dll SetCommState, SCT_result=%SCT_result% `nLasterror=%error%`nThe Script Will Now Exit.
Serial_Close(SERIAL_FileHandle)
ExitApp
}
Return SERIAL_FileHandle
}
;########################################################################
;###### Close COM Subroutine ############################################
;########################################################################
Serial_Close(SERIAL_FileHandle){
;###### Close the COM File ######
CH_result := DllCall("CloseHandle", "UInt", SERIAL_FileHandle)
If (CH_result <> 1)
MsgBox, Failed Dll CloseHandle CH_result=%CH_result%
Return
}
;########################################################################
;###### Write to COM Subroutines ########################################
;########################################################################
Serial_Write(SERIAL_FileHandle, Message){
;Global SERIAL_FileHandle
OldIntegerFormat := A_FormatInteger
SetFormat, Integer, DEC
;Parse the Message. Byte0 is the number of bytes in the array.
StringSplit, Byte, Message, `,
Data_Length := Byte0
;msgbox, Data_Length=%Data_Length% b1=%Byte1% b2=%Byte2% b3=%Byte3% b4=%Byte4%
;Set the Data buffer size, prefill with 0xFF.
VarSetCapacity(Data, Byte0, 0xFF)
;Write the Message into the Data buffer
i=1
Loop %Byte0% {
NumPut(Byte%i%, Data, (i-1) , "UChar")
;msgbox, %i%
i++
}
;msgbox, Data string=%Data%
;###### Write the data to the COM Port ######
WF_Result := DllCall("WriteFile"
,"UInt" , SERIAL_FileHandle ;File Handle
,"UInt" , &Data ;Pointer to string to send
,"UInt" , Data_Length ;Data Length
,"UInt*", Bytes_Sent ;Returns pointer to num bytes sent
,"Int" , "NULL")
If (WF_Result <> 1 or Bytes_Sent <> Data_Length)
MsgBox, Failed Dll WriteFile to COM Port, result=%WF_Result% `nData Length=%Data_Length% `nBytes_Sent=%Bytes_Sent%
SetFormat, Integer, %OldIntegerFormat%
Return Bytes_Sent
}
;########################################################################
;###### Read from COM Subroutines #######################################
;########################################################################
;########################################################################
;###### Read from COM Subroutines #######################################
;########################################################################
Serial_Read(COM_FileHandle, Num_Bytes, mode = "",byref Bytes_Received = "")
{
;Global COM_FileHandle
;Global COM_Port
;Global Bytes_Received
SetFormat, Integer, HEX
;Set the Data buffer size, prefill with 0x55 = ASCII character "U"
;VarSetCapacity won't assign anything less than 3 bytes. Meaning: If you
; tell it you want 1 or 2 byte size variable it will give you 3.
Data_Length := VarSetCapacity(Data, Num_Bytes, 0x55)
;msgbox, Data_Length=%Data_Length%
;###### Read the data from the COM Port ######
;msgbox, COM_FileHandle=%COM_FileHandle% `nNum_Bytes=%Num_Bytes%
Read_Result := DllCall("ReadFile"
,"UInt" , COM_FileHandle ; hFile
,"Str" , Data ; lpBuffer
,"Int" , Num_Bytes ; nNumberOfBytesToRead
,"UInt*", Bytes_Received ; lpNumberOfBytesReceived
,"Int" , 0) ; lpOverlapped
;MsgBox, Read_Result=%Read_Result% `nBR=%Bytes_Received% ,`nData=%Data%
If (Read_Result <> 1)
{
MsgBox, There is a problem with Serial Port communication. `nFailed Dll ReadFile on COM Port, result=%Read_Result% - The Script Will Now Exit.
Serial_Close(COM_FileHandle)
Exit
}
;if you know the data coming back will not contain any binary zeros (0x00), you can request the 'raw' response
If (mode = "raw")
Return Data
;###### Format the received data ######
;This loop is necessary because AHK doesn't handle NULL (0x00) characters very nicely.
;Quote from AHK documentation under DllCall:
; "Any binary zero stored in a variable by a function will hide all data to the right
; of the zero; that is, such data cannot be accessed or changed by most commands and
; functions. However, such data can be manipulated by the address and dereference operators
; (& and *), as well as DllCall itself."
i = 0
Data_HEX =
Loop %Bytes_Received%
{
;First byte into the Rx FIFO ends up at position 0
Data_HEX_Temp := NumGet(Data, i, "UChar") ;Convert to HEX byte-by-byte
StringTrimLeft, Data_HEX_Temp, Data_HEX_Temp, 2 ;Remove the 0x (added by the above line) from the front
;If there is only 1 character then add the leading "0'
Length := StrLen(Data_HEX_Temp)
If (Length =1)
Data_HEX_Temp = 0%Data_HEX_Temp%
i++
;Put it all together
Data_HEX .= Data_HEX_Temp
}
;MsgBox, Read_Result=%Read_Result% `nBR=%Bytes_Received% ,`nData_HEX=%Data_HEX%
SetFormat, Integer, DEC
Data := Data_HEX
Return Data
}
;########################################################################
;###### Read from COM Subroutines #######################################
;########################################################################
Serial_Read_Raw(SERIAL_FileHandle, Num_Bytes, mode = "",byref Bytes_Received = ""){
;Global SERIAL_FileHandle
;Global SERIAL_Port
;Global Bytes_Received
OldIntegerFormat := A_FormatInteger
SetFormat, Integer, HEX
;Set the Data buffer size, prefill with 0x55 = ASCII character "U"
;VarSetCapacity won't assign anything less than 3 bytes. Meaning: If you
; tell it you want 1 or 2 byte size variable it will give you 3.
Data_Length := VarSetCapacity(Data, Num_Bytes, 0)
;msgbox, Data_Length=%Data_Length%
;###### Read the data from the COM Port ######
;msgbox, SERIAL_FileHandle=%SERIAL_FileHandle% `nNum_Bytes=%Num_Bytes%
Read_Result := DllCall("ReadFile"
,"UInt" , SERIAL_FileHandle ; hFile
,"Str" , Data ; lpBuffer
,"Int" , Num_Bytes ; nNumberOfBytesToRead
,"UInt*", Bytes_Received ; lpNumberOfBytesReceived
,"Int" , 0) ; lpOverlapped
;MsgBox, Read_Result=%Read_Result% `nBR=%Bytes_Received% ,`nData=%Data%
If (Read_Result <> 1){
MsgBox, There is a problem with Serial Port communication. `nFailed Dll ReadFile on COM Port, result=%Read_Result% - The Script Will Now Exit.
Serial_Close(SERIAL_FileHandle)
Exit
}
;if you know the data coming back will not contain any binary zeros (0x00), you can request the 'raw' response
If (mode = "raw")
Return Data
;###### Format the received data ######
;This loop is necessary because AHK doesn't handle NULL (0x00) characters very nicely.
;Quote from AHK documentation under DllCall:
; "Any binary zero stored in a variable by a function will hide all data to the right
; of the zero; that is, such data cannot be accessed or changed by most commands and
; functions. However, such data can be manipulated by the address and dereference operators
; (& and *), as well as DllCall itself."
i = 0
Data_HEX =
Loop %Bytes_Received%
{
;First byte into the Rx FIFO ends up at position 0
Data_HEX_Temp := NumGet(Data, i, "UChar") ;Convert to HEX byte-by-byte
StringTrimLeft, Data_HEX_Temp, Data_HEX_Temp, 2 ;Remove the 0x (added by the above line) from the front
;If there is only 1 character then add the leading "0'
Length := StrLen(Data_HEX_Temp)
If (Length =1)
Data_HEX_Temp = 0%Data_HEX_Temp%
i++
;Put it all together
Data_HEX .= Data_HEX_Temp
}
;MsgBox, Read_Result=%Read_Result% `nBR=%Bytes_Received% ,`nData_HEX=%Data_HEX%
SetFormat, Integer, DEC
Data := Data_HEX
SetFormat, Integer, %OldIntegerFormat%
Return Data
}
Thanks for your time!
Has managed to get better communication between Windows and the Arduino. (with a different configuration).Made two windows in a GUI
One where I can enter characters.
Arduinon echoes back what is typed and returns that character to the PC
The other show the returned characters..
It works (in 9600bps), but first I send a headline and if the baud rate increases, "strange" characters always appear at the beginning of the test.
Don't know if the serial buffer in the Arduino / PC needs to be cleared before the characters start to read in sharp mode? (how to do that?)
In the Arduino SerialMonitor I got not readable information with higher baudrate (from another test program)
My ECHO-program in the Arduino
int incomingByte;
void setup() {
Serial.begin(9600);
}
void loop(){
if (Serial.available() > 0) {
incomingByte = Serial.read();
//Serial.print(incomingByte);
Serial.write(incomingByte);
}
}
I've FreeDos OS installed on VirtualBox on a windows xp, dual core, host machine. I installed FreeDos because I wanted to run a Pascal code using Turbo Pascal. When I run the code, it throws error 'Error 200: Division by zero.'. How can I solve this?
-Turbo Pascal 7.0, Free DOS 1.1, Virtual Box 4.3.6, Windows XP Service Pack 3 Host machine
-This error is unfortunately caused by fast Pentium CPUs and I found a patch on the internet that will resolve the error. (www.filewatcher.com/m/bp7patch.zip.62550-0.html) Now the other problem is, when i was tracing the code, it hangs at 'RxWait procedure when trying to execute while not odd(port[RXTX + 5]) do;'
uses crt;
const
{ COM1: RS232 port address }
RXTX = $3F8; { $2F8 if COM2: is used }
ACK = 6;
NAK = 21;
ESC = 27;
var
dummy,
checkSum : integer;
key : char;
protocol : integer;
procedure InitComm;
{ Set baudrate to 9600, 8 bits, no parity, 1 stop bit }
var i : integer;
begin
i := 1843200 div 9600 div 16;
port[RXTX + 3] := $80;
port[RXTX + 1] := hi(i);
port[RXTX]:= lo(i);
port[RXTX + 3] := 3;
port[RXTX + 4] := $A;
while odd(port[RXTX + 5]) do
begin
dummy := port[RXTX];
delay(10);
end;
end; { InitComm }
procedure Tx(data : integer);
{ Transmit a character on serial channel }
begin
while port[RXTX + 5] and $20 = 0 do;
port[RXTX] := data and $FF;
end; { Tx }
function RxWait : integer;
{ Waits for a character from serial channel }
begin
while not odd(port[RXTX + 5]) do;
RxWait := port[RXTX];
end; { RxWait }
procedure Tx2(data : integer);
{ Transmit a char on serial channel + Calculate check sum }
begin
Tx(data);
checkSum := (checkSum + data) and $FF;
end; { Tx2 }
procedure TxCommand(c1, c2 : char;
sendCheckSum : boolean);
{ Transmit command (no data) on serial channel }
begin
Tx(ESC);
checkSum := 0;
Tx2(ord(c1));
Tx2(ord(c2));
if sendCheckSum then
begin
Tx2(checkSum);
dummy := RxWait;
end;
end; { TxCommand }
function ReadNumber(n : integer) : real;
{ Read n bytes from serial channel }
var
number: real;
i : integer;
begin
number := 0;
checkSum := 0;
for i := 1 to n do
number := number * 256 + RxWait;
dummy := RxWait;
ReadNumber := number;
end; { ReadNumber }
procedure Revisions;
var
tmp : integer;
sw,
prot : real;
begin
TxCommand('P', 'R', FALSE);
checkSum := 0;
tmp := RxWait;
sw := tmp + RxWait / 100.0;
protocol := RxWait;
prot := protocol + RxWait / 100.0;
dummy := RxWait;
tmp := RxWait;
writeln('Software revision: ', sw:4:2);
writeln('Protocol revision: ', prot:4:2);
end; { Revisions }
procedure ReadCountReg;
begin
TxCommand('R', 'C', FALSE);
writeln(ReadNumber(4):11:0, ' coins counted.');
dummy := RxWait;
end; { ReadCountReg }
procedure ReadAccReg;
begin
TxCommand('R', 'A', FALSE);
writeln(ReadNumber(4):11:0, ' coins in accumulator.');
dummy := RxWait;
end; { ReadAccReg }
procedure Setbatch(limit : longint);
begin
TxCommand('W', 'L', FALSE);
case protocol of
1 : begin
Tx2(limit div 256);
Tx2(limit mod 256);
end;
2 : begin
Tx2( limit div 16777216);
Tx2((limit div 65536) mod 256);
Tx2((limit div 256) mod 256);
Tx2( limit mod 256);
end;
end; { case protocol }
Tx2(checkSum);
dummy := RxWait;
end; { Setbatch }
As far as I remember (more than 12 years ago), CRT unit had problems about Pentium CPUs and giving that division by zero error. I was using Turbo Pascal 7 those days. What I mean is that it may not be your coding error, but just CRT unit itself.
Old question I know, but there is another way to write Turbo Pascal code without incurring the wrath of the infamous RTE 200 bug. FreePascal (www.freepascal.org) is fully TP7 compatible and runs under a number of OSes including DOS, Windows and Linux.
Hope this helps!
I solved it setting the Execution Cap to 20%. So the processor is probably as slower as expected in those days. You can play with percentages until the error disappear
Regards
I have this code
--RAM module
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.numeric_std.all;
entity RAM is
generic(
address_length, data_length : integer);
port(
addr : in std_logic_vector(address_length-1 downto 0);
dat : inout std_logic_vector(data_length-1 downto 0);
rd, wr, en : in bit);
end entity RAM;
architecture RAM_impl of RAM is
type mem is array(2**address_length-1 downto 0) of std_logic_vector(data_length-1 downto 0);
begin
process(rd, wr, en)is
variable cont : mem;
begin
if(en = '1')then
if(wr = '1' and rd = '0')then
cont(to_integer(unsigned(addr))) := dat;
end if;
if(rd = '1' and wr = '0')then
dat <= cont(to_integer(unsigned(addr)));
end if;
end if;
end process;
end architecture RAM_impl;
--Test module
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.numeric_std.all;
entity Example4RAM is
end entity Example4RAM;
architecture Tester of Example4RAM is
signal rd, wr, en : bit;
signal str : std_logic_vector(15 downto 0);
signal ext : std_logic_vector(7 downto 0);
begin
module : entity work.RAM(RAM_impl)
generic map(
address_length => 16,
data_length => 8)
port map(str, ext, rd, wr, en);
tt : process is
begin
str <= X"0001";
ext <= "00000000";
rd <= '0'; wr <= '1';
wait for 5 ns;
en <= '1';
wait for 5 ns;
rd <= '0'; wr <= '0';
wait for 10 ns;
rd <= '1'; wr <= '0';
end process;
end architecture Tester;
When i run simulation on this RAM module str vector initializes fine but ext vector stays uninitialized. In RAM module str is in vector and ext is inout vector. Is this somehow making problem and does anyone know the solution? (I did change source since yesterday but it doesn't work still)
I added a RAM module and tinkered with the test stimulus slightly (ext is driven to all 'Z's when wr goes invalid (the behavioral model requires no hold over).
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity RAM is
generic (
constant address_length: natural := 16;
constant data_length: natural := 8
);
port (
signal str: in std_logic_vector (address_length-1 downto 0);
signal ext: inout std_logic_vector (data_length-1 downto 0);
signal rd: in BIT;
signal wr: in BIT
);
end entity;
architecture RAM_impl of RAM is
type ram_array is array (natural range address_length-1 downto 0)
of std_logic_vector (data_length-1 downto 0);
signal mem_array: ram_array;
begin
MEMORY:
process (str, ext, rd, wr)
variable addr: natural range 0 to 2**address_length -1 ;
begin
addr := TO_INTEGER(UNSIGNED(str)); -- heed the warnings
if wr = '1' then
mem_array(addr) <= ext;
end if;
if rd = '0' then
ext <= (others => 'Z');
else
ext <= mem_array(addr);
end if;
end process;
end architecture;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- use IEEE.numeric_std.ALL;
entity Example4RAM is
end entity Example4RAM;
architecture Tester of Example4RAM is
signal rd,wr,clk: bit;
signal str: std_logic_vector(15 downto 0);
signal ext: std_logic_vector(7 downto 0);
begin
module:
entity work.RAM(RAM_impl)
generic map (
address_length=>16,
data_length=>8
)
port map (
str,
ext,
rd,
wr
)
;
tt:
process
begin
str<=X"0001";
ext<="00000000";
wait for 5 ns;
rd<='0';wr<='1';
wait for 5 ns;
rd<='0';wr<='0';
ext <= (others => 'Z'); -- ADDED
wait for 10 ns;
rd<='1';wr<='0';
wait for 20 ns; -- ADDED
str <=X"0002"; -- ADDED
wait for 20 ns; -- ADDED
wait;
end process;
end architecture Tester;
The change to the stimulus includes a change to the RAM address showing that reading an uninitialized location returns 'U's (uu on the waveform):
ghdl -a exampleram.vhdl
ghdl -r Example4RAM --wave=Example4RAM.ghw
../../../../libraries/ieee/numeric_std-body.v93:2098:7:#0ms:(assertion warning):
NUMERIC_STD.TO_INTEGER: metavalue detected, returning 0
open *.ghw
Essentially, the process and the RAM drive ext with all 'Z's whenever either one shouldn't be driving a value out. Writing before reading hides the 'U' values from str address X"0001". As you see, if the address is changed to a location that is not initialized, the 'U's show up. Resolution delivers the RAM read data or provides write data to the RAM array on the bidirectional data bus (ext).
(This was done on a Mac with a ghdl mcode version (direct compile, like for Windows, requiring no explicit elaboration), and displayed using GTKWave).
The assertion warning (metavalue detected) comes from the default value assigned to str (all 'U's) at time zero (#0ms).
I am trying to set a service's failure actions using Inno Setup's Pascal scripting language. I receive the classic "access violation at address..." error. Seems that it is impossible because the language don't have any support to pointers. Any ideas? Here is the code snippet:
type
TScAction = record
aType1 : Longword;
Delay1 : Longword;
aType2 : Longword;
Delay2 : Longword;
aType3 : Longword;
Delay3 : Longword;
end;
type
TServiceFailureActionsA = record
dwResetPeriod : DWORD;
pRebootMsg : String;
pCommand : String;
cActions : DWORD;
saActions : TScAction;
end;
function ChangeServiceConfig2(hService: Longword; dwInfoLevel: Longword; lpInfo: TServiceFailureActionsA): BOOL;
external 'ChangeServiceConfig2A#advapi32.dll stdcall';
procedure SimpleChangeServiceConfig(AService: string);
var
SCMHandle: Longword;
ServiceHandle: Longword;
sfActions: TServiceFailureActionsA;
sActions: TScAction;
begin
try
SCMHandle := OpenSCManager('', '', SC_MANAGER_ALL_ACCESS);
if SCMHandle = 0 then
RaiseException('SimpleChangeServiceConfig#OpenSCManager: ' + AService + ' ' +
SysErrorMessage(DLLGetLastError));
try
ServiceHandle := OpenService(SCMHandle, AService, SERVICE_ALL_ACCESS);
if ServiceHandle = 0 then
RaiseException('SimpleChangeServiceConfig#OpenService: ' + AService + ' ' +
SysErrorMessage(DLLGetLastError));
try
sActions.aType1 := SC_ACTION_RESTART;
sActions.Delay1 := 60000; // First.nDelay: in milliseconds, MMC displayed in minutes
sActions.aType2 := SC_ACTION_RESTART;
sActions.Delay2 := 60000;
sActions.aType3 := SC_ACTION_RESTART;
sActions.Delay3 := 60000;
sfActions.dwResetPeriod := 1; // in seconds, MMC displayes in days
//sfActions.pRebootMsg := null; // reboot message unchanged
//sfActions.pCommand := null; // command line unchanged
sfActions.cActions := 3; // first, second and subsequent failures
sfActions.saActions := sActions;
if not ChangeServiceConfig2(
ServiceHandle, // handle to service
SERVICE_CONFIG_FAILURE_ACTIONS, // change: description
sfActions) // new description
then
RaiseException('SimpleChangeServiceConfig#ChangeServiceConfig2: ' + AService + ' ' +
SysErrorMessage(DLLGetLastError));
finally
if ServiceHandle <> 0 then
CloseServiceHandle(ServiceHandle);
end;
finally
if SCMHandle <> 0 then
CloseServiceHandle(SCMHandle);
end;
except
ShowExceptionMessage;
end;
end;
You have two problems in your script. Like Deanna suggested you have to use the var keyword in the declaration of the lpInfo parameter.
Also you need to change the TScAction type to an array with two elements.
Here is my script that you can include in your Inno Setup script.
const
SERVICE_CONFIG_DELAYED_AUTO_START_INFO = 3; //The lpInfo parameter is a pointer to a SERVICE_DELAYED_AUTO_START_INFO structure.
//Windows Server 2003 and Windows XP: This value is not supported.
SERVICE_CONFIG_DESCRIPTION = 1; //The lpInfo parameter is a pointer to a SERVICE_DESCRIPTION structure.
SERVICE_CONFIG_FAILURE_ACTIONS = 2; //The lpInfo parameter is a pointer to a SERVICE_FAILURE_ACTIONS structure.
//If the service controller handles the SC_ACTION_REBOOT action, the caller must have
// the SE_SHUTDOWN_NAME privilege. For more information, see Running with Special Privileges.
SERVICE_CONFIG_FAILURE_ACTIONS_FLAG = 4; //The lpInfo parameter is a pointer to a SERVICE_FAILURE_ACTIONS_FLAG structure.
//Windows Server 2003 and Windows XP: This value is not supported.
SERVICE_CONFIG_PREFERRED_NODE = 9; //The lpInfo parameter is a pointer to a SERVICE_PREFERRED_NODE_INFO structure.
//Windows Server 2008, Windows Vista, Windows Server 2003, and Windows XP: This value is not supported.
SERVICE_CONFIG_PRESHUTDOWN_INFO = 7; //The lpInfo parameter is a pointer to a SERVICE_PRESHUTDOWN_INFO structure.
//Windows Server 2003 and Windows XP: This value is not supported.
SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO = 6; //The lpInfo parameter is a pointer to a SERVICE_REQUIRED_PRIVILEGES_INFO structure.
//Windows Server 2003 and Windows XP: This value is not supported.
SERVICE_CONFIG_SERVICE_SID_INFO = 5; //The lpInfo parameter is a pointer to a SERVICE_SID_INFO structure.
SERVICE_CONFIG_TRIGGER_INFO = 8; //The lpInfo parameter is a pointer to a SERVICE_TRIGGER_INFO structure.
//This value is not supported by the ANSI version of ChangeServiceConfig2.
//Windows Server 2008, Windows Vista, Windows Server 2003, and Windows XP: This value is not supported until Windows Server 2008 R2.
SC_ACTION_NONE = 0; // No action.
SC_ACTION_REBOOT = 2; // Reboot the computer.
SC_ACTION_RESTART = 1; // Restart the service.
SC_ACTION_RUN_COMMAND = 3; // Run a command.
type
TScAction = record
aType1 : Longword;
Delay1 : Longword;
end;
type
TServiceFailureActionsA = record
dwResetPeriod : DWORD;
pRebootMsg : String;
pCommand : String;
cActions : DWORD;
saActions : array of TScAction;
end;
function ChangeServiceConfig2(
hService: Longword;
dwInfoLevel: Longword;
var lpInfo: TServiceFailureActionsA): BOOL;
external 'ChangeServiceConfig2A#advapi32.dll stdcall';
procedure SimpleChangeServiceConfig(AService: string);
var
SCMHandle: Longword;
ServiceHandle: Longword;
sfActions: TServiceFailureActionsA;
sActions: array of TScAction;
begin
SetArrayLength(sActions ,3);
try
SCMHandle := OpenSCManager('', '', SC_MANAGER_ALL_ACCESS);
if SCMHandle = 0 then
RaiseException('SimpleChangeServiceConfig#OpenSCManager: ' + AService + ' ' +
SysErrorMessage(DLLGetLastError));
try
ServiceHandle := OpenService(SCMHandle, AService, SERVICE_ALL_ACCESS);
if ServiceHandle = 0 then
RaiseException('SimpleChangeServiceConfig#OpenService: ' + AService + ' ' +
SysErrorMessage(DLLGetLastError));
try
sActions[0].aType1 := SC_ACTION_RESTART;
sActions[0].Delay1 := 60000; // First.nDelay: in milliseconds, MMC displayed in minutes
sActions[1].aType1 := SC_ACTION_RESTART;
sActions[1].Delay1 := 60000;
sActions[2].aType1 := SC_ACTION_NONE;
sActions[2].Delay1 := 60000;
sfActions.dwResetPeriod := 1; // in seconds, MMC displayes in days
//sfActions.pRebootMsg := null; // reboot message unchanged
//sfActions.pCommand := null; // command line unchanged
sfActions.cActions := 3; // first, second and subsequent failures
sfActions.saActions := sActions;
if not ChangeServiceConfig2(
ServiceHandle, // handle to service
SERVICE_CONFIG_FAILURE_ACTIONS, // change: description
sfActions) // new description
then
RaiseException('SimpleChangeServiceConfig#ChangeServiceConfig2: ' + AService + ' ' +
SysErrorMessage(DLLGetLastError));
finally
if ServiceHandle <> 0 then
CloseServiceHandle(ServiceHandle);
end;
finally
if SCMHandle <> 0 then
CloseServiceHandle(SCMHandle);
end;
except
ShowExceptionMessage;
end;
end;
Try using the var keyword in the declaration for the lpInfo parameter to specify that it's to pass a pointer to the structure to the function.