How can I tell if the NXT is on the Main Menu screen?

This is where you talk about the NXJ software itself, installation issues, and programming talk.

Moderators: roger, 99jonathan, imaqine

How can I tell if the NXT is on the Main Menu screen?

Postby clintonb » Thu Jan 03, 2013 4:03 pm

Is there any way to know if the main menu program is running on the NXT, when it is running leJOS 0.9.1?

The most obvious ways to determine this is to use the getCurrentProgramName() or stopProgram() APIs of NXTCommand, but neither are implemented when running leJOS on the NXT. (I don't suppose I could subclass something and provide an implementation for when my program is running, could I? That would solve my problem nicely.)

Why do I want to know this?

When a user uses Enchanting and decides to tells it to upload and run a new program, it needs to be on the Main Menu before it does this. If I upload a program named 'foo' while a previous version of 'foo' is already running, the NXT locks up with an error screen, and I have to take the batteries out. [I can type up the information on the screen if you'd like.] [Also note that it isn't clear to me that this happens 100% of the time, but it happens much of the time.] So, I've implemented a message that I can send to an Enchanting program on the NXT to tell it to stop. However, under Windows, if I send this message, and it is the Main Menu running instead of 'foo', I get an error screen -- one that I can cancel out of, but it causes problems for the end user. [I can type this one up, too, if you'd like.]

To work around this as best I can, I keep track of the state; I assume that when an NXT is connected to the computer (typically by plugging in a usb cable), that the Main Menu is running, and that if the computer starts a program, it is still running, unless the computer asked it to stop. Unfortunately, when testing a program that drives a robot around, a user will unplug the cable, test it, and plug the NXT back in, with the program running. Then, when they go to upload a newer version, the NXT locks up and they have to take the batteries out. Clearly, this is brittle and not a great solution. So, is there a way I can query the NXT to know that things are safe to upload and run a program, or to force it into a known state whereby I can do this?

Thank you,
Clinton Blackmore
clintonb
Active User
 
Posts: 82
Joined: Fri May 28, 2010 1:44 am
Location: Cardston, Alberta, Canada

Re: How can I tell if the NXT is on the Main Menu screen?

Postby skoehler » Thu Jan 03, 2013 7:06 pm

When I checked the implementation of the functions that allow you to receive messages from the NXT, I made sure that startupmenu of the NXT responds with some error code that indicates that no program is running.
Furthermore, the function to read messages from the NXT throws an LCPException when no proram is running but it returns null if the message Queue is empty. LCPExceptions are also thrown in other cases, but an LCPException has a method for retrieving the exact error code, so that you tell whether it's the error code for "no program is running" or something else. So in case, your program runs an LCP responder, it should be possible for you to tell whether the NXT is running a program or not.

Unfortunately, all of the above may only apply if you're using a snapshot.

Of course, it would also be nice if getCurrentProgramName() would work. But unfortunately, this hasn't been fixed yet.
skoehler
leJOS Team Member
 
Posts: 1115
Joined: Thu Oct 30, 2008 4:54 pm

Re: How can I tell if the NXT is on the Main Menu screen?

Postby clintonb » Thu Jan 03, 2013 8:42 pm

Thank you, Sven.

I'll try doing what you've mentioned, and integrate the newest snapshot if I must.

Cheers,
Clinton
clintonb
Active User
 
Posts: 82
Joined: Fri May 28, 2010 1:44 am
Location: Cardston, Alberta, Canada

Re: How can I tell if the NXT is on the Main Menu screen?

Postby clintonb » Fri Jan 04, 2013 5:07 am

Hello again,

I've tried using my understanding of what you are suggesting, and am not able to tell the Main Menu apart from another program, even using the latest snapshot. What I understood from your reply is that when I am performing a read command (such as NXTCommand messageRead()), I should get an error code from the Main Menu, but not from a running program. (It is altogether possible that I misunderstood).

