External uart and timer ticks per seconds problem

Hi all.

I have a problem with my uart driver and thread execution. For the correct functioning of my device I had to bring the ticks per second to 2000.
With this value I have problems with access to external uart, probably since the CS is multiplexed for different devices that are used by different threads.
It appears that some uart registers are not set correctly. If I reset the ticks for 100 seconds everything works.
I tried to set delay cycles on CS4 but it still doesn't work.
What do you think it can depend on? I attach CS multiplex image

Best Regards

Paolo

  • Hi Paolo-
    When you say for the correct functioning of your device you need timer ticks at 2,000 per second- could you explain why that is? What in your application requires this.

    When you say you set the ticks to 100 seconds, is that 100 per second?

    If the UAR is being accessed by multiple threads, are you using a semaphore to control access to the UART?
  • In reply to WarrenM:

    Hi Warren
    I increased the tick rate because I needed some threads to be scheduled more frequently (I don't know if it's the best solution).
    Each UART has its own thread, so I don't think semaphore is needed. The problem, I think, that depends on the micro's cs being multiplexed and the CS switching too fast during the thread switch (I'm trying to understand something with a logic analyzer).
    Any idea is welcome.

    Paolo
  • In reply to Paolo Miatto:

    Hi Paolo,

    Are all your threads running at the same priority? If they are then they will be time slicing ecery tick (default setting) so this is why you are seeing the need to speed up the timeout.

    I would recommend having each thread with a unique priority. This should stop the threads completing aggressively for CPU time.

    Regards,

    Ian.
  • In reply to Ian:

    Hi Ian.

    Each thread has its priority, but if I want sleep one thread for 0,5ms i need change ticks or am I wrong?

    I tried to analyze the signals with the logic analyzer and I have an acquisition that I don't understand. The uart CS sometimes has wrong times compared to how it should be (with low A3, A4, A5 it should be identical to CS_MULTI). I attach image

    Best Regards

    Paolo

     

  • In reply to Paolo Miatto:

    Paolo, If you need a thread to sleep for 500uS then I would highly recommend using a hardware timer and a semaphore. Instead of tx_sleep() call the timers start function and then use the tx_semaphore_get with a TX_WAIT_FOREVER. Put the semaphore in the timer's interrupt handler. Hardware timers are going to be more precise than a tx_sleep and you can set the priority of the timer interrupt.
  • In reply to Dale Drinkard:

    Hi.
    It may be a solution, but I would like to understand what is wrong. Since it looks like a bus access problem, the problem may remain.
  • In reply to Paolo Miatto:

    Hi Paolo,

    The ThreadX tivk occurs every 10ms so this is the resolution of tx_sleep() which is far longer than the 500us you require. Dale's hardware timer approach will be able to give you that sort of delay. Can you share the code that is causing the problem?

    Regards,

    Ian.
  • In reply to Ian:

    Hi Ian.
    The ticks are 0.5ms since I brought them to 2000.
    The project is very large and I cannot share it due to company policy. I will try to keep ticks at 100ms for threads accessing uarts.
  • In reply to Paolo Miatto:

    Hi Paolo,

    If the ticks are set to 0.5us and you specify a delay of 1 tick you will likely get a delay smaller than this. This is because the tick count for that thread will be decremented from 1 to 0 and expire on the next systick ISR which could happen at any time in a 0.5us window i.e. just after the call to tx_sleep(1). A hardware timer is a better solution.

    I appreciate you cannot share the complete project but could you show the UART code which demonstrates the problem? Perhaps reduce the code to the minimum to show the problem?

    Did you confirm that each thread has its own priority?

    Can you confirm if my understanding is correct?
    1. You are using one UART channel to communicate to multiple devices each using its own chip select.
    2. The UART is accessed from more than one thread.

    If the above are both true then the likely problem is that thread A starts executing and asserts the chip select for a peripheral. It is then pre-empted by thread B which needs to use the UART and it asserts its chip select.

    At this point both chip selects are asserted. Is this what you are seeing?

    If this is the case then you should use a mutex to control access to the UART. Before a thread can use the UART it must successfully get the mutex. When it is finished with the UART then it must return the mutex. Only the thread with the mutex will access the UART and any other thread will have to wait for the mutex before accessing the UART. This will control access to the single UART resource.

    Regards,

    Ian.
  • In reply to Ian:

    Hi Ian.
    The problem occurs only with the complete project with fast ticks. I can also use the timer, but I don't need the thread to run exactly every 0.5ms, only every 10ms is too slow.

    Each thread has its own priority.
    There are several UARTs, each is used only in one thread. The CS of each UART derives from a single CS of the micro.

    Anyway I'm trying to keep the ticks at 10ms and to use the timer, but I'm afraid that the problem will occur again using the uart.

    Best Regards
    Paolo
  • In reply to Paolo Miatto:

    Hi Paolo-
    I believe Ian's above analysis is most likely correct- there seems to be some interference with the decoder operation due to multiple threads accessing it in an unprotected way.

    Can you get a scope capture of the decoder outputs to see, as Ian suspects, threads are 'crashing' into the decoder and switching the CS at inappropriate times?

    If we don't hear back from you we will assume Ian's description is correct, and you have resolved the issue.

    Thanx!
  • In reply to WarrenM:

    Hi WarrenM Ian.
    I solved it by keeping ticks at 10ms and using the semaphore for faster procedures. If I raised ticks to 1 ms it doesn't work.

    Best Regards
    Paolo
  • In reply to Paolo Miatto:

    Thanx for letting us know.