I have what seems like a simple need and that is for one thread to turn an LED on and another thread to turn it off. The output port is a variable and variables can't be read/write shared across threads which makes it impossible, I think, for two threads to use the same port in this way. The compiler errors out with "...violates parallel usage rules."
What is the typical approach used to deal with shared ports? Channels have two ends (at least in XC I can't have a multi-end-to-one-end channel, correct?), so I couldn't create another thread with a channel that could service two other threads.
How would you ever share a resource like a port between threads? Is it possible to do in XC without creating a new channel for each thread to talk to a single thread which has write access to the port?
Still cutting my teethe on XMOS, understand XMOS XC conventions for getting basic things done (and probably will be for months - TIA for your help),
Landon
Are shared output ports possible?
-
- Experienced Member
- Posts: 71
- Joined: Mon Sep 06, 2010 4:05 pm
-
- Respected Member
- Posts: 395
- Joined: Tue May 18, 2010 12:25 am
I think you do have to have multiple threads, a owner thread, and n amount of threads that need to control it. The owner would just have a channel to each, and listen on all of them.
-
- Experienced Member
- Posts: 71
- Joined: Mon Sep 06, 2010 4:05 pm
Ok, just to put a cap on this, I wrote this example which shows two threads sharing an LED port via a 3rd thread which is communicating with the first two threads via separate channels. thing1() is turning on the LED and thing2() is turning it off. led_manager() starts thing1 and thing2 with two different channels and then listens to both waiting for the first input of either, sets the input to 'led' and led is used to set the LED ports state.
Seems like there should be an easier way to do this simple thing, but maybe not. If so, feel free to suggest it - I would like to learn.
Seems like there should be an easier way to do this simple thing, but maybe not. If so, feel free to suggest it - I would like to learn.
Code: Select all
#include <xs1.h>
#include <platform.h>
// LEDs
#define IO_CORE 0
on stdcore[IO_CORE] : out port p_leds_3_0 = XS1_PORT_4F;
#define LED_DELAY 1000000
void thing1(chanend channel1)
{
timer t;
unsigned time;
while( 1 )
{
t :> time;
time += LED_DELAY;
t when timerafter(time) :> void;
channel1 <: 1; // on
}
}
void thing2(chanend channel2)
{
timer t;
unsigned time;
while( 1 )
{
t :> time;
time += LED_DELAY + 25000;
t when timerafter(time) :> void;
channel2 <: 0; // off
}
}
void led_manager()
{
int led;
chan chan1, chan2;
par {
thing1( chan1 );
thing2( chan2 );
while( 1 )
{
// listen to channel 1 and 2, modify LED
select {
case chan1 :> led :
break;
case chan2 :> led :
break;
}
p_leds_3_0 <: led; // gonna be a 0 or 1 - single LED
}
}
}
int main()
{
par
{
on stdcore[IO_CORE] : led_manager();
}
return 0;
}
-
- Respected Member
- Posts: 259
- Joined: Thu Sep 16, 2010 9:15 am
There is a way. You just do a simple assembler routine that outputs the value you want to the port. remember it is the compiler the one that complains :). But be aware of some nasty bugs you may introduce by using this technique a bit too liberally :)
-
- XCore Expert
- Posts: 754
- Joined: Thu Dec 10, 2009 6:56 pm
I think it will be fine if you use a lock around the code that deals with the port.ale500 wrote:There is a way. You just do a simple assembler routine that outputs the value you want to the port. remember it is the compiler the one that complains :). But be aware of some nasty bugs you may introduce by using this technique a bit too liberally :)
Possible issues are that two instructions accessing the same port from different threads are in the pipeline, a lock will prevent that. Second if you use events on the port and a different thread accesses the port, the event will be fired to the last thread that has accessed the port, so don't use events.