Announcement

Collapse
No announcement yet.

Launching program from the SD

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Launching program from the SD

    Hi,
    In order to overtake the program size limit for a single program in FLASH, I am willing to store some programs on the SD card.
    The "main program" (stored in the flashbank 0) would just be launcher.
    This program will not have any UI. It will simply make a few actions (check for files on the SD card, ...), and launch a 1st "app" from the SD called Menu (.4XE / .4FN).

    Menu will offer the user several buttons to choose which app he wants to use.
    Menu will then launch the corresponding app selected by the user, from the SD (4XE or 4FN).
    When the user is done with this app, a return button will exit and go back to Menu.

    Click image for larger version

Name:	apps.PNG
Views:	48
Size:	7.8 KB
ID:	71275

    Since the apps are independant for each other, it does not really matter if the context is stored when launching an app.
    It is ok for me to re-initialize my Menu app when I return from another app. The most important data will be store in a txt file on the SD, so it's just a matter of reading it.
    So, at this point, both file_Run() or file_Exec() seem to do the job.


    Here is where it gets tricky : all app need to have access to the serial/UART.
    How should I process with that ? Can I initialise the UART buffers (RX and TX) in myLauncher, and then access then from any of my apps with some pointers ?

    At the moment, re-init the UART everytime I open an app. Since I need to be able to send/receive big frame, I am using some large buffers as global variables (> 1000 byte).
    I tried a few things with file_Exec(), file_Run(), mem_Free() and returns, but after several opening/closing app, the screen crashed because of stack overflow.
    I believe that the memory is not completely freed when I return from an app. Therefore, everytime I re-open an app, some more RAM get allocated, until a stack overflow occurs.

    In each of my app code, I have something like this :
    Code:
    // Global var
    var TXRXbufffer[1000] ;
    var RXbuff[1000];
    
    func main()
    
    
       COM2_RX_pin(PA10);
       COM2_TX_pin(PA8);
       com2_Reset();
       com_SetBaud(COM2, 39700); // Parameter for the function is Baud/10
       com2_Init(RXbuff, BACKGROUND_SERIAL_COM_BUFFER_SIZE,0);
       com2_TXbuffer(TXRXbufffer,TX_COM_BUFFER_SIZE_ENCODED_FRAME, PA8);
    
    
       repeat
    
          // Some actions
          // Different for each app
    
          // Check if there is some data
          get_serial_messages();
    
          foreever
    endfunc
    Code:
    func get_serial_messages()
       var singleData ;
    
       singleData := serin2();
    
       if(singleData >= 0)
           // Some processing
       endif
    
    endfunc
    I think I understand the concept of parent and child program, but I haven't been able to find the application note (there are no more filters on the website ?!). Therefore, there are probably some details that I am missing.

    myLauncher is prety basic, and uses Designer
    The other program are coded in Visi.
    I am using the pro version.
    Attached Files

  • #2
    After some tests, I solved a first problem. In my APP program, I had the return instruction placed in a subroutine.
    I beleive that the compiler is getting confused wether the return instruction is to return from my subroutine, or exit the program.
    I updated my program to only exit an APP from its main().
    Basically, something like this (discare syntax, it is only meant to describe):

    Code:
    // App
    
    var needExit := 0 ;
    
    func main()
    
       [ Some Inits ]
    
       // Replaced the repeat/forever
       while(!needExit)
    
          [ Some actions ]
    
          manageTouchButtons() ;
    
       wend
    
       mem_Free(hndl) ;
       return ; // Optionnal
    endfunc
    
    
    //Subroutine
    func manageTouchButtons()
    
       if(exitButtonPressed)
          needExit := 1 ;
       endif
    
    endfunc

    At the moment, I am using the following mechanism. So far, it does not seem to cause any error. I haven't looked at the UART though.
    Click image for larger version