What I find instead is that I get the LCPExcption "protocol error" when there is no data to be read, with the snapshot, and, with leJOS 0.9.1, I get a message length of 0 and no exception. For a given version of leJOS, I get the same output regardless of if the NXT is running my program or the Main Menu.

Here is my test application, MainMenuProbe.java:

Code: Select all
import java.io.*;
import lejos.nxt.remote.*;
import lejos.pc.comm.*;

// The purpose of this application is to determine if the Main Menu application is running.

public class MainMenuProbe {

   private String nxtname = "";
   private String address = "";
   private int protocols = NXTCommFactory.USB; // | NXTCommFactory.BLUETOOTH;
   private NXTCommand nxtcommand;                   
   private NXTConnector nxtconnector = new NXTConnector();

   public void delay(int ms) {
      try {
         Thread.sleep(500);     
      } catch (InterruptedException e) {
         // we are unlikely to be interrupted
         throw new RuntimeException(e);
      }   
   }

   MainMenuProbe() {
      while (true) {
     
         // Connect to an NXT
         boolean connected = false;
         System.out.print("Connecting");
         while (!connected) {
            delay(500);
            System.out.print(".");
           
            try {
               connected = nxtconnector.connectTo(nxtname, address, protocols);
            } catch (java.lang.RuntimeException e) {
               System.out.println("\nRuntimeException occurred while trying to connect to NXT: " + e.getMessage());
            }
         }
         System.out.println(" Connected.");
                 
         nxtcommand = new NXTCommand(nxtconnector.getNXTComm());
         try {
            System.out.println(" Connected to NXT running v" + nxtcommand.getNXJFirmwareVersion());
         } catch (IOException e) { }
         
         // Communicate with the NXT until we are disconnected
         try {
            System.out.print("Reading data: ");
            while (true) {
               byte [] message;
               try {
                  message = nxtcommand.messageRead((byte) 0, (byte) 0, true);
               } catch (LCPException e) {
                  if (e.getMessage() == "protocol error") {
                     System.out.println("No data ready.");
                     delay(500);
                     continue;
                  } else {
                     throw e;
                  }
               }
               
              System.out.printf("%d, ", message.length);
              delay(500);   
            }
         } catch (IOException e) {
            System.out.println("\nIOException occurred while reading messages: " + e.getMessage());
         }
         System.out.println("\nDisconnected.");
         try {
            nxtcommand.disconnect();
            nxtconnector.close();
         } catch (IOException e) {}
      }
   }

   public static void main(String[] args) {
      new MainMenuProbe();
   }
}


I compile and run it thusly:
Code: Select all
nxjpcc MainMenuProbe.java && nxjpc MainMenuProbe


Here are the results, using the latest snapshot, connecting to the NXT running the Main Menu, and then disconnecting, after a while:

Connecting..................................Found NXT: NXT 00165313C275
Connected.
Connected to NXT running v0.9.1(6817)
Reading data: No data ready.
No data ready.
No data ready.
No data ready.
No data ready.
No data ready.
No data ready.
No data ready.

IOException occurred while reading messages: Error in write: -1073807194

Disconnected.
Connecting.
RuntimeException occurred while trying to connect to NXT: already connected
.
RuntimeException occurred while trying to connect to NXT: already connected
.


and when connecting to an Enchanting application running on the NXT:

Connecting.......Found NXT: NXT 00165313C275
Connected.
Connected to NXT running v0.9.1(6817)
Reading data: No data ready.
No data ready.
No data ready.
No data ready.
No data ready.
No data ready.
No data ready.
No data ready.
No data ready.
No data ready.
No data ready.
No data ready.
No data ready.

IOException occurred while reading messages: Error in write: -1073807194

Disconnected.
Connecting.
RuntimeException occurred while trying to connect to NXT: already connected
.
RuntimeException occurred while trying to connect to NXT: already connected
.



Here are the results when using leJOS 0.9.1 (well, it is slightly modified, but much closer to 0.9.1), and connecting to the main menu:

