EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  <20152016  2017  2018  2019  2020  2021  2022  2023  2024  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  <20152016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: epics on ios
From: "Mezger Anton Christian (PSI)" <[email protected]>
To: "Pelaia II, Tom" <[email protected]>
Cc: "'[email protected]'" <[email protected]>
Date: Fri, 20 Feb 2015 10:48:32 +0000
Dear Tom,

I could finally solve my problem. Everything was correct except a very simple stupid problem. I had a flushio called periodically, even when nothing had to be flushed. In this case a default context is created by EPICS, which prevent my recreating a context as preemptive. This happened while many different threads are used.

The way you did the things, persuaded me to stay on the problem. Thank you very much.

Best regards

Anton

-----Original Message-----
From: Pelaia II, Tom [mailto:[email protected]] 
Sent: Dienstag, 17. Februar 2015 17:23
To: Mezger Anton Christian (PSI)
Subject: Re: epics problem on ios

Hi Anton,

I have success closing channels upon entering background and connecting them upon entering foreground. I don't experience the issue you are having. However, based on what you said, I don't see a problem with what you are doing. Below I've posted relevant code that hopefully may help. The full code is available on Source Forge at ( http://sourceforge.net/projects/capod/ ), but Source Forge is currently offline now.

In my app delegate, I have the following relevant code:

// handle the event of the application entering the background
- (void)applicationDidEnterBackground:(UIApplication *)application {
    [_managedObjectContext save:nil];
    self.channelOpenBeforeBackground = self.probeModel.active;      // record whether channel access was active prior to entering background
    [_probeModel closeChannelAccess];
}


// application has resumed from being in the background
- (void)applicationWillEnterForeground:(UIApplication *)application {
    if ( self.channelOpenBeforeBackground )  [self.probeModel openChannelAccess]; }

I also create the channel access context upon entering the foreground and destroy it upon entering the background.

My Probe Model code has the following relevant code:

- (void)openChannelAccess {
    if ( !self.active ) {
        // construct the address list
        [self setupAddressList];



        // create a new CA context
        [ChannelAccessContext prepare];



        // startup the channels
        NSArray *channels = [self.managedObjectContext executeFetchRequest:self.channelFetchRequest error:nil];
        for ( ProbeChannel *channel in channels ) {
            [self monitorChannel:channel];
        }



        [ChannelAccessChannel flushIO];



        self.active = YES;
    }
}


- (void)closeChannelAccess {
    if ( self.active ) {    // check whether there is anything to close
        self.active = NO;



        // shutdown the channels
        NSArray *channels = [self.managedObjectContext executeFetchRequest:self.channelFetchRequest error:nil];
        for ( ProbeChannel *channel in channels ) {
            [channel removeObserver:self forKeyPath:@"latestRecord"];
            [channel destroyProbe];
        }
        [ChannelAccessChannel flushIO];



        // destroy the current CA context
        [ChannelAccessContext destroy];
    }
}


- (void)setupAddressList {
    NSArray *channelAddresses = [self.managedObjectContext executeFetchRequest:self.addressFetchRequest error:nil];
    NSString *addressList = [ChannelAddress channelAddressList:channelAddresses];
[ChannelAccessContext setAddressList:addressList]; }


My Channel Access Context

+ (void)prepare {
// create a new context if one does not already exist if ( !ca_current_context() ) { ca_context_create( ca_enable_preemptive_callback ); } }


+ (void)destroy {
if ( ca_current_context() ) {
ca_context_destroy();
}
}


// get the space delimitted string of channel addresses
+ (NSString *)addressList {
return @( getenv( CA_ADDRESS_LIST_ENVIRONMENT_LABEL ) ); }


// set the space delimitted string of channel addresses
+ (void)setAddressList:(NSString *)addressList {
// work with an immutable copy of the passed address list in case the passed string is mutable and changes NSString *localAddressList = [addressList copy];


char * autoAddr = localAddressList != nil && [localAddressList length] > 0 ? "NO" : "YES"; setenv( "EPICS_CA_AUTO_ADDR_LIST", autoAddr, 1 );

if ( localAddressList != nil && [localAddressList length] > 0 ) { NSUInteger bufferSize = ( [localAddressList length] + 1 ) * sizeof( char ); char *buffer = (char *)malloc( bufferSize ); [localAddressList getCString:buffer maxLength:bufferSize encoding:[NSString defaultCStringEncoding]]; setenv( CA_ADDRESS_LIST_ENVIRONMENT_LABEL, buffer, 1 ); free( buffer ); } else { unsetenv( CA_ADDRESS_LIST_ENVIRONMENT_LABEL ); } }



Best regards,
Tom
_____________________________________________________________________________________
Thomas Pelaia II, Ph.D.  | Applications Leader, Accelerator Physics, Research Accelerator Division Spallation Neutron Source  |  Oak Ridge National Lab, Building 8600, MS-6462, Oak Ridge, TN 37831
phone: (865) 414-7960  | FaceTime: [email protected]<mailto:[email protected]> |  fax: (865) 574-6617  |  homepage: http://www.ornl.gov/~t6p

On Feb 14, 2015, at 6:50 AM, Mezger Anton Christian (PSI) <[email protected]<mailto:[email protected]>> wrote:

Dear Tom,

I made some tries.

when the application goes into the background and comes to the foreground again, I do not need to do anything, The channels stay connected (on Ipad, not on Iphone). However when the application goes in suspended mode, the socket gets closed.

In order to come around this, I delete all the channels and close the context. Afterwards I create the context again. This does not work, while I get the error message that preemptive callback can not be enabled. When creating then the channels, I get no connections.

How did you solve that? It seems to me that in an application it is not best to create a context, delete it and create it again with preemptive callback.

I hope you have a solution !

best regards

Anton



Navigate by Date:
Prev: Re: Read record field in asynDriver Ralph Lange
Next: RRM offline? Benjamin Franksen
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  <20152016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: epics on ios Mezger Anton Christian (PSI)
Next: medm3.1.8 linker problem yann stephen
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  <20152016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 16 Dec 2015 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·