Hi,
You can never call any pend functions in an interrupt, just post functions. You should not be using the interrupt serial driver from interrupts either since it is possible for it to pend on either a read or a write. A critical section in a task will not block an interrupt from occurring. You can not have a critical section in an interrupt. These OS objects can only be posted by the task that successfully pended it. Since an interrupt is not located in a task this will not work.
You should also not be calling any of the CAN functions from an interrupt, this is likely why you are having problems. Interrupts can only call very limited OS functions. You should only be calling post functions from an interrupt. You should probably set up another task fot sending your RTR messages. This task should be pending on a timer semaphore. In your timer interrupt you should just post to this semaphore which will let the send task run. This should be very similar to the semaphore example except you will post from the interrupt instead of another task:
C:\nburn\examples\RTOS\OSSemaphore
-Larry
Using the CAN bus
Re: Using the CAN bus
Hi, Larry!
You are completely right! When I try to read CAN messages from an ISR function I get a critical trap. So, I found a solution - I set a flag from an timer ISR function, and from another normal function I read and write messages if I see this flag, and then I switch off this flag. It's not a hard real-time, but I do not need to receive messages faster then I can process them. The main requirement - I have not to miss messages. The main cycle of my app is about 100-200 ms, I think the queue of 512 messages is quite enough for my task. Everything works like a charm. Thank you for an advice. Now I have ported CANfestival to NetBurner and I'm able to communicate with other CANopen nodes.
It would be much much harder without your and Dave's advice. Thank you, very much!
You are completely right! When I try to read CAN messages from an ISR function I get a critical trap. So, I found a solution - I set a flag from an timer ISR function, and from another normal function I read and write messages if I see this flag, and then I switch off this flag. It's not a hard real-time, but I do not need to receive messages faster then I can process them. The main requirement - I have not to miss messages. The main cycle of my app is about 100-200 ms, I think the queue of 512 messages is quite enough for my task. Everything works like a charm. Thank you for an advice. Now I have ported CANfestival to NetBurner and I'm able to communicate with other CANopen nodes.
It would be much much harder without your and Dave's advice. Thank you, very much!
Best regards,
Oleg Osovitskiy
Oleg Osovitskiy
-
- Posts: 513
- Joined: Sat Apr 26, 2008 7:14 am
Re: Using the CAN bus
Oleg: Instead of setting a flag and reading it, create and init a semaphore. Within your ISR, post to it. Then create a task that pends on the same semaphore and does whatever's needed in response. Semaphores are really easy to use. See the example project in C:\nburn\examples\RTOS\OSSemaphore as well as the semaphore chapter in C:\nburn\docs\NetworkProgrammersGuide\NNDKProgMan.pdf, I believe section 15.1.2. The pending task will respond to the posts until there are no longer semaphores to process so you will achieve your design goal and will never miss an event. The task switch time is a few uSec assuming the pending task priority is properly configured so it can run. tasks are a nice way to modularize your code too.