Connecting..........Found NXT: NXT 00165313C275
Connected.
Connected to NXT running v0.9.1(6595)
Reading data: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
IOException occurred while reading messages: Error in write

Disconnected.
Connecting.
RuntimeException occurred while trying to connect to NXT: already connected
.
RuntimeException occurred while trying to connect to NXT: already connected
.


and when connecting to an Enchanting application on the NXT:

Connecting............Found NXT: NXT 00165313C275
Connected.
Connected to NXT running v0.9.1(6595)
Reading data: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
IOException occurred while reading messages: Error in write

Disconnected.
Connecting.
RuntimeException occurred while trying to connect to NXT: already connected
.
RuntimeException occurred while trying to connect to NXT: already connected
.



I'm afraid I don't see any difference between connecting to the Main Menu or to my application.

Cheers,
Clinton
clintonb
Active User
 
Posts: 82
Joined: Fri May 28, 2010 1:44 am
Location: Cardston, Alberta, Canada

Re: How can I tell if the NXT is on the Main Menu screen?

Postby gloomyandy » Fri Jan 04, 2013 12:17 pm

What exactly does a user program running on the NXT do? Does it always have some sort of LCP responder running as part of it?

Also you mentioned that you had a crash that required the batteries to be removed from the NXT to restart it. Does this mean that the display was showing some form of Data Abort? If so this should never really happen. Can you reproduce this with the latest snapshot?
User avatar
gloomyandy
leJOS Team Member
 
Posts: 3004
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Re: How can I tell if the NXT is on the Main Menu screen?

Postby clintonb » Fri Jan 04, 2013 3:26 pm

gloomyandy wrote:What exactly does a user program running on the NXT do? Does it always have some sort of LCP responder running as part of it?


Hi Andy.