Name:	app.PNG
Views:	38
Size:	6.1 KB
ID:	71287

    This means that the context of MENU is still in RAM when the APP is executed, which I don't really need. Replacing file_Exec() by file_Run() nohing seem to happen when returning from the APP.
    The file_Exec() is not in the main() of MENU. Is that an issue ?
    Attached Files

    Comment


    • #3
      Hi,

      It might be best to use flash_Run and have the seperate programs in different flashbanks. flash_Run wil release all memory, like a reset so the comms settings will have to be re-initialized. When you want to return from a running program you can software reset that will restart the display from flashbank 0

      Looking at your diagram above, you could then have the Menu in flashbank 0 so that it will always start from the menu.

      flash_Run is explained on page 222 of the manual

      https://4dsystems.com.au/mwdownloads...d/link/id/720/

      Best regards

      Paul

      Comment


      • #4
        Hi Paul,

        Thanks for your message.

        Using the other flashbank could be a good solution. However, I will probably have more than 6 apps.
        In that case, everytime I need to open an app, I would have to :
        - Erase the previous content of the Flashbank using flash_EraseBank()
        - C
        opy the 4FN/4XR program from the SD into the flashbank using flash_LoadFile()
        - Run the program from the flashbank using flash_Run()


        From datasheet, I can see that the FLASH is rated for 10000 write cycles.
        For this particular project, the end user will not change app very often (on average, less than once a day), so this could work.
        But this solution will not work for all cases : changing from App#1 to App#2 12 times a day will reach the flash endurance in 2 years.

        Is there a quick way to compare the content of a flashbank with a file on the SD ?
        Doing that would prevent re-copying a file in a flashbank in case it is already loaded.
        The only options I see so far are :
        - Compare byte per byte, using flash_GetByte() and file_GetC()
        - Keep track of what has been copied in each flashbank using a dedicated file on the SD card

        Comment


        • #5
          Hi Vincent

          If you had this code in each program underneath the #platform

          #DATA
          byte porgNmae "PROGRAM1"
          #END

          Numbered from 1 to 6 then this name will be close to the beginning of the file, it started at byte position 23 when I looked at it with a hex editor. You would then only need to check for these 8 bytes to find out what is already in a flashbank using flash_GetByte(bank, ptr);It wouldn't be necessary to know the contents of the SD card as you can make the decision to load just based on what program is in flash.

          Best regards

          Paul

          Comment


          • #6
            Originally posted by pauleilio View Post
            If you had this code in each program underneath the #platform

            #DATA
            byte porgNmae "PROGRAM1"
            #END

            Numbered from 1 to 6 then this name will be close to the beginning of the file, it started at byte position 23 when I looked at it with a hex editor.[/FONT]
            This looks like a good option to me. Thanks.
            Will the position always be starting at 23, or could that be compiler dependant ?
            Let's say I compile the same program using an older version of the IDE, or a futur release. Will the position of the constant be the same ?

            Comment


            • #7
              Hi,

              I'm not certain that it will always be at that position. It might be a good idea to start the serch at 0 until PROGRAM is found and the just translate the number at the end.

              Code:
              var check[7] := ['P','R', 'O', 'G', 'R', 'A', 'M'];
              
              var n, o, chk, prgNum;
              prgNum := 0;
              for(n := 0; n < 100; n++)
                chk := 0;
                for(o := 0; o < 7; o++)
                  if(flash_GetByte(1, n + o) == check[o]) chk ++;
                next
                if(chk == 7)
                  prgNum := flash_GetByte(1, n + 7) - 48;
                  print("\r\nProgram ", prgNum, " Found at position ", n);
                  break;
                endif
              next

              Comment


              • #8
                Paul,

                It indeed sounds like a good idea.
                My backup plan was to try how long it would take to compare the entire program with the source file on the SD. If the execution time was reasonable, I would have gone that way.

                You suggestion is better :
                - In case the constant is always at the begining, I get a quick comparaisson
                - In case, because of a new compiler (or whatever reason), it is located further in the compiled code : worst case scenario is parsing the entire file, which is what I was going for anyway.


                Thanks.

                Comment

                Working...
                X