Menu

Multiterminal

2025-09-05
2025-09-09
  • Pere font vilanova

    I've been programming the code in the photo for some time without any success.
    - Sometimes data was displayed in the PUTY terminal, but I couldn't enter data. I could only input it from the serial terminal, but then I couldn't see what I typed.
    - Sometimes PUTY would work, but the serial terminal would freeze.
    Suddenly, it occurred to me that some process was blocking the program and it was stuck in an endless loop. So, I started pressing PAUSE in all the places that seemed critical, and... Eureka, it worked... but after a while, everything would freeze. I increased the values of the stacks and other parameters in the task definition, and boom... now everything works perfectly.
    The question is if you can give me some idea of what values to set for the stack size and what criteria to follow when setting PAUSE... since I probably have too many now... but I don't quite understand the process...
    I would appreciate your help in this regard.
    The program allows me to use two screens simultaneously. One via USB and the other via Wi-Fi.

     
  • Mikael Nordman

    Mikael Nordman - 2025-09-05

    Hi,
    FlashForth has a limitation that INTERPRET, EVALUATE, and QUIT does not work in a background task. I don't remember exactly why. They may work, but can not be relied on to work fully because the interpreter is not re-entrant. It uses global variables and flags for many things so the operator task and the background task will interfere with each other.

    Have a look at https://sourceforge.net/p/flashforth/code/ci/master/tree/forth/task-bgio.fs
    and its comments. There you can see how to use KEY with ACCEPT in a BG task
    to collect data into the TIB of the BG task.
    Regarding the stack sizes I check with DUMP the return and data stack to see if there are some overruns. It all depends on your codes stack usage. You can start out with big stacks and then decrease the size to see when it stops working.

    Here also some info.
    https://sourceforge.net/p/flashforth/discussion/726813/thread/e0bea786b3/

     
  • Mikael Nordman

    Mikael Nordman - 2025-09-05

    Regarding PAUSE it is only needed before RX1? because RX1? itself does not call PAUSE.
    RX1, RXU, TX1, TXU will call PAUSE so there will be enough PAUSES.
    A certain amount is needed for the USB interface not to freeze, because PAUSE is also driving the basic USB state machine.

    Making RXn? call PAUSE is actually a change that should be done, because there has been many questions about this earlier.

     

    Last edit: Mikael Nordman 2025-09-05
  • Pere font vilanova

    thanks for the information, i will read it. anyway, in this case the interpret command is working in bg, i will check in depth next days. also i will try the correct size of stacks and i will check the correct quantity of pauses and position

     
  • Mikael Nordman

    Mikael Nordman - 2025-09-06

    I think that if you do not compile simultaneously in the tasks, there is actually a chance that using the interpreter works just fine.
    You could try putting just ABORT in the end of the BG task. it will enter the infinite QUIT loop that drives the interpreter.

     

    Last edit: Mikael Nordman 2025-09-06
  • Pere font vilanova

    hello Mikael. after see your links, I have changed my code, as showed in the file attached. it works very well, but with some limitations.
    I'd like it if you could help me with my initial idea:
    If I type >wifi from the serial terminal, control of the scamp goes to the wifi terminal, and if I type >terminal from the wifi terminal, control goes to the serial terminal. It works like a charm. So, how could I create a background task that would do this automatically, with two tasks that would pass control from one terminal to the other? I've done multiple tests, and none of them work for me. The idea is to not use accept, key, or interpret... just the switching of input and output sources.
    Maybe it's impossible?

     
    • Mikael Nordman

      Mikael Nordman - 2025-09-06

      I find it hard to understand what you mean by 'control' ? Control of the interpreter in the operator task ?
      You can do that without any BG tasks. Just use your >terminal and >wifi in the operator task as you have already defined.

      This is how to switch the I/O of the operator task from any task.

      : >terminal
         ['] rxu  operator 'key  his !
         ['] rxu? operator 'key? his !
         ['] txu  operator 'emit his !
      ;
      : >wifi
         ['] rx1  operator 'key  his !
         ['] rx1? operator 'key? his !
         ['] tx1  operator 'emit his !
      ;
      
       
  • Mikael Nordman

    Mikael Nordman - 2025-09-06

    With the word HIS you can access the user variables of a specific task.

     
  • Mikael Nordman

    Mikael Nordman - 2025-09-06

    What about this ? It would automatically switch the operator task to the I/O that sends in characters.

    Not tested.

    : >wifi
       ['] rx1  operator 'key  his !
       ['] rx1? operator 'key? his !
       ['] tx1  operator 'emit his ! ;
    : >terminal
       ['] rxu  operator 'key  his !
       ['] rxu? operator 'key? his !
       ['] txu  operator 'emit his ! ;
    
    0 40 40 0 task: io-switch-task
    
    \ TODO: implement TERMINAL? and WIFI? 
    : io-switch
      begin
        pause
        rx1? terminal? and if >wifi then
        rxu? wifi?     and if >terminal then
      again 
    ;
    : run-io-switch ['] io-switch io-switch-task tinit io-switch-task run ;
    
     
    • Mikael Nordman

      Mikael Nordman - 2025-09-08

      I tried a few hours to get the background io-switch to work, but it did not want to.
      Giving the >terminal or >wifi from the currently active port works.
      Giving a command to the BG task to make switch using a global variable works.
      But not with rx1? and rxu? .

      -wifi
      marker -wifi
      
      : to-wifi
         ['] rx1  operator 'key  his !
         ['] rx1? operator 'key? his !
         ['] tx1  operator 'emit his ! ;
      : to-term
         ['] rxu  operator 'key  his !
         ['] rxu? operator 'key? his !
         ['] txu  operator 'emit his ! ;
      
      0 40 40 0 task: io-switch-task
      ram false value wifi
      
      : io-switch
        false to wifi
        to-term
        begin
          rx1? wifi false = and if to-wifi true to wifi then
          rxu? wifi and         if to-term false to wifi then
        again 
      ;
      : run-io-switch ['] io-switch io-switch-task tinit io-switch-task run ;
      
       
  • Pere font vilanova

    I find it hard to understand what you mean by 'control' ? Control of the interpreter in the operator task ?
    You can do that without any BG tasks. Just use your >terminal and >wifi in the operator task as you have already defined.
    THANKS FOR THE HELP. YOU ARE RIGTH, but with my words when i do >wifi i can work with a putty terminal in uart1 but... the teratem in serial,port stops. the only way to start it again is do >terminal from uart1, but then putty terminal in uart1 stops. my goal was use both terminals at the same time.
    now i will try your suggestions to improve the code in order to use both terminals ( teraterm and putty) using always the internal interpret of flashforth. i will inform you about...

     
    • Mikael Nordman

      Mikael Nordman - 2025-09-08

      I tested a bit the background interpreter that uses ABORT. It seems to work quite well, except for the multitasking words which are hard coded to only run from the operator task. These are TASK: TINIT SINGLE END RUN TASKS.

      Hopefully all other words can be executed in the background and operator tasks in the interpretation state.

      When compiling new definitions or appending data to the dictionary only one of the terminal at a time can be used.
      There is only one dictionary so if two tasks write to it at the same time, the data will be intermingled and thus corrupt.

      90 80 80 0 task: bg.task
      
      : bg.terminal
         ['] rx1  'key  !
         ['] rx1? 'key? !
         ['] tx1  'emit !
        decimal
        abort
      ;
      : run.bg.terminal
        ['] bg.terminal bg.task tinit bg.task run ;
      
       
  • Pere font vilanova

    i tried in a very similar way and also not working. i find a code that if a i write code in term and enter nothing but when i write code in wifi and enter then execute the term and when do enter in term then execute in wifi.......? after that in becomes little crazy.
    i have some new idea, but i can't try until tomorrow.....maybe not possible....

     
  • Pere font vilanova

    I have got time to try but, not working. but yor solution 1 day ago with abort is good option for me.
    i checked and is going quit well, even you can send messages from one to another.
    thank you a lot for all your help..
    the echo in putty terminal is because i forgot remove the echo in setup

     
    🎉
    1

    Last edit: Pere font vilanova 2025-09-09

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.