No announcement yet.

Compiled Program memory usage

  • Filter
  • Time
  • Show
Clear All
new posts

  • Compiled Program memory usage

    How can I tell how much memory space my compiled program needs?
    I have code which i load to a PIC16F886 and it runs all day long, I have a variation on that code which i can load OK to one PIC and it runs, I load it to another and it does not run.
    I just want to be sure that I am not close to any limits.

    THe compiled code in HEX files is 23K for the smaller and 27K for the larger yet the larger one runs OK on one PIC and not on another - all PICS are new and from the same source and would most definitely be guine microchip parts.

    The basic code used to run just fine on a PIC16F690 but I needed more output ports so I switched to the PIC16F886 as it was supported by the version of PICbasic that I was using.

    As far as I can tel they both have 256 bytes of EEprom but the PIC16F886 has twice the program space of the PIC16F690 (14K vs 7k) so I cant think that is the problem.

    Apart from serial data in and out on RC6/RC6 I have 33K resistors on RA0 - RA7, RC0 to RC5 and RB0 to RB7 - these all drive the bases of MPSA42 transistors. I have 5V on pin 20VDD , GND on pins 19 and 8 VSS with 100nf cap across them then I have RE3/MCLR/VPP, ICSPDAT, ICSPCLK, VDD and VSS bought to a connector for ICSP.

    When the code starts it does a little serial handshaking with other identical devices in a string of them (up to 255) and I can see that data coming out of the serial port - thereafter it appears to hang.

    I do have a PICKit ICSP device (though I have not used it) - is there any way I can use that with PICBasic to step through and debug the code?

    I suspect that I will most likely need to re-develop the smaller code to the larger code, testing it all the way to see what breaks it.

    Any pointers to where I should look would be much appreciated.

    - Richard
    Attached Files
    Last edited by scalesr1; 4 weeks ago. Reason: Added additional information

  • #2
    Do you have any pullup resistors on RC6 and RC7? I would use 10K's on them. I have NO IDEA what kind of serial commands you are using as there is no code to check. If these lines are to become disconnected and float to ground it could be hanging the RS232 commands.
    Dave Purola,


    • #3
      It might be a Watch Dog Timer issue. Another thing, you don't show a pull-up resistor on MCLR (RE3). The consensus is use at least a 10k there; I use 4.7k after a 10k failed in the field once. You say it "hangs", but maybe it's RESETting.
      We can crack this cotton PIC'n thang!


      • #4
        I have made some progress and managed to narrow it down to just one thing. I have a line that defines a buffer 'RX_BUFFER [17]. The simple act of increasing that to 25 is enough to break things. Without doing this everything works just fine, serial data in, serial data out and all the ports being switched just the way that the code is asking them to do.
        This (to me) suggests that it's a memory capacity thing though this code previously ran on a PIC16F690 which has less SRAM (256 bytes as opposed to 368 bytes on the PIC16F886) so I would be surprised if adding 8 bytes of storage would exceed the limit.
        Hence the query about how to work out what the actual memory requirements of the compiled program are. Is there any way to find this out?
        I'll continue to develop the code though I do need to sort the issue out.
        If it is a memory thing then perhaps moving to yet another PIC with the required number of ports and more RAM might be the answer.
        In answer to the other suggestions, there are NO pullups on RC6, RC7 or RE3/MCLR - the fact that I have not used them in the past clearly does not mean it's good practice but right now the thing is running apparently perfectly albeit for the issue of the size of RX_BUFFER.


        • #5
          After you compile you will have a .lst Listing file in your project folder. Open it with a text editor. At the bottom it will list your memory usage.
          We can crack this cotton PIC'n thang!


          • #6
            If you're actually changing a line from "RX_BUFFER[17]" to "RX_BUFFER[25]" without increasing the size of the buffer declaration, then you're probably overrunning the array.

            If you're changing the declaration and meant to write "RX_BUFFER VAR BYTE[17]" changed to "RX_BUFFER VAR BYTE[25]", I suspect that when you increase the size of the array it forces PBP to move it to a different bank of RAM. You can see this in the .asm file. When the array moves, other variables move to accommodate it. If you have no inline Assembly in your program, none of this should cause a problem. Perhaps if you post the program we can spot potential problems.

            You can also force PBP to place the array (or any variable) to a specific bank:

            RX_BUFFER VAR BYTE[17] BANK0

            The generated .asm file will show where PBP is placing all the variables. PBP will abort the compile with an error message if it can't fit all the variables in memory.
            Charles Leo
            ME Labs, Inc.


            • #7
              Hello and thank you for your replies.

              Firstly - I can see that from the LST file, it reports:

              Program Memory Words Used: 4656
              Program Memory Words Free: 3536

              Though it does not seem to give any indication of the amount of RAM required for variable storage etc.

              On the second point, yes, sorry, I messed that up - it is indeed changing RX_BUFFER Var Byte [17] to RX_BUFFER Var Byte [25]. There is a lot of inline assembly in the program.

              I didn't want to just post the code without trying a little harder first. As it has now been mentioned I have attached the source code. Hopefully this might turn up something.

              Attached Files


              • #8
                does your interrupt restore a context that was never saved ?
                or does pbp save automatically for those chips ?

                ok i can answer that ,

                01182 if (RESET_ORG == 0)
                0004 00A0 01183 movwf wsave ; 1 (10) Save the W register
                0005 0E03 01184 swapf STATUS, W ; 1 Get STATUS to W without wrecking it
                0006 0183 01185 clrf STATUS ; 1 Point to bank 0
                0007 00BA 01186 movwf ssave ; 1 Save the STATUS register
                0008 080A 01187 movf PCLATH, W ; 1 Save PCLATH
                0009 00B5 01188 movwf psave ; 1
                01189 else
                01190 ifdef PM_USED
                yep it does
                Last edited by richard; 4 weeks ago.


                • #9
                  is the code you posted the working code or the code that fails ?


                  • #10
                    Hello again, The code that I posted 'works' unless I had RX_BUFFER vary byte [25] set as opposed to RX_BUFFER var byte [17] - or so I believed.
                    In an effort to chase that out - I compiled files with the [value] set from 17 up to 25 in increments of 1 and I tested each in turn - hoping to find when it 'broke' - as it happened, they all worked - right up to 25 so I have no idea what 'problem' I was actually looking at.
                    I have loaded this code on to three different boards and they do all appear to work (currently).
                    I'm now going away to test more, much more and will report back.
                    Additionally, an earlier suggestion talked about pulling MCLR high with a resistor - which I have not done, In the CONFIG section I set MCLRE_OFF which I thought did this using an internal pullup.
                    I will report back asap


                    • #11
                      Your asm code assumes all the variables referenced are in BANK0. Try declaring all variables that are referenced from asm code with a BANK0 modifier. If they won't all fit in BANK0 when you expand the buffer array (PBP will tell you "unable to fit variable in specified bank"), you'll need to add bank-selection lines before and after any asm line that references a variable that isn't in BANK0.

                      Make sure you do it for all of them. I see the following without looking too hard:

                      RX_BYTE_CNT Var Byte BANK0 ; count of the number of data bytes received
                      RX_BUF Var BYTE BANK0 ; buffer for the received byte
                      BYTE_CNT VAR BYTE BANK0 ; 'bytes processed' counter
                      PROGRESS var byte BANK0
                      RX_BUFFER Var Byte [17] BANK0
                      Charles Leo
                      ME Labs, Inc.


                      • #12
                        Thank you for that, I just read about PIC16F and Bank size here:
                        From that I assume that each BANK is 128 bytes.
                        I will check the list of variables that are referenced in the ASM code and specify their BANK number - as you suggest - I will firstly set them all to BANK0 and see if I can get any compilation errors.
                        If I do then I could perhaps move RX_BUFFER to BANK1.
                        I have looked at the manuals but am uncertain how to add BANK selection lines before and after any ASM line that references a variable that isn't in BANK0.

                        I just noticed these warnings - even when I compile code that appears to run perfectly:

                        Message [306] C:\PICTEMP\STEP6ANW3R25WITHBYTE3READ.ASM 1746: Crossing page boundary - - ensure page bits are set.
                        Message [306] C:\PROGRAM FILES (X86)\PMP3_1\PBPPIC14.LIB 745: Crossing page boundary - - ensure page bits are set.
                        ​​​​​​​Message [306] C:\PROGRAM FILES (X86)\PMP3_1\PBPPIC14.LIB 663: Crossing page boundary - - ensure page bits are set.

                        I then opened the .ERR file that was also generated at it is full of similar messages (attached and renamed to .TXT), I get the feeling that I should be really concerned about these - should I be?
                        Attached Files


                        • #13
                          I specified BANK0 for all the variables referenced in ASM sections and got no additional errors.


                          • #14
                            I have to amend my previous advice. I didn't see the abundance of asm code throughout the program in addition to the ISR. You should add the BANK0 modifier to any variable used in ANY asm block.

                            Code pages are a different subject and you may have a concern there. PBP-generated asm will always handle jumps across code page boundaries, but if your inline asm happens to land where a jump across a boundary executes, I don't see any asm code to handle it. This isn't a concern with the ISR because it's placed early in the program, but the asm blocks placed lower might be an issue. See section 7.2 in the PBP3 Reference Manual.

                            Charles Leo
                            ME Labs, Inc.


                            • #15
                              Thank you for that tip - would it be a relatively simple approach to just move the RX_BUFFER var byte [25] to bank1 and then deal with that in the asm code? If so - how do I handle that within the asm code?
                              On a different tack, am I having to deal with all of this because of the nature of the PIC in question and would perhaps a more 'modern' PIC offer the required number of ports, appropriate RAM and eeprom size without the need to handle the paging and if so, what should I be looking at? I ask just in case there is a simpler more contemporary way of resolving this issue.