Re: Loop problem: CPU usage
Hey thanks for the fast reply. Things getting clearer now, its kinda confusing when everyone that i talked to at work they mention that i have to write a serial driver and such.
So lets say i decide all communication is going to be serial. You did mention sendchar and getchar routines. Lets say i send 10 bytes thru the port, from my PC. Where those bytes are stored in the board? in memory? in registers that i can then reference too? ( maybe im thinking too OO but all my coding have been with OO languages ).
Lets say im trying to do this:
Code:
int echo(serialRead) // where serialRead is the data received in the port.
{
return(serialRead) // echos it back
}
In the microcontroller board, how i get serialRead? are those values store where and how can i get to them?
Re: Loop problem: CPU usage
It is specific to the board. You will have to read the documentation (there are almost always samples also). :eek:
Re: Loop problem: CPU usage
Hi all.
I got my evaluation board and have been making some pretty good progress. After a few initial problems I got the IDE (Rowley) and JTAG debugger working nicely.
I've been playing with the I/O and serial comms and so far everything looks pretty good.
Right now I'm playing with freeRTOS (www.freertos.org) which is pretty impressive. Early days yet, but this looks like a pretty useful OS for delaing with time critical tasks and slower operations like running the LCD display at the same time. Does anyone have any experience of freeRTOS? So far my only issue is the default max tick (interrupt) frequency of 1000Hz but I'm still digging.
I'd definitely recommend my evaluation board and IDE for any first timers. I think I was pretty lucky in my choice of components.
All the best.
Ben.
Re: Loop problem: CPU usage
Quote:
Originally Posted by shoppinit
I got my evaluation board and have been making some pretty good progress. After a few initial problems I got the IDE (Rowley) and JTAG debugger working nicely.
Right now I'm playing with freeRTOS (
www.freertos.org) which is pretty impressive. Early days yet, but this looks like a pretty useful OS for delaing with time critical tasks and slower operations like running the LCD display at the same time. Does anyone have any experience of freeRTOS?
No, I write my own operating systems. However, some other developers whom I know use the MicroC-OS. It is a very light weight kernel. I do not know if there is support for your microcontroller. If you are interested in this kind of thing, then take a look at this: http://www.amazon.com/MicroC-OS-II-K.../dp/1578201039
Back to your UART / RS232 design: A good design tip for you would be to write an interrupt handler for your UART receive. You should not rely on the multitasking tick of 1kHz for your response time. Write an interrupt handler for the UART receive and set an operating system event for processing the data.
Quote:
Originally Posted by dvazriel
So lets say i decide all communication is going to be serial. You did mention sendchar and getchar routines. Lets say i send 10 bytes thru the port, from my PC. Where those bytes are stored in the board? in memory? in registers that i can then reference too? ( maybe im thinking too OO but all my coding have been with OO languages ).
You need to write a serial driver or possibly find one in some kind of a sample for your board. Many microcontrollers have one single serial receive buffer with a depth of one byte. Others have multi-byte queues. I did mention above that a sensible design is an interrupt controlled serial driver responsible for sending and receiving bytes. You need to use the microcontroller hardware for send / recv and combine this with enough software for your communications buffers. Please try to investigate this kind of thing.
Look at the books in the Amazon URL: The book with 'building blocks' from La Brosse describes this kind of stuff in great detail: http://www.amazon.com/Embedded-Syste...361063-0877445
Sorry, I should have mentioned these links earlier. Your company should buy these two books for your microcontroller development processes.
Good luck. Chris.
Re: Loop problem: CPU usage
Thanks for the info, Chris.
I'm liking freeRTOS. It means I can program events / interrupts like in Windows. Since my application is simple though, I may just have a polling loop checking to see if action is required on an object and use a couple of interrupts to deal with IO and UART.
My UART Rx is interrupt driven and seems to work well for single character transmissions which is all I've tested so far. I'm taking on board your comments about writing the necessary buffers for dealing with chains. I need this to be reliable though and the whole communication with the PC worries me a little. I'm thinking that I'll have a thread waiting for comms from the micro, but I don't know if I should do any handshaking... it's a bit of a new area for me. Any ideas?
Thanks again for all the good info.
Ben.
Re: Loop problem: CPU usage
While a "custom OS" is often chosen by hard-core embedded developers to meet specific requiremets. The available ones offer significant advantages, as they really help bootstrap the development process...
1 Attachment(s)
Re: Loop problem: CPU usage
Hi Ben, it's good to see that you are making progress.
Quote:
Originally Posted by shoppinit
I'm liking freeRTOS.
If you like it, then use it. If you *really* want to write your own polling OS, then you can do this. However for a first project like yours, I agree with TheCPUWizard in so far as it might simply be better to use the existing OS from the free ware community.
Quote:
Originally Posted by shoppinit
My UART Rx is interrupt driven and seems to work well for single character transmissions which is all I've tested so far. I'm taking on board your comments about writing the necessary buffers for dealing with chains.
I have attatched a low-level driver from another CPU architecture which I wrote years ago in C. It shows very clearly how to implement a ring buffer and interrupt-driven send/recv. Because this is a hardware-driver, it is platform dependent and you will need to modify it for your architecture. However, I tried to separate at least some of the hardware dependencies using inline functions. The macro ISR_CAT2(...) generates the interrupt handler. Of course, you need to replace this with hand-coded interrupt idioms for your tool chain. You must also use the UART registers for your architecture. Please note that the Rx and Tx interrupts are disabled before all buffer operations (shared critical data). This is essential for an interrupt driven communications driver. Also note that the Tx send operation is carried out using an interrupt chain until the buffer is empty.
Quote:
Originally Posted by shoppinit
I need this to be reliable though and the whole communication with the PC worries me a little. I'm thinking that I'll have a thread waiting for comms from the micro, but I don't know if I should do any handshaking.it's a bit of a new area for me. Any ideas?
Develop a simple protocol with the following rudimentary information:
- Frame wake-up, followed by
- service ID, followed by
- the number of data bytes in the transmission, followed by
- these data bytes, followed by
- a checksum such as CRC8 or modulo2.
This kind of single-frame protocol can be simple and bi-directional.
Sincerely, Chris.
Re: Loop problem: CPU usage
Quote:
Develop a simple protocol with the following rudimentary information:
- Frame wake-up, followed by
- service ID, followed by
- the number of data bytes in the transmission, followed by
- these data bytes, followed by
- a checksum such as CRC8 or modulo2.
This kind of single-frame protocol can be simple and bi-directional.
Most common: (items in <brackets> are well defined ASCII characters.
Code:
<SOH>FixedSizeHeadeerInfo<STX>VariableLengthMessage(LengthInHeader)<ETX>[CheckSum]
Re: Loop problem: CPU usage
Hi again.
Thanks for all the great info. It's helped me to program the µC nicely, though now my problems are all on the PC side. I expected the opposite!
The µC seems to be able to send and receive faster than I need it to, but the PC can't seem to keep up.
I'm using the CSerial class for driving serial comms and the Rx works really well. I've got the Rx code in a thread on its own waiting for a serial event and that part works ok.
I've got another thread that transmits independantly of what the Rx thread is doing - still using the same instance of CSerial - but if I ask that thread to transmit too often then the whole thing comes crashing down with an ERROR_INVALID_PARAMETER (87) error.
I've been turning this around for hours without finding a clue to the solution.
I believe the µC UART Rx and Tx functions are independant so I don't have any sharing issues but I'm not sure about the PC side. Maybe I can't write and read date to the com port at the same time?
I'm Rxing and Txing chains of 3 or 4 bytes at a time.
Any ideas? I really appreciate your help.
Ben.
P.S. At least this is coming slightly back on topic!
Code:
bool fContinue = true;
do
{
// Wait for an event
lLastError = the_analyser->serial.WaitEvent();
if (eEvent & CSerial::EEventRecv)
{
QueryPerformanceCounter(&date);
the_analyser->lastRxTime = date.QuadPart;
// Read data, until there is nothing left
DWORD dwBytesRead = 0;
char szBuffer[101];
do
{
// Read data from the COM-port
lLastError = the_analyser->serial.Read(szBuffer,sizeof(szBuffer)-1,&dwBytesRead);
if (lLastError != ERROR_SUCCESS)
return the_analyser->ShowError(the_analyser->serial.GetLastError(), _T("Unable to read from COM-port."));
if (dwBytesRead > 0)
{
// Finalize the data, so it is a valid string
szBuffer[dwBytesRead] = '\0';
// Display the data
printf("Message '%s' received at: %I64d\n", szBuffer, date.QuadPart);
//printf("%s\n", szBuffer);
}
}
Code:
lLastError = serial.Write(Tx, 3);
if (lLastError != ERROR_SUCCESS)
ShowError(serial.GetLastError(), _T("Unable to send data"));
Re: Loop problem: CPU usage
Quote:
Originally Posted by shoppinit
I'm Rxing and Txing chains of 3 or 4 bytes at a time.
Ben,
We need to look at the design constraints for the PC-side more closely, in particular the baud-rate as well as the desired transmission and reception frequencies for data packages.
What underlying baud rate are you using (57600 bps)? With what frequencies do you want to send and receive Rx and Tx packages of 3-4 bytes? Are you using (or do you want to use) any kinds of windows messages for receive, for send or for both?
The PC will be able to keep up. You just need to make sure that you use events sparingly and make sensible use of software buffers. You see, the problem with the PC is where we started this thread in the first place: It can not respond in a healthy fashion to ms-based real-time requirements.
Explain your design a bit more.
Sincerely, Chris.
Re: Loop problem: CPU usage
Additionally are you using:
1) "Three Wire" [Tx,Tx,Gnd]
2) "Three Wire With Software Handshake" (typically XON/XOFF)
3) "Hardware Handshaking" [RTC/CTS, etc..]
Re: Loop problem: CPU usage
Hi Chris,
1. µC detects objects, stores information in a structure then sends a 3 byte message to the PC (115200 baud), including a unique number for the object.
2. The PC receives the message - there's a thread with WaitForSingleObject that unblocks when an Rx event occurs. This works really well, and quickly.
3. The PC carries out the analysis required and when done sends back the result (good or bad) with the object number. It has quite a large window (~200ms) to do this.
4. The µC interrupts on Rx and inserts the result of that unique object number into the structure.
5. At the appropriate time, the µC carries out action based on the result of the analysis received from the PC. If the result isn't received in time it carries out the default action.
The frequency of the Rx and Tx could be anything up to 60 times per second. I'm not using windows messages - my test program is console based for the time being (and will probably stay that way).
I'm not using any kind of handshaking (I don't think the LPC2138 supports it) so there's no flow control of any kind.
I think the problem is my poor understanding of overlapped I/O. I've made progress since my last post. I tried using non-overlapped at first, but that created all sorts of problems including the (87) error. Now I'm using non-overlapped things seem to be more reliable, but my confidence level is low!
Ben.
Re: Loop problem: CPU usage
Quote:
Originally Posted by TheCPUWizard
Additionally are you using:
1) "Three Wire" [Tx,Tx,Gnd]
2) "Three Wire With Software Handshake" (typically XON/XOFF)
3) "Hardware Handshaking" [RTC/CTS, etc..]
The LPC2138 doesn't seem to have any UART functions other than Rx / Tx. No CTS, etc...
There's definitely no XON/XOFF going on.
Table 72: UART0 pin description
Pin Type Description
RXD0 Input Serial Input. Serial receive data.
TXD0 Output Serial Output. Serial transmit data.
I've just looked at the manual again, and UART1 has a full modem interface - CTS, RTS, DTR, etc. Unfortunatly I can't use this one because the serial port on my evaluation board is wired to UART0. I could solve this by getting a different board...
Re: Loop problem: CPU usage
[QUOTE=shoppinit]I think the problem is my poor understanding of overlapped I/O. I've made progress since my last post. I tried using non-overlapped at first, but that created all sorts of problems including the (87) error. Now I'm using non-overlapped things seem to be more reliable, but my confidence level is low!
QUOTE]
Ben,
Based on your last two posts, you should probably be fine without any handshaking. The Rx side (froma PC point of view) is working, and that is where it is most likely needed. On the Tx side, I was wondering if the uC could be expecting handshake from the PC, but not getting it (since it does not support it, this is eliminated.
However your least paragraph of the post I quoted has be confused. You say you tried non-overlapped first, then switched to non-overlapped. :confused: :confused: :confused:
Re: Loop problem: CPU usage
Quote:
Originally Posted by TheCPUWizard
[However your least paragraph of the post I quoted has be confused. You say you tried non-overlapped first, then switched to non-overlapped. :confused: :confused: :confused:
I mean, when I started developping the comms I wanted to use non-overlapping I/O so I could keep control over what was happening. The problem was that using non-overlapping my Tx thread would block until an Rx event occured. I couldn't get to the bottom of this so I switched to overlapped which works now... but the additional complexity worries me.
I've just tested the Rx and Tx at 60 per second and both the µC and the PC seem to be able to keep up so that's quite encouraging.