View previous topic :: View next topic |
Author |
Message |
Linuxbuilders
Joined: 20 Mar 2010 Posts: 193 Location: Auckland NZ
|
int_RDA buffer problem |
Posted: Sun Aug 15, 2010 12:58 am |
|
|
Hi, could you advise on this:
I have such RX routine as below:
Code: |
#int_RDA HIGH
void comms() {
int strntemp[19]; //string to be loaded with rs232 capture
int max_buffer = 0;
int next_in = 0;
char c;
if (kbhit()) {
do {
c = getc();
strntemp[next_in] = c;
next_in++;
max_buffer++;
} while (max_buffer < 19); //*
memcpy(rx_buffer_encrypted[rxbuffer],strntemp,19);
} //if
} //void
|
where global vars are:
Code: |
//RX VARS//
int rx_buffer_encrypted[11][19]; //rx buffer
|
Now the problem is that the compiler does not allow me to have bigger buffer than 11 places. When I increase it then I get an error:
>>> Warning 216 "main.c" Line 663(37,38): Interrupts disabled during call to prevent re-entrancy: (@MUL1616)
And I can't understand why. What is happening when I get the buffer bigger? Why it is not happy?
18F4520 and PCH 4.107
Thank you. _________________ Help "d" others and then you shell receive some help from "d" others. |
|
![](templates/subSilver/images/spacer.gif) |
sjb
Joined: 13 Apr 2010 Posts: 34 Location: UK
|
|
Posted: Sun Aug 15, 2010 4:38 am |
|
|
That's quite a bit of data you're trying to place on the stack so perhaps it a threshold when the compiler tries to do something else with it, which then make the process non-rentrant.
Other possible cause are the getc() call, although I think this is actually a macro that will result in the code being inlined.
The whole 'lets do lots in the interrupt' method you're using is not really helping you here. Dare I suggest a rethink?
Also, the getc() function might block(*) when there is no data in the uart rx buffer - that would hang the code in the interrupt until another character is received. Is that what you really want?
(* I can't quite remember - look at the .lst file to see what's really happening) |
|
![](templates/subSilver/images/spacer.gif) |
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Sun Aug 15, 2010 9:21 am |
|
|
1) If the UART interrupt was enabled, the hardware is in control, so getc() is all you need to get the incoming char.
2) kbhit() it is not necesary in your code, the START bit was already detected and the task was re-directed to
the interrupt handler because of this.
3) Do not use an interrupt routine to do any long time task, such as a loop, memory copy operation or any complex task.
4) During an UART interrupt, just get the incoming char, store it and leave the interrupt.
5) Declare the input buffer strntemp[19] as a global variable and do any further operation with it outside the interrupt.
6) Do not forget to use ERRORS in the #use RS232 pre-processor directive to clear the UART receiver.
Humberto |
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sun Aug 15, 2010 10:18 am |
|
|
In addition to Humberto's comments:
Quote: | >>> Warning 216 "main.c" Line 663(37,38): Interrupts disabled during call to prevent re-entrancy: (@MUL1616) | First of all, it is a warning, not an error. Your program will work, but with a (small) limitation.
If you had searched this forum you would have noticed this warning is quiet common. The warning is telling you that a function inside the Interrupt routine is calling the same function as is being called from main. Because the CCS compiler does not allow re-entrant functions it protects against errors by temporarily disabling the interrupts before calling the clashing function. Whether this is a big problem or not is upon you to decide.
The function causing the clash is also mentioned: MUL1616. This is the CCS compiler internal function for multiplying two int16 variables. I haven't checked, but I guess the compiler is using this function to calculate the address offset into the array and inside main it has to use the same function too. Considering that serial data reception is slow in terms of computer speed, I for now would ignore the warning.
But please redesign the code so it does only process the reception of 1 single character. An interrupt should be as fast as possible, now you are defeating the whole purpose of interrupts and could just as well have left them out. |
|
![](templates/subSilver/images/spacer.gif) |
neverlog
Joined: 02 May 2010 Posts: 36
|
|
Posted: Mon Aug 16, 2010 1:33 am |
|
|
Just make sure your buffer size is multiple of 8, it will solve your problem. |
|
![](templates/subSilver/images/spacer.gif) |
Linuxbuilders
Joined: 20 Mar 2010 Posts: 193 Location: Auckland NZ
|
|
Posted: Mon Aug 16, 2010 6:37 am |
|
|
thank you, will redesign it, thnx for help. _________________ Help "d" others and then you shell receive some help from "d" others. |
|
![](templates/subSilver/images/spacer.gif) |
|