MOD54415 Serial Rx Interrupt Question

Discussion to talk about software related topics only.
Post Reply
GeneralUser
Posts: 17
Joined: Mon Apr 21, 2014 4:49 am

MOD54415 Serial Rx Interrupt Question

Post by GeneralUser »

Hey guys, sounds like a stupid question, but how can I setup my software to receive serial input in a system where I have at least 8-10 other higher priority tasks running?

From what I see, I can't use the read() function since it blocks forever. If I use the ReadWithTimeout() it blocks for X tics and right now I have left my TICKS_PER_SECOND unchanged (set to 20) which means the ReadWithTImeout() could block for up to 50ms.
If I have to use an ISR, is the theory, create the ISR and use a semaphore to lock/unlock my endless serial receive task? Lastly, if this is the correct way, is there an example that demonstrates how to setup an ISR using the correct vector locations?

Thank you in advance!
sulliwk06
Posts: 118
Joined: Tue Sep 17, 2013 7:14 am

Re: MOD54415 Serial Rx Interrupt Question

Post by sulliwk06 »

So you're trying to set up your serial receive task at a higher priority than your other tasks, right? Is there a reason why you can't use a select() call on the serial port? It won't get in the way of your other tasks.
User avatar
dciliske
Posts: 624
Joined: Mon Feb 06, 2012 9:37 am
Location: San Diego, CA
Contact:

Re: MOD54415 Serial Rx Interrupt Question

Post by dciliske »

You want to use 'select()'. Take a quick look at the 'SerialToSerial' example. 'Select' takes a list of file descriptors to watch, and then blocks on a semaphore until either it times out, or one of the watched fds is ready. You can then proceed with a call to 'read', which will only read as much as is available at that moment (read is only guaranteed to read 1 byte, hence no blocking).

Actually, now that I write this out, I'm not sure what your situation is exactly. Can you rephrase what the scenario is? You have 8-10 tasks that are higher priority than the serial handling task that you don't want to block? or are they lower priority?

-Dan
Dan Ciliske
Project Engineer
Netburner, Inc
GeneralUser
Posts: 17
Joined: Mon Apr 21, 2014 4:49 am

Re: MOD54415 Serial Rx Interrupt Question

Post by GeneralUser »

My serial task should be the lower priority (user input via a serial message). Higher priority tasks involve reading A/D, monitoring edge interrupts, PWM output, CAN output, etc...I can't have my serial task blocking anything so I thought I would use the ISR and pend on the UART Status Registers (USRn).

So my understanding is that my serial task would be like one level down from the main loop (MAIN_PRIO - 1) and my other tasks are like (MAIN_PRIO - 20) or lower...
User avatar
dciliske
Posts: 624
Joined: Mon Feb 06, 2012 9:37 am
Location: San Diego, CA
Contact:

Re: MOD54415 Serial Rx Interrupt Question

Post by dciliske »

If you assign your serial task (i.e. MAIN_PRIO-1) at lower priority than your other tasks (i.e. MAIN_PRIO-20), it will not block them. When the higher priority task is ready to run, it will preempt the lower task, even if you are in the middle of the read (or ReadWithTimeout) call.
Dan Ciliske
Project Engineer
Netburner, Inc
GeneralUser
Posts: 17
Joined: Mon Apr 21, 2014 4:49 am

Re: MOD54415 Serial Rx Interrupt Question

Post by GeneralUser »

Ah, I didn't catch that...I thought the read() or readWithTimeout() would block forever until a character is ready. Ok, I will just use the select() as such:

while (1)
{
fd_set readSerial;
FD_ZERO(&readSerial);
FD_SET( fdSerialPort, &readSerial );

if (select( FD_SETSIZE, &readSerial, (fd_set *) 0, (fd_set *) 0, 0 ))
{
// Post process serial data here
}
}
User avatar
dciliske
Posts: 624
Joined: Mon Feb 06, 2012 9:37 am
Location: San Diego, CA
Contact:

Re: MOD54415 Serial Rx Interrupt Question

Post by dciliske »

You're actually partially correct: read will block until it reads at least one byte (ReadWithTimeout will only block until the timeout occurs). However, they will only block that task (and potentially those below it, I'm not 100% on whether it busy waits or uses a semaphore). It does not preempt the OS scheduling.
Dan Ciliske
Project Engineer
Netburner, Inc
rnixon
Posts: 833
Joined: Thu Apr 24, 2008 3:59 pm

Re: MOD54415 Serial Rx Interrupt Question

Post by rnixon »

I think I may not be reading all these comments correctly, so I might be missing something, but I have a few comments:

MAIN_PRIO-20 is a higher priority, not a lower one. MAIN_PRIO default is 50. So if a task is at 50-20 = 30, it will preempt anything 31 through 63 (the idle task).

Serial ports come up in polled mode, but if you close them and re-open, they open in interrupt driven mode with a buffer. What would you consider an isr that read the uart directly when it is already done an buffered for you? I'm not saying there isn't a valid reason, just curious. In this mode when you call read() it reads from the buffer if there is data there. If not it will block until at least one char is available. I think the default buffer size is 1500 bytes, but that can be configured in predef.h or constants.h, don't remember which (you need to rebuild the system libs for any changes to take place in the \nburn\include directory).

One idea is that you do make your serial task a high priority (low priority number), and use the read() function. If no chars are available the function blocks and all the other tasks you mention run. When there is data in the serial buffer read() quickly gets the data. If you make the serial task a low priority (high number) and the other tasks you mention don't let it run often enough, you will lose chars once the buffer fills up.
GeneralUser
Posts: 17
Joined: Mon Apr 21, 2014 4:49 am

Re: MOD54415 Serial Rx Interrupt Question

Post by GeneralUser »

I guess my misunderstanding was the term "block"....I assumed if I made my serial task a high priority (lower number), and used the read() function, it would block (not let any other tasks perform), until a valid character was received. Since this doesn't appear the case, I agree, I should make the serial task a high priority so I don't miss anything. So blocking does not mean that other tasks of low priority cannot run correct?
sulliwk06
Posts: 118
Joined: Tue Sep 17, 2013 7:14 am

Re: MOD54415 Serial Rx Interrupt Question

Post by sulliwk06 »

The best way to think of it is that a task blocks itself from running, allowing lower priority tasks to run.
Post Reply