|
|
View previous topic :: View next topic |
Author |
Message |
kmp84
Joined: 02 Feb 2010 Posts: 354
|
Not enough RAM Error 74. [Solved] |
Posted: Sat Dec 12, 2020 11:43 am |
|
|
Hello,
I have two program 'A' and 'B'. When I compile separately they work. Program 'A' take 3 % RAM , program 'B' take 1% RAM. When merging them together compiler say : "Error 74 ... Not enough RAM for all variables".
Is this some stack overflow problem?
CCS v.5.093, dspic33EP512MU810.
Last edited by kmp84 on Mon Dec 14, 2020 2:18 pm; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Dec 12, 2020 1:31 pm |
|
|
Post a small test program that shows the problem. |
|
|
kmp84
Joined: 02 Feb 2010 Posts: 354
|
|
Posted: Sat Dec 12, 2020 1:47 pm |
|
|
Hi,
Program 'B':
Code: |
#include <33EP512MU810.h>
#device ICSP=1
//#device adc=12
#use delay(crystal=8MHz, clock=40MHz)
#FUSES NOWDT //No Watch Dog Timer
#FUSES CKSFSM //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOJTAG //JTAG disabled
/* HW UART1 */
#pin_select U1RX=PIN_E1 // Rx Com1.
#pin_select U1TX=PIN_E0 // Tx Com1.
#define EN1_485 PIN_D1 // RE/DE Com1.
#use rs232(UART1,baud=38400,errors,enable=EN1_485)
#define CAN_BAUD_RATE 1000000 //500000//250000//125000
/* CAN BUS-1 */
#pin_select C1TX=PIN_F0
#pin_select C1RX=PIN_F1
#case
#include <can-PIC24_dsPIC33.c>
#define PER_EN PIN_D5
#define PER_ON() output_low(PER_EN)
#define PER_OFF() output_float(PER_EN)
void main(void)
{
delay_ms(300);
PER_ON();
//CAN_TX_HEADER tHeader;
CAN_RX_HEADER rHeader;
//uint8_t tData[8];
uint8_t rData[8];
unsigned int16 i,j;
enable_interrupts(GLOBAL);
for(i=0;i<8;i++) {
rData[i] = 0;
}
delay_ms(1000);
can_init();
printf("\r\n\nCan Bus Sniffer Running at:%7.3lwKbps.\r\n\n", CAN_BAUD_RATE);
i = j = 0;
while(TRUE)
{
if(can_kbhit())
{
if(can_getd(&rHeader, rData) == CAN_EC_OK)
{
printf("\r\n\nCAN Mess:%u, Id=0x%lX, Ext.Id=%u, DLC=%u, RTR=%u\r\nData: ", i++, rHeader.Id, rHeader.ext, rHeader.Length, rHeader.rtr);
for(j=0;j<8;j++){
printf(" 0x%X", rData[j]);
}
}
}
}
} |
Program 'A' can't post because it's CCS PIC 24 bit Wizard TCP/IP example. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9229 Location: Greensville,Ontario
|
|
Posted: Sat Dec 12, 2020 3:52 pm |
|
|
hmm, according to Google, that PIC has 52KB of SRAM...
so I suspect the CAN driver has a HUGE 'buffer' ??
Your test program might use 8-20 bytes ?? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Mon Dec 14, 2020 1:41 am |
|
|
Does the compile status (not the main window, but the results put up at the
bottom of the IDE), give any warnings in the combined program?. My guess
would be something like a #define that is being set twice, or is set to a
different value in the 'combined' program, that results in a very much
larger allocation for something.
It's going to be something wrong in the 'combining' of the two program. The
question is 'what'. |
|
|
kmp84
Joined: 02 Feb 2010 Posts: 354
|
|
Posted: Mon Dec 14, 2020 4:25 am |
|
|
Hi,
CCS support answer me to check .sym file for variables that are marked with "na" not allocated in ram and i found this:
W0 -W1 @MULFF.P27
W0 -W3 @MULFF64.P28
W0 -W1 @DIV3232A.P29
W0 -W1 @DIVS3232A.P30
W0L WREG0
na ecan1_message_buffer
W1 @SCRATCH
W1 @READ_PACKED_MEMORY.P1
W1 @READ_ROM_MEMORY_LOW.P2
W1L WREG1
which is in "can-PIC24 dsPIC33.c" driver's library.
Code: |
// Buffer for CAN1
#BANK_DMA
uint16_t ecan1_message_buffer[CAN_BUFFER_SIZE][8];
uint8_t ecan1_last_fifo_buffer = (CAN_BUFFER_SIZE - 1);
#if getenv("ENH24") == TRUE
#if (getenv("DEVICE") != "PIC24EP256GU810") && (getenv("DEVICE") != "PIC24EP256GU814") && \
(getenv("DEVICE") != "PIC24EP512GP806") && (getenv("DEVICE") != "PIC24EP512GU810") && (getenv("DEVICE") != "PIC24EP512GU814") && \
(getenv("DEVICE") != "DSPIC33EP256MU806") && (getenv("DEVICE") != "DSPIC33EP256MU810") && (getenv("DEVICE") != "DSPIC33EP256MU814") && \
(getenv("DEVICE") != "DSPIC33EP512GP806") && (getenv("DEVICE") != "DSPIC33EP512MC806") && (getenv("DEVICE") != "DSPIC33EP512MU810") && (getenv("DEVICE") != "DSPIC33EP512MU814")
#locate ecan1_message_buffer = 0x1200 //using this address incase code is being debugged
#endif
#endif
|
To tell again two programs separated work with no problem. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Mon Dec 14, 2020 4:39 am |
|
|
If you compile your program B, you can see this being allocated:
D000-D1FF ecan1_message_buffer
Into the DMA space correctly.
The point is that something in the program A has to be interfering with
this allocation.
Does program A use DMA?.
Does program A specifically allocate any memory?.
If it is using DMA, there is a restriction in the compiler, that all #BANK_DMA
statements need to be sequential in the code. Also if you allocate a variable
that is not a multiple of the DMA bank size you may need to use __attribute__
to force correct alignment of the next variable. If you have
other #BANK_DMA instructions placed elsewhere in the code, this could
cause your problem. |
|
|
kmp84
Joined: 02 Feb 2010 Posts: 354
|
|
Posted: Mon Dec 14, 2020 5:01 am |
|
|
Hi mr.'Ttelmah',
Program 'A' is "CCS Project 24 bit Wizard" generated code. In my case "sample" TCP/IP icmp request example. It's not my code, but I didn't see any other #locate or #BANK_DMA directives. |
|
|
kmp84
Joined: 02 Feb 2010 Posts: 354
|
|
Posted: Mon Dec 14, 2020 11:26 am |
|
|
ok, this is Program 'A' which are generated from 'Project 24 bit Wizard' tool based on ENC28J60 eth. controller:
Code: |
#include <main.h>
void IPAddressInit(void)
{
//MAC address of this unit
MY_MAC_BYTE1=MY_DEFAULT_MAC_BYTE1;
MY_MAC_BYTE2=MY_DEFAULT_MAC_BYTE2;
MY_MAC_BYTE3=MY_DEFAULT_MAC_BYTE3;
MY_MAC_BYTE4=MY_DEFAULT_MAC_BYTE4;
MY_MAC_BYTE5=MY_DEFAULT_MAC_BYTE5;
MY_MAC_BYTE6=MY_DEFAULT_MAC_BYTE6;
//IP address of this unit
MY_IP_BYTE1=MY_DEFAULT_IP_ADDR_BYTE1;
MY_IP_BYTE2=MY_DEFAULT_IP_ADDR_BYTE2;
MY_IP_BYTE3=MY_DEFAULT_IP_ADDR_BYTE3;
MY_IP_BYTE4=MY_DEFAULT_IP_ADDR_BYTE4;
//network gateway
MY_GATE_BYTE1=MY_DEFAULT_GATE_BYTE1;
MY_GATE_BYTE2=MY_DEFAULT_GATE_BYTE2;
MY_GATE_BYTE3=MY_DEFAULT_GATE_BYTE3;
MY_GATE_BYTE4=MY_DEFAULT_GATE_BYTE4;
//subnet mask
MY_MASK_BYTE1=MY_DEFAULT_MASK_BYTE1;
MY_MASK_BYTE2=MY_DEFAULT_MASK_BYTE2;
MY_MASK_BYTE3=MY_DEFAULT_MASK_BYTE3;
MY_MASK_BYTE4=MY_DEFAULT_MASK_BYTE4;
}
void main(void)
{
IPAddressInit();
TickInit();
enable_interrupts(GLOBAL);
StackInit();
while(TRUE)
{
StackTask();
StackApplications();
//TODO: User Code
}
} |
This is "main.h":
Code: |
#include <33EP512MU810.h>
#device PASS_STRINGS=IN_RAM
#device ICSP=1
/*
TCP/IP Stack enabled.
Many TCP/IP configuration settings (servers enabled, ports used,
etc) are defined in TCPIPConfig.h.
Many hardware configuration settings (SPI port and GPIO pins used)
are defined in HardwareProfile.h.
*/
#include "tcpip/PCDxxxx.h"
#define __PIC24F__
#define __C30__
#define WIFI_MAX_SSID 32
#include <stdint.h>
#use delay(clock=80MHz,crystal=8MHz)
#FUSES NOWDT //No Watch Dog Timer
#FUSES CKSFSM //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOJTAG //JTAG disabled
#define MIN(a,b) ((a > b) ? b : a)
#define wf_debug_printf(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p)
#include "tcpip/TCPIPConfig.h"
#include "tcpip/HardwareProfile.h"
#include "tcpip/StackTsk2.h"
#if TCP_CONFIGURATION > 0
TCPSocketInitializer_t TCPSocketInitializer[TCP_CONFIGURATION] =
{
#if defined(STACK_USE_CCS_HTTP2_SERVER)
{TCP_PURPOSE_HTTP_SERVER, TCP_ETH_RAM, STACK_CCS_HTTP2_SERVER_TX_SIZE, STACK_CCS_HTTP2_SERVER_RX_SIZE},
#endif
#if defined(STACK_USE_SMTP_CLIENT)
{TCP_PURPOSE_DEFAULT, TCP_ETH_RAM, STACK_CCS_SMTP_TX_SIZE, STACK_CCS_SMTP_RX_SIZE},
#endif
#if defined(STACK_USE_MY_TELNET_SERVER)
{TCP_PURPOSE_TELNET, TCP_ETH_RAM, STACK_MY_TELNET_SERVER_TX_SIZE, STACK_MY_TELNET_SERVER_RX_SIZE},
#endif
#if defined(STACK_USE_CCS_HTTP_CLIENT)
{TCP_PURPOSE_GENERIC_TCP_CLIENT, TCP_ETH_RAM, STACK_MY_HTTPC_TX_SIZE, STACK_MY_HTTPC_RX_SIZE},
#endif
};
#else
#undef TCP_CONFIGURATION
#define TCP_CONFIGURATION 1
TCPSocketInitializer_t TCPSocketInitializer[TCP_CONFIGURATION] =
{
{TCP_PURPOSE_DEFAULT, TCP_ETH_RAM, 250, 250}
};
#endif
#include "tcpip/StackTsk2.c" |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Mon Dec 14, 2020 12:15 pm |
|
|
OK.
The problem is that PCDxxxx.h is turning on PSV.
The PSV buffer is not compatible with the DMA setup for the CAN DRIVER.
Now with PASS_STRINGS=IN_RAM, provided nothing attempts to construct
pointers to a const, it may work without PSV enabled.
So try remarking out the line in PCDxxxx.h #device PSV=16
Report it to CCS, since it means they really need to look into how their
functions behave with this enabled. |
|
|
kmp84
Joined: 02 Feb 2010 Posts: 354
|
|
Posted: Mon Dec 14, 2020 1:22 pm |
|
|
Thank you mr.'Ttelmah',
TCP&CAN bus example working!
There is nothing in CCS help about #device PSV=16.
But here is short info:
Quote: |
The upper 32 Kbytes of the PIC24H data memory address space can optionally be mapped intoany 16K word program space page. This mode of operation, called Program Space Visibility(PSV), provides transparent access of stored constant data from X data space without the needto use special instructions (i.e., TBLRD, TBLWT instructions).
PSV canonly be used to access values in program memory space. Table instructions must be used toaccess values in the user configuration space |
Why CCS enabled this option when not needed? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9229 Location: Greensville,Ontario
|
|
Posted: Mon Dec 14, 2020 2:16 pm |
|
|
You'd have to ask CCS directly but...often their 'defaults' aren't what I or others 'think' that 'defaults' should be !
One example... when using #rs232(...options..) 'ERRORS should automatically be the default, as without it the UART can lockuo(stop) due to a framing error.
Another is that the default for certain pins are 'peripherals' and not basic,simple digital I/O. I'm old enough to think in simple I/O and consider peripherals like UARTS, ADC,DAC, etc. are 'optional' things I can use..I don't consider them to be the primary or default uses of pins.
I'm sure glad it's 'up and running' !
Jay |
|
|
kmp84
Joined: 02 Feb 2010 Posts: 354
|
|
Posted: Mon Dec 14, 2020 2:31 pm |
|
|
Quote: |
1.
One example... when using #rs232(...options..) 'ERRORS should automatically be the default, as without it the UART can lockuo(stop) due to a framing error.
2.
Another is that the default for certain pins are 'peripherals' and not basic,simple digital I/O. I'm old enough to think in simple I/O and consider peripherals like UARTS, ADC,DAC, etc. are 'optional' things I can use..I don't consider them to be the primary or default uses of pins
|
This is good suggestion, especially ADC ports should be disabled at defaults. In '_normal_' chips and compilers all port are set as digital inputs or high impedance. Many issue here are exactly for ADC ports enabled. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Tue Dec 15, 2020 2:06 am |
|
|
PSV, is actually a very 'cool' feature.
With it enabled, you can have const variables, and access them exactly as
if they are in RAM. Pointers work, and also the actual access code can use
the standard RAM functions. It makes these PIC's very much more usable.
However problem is that it needs a window in the RAM to be used.
What is happening here is that the window and the DMA area are clashing
with one another...
So for 90% of users, I'd say 'use PSV, it makes the chip more compatible
with other compilers'. However for the small percentage using things like
DMA, 'caveat'.....
They do it in the TCP library, to increase the compatibility with the MicroChip
compilers. However 'Pass_strings' brings 90% of the same compatibility,
without needing the PSV window space.
When I walked through the stuff being loaded, I realised that this was being
done, and that it might well bring problems with the DMA allocation. Given
that you had already found that it was the DMA buffer that was not being
allocated, I suspected removing this might fix it.
Worth saying Jay, that on the recent compilers, the default is to always
set all pins as digital for you. So CCS have moved to this being assumed.
However 'ERRORS' is really annoying. What is worse, is that many of
the old 'examples' don't show this. Definitely a 'minus score' on this.... |
|
|
kmp84
Joined: 02 Feb 2010 Posts: 354
|
|
Posted: Tue Dec 15, 2020 2:42 am |
|
|
Thanks again mr.'Ttelmah' for help!
P.S I have no experience with DMA units in Microchip. Where is good place to getting familiar with it?
Best Regards! |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|