Yes, the end-user program is always running an LCP responder. I write messages to it from the computer, and read messages from it. [At some point, I'd like to switch to using sockets (?) instead of message reads and writes, but this is how it works now.] The messages tell it if a variable has changed and allow for a message to be broadcast between threads or devices.

gloomyandy wrote:Also you mentioned that you had a crash that required the batteries to be removed from the NXT to restart it. Does this mean that the display was showing some form of Data Abort? If so this should never really happen. Can you reproduce this with the latest snapshot?


It took a few tries, but I was able to reproduce it with the latest snapshot (firmware version 0.9.1(6817)).

Data abort
PC 0010870C
AASR 04020400
ASR 00020201
OPCODE ???
DEBUG1 00000000
DEBUG2 00000000


I suspect reproducing it is as simple as:

- run program 'foo' on the NXT.
- upload a new version of 'foo' to the NXT.
- send an LCP message to tell 'foo' to run.

Perhaps running "nxjupload -r somefile.nxj", waiting a few moments, and running it again, would reproduce it. (Sorry, I haven't tried that exact step.) It could be that the LCP connection I establish between the computer and NXT has some effect.

Cheers,
Clinton
clintonb
Active User
 
Posts: 82
Joined: Fri May 28, 2010 1:44 am
Location: Cardston, Alberta, Canada

Re: How can I tell if the NXT is on the Main Menu screen?

Postby clintonb » Fri Jan 04, 2013 3:35 pm

I'm going to try to create a custom Startup application; if it can listen for and respond to messages, and allow me to define new messages, such as one to query if the menu or an Enchanting application is running, then I'll be in good stead!
clintonb
Active User
 
Posts: 82
Joined: Fri May 28, 2010 1:44 am
Location: Cardston, Alberta, Canada

Re: How can I tell if the NXT is on the Main Menu screen?

Postby gloomyandy » Fri Jan 04, 2013 5:38 pm

Hi,
I assume in this case that foo must have an LCP responder as part of it? I can imagine this would be bad as you are in effect potentially over-writing the currently running program with the new one, the file system used by leJOS is very simple and does not really deal with these sorts of issues. What happens if instead of foo you upload and run foo2?

Andy
User avatar
gloomyandy
leJOS Team Member
 
Posts: 3004
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Re: How can I tell if the NXT is on the Main Menu screen?

Postby skoehler » Fri Jan 04, 2013 5:46 pm

clintonb wrote:- run program 'foo' on the NXT.
- upload a new version of 'foo' to the NXT.
- send an LCP message to tell 'foo' to run.


This is definitely bad. You are effectively overwriting the program code of foo WHILE it is being executed. This has to crash. You should tell your program to terminate. Then wait until the menu is running again. Then upload a new version of foo.

Note, that the suggestion by Andy will also not work. As the filesystem is so simple, we have to defragment it after or before each upload. I don't remember exactly, but I can look that up if you want. A defragmentation of the filesystem would mean, that the file foo is moves around in the flash, WHILE it is being executed, but the firmware is never informed about the relocation of foo. Hence, this will crash too. Maybe not everytime. But sometimes.

The menu is the only java program, that can safely defrag the filesystem and accept file uploads etc., as it is stored outside the filesystem.
skoehler
leJOS Team Member
 
Posts: 1115
Joined: Thu Oct 30, 2008 4:54 pm

Re: How can I tell if the NXT is on the Main Menu screen?

Postby clintonb » Fri Jan 04, 2013 5:58 pm

gloomyandy wrote:Hi,
I assume in this case that foo must have an LCP responder as part of it?


Well, unless I use some other method to communicate between the PC and the NXT, yes.

gloomyandy wrote:I can imagine this would be bad as you are in effect potentially over-writing the currently running program with the new one, the file system used by leJOS is very simple and does not really deal with these sorts of issues. What happens if instead of foo you upload and run foo2?

Andy


Yes, I do not expect to be able to overwrite a program while it is executing and not have a problem! I never thought of uploading the next version as foo2. That's a clever idea.

However, I'm concerned about there being enough space. I'd rather delete the 'foo' and then upload 'foo' (or 'foo2'), because, with some image and sound assets, there may not be room for a new foo on the NXT.
clintonb
Active User
 
Posts: 82
Joined: Fri May 28, 2010 1:44 am
Location: Cardston, Alberta, Canada

Re: How can I tell if the NXT is on the Main Menu screen?

Postby clintonb » Fri Jan 04, 2013 6:09 pm

skoehler wrote:This is definitely bad. You are effectively overwriting the program code of foo WHILE it is being executed. This has to crash. You should tell your program to terminate. Then wait until the menu is running again. Then upload a new version of foo.


There is no question that this is bad. I expect it to crash, frankly. I want to wait until the menu is running, which prompted the question -- how can I tell if the menu is running? [As I tried to explain, I'm not sure if the program is running or not when someone connect the PC to the NXT, and when I send a quit message to the stock Main Menu [from a Windows PC] users get an exception on the NXT. If I assume that the menu is running when someone plugs in an NXT, and thus don't send a stop command as I don't want an exception on the NXT, and it turns out I'm wrong and 'foo' is running, then I try to upload on top of it and get a data abort.]

skoehler wrote:Note, that the suggestion by Andy will also not work. As the filesystem is so simple, we have to defragment it after or before each upload. I don't remember exactly, but I can look that up if you want. A defragmentation of the filesystem would mean, that the file foo is moves around in the flash, WHILE it is being executed, but the firmware is never informed about the relocation of foo. Hence, this will crash too. Maybe not everytime. But sometimes.


Ouch! (No, I don't think I need you to look that up, but it is good to know!)

skoehler wrote:The menu is the only java program, that can safely defrag the filesystem and accept file uploads etc., as it is not stores inside the filesystem.


Ah.

My current plan of attack is to create a modified Main Menu application that accepts my 'quit the running program' message without throwing an exception, and, possibly, responds to a 'are you the main menu' query of some sort. Thus, I can always execute a 'quit' command, check for the menu, and now I'm in a good state.

Are there timing conditions I should be wary of? What happens if 'foo' is in the process of quitting, or the NXT is resetting, and I send a message to it? (Is there a short, safe, wait interval?) I'm hoping my PC program copes with this as-is, and I suppose testing is the only way to know, but you might have some idea.

Cheers,
Clinton
clintonb
Active User
 
Posts: 82
Joined: Fri May 28, 2010 1:44 am
Location: Cardston, Alberta, Canada

Re: How can I tell if the NXT is on the Main Menu screen?

Postby skoehler » Fri Jan 04, 2013 6:21 pm

clintonb wrote:My current plan of attack is to create a modified Main Menu application that accepts my 'quit the running program' message without throwing an exception, and, possibly, responds to a 'are you the main menu' query of some sort. Thus, I can always execute a 'quit' command, check for the menu, and now I'm in a good state.


Your program has to accept the "quit the running program" message. When your program runs, the main menu does not run and vice versa.
I admit, checking whether the menu is currently running is a problem. I have to look at the LCPResponder to get that fixed.

clintonb wrote:Are there timing conditions I should be wary of? What happens if 'foo' is in the process of quitting, or the NXT is resetting, and I send a message to it?


Yes, there are. When program foo quits, you have to wait a little bit before sending the next LCP command. Otherwise, the command is lost and you will wait for a reply forever - well I think there is a 20 seconds timeout.
I believe, it would be a good idea to let program foo turn of USB when it terminates. This way, the PC will not try to reuse the current connection to talk to the main menu. However, on windows, you will get the "ding dong" sound.

Unfortunately, the hand-over of the USB connection between programs and the main menu is not quite as elegant as it could be. I am aware of some of the problems and I have been thinking about proper solutions. But it's complicated.
skoehler
leJOS Team Member
 
Posts: 1115
Joined: Thu Oct 30, 2008 4:54 pm

Re: How can I tell if the NXT is on the Main Menu screen?

Postby clintonb » Sun Jan 06, 2013 3:41 am

I have come to a solution slightly different than replacing the main menu application, by subclassing LCPResponder, similar to the way it is done in the main menu application, StartUpText.java.

Code: Select all
public class CustomLCPResponder extends LCPResponder {

   public CustomLCPResponder(NXTCommConnector connector) {
      super(connector);
   }
   
   protected int command(byte[] inMsg, int len, byte[] reply) {
      int return_value = super.command(inMsg, len, reply);
      if (inMsg[1] == LCP.STOP_PROGRAM) {
         reply[2] = 0;   // == command ran successfully
      }
      return return_value;
   }
   
   protected void postCommand(byte[] inMsg, int inLen, byte[] replyMsg, int replyLen)
   {
      super.postCommand(inMsg, inLen, replyMsg, replyLen);
      if (inMsg[1] == LCP.STOP_PROGRAM) {
         System.exit(0);
      }
   }
}


and:

Code: Select all
LCPResponder bt = new CustomLCPResponder(Bluetooth.getConnector());
LCPResponder usb = new CustomLCPResponder(USB.getConnector());


instead of:

Code: Select all
LCPResponder bt = new LCPResponder(Bluetooth.getConnector());
LCPResponder usb = new LCPResponder(USB.getConnector());


allows me to call nxtcommand.stopProgram() and actually stop the program.

Incidentally, the return value doesn't seem to vary between my implementation and the stock main menu's implementation of stopProgram. I expected a non-zero return code (0xFD) from the menu, but get zero all the time. It isn't a big deal and I didn't really look into it.

Cheers,
Clinton
clintonb
Active User
 
Posts: 82
Joined: Fri May 28, 2010 1:44 am
Location: Cardston, Alberta, Canada


Return to NXJ Software

Who is online

Users browsing this forum: Google [Bot] and 1 guest

cron
more stuff