DMA complete ISR -> mailbox post -> SV#8 Topic is solved

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderators: RoccoMarco, barthess

elagil
Posts: 92
Joined: Tue Sep 19, 2017 7:38 am
Has thanked: 8 times
Been thanked: 7 times

DMA complete ISR -> mailbox post -> SV#8

Postby elagil » Thu Sep 28, 2017 3:03 pm

Hello!

I am trying to send a mailbox message from a DMA complete ISR to some thread that should process data.

However, I am running into SV#8 errors instantly!

It seems like "ch.dbg.lock_cnt" is equal to 1 in "_dbg_check_enter_isr()". What does that mean?

This is the dma ISR handler.

Code: Select all

void dma_complete_handler(stm32_dma_stream_t * dmastp)
{
  /**
   * Current buffer is Memory 0
   */
  m_send.control = DATA_READY;
  if((dmastp->stream->CR & DMA_SxCR_CT) == 0)
  {
    m_send.datap = mem0;
  }
  /**
   * Current buffer is Memory 1
   */
  else
  {
    m_send.datap = mem1;
  }

  m_send.len = 1024;

  chSysLockFromISR();
  chMBPostI(&mb_sender, (msg_t)&m_send);
  chSysUnlockFromISR();
}


This is where the mailbox is read:

Code: Select all

THD_FUNCTION(tcp_sender, p) {
  (void)p;

  struct netconn * conn;
  uint32_t status = CLIENT_DISCONNECTED;
  chRegSetThreadName("tcp_sender");

  while (true)
  {
    /**
     * Wait for signal from DMA ISR to start transmitting data
     */
    msg_t msg;
    m_send_t * m_send;

    if (chMBFetch(&mb_sender, &msg, TIME_INFINITE) == MSG_OK)
    {
      m_send = (m_send_t *) msg;
      switch (m_send->control)
      {
      case CLIENT_CONNECTED:
        conn = m_send->conn;
        status = CLIENT_CONNECTED;
        break;

      case CLIENT_DISCONNECTED:
        conn = NULL;
        status = CLIENT_DISCONNECTED;
        break;

      case DATA_READY:
        if(status == CLIENT_CONNECTED)
        {
          netconn_write( conn, m_send->datap, m_send->len, NETCONN_NOCOPY );
        }
        break;
      }
    }

  }
}


The DMA is configured to run that function when the transfer complete interrupt is triggered:

Code: Select all

  dmaStreamAllocate(STM32_DMA2_STREAM2,
                    0,
                    (stm32_dmaisr_t)dma_complete_handler,
                    (void *)STM32_DMA2_STREAM2);


Thanks for your input,
Adrian

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: DMA complete ISR -> mailbox post -> SV#8

Postby Giovanni » Thu Sep 28, 2017 4:42 pm

Hi,

Check you DMA IRQ priority, it must not be zero or one. Valid priorities start from 2. Also verify that your ISR has the IRQ macros placed correctly.

Giovanni

elagil
Posts: 92
Joined: Tue Sep 19, 2017 7:38 am
Has thanked: 8 times
Been thanked: 7 times

Re: DMA complete ISR -> mailbox post -> SV#8

Postby elagil » Fri Sep 29, 2017 8:08 am

Ok, so I increased priority to 3. What is the range of valid priorities?

I also added the wrapping IRQ macros:

Code: Select all

void dma_complete_handler(stm32_dma_stream_t * dmastp, uint32_t flags)
{
  CH_IRQ_PROLOGUE();
  /**
   * Current buffer is Memory 0
   */
  m_send.control = DATA_READY;
  if((dmastp->stream->CR & DMA_SxCR_CT) == 0)
  {
    m_send.datap = mem0;
  }
  /**
   * Current buffer is Memory 1
   */
  else
  {
    m_send.datap = mem1;
  }

  m_send.len = 1024;

  chSysLockFromISR();
  chMBPostI(&mb_sender, (msg_t)&m_send);
  chSysUnlockFromISR();

  CH_IRQ_EPILOGUE();
}


I get a different error now, when the message is to be fetched. "chSysUnlock" in the fetching thread fails. It says:

"The following condition can be triggered by the use of i-class functions in a critical section not followed by a chSchResceduleS(), this means that the current thread has a lower priority than the next thread in the ready list."

I shall call chSchResceduleS() but this is not allowed in the ISR. When I call it before chSysUnlockFromISR(), it tells me that its use was illegal (as expected). So, where do I use it?

EDIT: As CH_IRQ_EPILOGUE() itself should do the rescheduling, I am not sure what is wrong.

Thanks!

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: DMA complete ISR -> mailbox post -> SV#8

Postby Giovanni » Fri Sep 29, 2017 8:43 am

You should look at the stack trace when the system stops.

Giovanni

elagil
Posts: 92
Joined: Tue Sep 19, 2017 7:38 am
Has thanked: 8 times
Been thanked: 7 times

Re: DMA complete ISR -> mailbox post -> SV#8

Postby elagil » Fri Sep 29, 2017 8:53 am

I did now.

I have multiple mailboxes for different threads. What fails, is fetching from a mailbox in a thread that is not related with the ISR. The ISR to another mailbox. The failing thread looks like this (it blinks a led):

