Serial driver queues control

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

Moderator: RoccoMarco

Post Reply
Akronoz
Posts: 10
Joined: Mon Mar 31, 2014 7:58 am

Serial driver queues control

Post by Akronoz »

Hi, im new with chibios and im try to learn with all the documentation, but i have some problems yet.

I need a correct code to read and send data to the serial port and avoid overflow, because when i have it, the application crashes at 'unhandled exception', i need a way to recover from an overflow. In the case of sending data , debugging the program i saw that the crash become when the SD2.oqueue.q_count reaches zero, but i don't know how to limit it and how to wait until the queue is empty, I tried to read it from SD2 struct but when i wait, the q_count dont change.

Code: Select all

static WORKING_AREA(wa_th_SDT, 256);
static msg_t th_SD2_envia(void *arg) {                                     
    chRegSetThreadName("SD2_envia");   
    (void)arg;
    msg_t msg_pos;
    S_Message_t  msg_dat,msg_resend[SZ_BUF_RS]; 
    uint32_t i,size,sizeframe,count,pos=0;
   
    while(!chThdShouldTerminate()){if(SD2_ON){
      if(chMBGetUsedCountI(&S_T_mailbox)>0){                                   //wait for messages in mailbox
        while(chMBFetch(&S_T_mailbox, &msg_pos, MS2ST(1))!= RDY_OK);
        chSysLock();
        msg_dat = *(S_Message_t *)msg_pos;               //Get the data, msg_pos is a pointer to structure
        chSysUnlock();       
   //////////////////////
        /// initialize dataT[] with the data stored in msg_dat
   //////////////////////                 
        count = sdWriteTimeout(&SD2,(uint8_t *)dataT,sizeframe,MS2ST(DM_SR_DATA));

        if(count<(HEADER_SZ+size)){                                                     //error sending, it retry S_RESEND_TIMES
          if(msg_dat.ResendTimes < S_RESEND_TIMES){
            msg_dat.ResendTimes++;
            msg_resend[pos] = msg_dat;
            chMBPost(&S_T_mailbox, (msg_t) &msg_resend[pos], MS2ST(10));             //put it in mailbox queue
            pos++;
            if(pos>=SZ_BUF_RS)pos=0;
          }
        }
      }
      chThdSleepMicroseconds(DU_CHECK_ST_MAILBOX);      //Delay between mailbox check                             
    }else{chThdSleepMilliseconds(100);}}
    return 0;
}

Im getting problems also whit the receiver thread.

Another question, I used mailboxes but i work with a packet struct, i post to the mailbox the pointer of the actual struct, and i fetch it but im not sure if that is the correct way to protect the data because other tread can overwrite the data stored in the pointer when it reaches a limit, i used chSysLock to minimize the time between fetch the pointer and copy data to other variable.

Thanks, and i sorry for my regular English.
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Serial driver queues control

Post by Giovanni »

Hi,

I don't understand much of what you are trying to do but I suspect that mailboxes are not what you need to use there. Is the sender another thread or an ISR? if it is a thread then probably you could use synchronous messages instead of the mailbox.

Giovanni
Akronoz
Posts: 10
Joined: Mon Mar 31, 2014 7:58 am

Re: Serial driver queues control

Post by Akronoz »

Thanks for the reply.

In the application there are some treads that can generate events, like changes at inputs, when a event is generated, i build a packet with the event data and i have to pass to a Serial transmiter thread or CAN transmiter thread depending on the message.

Which is the reason why is better to use syncronous messages?.I think the problem is an overflow on the serial port when the events frequency is greater than the sdWriteTimeout can send and the unhandled exception appears when the queue is full.

There is a correct way to manage the outgoing and input data trough the serial driver without risk of overflow?
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Serial driver queues control

Post by Giovanni »

sdWriteTimeout() should not generate exceptions, it either returns with a timeout (returned value less than the sent value) indication or waits internally if a timeout is not specified.

I recommend enabling the debug options in chconf.h.

Giovanni
Akronoz
Posts: 10
Joined: Mon Mar 31, 2014 7:58 am

Re: Serial driver queues control

Post by Akronoz »

I will try to use the debug mode now, thanks.

But about the syncronous messages i think i cant use that because i have more than one treag generating messages i need the mailboxes no?.
One question more question, the code I posted ar correct to work with mailboxes and the serial port?

Thanks Giovanni for fast reply again :)
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Serial driver queues control

Post by Giovanni »

I just see a misplaced i-class function, the debug options should find that too. I don't know if the logic of your code is correct, my guts tell me that there is a problem with all those sleep, it looks too complicated.

About synch messages, you can definitely have more than one thread sending messages to a server thread, their purpose is exactly the implementation of client/server architectures and are more efficient than mailboxes at that.

Giovanni
Akronoz
Posts: 10
Joined: Mon Mar 31, 2014 7:58 am

Re: Serial driver queues control

Post by Akronoz »

If I cant use I class function , how can I check the free space in the mailbox?
About sync messages, my application needs a queue of messages, and I think that is only possible using mailbox.
About the sdWriteTimeout, its posible to know the free space in the internal queue while the function is waiting to send the data throug the serial port, or is inaccesible by user of the driver?

Thanks a lot.
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Serial driver queues control

Post by Giovanni »

You can use i-class from thread context, you need to call them from within a lock, see "kernel concepts" in the documentation.

It is possible to call sdWriteTimeout() with TIME_IMMEDIATE, if the queue is full the function would return immediately. You may also use queues function on internal driver queues but you would be breaking the defined interface by looking inside.

Giovanni
Post Reply