Page 1 of 1

Application Update Semaphore

Posted: Thu Aug 01, 2013 12:57 am
by roland.ames
I have a project that allows the user to update the NB App in more than one way, the standard AutoUpdate as well as sending the file over a TCP link, as well as reading the file from SD-card.

I want to use a semaphore to ensure that only one of these methods is used at any one time. So if an AutoUpdate is in process, an attempt to update the app via SD card or TCP will be blocked.

I have a semaphore, which is initialised to 1.

Code: Select all

    OSSemInit(&NBAppSem,1);
Before a task can accept the *_APP.s19 file, it must Pend on the semaphore, and then when the update process is complete, Post to the semaphore.

Code: Select all

    update_shutdown_func = Shutdown;
In my Shutdown function I have:

Code: Select all

    if ( OSSemPendNoWait(&NBAppSem) != OS_NO_ERR )
    {
        puts("AutoUpdate Blocked by NBAppSem\n");
        return 0;
    }
    return 1;
but if the AutoUpdate aborts / fails in any way I have no way to Post to that Semaphore to then allow retry of AutoUpdate or loading of the app via TCP or SD-card.

From my initial look at the code that implements the AutoUpdate process in PC and NB, the process can be aborted by the PC without informing the NB.
So even if I have my own version of autoupdate.cpp where I Post to the NBAppSem inside DoExecute or inside DoStart in the case of UPDATE_RESULT_AUTH_FAILED or UPDATE_RESULT_AUTH_FAILED or UPDATE_RESULT_NOMEM or inside DoData in the case of UPDATE_RESULT_ERROR, it is still possible for an AutoUpdate to be initiated (causing Shutdown to be executed), and then the process aborted by the PC because of error or timeout, and the NB would not be aware that this has happened, and so would not know when to Post to the NBAppSem.

Does anyone have any ideas on how this might be done?

Re: Application Update Semaphore

Posted: Fri Aug 02, 2013 3:54 pm
by Ridgeglider
I think it's plausible to use a semaphore to control having only one method of updating operating at a given time. I also agree that the scenarios you mention may allow any update method to fail while, at the same time allowing the NB, or the user to believe an update was successful. One workaround uses three variables. The first, call it 'VersionNumber', is a constant stored in the normal code image. The other two are variables stored in User Flash. These two user-flash variables are loaded when the update process begins. The first user flash variable, 'UpdateInitiated' stores a status Boolean that is set to indicate that an update was initiated. The second user flash variable stores a version number and is called 'PreUpdateCodeVersion'. Upon reboot, the code always checks the status of 'UpdateInitiated': if false, nothing happens, but if true, an update was in progress. To be sure it succeeded, you'd then compare 'VersionNumber' against 'PreUpdateVersionNumber'. If the two are the same, the update failed and you can trigger whatever action is appropriate. If the two are different, clear the 'UpdateInitiated' flag and continue because the update succeeded. You could also use additional flash user vars to document how the last update was done, or to allow checks to ensure that version numbers always go up, never down etc.

Re: Application Update Semaphore

Posted: Sun Aug 04, 2013 7:51 pm
by roland.ames
Thanks for the suggestion, but I don't think it will do what I want.

The problem is that the NB does not always know if/when the AutoUpdate PCtool has aborted the AutoUpdate process. The NB can tell when it terminates normally because 'DoExecute()' is called. It can handle cases where the abort is because of UPDATE_RESULT_AUTH_FAILED, or UPDATE_RESULT_SHUTDOWN_FAILED, or UPDATE_RESULT_NOMEM or UPDATE_RESULT_ERROR, because these are triggered by the NB, but there are other ways the PCTools app can abort without the NB knowing that the abort has happened.

If the NB is reset there is no problem, the semaphore is reinitiated to 1 in my startup code, and then any update method can be used, as the semaphore is available for Pend. I am not concerned with which version is loaded, in fact it is necessary to allow older versions or the same version to be uploaded.

the problem arises if an AutoUpdate is initiated from the PC, and then is aborted due to some error. Even if the user is aware that this has happened, because the dialog on the PC reports an error, they cannot then try again (with any method) without resetting the NB, because the semaphore has not been posted back to its initial value of 1.

I want the user to be able to retry the AutoUpload (any method) without having to reset the NB.

The more I think about this the less likely it is that it can be done without changing the handshaking between PC and NB during autoupdate. It requires the PCtools autoupdate app to inform the NB that the process has been aborted. I guess I could just use a timeout and assume that no activity for a few seconds means the process has aborted, but then I have to think about what happens if the NB times out before the PCtool has given up.

Re: Application Update Semaphore

Posted: Mon Aug 05, 2013 4:10 am
by Ridgeglider
Now I see what you're trying to do. I think you're right that add'l handshake w/PC would help. You mentioned a timer that looks for no activity, perhaps a stalled packet count for the AutoUpdate task? Another option sort of like the stack check tools might look at the AutoUpdate task's stack position. If it stalls then perhaps an abort on the PC side occurred? Either might work as alternatives to a more straightforward handshake w/PC.