Intel® Makers
Intel® Edison, Intel® Joule™, Intel® Curie™, Intel® Galileo
Announcements
Welcome - This is a Peer-to-Peer Forum only. Intel has discontinued these products but you may find support from other customers on this Forum
9868 Discussions

Application Running On Powerup

idata
Community Manager
1,256 Views

How do I set an application to run automatically once the Edison is powered up?

0 Kudos
17 Replies
Matthias_H_Intel
Employee
217 Views

I think this has been discussed in this forum in other threads: you would want to write systemd service files

idata
Community Manager
217 Views

I got it up and running but the issue I'm having is network connections. It's kind of weird. The application I have sends a UDP announcement once it starts to run. When the Edison is connected to a client network everything seems to work find. But when I set the Edison up as an AP and connect to it via my laptop the UDP announcement packets are not transmitting. I started out with the service 'After' option set to 'network.target' and then tried 'network.open.target' and nothing seems to matter. What setting is needed for the software to run under AP conditions?

Matthias_H_Intel
Employee
217 Views

"problem" with network target: when is the network up?

After "network.target" doesn't mean you do have full internet access. And as systemd is by design deserialized you'll never know exactly the order service files will get started.

what you can do e.g. is to have your binary been restarted if it's not successful. You can schedule it for some sec later to give the network some time to fully start.

MMied
New Contributor III
217 Views

You can also try to replace "network.target" by "network.service". I do so on my Archlinux pc's and it works fine.

Matthias_H_Intel
Employee
217 Views

Good catch - however, AFAIK you still don't have a guarantee that the network is up to the extent you'd expect, e.g. you might not be able to ping an external ip right away but would have to wait till your network manager is done

idata
Community Manager
217 Views

What I'm looking for I guess is not so much the network being up, but the IP and all of that stuff being assigned. The software when launches will start broadcasting a UDP port, but of course it needs to open up the socket. For some reason it seems like when I connect to a client it is occurring fast enough to which the software has everything it needs to function properly. When it's setup as AP mode it seems like for some reason maybe the network settings haven't completed when the software starts to run. I've created a version of the software to check to see if it's successfully created a socket and to keep trying till it does all while logging the status. In both cases running as a AP or connected to a Client Network I get the same results so I'm not totally sure what is going on.

idata
Community Manager
217 Views

Is there a way to tell when the OS has successfully connected to a network, or setup a network? First off I would like to know this so that I could possibly turn an LED on to tell the users that when they setup the client network it worked and we are now on... Also I could use this as possibly a way to then launch my application.

PMart13
Valued Contributor II
217 Views

jblackston In following mhahn and mmi line of suggestions,

I might be inclined to include a loop (sudo-code below) that holds the rest of your routines in pattern until it has been successful

then you know your network is up and your code continues onward.

setup_upd_stuff {

desired_result = a_known_good_value

}

function attempt_ping() {

// attempt your ping

// catch any exceptions so program does not exit

return ping_result

}

pinged_successfully = false;

repeat

if (attempt_ping = desired_result) then

pinged_successfully = true;

until pinged_successfully;

... program continues on after success.

// checking if your IP has been assigned with System('ifconfig > ipcheck.log') --> check log created

AT9
Honored Contributor II
217 Views

Another one would be to try and see if there's any other systemd, more relevant to this context, service, to which you can set your service to depend upon. How exactly do you configure it in the AP mode?

PMart13
Valued Contributor II
217 Views

in mhahn's comment # 3, we can't truly depend that they execute and complete in sequence.

AT9
Honored Contributor II
217 Views

Well, that's true, but what's also true is that you can specify dependencies on other services and then we do have a guarantee one doesn't start earlier then the other.

So if there's a service, say timesyncd - which uses network - which is also needed for the application in question, in addition to the bare network service, then we could try setting the dependency to that service, not to the network one - that's what I'm trying to describe here.

idata
Community Manager
217 Views

Ok, I'll look into that and check try the timesyncd and see how that works out... I tried the step in deium's comment in my code but i found that it seemed to function the same when the software ran connecting to a client. It didn't seem to show that there was an IP failure in the log I generated for the application. This almost goes in the same idea of how do these embedded systems that run Linux turn on a LED to signify to the customer that it's successfully connected to a network (or created a AP).

PMart13
Valued Contributor II
217 Views

if that code was implemented properly, the code would be in a continuous loop until you had a successful ping, then continuing onward to your desired routine.

So if that wasn't the case, it wasn't coded correctly.

idata
Community Manager
217 Views

What am I suppose to setup the ping, because how do I get the software to know if the device is connecting to a client or AP? I would assume when I ping the IP address I'm pinging would depend which connection is taking place. Or am I miss understanding your idea of implementation?

PMart13
Valued Contributor II
217 Views

>> I tried the step in deium's comment in my code but i found that it seemed to function the same (implied as unsuccessful)

if you are looking for a network connection as a client, then once your network is up a ping would be successful -- I believe one of your desired results.