Code: Select all

 
while (true) {
    msg_t msg;
    if (chMBFetch(mb_blinker, (msg_t*)&msg, TIME_IMMEDIATE) == MSG_OK) {
      STATE = msg;
    }
    // do something
    chThdSleepMilliseconds(1000);
}


Here, chSysUnlock() is called within chMBFetch() and fails, because:

ch.rlist.current->prio is 2 and ch.rlist.queue.next->prio is 128 (so ch.rlist.current->prio >= ch.rlist.queue.next->prio not true)

and

ch.rlist.queue.next == (thread_t *)&ch.rlist.queue

are not equal. Unfortunately, this does not help me much. I just know that somehow the thread queue is incorrectly sorted after the ISR.

elagil
Posts: 92
Joined: Tue Sep 19, 2017 7:38 am
Has thanked: 8 times
Been thanked: 7 times

Re: DMA complete ISR -> mailbox post -> SV#8

Postby elagil » Fri Sep 29, 2017 1:02 pm

I tried a different approach. I use events now, because I thought that the struct pointer that I transferred over the mailbox may pont to an invalid struct when it is read.

Let me briefly summarize the initialization and programm calls:

1.) start all threads
2.) enable DMA. DMA allocation now looks like this:

Code: Select all

 
  dmaStreamAllocate(STM32_DMA2_STREAM2,
                    3,
                    (stm32_dmaisr_t)dma_complete_handler,
                    (void *)STM32_DMA2_STREAM2);


The events are properly triggered and detected in the listening thread. Then, there is one context switch to the idle thread and finally, it tries to switch into a thread address that does not exist. Why is that?

Find the ISR handler here in its new form:

Code: Select all

void dma_complete_handler(stm32_dma_stream_t * dmastp, uint32_t flags)
{
  CH_IRQ_PROLOGUE();

  (void) flags;

  /**
   * Current buffer is Memory 0
   */
  if((dmastp->stream->CR & DMA_SxCR_CT) == 0)
  {
    chSysLockFromISR();
    chEvtBroadcastFlagsI(&dma_event_source, DMA_MEM0_READY);
    chSysUnlockFromISR();
  }
  /**
   * Current buffer is Memory 1
   */
  else
  {
    chSysLockFromISR();
    chEvtBroadcastFlagsI(&dma_event_source, DMA_MEM1_READY);
    chSysUnlockFromISR();
  }

  dmaStreamClearInterrupt(dmastp);

  CH_IRQ_EPILOGUE();
}


And this is the listener:

Code: Select all

THD_FUNCTION(tcp_sender, p) {
  (void)p;

  event_listener_t dma_listener;
 
  chRegSetThreadName("tcp_sender");

  chEvtRegisterMaskWithFlags(&dma_event_source, &dma_listener,
                             EVENT_MASK(0), DMA_MEM0_READY | DMA_MEM1_READY);

  while (true)
  {
    /**
     * Wait for signal from DMA ISR to start transmitting data
     */
    eventmask_t evt = chEvtWaitAny(ALL_EVENTS);

    if (evt & EVENT_MASK(0)) {
      /* Event from the DMA. Get memory location. */
      eventflags_t flags = chEvtGetAndClearFlags(&dma_listener);
    }

  }

}


I am sure I am overlooking something obvious. I also attached snapshots of the trace and thread views.

Best regards,
Adrian
Attachments
Capture.PNG
trace2.PNG
trace2.PNG (9.93 KiB) Viewed 2947 times
trace.PNG

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: DMA complete ISR -> mailbox post -> SV#8

Postby Giovanni » Fri Sep 29, 2017 1:35 pm

Hi,

Have you verified stacks usage? you could have a stack overflow.

Giovanni

elagil
Posts: 92
Joined: Tue Sep 19, 2017 7:38 am
Has thanked: 8 times
Been thanked: 7 times

Re: DMA complete ISR -> mailbox post -> SV#8

Postby elagil » Fri Sep 29, 2017 1:39 pm

I do not get stack sizes to display. As you see, they are not shown. I enabled all related options in chconf.h, I think.

I compile with -O0 and these are my settings:

#define CH_DBG_ENABLE_STACK_CHECK TRUE
#define CH_DBG_FILL_THREADS TRUE

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: DMA complete ISR -> mailbox post -> SV#8

Postby Giovanni » Fri Sep 29, 2017 1:41 pm

Strange, I need to check the plugin.

You may try to increase stack sizes and see if the problem stays. Note that -O0 increases stack usage, it could make the problem worse.

Giovanni

steved
Posts: 825
Joined: Fri Nov 09, 2012 2:22 pm
Has thanked: 12 times
Been thanked: 135 times

Re: DMA complete ISR -> mailbox post -> SV#8

Postby steved » Fri Sep 29, 2017 1:43 pm

Giovanni wrote:Strange, I need to check the plugin.

This was a problem with Chibistudio until recently - fixed in SVN and on the update site (neither of which is presumably accessible until SF sort themselves out).


Return to “STM32 Support”

Who is online

Users browsing this forum: No registered users and 24 guests