View Full Version : Read-Write Synchronisation in SIOC
aVaTar
10-19-2011, 10:38 AM
Hi all, I've been playing around with SIOC, so far so good. Basic functionality is ok.
What I now have a problem with - is synchronization between reads and writes.
Imagine MCP V/S indicator value(has read offset and write offset), and the corresponding encoder to change Write Offset.
Now whenever encoder changes, all is simple - we write at the Write Offset and eventually Read Offset reflects the change and the display picks it up.
So the flow is like so:
{Encoder Routine} -> Write Offset -> {Whatever FS, FSUIPC does} -> Read Offset -> {Read Offset Change Routine} -> Display...
When however the variable change internally, only Read Offset changes value. So in my case I click V/S Button the V/S Speed gets current vertical speed value and the change is reflected in the Read Offset of course, so I can see the right value on the screen. If I now turn the encoder, the value resets to whatever Write Offset holds, which makes sense, but is not right.
I can see at least one ugly solution, with temporary variable telling us if Write Offset has been recently changed. There could be other variations on that theme as well but these are not elegant.
Anyone tackled that problem before?
Cheers,
Vadim
Hi Vadim,
Anyone tackled that problem before?
Yes of course.
As an example a generic SIOC script for the CRS part of a NAV1 radio (from my HowTo page). Works for most add-ons:
Var 1 name FI_Crs Link FSUIPC_IN Offset $0C4E Length 2
{
&Crs = &FI_Crs
}
Var 2 name Crs
{
&D_Crs = &Crs
}
Var 3 name RO_Crs Link IOCARD_ENCODER Input 61 Aceleration 4 Type 2
{
L0 = &RO_Crs
&Crs = ROTATE 0 359 L0
&FO_Crs = &Crs
}
Var 4 name D_Crs Link IOCARD_DISPLAY Digit 25 Numbers 3
Var 5 name FO_Crs Link FSUIPC_OUT Offset $0C4E Length 2
kind regards,
Nico
aVaTar
10-19-2011, 07:33 PM
Hi Vadim,
Yes of course.
Thought as much :p.
Ok, I think that's a neater solution than what I though of initially.
Just to re-state it in words if anyone finds this post, use a temporary variable to hold the state, it changes in response to Read Only Offset changing value and us changing the value manually...
I was trying to avoid creating a 3rd variable besides Read Only and Write Only. But I guess its unavoidable :)
I'll give it a go later, thanks heaps Nico!
Hi,
I was trying to avoid creating a 3rd variable besides Read Only and Write Only. But I guess its unavoidable :)
The Crs variable is "not unavoidable" but by design :=) A rotary always needs a value to act upon and to keep the value between turns. Even if you did not need read/write synchronisation you would need the Crs variable.
We can further reduce the number of variables by using a FSUIPC_INOUT variable:
Var 1 name X_Crs Link FSUIPC_INOUT Offset $0C4E Length 2
{
&Crs = &X_Crs
}
Var 2 name Crs
{
&D_Crs = &Crs
}
Var 3 name RO_Crs Link IOCARD_ENCODER Input 61 Aceleration 4 Type 2
{
L0 = &RO_Crs
&Crs = ROTATE 0 359 L0
&X_Crs = &Crs
}
Var 4 name D_Crs Link IOCARD_DISPLAY Digit 25 Numbers 3
But the code in my previous post better illustrates the flow of information for the readers of this forum, imho.
Have Fun coding in SIOC!
Cheesr,
Nico
aVaTar
10-20-2011, 02:39 AM
Hi,
The Crs variable is "not unavoidable" but by design :=) A rotary always needs a value to act upon and to keep the value between turns. Even if you did not need read/write synchronisation you would need the Crs variable.
Well, for that I used the Write Offset variable, so that I don't have to keep same value twice, minimizing maintenance(I work as a software engineer :) )
But in this case we specifically want to keep the value locally and not in FSUIPC memory:
// Rotate local copy
&Crs = ROTATE 0 359 L0
// Write local copy into FSUIPC address space
&FO_Crs = &Crs
Whereas I was doing this:
// Write into FSUIPC address space
&FO_Crs = ROTATE 0 359 L0
Basically, in my code I made an assumption that the no one will change "my(not)" variable. Once that assumption is not fulfilled, the code has to be modified the way you showed.
(I work as a software engineer :) )
Then you should know that you have to write code such that is is easy to understand by human readers of your code, and not to make difficult to understand optimisations ;-)
Using FO_Crs in the ROTATE statement is not a good approach because you also have to write to the Display. It is better to centralise the writing to the Display in the code attached to the Crs variable (especially if you want further enhancements such as cold and dark support, and you will, I can tell you ;-)).
Nico
aVaTar
10-20-2011, 03:15 AM
Using FO_Crs in the ROTATE statement is not a good approach because you also have to write to the Display
That's actually not a problem here, because display simply tracks any changes to the Read Only variable.
But don't worry Nico, I weren't prematurely optimizing :) but rather trying to keep it as simple as it can be without bastardizing good design.
And actually having 3 variables (Read, Write and Temp) as a design principle is not good(to put it mildly!). But yet again we can't control that and those offsets are in another process' memory so I'm thankful we have at least that way to "intrude" on FS memory spaces and change things around.
So, given the solution we have to work with (FSUIPC) and SIOC, I totally agree with you. As usual every system has it's quirks :)
Also thanks for information on your website, I particular liked using subroutines for hardware output. That's a nice design pattern.
Also thanks for information on your website, I particular liked using subroutines for hardware output. That's a nice design pattern.
Thank you!
I am a fan of the KISS principle too, but the requirements of Read/Write synchronisation are such that I cannot make it more simpler than with a Read/Write variable in the FSUIPC space and a local variable for Display and Manual changes.
Note that Read/Write synchronisation is for some offsets more than synchronising with the 'start-up value' in FlightSimulator (FSUIPC space). The VS offset for instance also changes during a flight. As soon as the VS window opens you have to synchronise with it in your hardware. My 'design pattern' takes care of that.
But like we say in Europe: "There are many ways leading to Rome..."
Nico
I want to add one insight here...
I use project magenta software and for the encoders in the FCU I had the issue that using a code proposed by Niko Kaan
didnt work. When I turned the encoder slowly then it worked flawless but turning faster caused the value to start to
jumo.
The reason is that the encoder script is using the value to increment it but the value coming back from the fcu in the
read cycle comes a little later and the value jumps back.
I have overcome this by blocking the FSUIPC_IN value from updating the local value for the encoder during half a second
with a timer. So as long as i am turning the rotary the FSUIPC_IN value is blocked but when I stop turning it the updates
are allowed again.
This made a very stable encoder update ans is running for two years already.
Greetz Peter
aVaTar
10-20-2011, 04:06 AM
Ehh.... hold on.. that's the problem I'm trying to solve :) And that's the ugly solution I was thinking about...
I must admit I haven't tried modifying the code yet, but tracing through the proposed code again I don't see how intermediate variable helps...
I'm definitely confused now :D
Yes, actually Nico, in your code what happens is that you have concurrent unsynchronized changed to &Crs variable(which is temp variable).
I coded to write directly to Write Offset variable, but the principle is the same, we have concurrent changes to the variable that gotta be synchronized.
Hi guys,
Peter is right. However, you can minimize the effect (and almost let it disappear) by increasing the update frequency of FSUIPC offsets in sioc.ini, but it may still happen although I have not noticed it in this CRS example, which I use in my sim for say 6 years now ...
Maybe Project Magenta is causing an extra delay ?
The R/W variables (in SIOC) representing MCP Heading, VS, Altitude and so on, provided by my lekseecon program do not suffer from this. In lekseecon I take care of that by doing exactly what Peter proposes, keeping one channel 'silent' if the other channel is in use and vice versa (so both ways).
Nico
Hi all,
indeed project magenta is slower then fs addons. The reason is simple, fcu is running outside of FS process so a takswitch
is needed to let fcu do its job. Also I think fcu will not read the fsuipc offsets so fast.
I had this problem always with PM.
To give another hint. I helped out someone using jeehell software and that person send email to the designer. he answered that his software will read fsuipc every 200ms. So this shows also that in this case also this problem will appear.
No use to decrease SIOC fsuipc access times.
Better to keep quiet one channel when turning the encoder.
Greetz Peter
Hi Peter,
I agree with you in general, but I looks like the R/W FSUIPC offsets provided by Pete Dowson do not suffer from this. Maybe Pete also takes care of keeping one channel silent in his software?
(because my CRS example works like a charm...)
Cheers,
Nico
P.S. Are you going to Lelystad november 5th? Would be nice to meet again.
yes of course I will attend at lelystad. Cant miss that ... its the highlight of the year for me... i am counting the days
if i can make it I would like to go on saturday 5th, will depend on my wife work schedule.
if not it will be sunday. I will ask again my wife tonight to push them to give the schedule early so I can plan.
greetz Peter