if you are looking for an access point setup, I am most certain unless you are attempting an island-isolated network, it too would be connected to a network able to ping the next hop to know that it too was up and running, the ping would be successful - again I believe one of your desired results.

if you were truly looking for an island-isolated network - I again believe that pinging "self" would show that a round trip would say the network layer is active - one of your desired results.

Since systemd doesn't guarantee the order in which your code is going to be launched, putting a loop in your code that holds your code in place until "your conditions" are satisfied and then continues, ensures that your precursors are met before running the rest of your code. Therefore, with you wanting your LED to light up to signal that they were connected, it would be definite that a ping could not occur before a connection, and a ping does one step better - not only has the network connection been made, but proves that data can be both sent and received. If your code had such a mechanism, it would not exclusively matter which order it was launched in since it holds until your conditions are met before lighting your LED.

I am seeing you say your program is prematurely starting before the network is up.

nless I am misunderstanding your implementation, you don't describe your network as an isolated server, so therefore the access point connects to it's next hop.

idata
Community Manager
217 Views

I can't completely give you the code because its using a library for most of the communication. I'm using IPWorks to handle communications., I'll try and post what I got, not sure how you can post/attach files in this forum.

What I'm doing is waiting for the "wlan0" interface to start up using the IPInfo class in the IPWorks library. After I register that the "wlan0" is finally up I continue on with the code. I've even gone as far as grabbed the interfaces IP address and set it up as a broadcast UDP address. Instead of 255.255.255.255 I convert the address of 10.0.1.4 to 10.0.1.255 to handle the UDP broadcasting.

I've also added output text so that while I'm checking to how many times I have to rechecking the interface. I've notice that of course if I'm running in AP mode it comes up right away, if its connecting to a client network it will take a few retries which would be expected. I'm not totally sure as to why UDP broadcast works when connected to the client and not in AP mode. I'm wondering if for some reason the broadcast is going thru one of the other interfaces and that's why I'm missing it. If I manually take down the other interfaces (usb0 & lo) it still doesn't work.

As far as launching the service. When referring to the service via the 'After' tag in the service file do you refer to the service file running, or the actually application that runs. So for your requirement of timesyncd would I set After to "/lib/systemd/systemd-timesyncd" or to "systemd-timesyncd.service"? I'm wondering because ever so often I'll get errors on bootup "[FAILED] Failed to start Load/Save RF Kill Switch Status of rfkill1." Even if my service isn't even setup to run. do you know what rfkill1 is?

PMart13
Valued Contributor II
217 Views

jblackston, rfkill is radio on/off control. While the radio is coming on it may block/ignore requests until it has powered up, or powered down. Fractions of a second off in the timing.

What we see in the threads, systemd is going to launch your service in a sequence after the systemd-timesyncd.service (with out without .service is the same from command-line, for the sake of non ambiguity, I'd include the .service extension inside the service files just to make sure), but this does not guarantee that timesyncd is going to have completed before your service launches. If this was a single core sequential programming, you wouldn't have to do anything else, yours in the next in line. However, this is multi-tasking on multiple cores, where on trial run to trial run, an execution thread can complete quicker or slower than usual because of many variables. when the network is concerned, hop to hop on a route could be taking longer just because the machine was busier than normal (such as the case where the timesyncd daemon is getting the time from google and attempting to adjust for latency differences in the hops).

A successful ping, or timesync becomes a good choice in that it shows to you that the network is up and usable, data has already been sent and received, your network has been proven good.

Now, your coding needs to take into consideration the exceptions in the real world. My suggestion was a loop that waited for a successful ping, there are 1000 other possible choices. If you had a power outage and your internet connection was down, you would get what I mean. So what control loops are you putting in your coding to compensate. When you program didn't see the desired result, you have to have some type of code that compensates -- some times call exception handling. As a pascal programmer my source block looks something like this.

function WaitForMyCondition : Boolean;

var

success : Boolean // a true of false variable type

attempt : integer; // counter variable

begin

attempt := 0; success := false; // initialize my counter and default success to false

repeat

try

// test My condition - which may or may not pass.

// if it fails before the success := true line, it will jump to the except block and success will equal false as before.

statements to test my condition

success := true; // if it made it this far, none of my conditions failed, then set success equal to true

except

on e:exception do // handle my exception - in this case I want to log my error

logError(e.message);

finally

if success = false then // put in a delay of 0.5 seconds before attempting the next attempt, but only if it failed

sleep(500);

end;

attempt := attempt + 1; // increase my counter

until (attempt >= 3) or (success = true); // repeat the statements until either successful or I have tried three times

WaitForMyCondition := success; // return my result

end;

Now, hopefully this gives ideas you can work with to catch the exceptions that are occurring, delay and attempt again before the main block of your program fails to execute. Think Rosetta and Philae. Philae (when awake of course) powers its radio for 2 minutes and attempts communications to Rosetta. If it makes it's connection, then it sends and receives whatever data it needs to - but if after 2 minutes it failed to connect, it powers its radio off for the next 28 minutes and will try again later. It looks like you might only need a few fractions to a few seconds.

Reply