[C.CC USERS] placed variables?

Patrick J.G.C. Weemeeuw pweemeeuw at telenet.be
Mon Aug 9 22:01:21 BST 2010


Hi Matt,

Thank you for your prompt and elaborate answer.

A bit of context. What I am aiming at, is a long running 64 bit TIMER variable. Perhaps to monitor the temperature and pump activation of the swimming pool. (If I 
ever will get that far, remains to be seen, as I tend to lose interest when the problem is 'theoretically solved'). This would be a long-running, stand alone 
process, and I want to keep a history of events for later downloading when I connect via the serial over USB. I want the timer to be correct, in the sense that it 
doesn't miss ticks, albeit that it is only updated every 'clockresolution' (in the code below) milliseconds. This gives not yet accurate time (because it will 
still depend on crystal accuracy, and drift with temperature changes), but at least it gives a base for reasonably good interpolation when connected with the 
host, which does have accurate time.

I can't solve that with channels, because I want this timer to be unsynchronized, and I want to access it from several places in the code, exactly like the TIMER 
process. I think that to achieve something like this, I have no choice but to bypass the regular occam mechanisms, and access memory directly. I had hoped that 
there was some kind of malloc, that could reserve some memory by decrementing the top of memory pointer, or something such that could safely allocate a chunk of 
memory.

[ I'm wondering: when interfacing with external libraries, there must be some mechanism to allocate static data structures in occam, but perhaps this is not 
supported on the arduino platform? ]

-- Patrick


On Mon, Aug 09, 2010 at 12:20:22PM -0400, Matt Jadud wrote:
> Hi Patrick,
> 
> On Mon, Aug 9, 2010 at 11:20 AM, Patrick J.G.C. Weemeeuw
> <pweemeeuw at telenet.be> wrote:
> > After playing a bit with occam on my arduino -- I like it very much -- I want to keep track of time for my measurements.
> 
> 
> >
> > I thought about something along the following lines:
> >
> > -----------------------------------------
> >
> > #INCLUDE "plumbing.module"
> >
> > VAL INT clockresolution IS #03E8: -- one tick every 1000 ms
> >
> > PROC timekeeper ()
> >  PLACED INT64 now: -- which address?
> >  TIMER tim:
> >  INT t:
> >  SEQ
> >    WHILE TRUE
> >      SEQ
> >        tim ? t
> >        -- maintain 'now' here, based on t and t's previous value
> >        serial.write.string(TX0, "time: ")
> >        serial.write.int(TX0, now)
> >        serial.write.newline(TX0)
> >        delay(clockresolution)
> > :
> 
> Good thinking. I'll try and get some pointers online to more resources
> shortly, which will help with timer exploration. This will output the
> time every now and then.
> 
> Another way to do this is the following:
> 
> TIMER tim:
> INT start, end:
> SEQ
>   tim ? start
>   .. do stuff ..
>   tim ? end
>   .. show difference between start and end (time is in ms)...
> 
> You could do that directly in your code, or you could wrap it up in a proc:
> 
> PROC timkeeper (CHAN SIGNAL gate?, CHAN INT diff!)
>   TIMER tim:
>   INT start, end:
>   WHILE TRUE
>     SEQ
>       gate ? SIGNAL
>       tim ? start
>       gate ? SIGNAL
>       tim ? end
>       diff ! (end - start)
> :
> 
> Admittedly, you'll get some comms/scheduling overhead in this, which
> may be undesirable. The overhead would be because timer reads are
> scheduling points, so things can happen in-between all of those
> communications. This is where the *soft* realtime nature of our
> implementation can bite you if you're not thinking about it. If you
> needed to get the current time without descheduling for performance
> reasons, we could talk about that.)
> 
> Not knowing more about what you're trying to time, that is about all I
> can say there.
> 
> > I have 2 questions:
> > - are placed variables supported in concurrency/plumbing (I'm still confusing the names)?
> 
> Yes. In fact, if you look in the platform-specific code, you'll see
> where we place the ports array. We have code that looks like this:
> 
> http://projects.cs.kent.ac.uk/projects/kroc/trac/browser/kroc/trunk/tvm/arduino/occam/include/arch/common/pin.module#L37
> 
> PLACED [MAX.PORT]BYTE ports 0:
> #PRAGMA DEFINED ports
> 
> I cannot remember, but it might be that we can only place arrays.
> Regardless, the code above places an array of bytes of length 512
> (MAX.PORT is defined elsewhere) starting at memory address zero. By
> placing the variable, we are not manipulating memory... but at the
> point that we write to it, we *are*. On the Arduino, we do this to
> access the registers of the AVR natively. (The #PRAGMA tells the
> compiler not to yell at us about the array being undefined; that's a
> dangerous thing to do in occam-pi, but when you're doing direct
> hardware programming, it's obvious that we sometimes have to get
> directly at registers.)
> 
> At this point, we can do things like the following:
> 
> ports[r.port] := (ports[r.port] /\ (~BV (bit))) \/ ((BYTE state) << bit)
> 
> where "r.port", "state", and "bit" are variables that were passed into
> the PROC.
> 
> ports[PORTB]
> 
> uses the symbolic constant PORTB (pulled directly from the C header
> file) to access into the correct location in memory on the AVR. When
> we are programming "natively" against the AVR, the code looks very,
> very similar to C... except we do it entirely by referencing into the
> PLACEd array.
> 
> Does that make sense? The constant files for the various chips are in
> the arch/ directory.
> 
> > - what address should I use in the variable declaration?
> 
> Well, that's up to you. I would not casually do direct memory
> manipulation. If what you're trying to do is manipulate AVR registers,
> then look at any of our code in arch/ for examples. If you're trying
> to pass values from one PROC to another, then use channels. There are
> no global variables in occam-pi, and if you try and force the issue
> with a placed value, you might:
> 
> 1. Put it directly into an AVR register, causing a crash.
> 2. Put it directly into memory statically allocated to the VM, causing a crash.
> 3. Put it directly into memory statically allocated to your program,
> causing a crash.
> 4. Find a bit of unused RAM, and get lucky.
> 
> :)
> 
> Up to you. Feel free to ask more questions/say more about what you're
> trying to achieve if that didn't help.
> 
> (I'll be getting up to speed on fixing some things and getting
> resources on-line -- my day job of being a professor is kicking into
> gear at this point...)
> 
> Cheers,
> Matt




More information about the users mailing list