Menu

Adding 2 more lines of code freezes PIC

Help
MBB
2012-09-13
2013-05-30
  • MBB

    MBB - 2012-09-13

    I'm using a PIC 16f876 which allows 8k words of code.

    I have a program that is working on the PIC.

    If I add a LOCATE / PRINT command the PIC freezes after the LOCATE / PRINT is executed.

    Extracting the word count from the HEX code, shows their are 2451 words in the program.

    The compile screen says the program used:

    Input lines:  0
    Variables: 111 <368 max>
    Constants: 203 <400 max>
    Subroutines: 161 <500 max>
    Assembly program lines written: 0  <20000 max>
    …..
    …..
    …..
    Program assembled successfully.

    So, what makes the program freeze?

     
  • Mauried

    Mauried - 2012-09-14

    Possibly stack overflow.
    Is the Locate / Print command in a sub routine.
    Do you have any nested sub routines , ie a sub routine inside another one.
    Solving stack overflow problems is tricky other than by going the LST file and counting the number of stack pushes and pops.

     
  • MBB

    MBB - 2012-09-15

    Thanks!
    No, It's not in a sub routine.

    There are no nested routines.

    Do you know what commands I should look for in the .lst file for stack overflow?

    Some additional information:  I took a working program and changed a " > " statement to a " >= " statement and the program stop working, again. ( i.e.  A > B  to  A >= B.)

     
  • Nobody/Anonymous

    How close to full is the program memory?
    If the code is using all the memory pages which the LST file will tell you, then try this.
    In your program where the code is thats stopping it from working, ie the Locate / Print
    Try adding some NOP instructions and then recompile and see if it runs OK.
    The NOPs dont do anything, other than change the size of the program which can make the compiler shuffle code from one memory page to the next one, which sometimes fixes the problem.

    You may need to do this a few times, adding a few more NOPs each time.
    Ive not used 16F876, but Ive had a similar problem in the past with 16F886 where the program was large and using
    all the memory pages.
    Never worked out exactly what the problem was, other than the compiler seemed to be incorrectly calculating the program size when the program is getting large.

     
  • MBB

    MBB - 2012-09-17

    Thanks! 

    The NOPs worked but there must be an easier and more correct means of fixing this problem.

     
  • Mauried

    Mauried - 2012-09-18

    The problem as far as I have been able to work out , is that the program ends up in running code from the wrong page due to
    the PCLATH register being incorrectly set.
    I havnt been able to reproduce on a consistant basis what the fault is , but the adding of the NOPS changes the way the compiler works out where in memory to locate the program code, so that the page issue vanishes, temporarily.
    The Call and Goto commands are the offending ones, especially when they jump a page boundary.
    You can sometimes pick that this issue will be a problem , if the Compiler says there isnt enough room for your program
    after you have removed some instructions.

     
  • MBB

    MBB - 2012-09-19

    Thanks for all your help!

     
  • Nobody/Anonymous

    I just got nailed by this bug; there has been some real hair-pulling around here!

    My program uses HSerSend and the LCD routines. If I comment out the former, the code ends up under 2K and the LCD works fine. If I put HSerSend back in, then the code spills over into Bank 2 and the LCD stops working correctly and the program hangs. I can see in the .LST file where GC breaks off around 0x0600 and bumps the remaining code up to 0x0800.

    If I put a dummy HSerSend in at the start of the program, GC reports I'm out of program space (with over 1K left over in reality).

    I'm at loss to figure out what I should do next. Any suggestions on what tests I can do to get some more information?

    Is there any way to have GC rearrange the order of its subroutines?

     
  • Anonymous

    Anonymous - 2012-09-29

    Hello all,

    Yes, I think we have a serious bug here. I'm using a PIC16F88 with a program consisting of about a dozen subroutines with no nesting beyond two levels. Total program space used is around 2500 bytes. Some of the subroutines end up in Page 0, while others end up in Page 1.

    Parts of the program work and other parts don't. If I remove enough chunks to bring the program size below 2048 bytes, everything works. If I start adding stuff back in, once the size increases to require Page 1, things start acting up again.

    I suspect some of the PAGESEL $ commands are being left out, or something similar.

    Most bugs are pretty trivial and can be worked around, but this one seems particularly troublesome. Being restricted to Page 0 only isn't a great choice.  What do you think?

    Thomas Henry

     
  • Mauried

    Mauried - 2012-09-30

    There are a number of problems that can occurr with largish programs in the PICs with paged memory.
    First one is stack overflow, which isnt a Compiler problem, its just a limitation of small PICs.
    PICs like 16F88 have only a 8 level stack which loops around if it overflows.
    Overflow will cause your program to crash.
    Many of the commands in Gcbasic such as Hserout or LCDprint are themselves subroutines which will push the stack pointer.
    You can look in the include/lowlevel directory in Gcbasic you can see all the commands and how they are implemented.
    Its possible to figure out how many stack pushes each command uses.
    Try and avoid lots of complex commands in subroutines.

    The page boundary problem is differant , and I have never been able to figure out exactly whats happening.
    Try and avoid gotos in subroutines which go outside the current page.
    You will have to go thru the LST file to see if this is happening.
    If the Compiler is complaining about not enough memory, when you know there is , its likley its not calculating properly
    how large the program is , and this is usually a giveaway that your program will have probs running.
    Moving to 18F or higher,  or AVR chips in the long term is the best fix

     
  • Anonymous

    Anonymous - 2012-09-30

    Hi Mauried,

    Thanks for your comments.

    You mention that we should try to avoid GOTOs that leave the current page. But do we (the programmers) have any control over that? I tried moving my code around in various ways, but it seems GC Basic had its own ideas about where to store the code and in what order. For example, in the current program, I have six screen menus, each in its own subroutine. No matter how I rearrange them physically in the code (123456, 654321, 123654, etc.) GC Basic always decided to put a couple in Page 0 and the rest in Page 1. I can't see that I have any control over that.

    I could divvy up my code so that there would only be one page-jump (which I could fix in assembler to make sure the PAGESEL command is in place). But like I say, I'm not sure I have any control over that.

    Which makes me think, maybe a nice feature for a later version would be a compiler directive that forces a particular chunk of code to end up in a desired page.

    But in the meanwhile, I come back to, can't we fix GC Basic to handle using any chunk of program memory? I mean, in my case, I've got 4K of memory but can't reliably use more than 2K of it.

    Thanks for listening,

    Thomas Henry

     
  • Hugh Considine

    Hugh Considine - 2012-09-30

    I really have no idea why things aren't working properly, sorry! If you can send some code to me at w_cholmondeley at users dot sourceforge dot net, I am happy to examine the compiler while it is working with your code and see what is going wrong!

    GCBASIC tries to assign subroutines to pages based on this algorithm:
    1. Calculate the size of each subroutine
    2. Sort subroutines in order of size
    3. Assign some subroutines (interrupt handlers and initialisation routines defined with #startup) to page 0
    4. Go through the list of subroutines, trying to put them where they will fit. First, it will try to put a sub in page 0 - if it doesn't fit, then it will try page 1, page 2, etc.
    5. Recalculate the size of each subroutine once page selection code is added, and check if they still fit
    6. If subroutines don't all fit, go back to step 2 with the new sizes and try placing things again
    7. If it has tried to place subroutines 10 times and none of the combinations have worked, show an error and quit.

    This code has been in place since about 2009, and has dealt with most of the problems and removed the need to manually specify the use of lcall. However, it's clearly still not perfect!

    Trying to work out where to put subroutines is not an easy thing for the compiler to do. If you have 10 subroutines and 4 banks, I think there are 4 ^ 10 (about a million) possible combinations (including those where the subroutines don't fit). Each extra subroutine multiplies the number of combinations by the number of banks. Perhaps I need to look for some better algorithms, but in the mean time I will look at any code you can send me and see if I can spot the problem.

    It's also important to keep subroutines smaller if possible, that algorithm above doesn't work well if you have 3 1200 word subroutines. That's only 3600 words, which looks like it should fit into 4096 words of memory, but GCBASIC doesn't allow subroutines to span multiple pages because that would require pagesels for gotos as well. It will put the first sub into page 0, and the second into page 1, but then will only have about 800 words left in each bank - not enough to put the third sub into either of them.

     
  • Frank

    Frank - 2012-09-30

    I had a look at the "out of program space" bug a few months ago and wrote some print statements in the compiler to try and figure it out. It looks like the compiler gets stuck in a loop of trial fits sometimes. In the simplest case one trial fit leads to a second that leads back to the first but depending on the program you can get loops of  upto 6 or more trial fits before it cycles back to the first. I don't have any solution to the problem as it seems like it might be inherent to the algorithm. I did try reversing the order the subroutines are placed in memory so it starts with the smallest subroutines first and that seems to work much more often than fitting the largest subroutines first for some reason. I guess you could have the compiler make 10 attempts to fit the smallest subs first and if that doesn't work make 10 attempts with the largest subs first.

    Some of the posters though are having the problem discussed in this thread -

    https://sourceforge.net/projects/gcbasic/forums/forum/596084/topic/3763039

    Its still not really fixed as whatpic has said in another thread. Did you get my last email about that Hugh? It was some time ago now I know.

    Frank

     
  • Mauried

    Mauried - 2012-10-01

    This isnt a fix, but Hugh may be able to answer.
    Is it possible to include ORG directives in the Basic program , so that the writer can force the compiler
    where to put the subroutines.
    Manual placement may work better than trying to fit them all in automatically.
    Also, there arnt many PICS that have this problem.
    It can only occurr in 16F series chips with more than 2048 words of memory.

     
  • Anonymous

    Anonymous - 2012-10-13

    Hi all,

    I can confirm some of the behavior mentioned above. I'm using a PIC16F88 with 4K of program space.

    When my code gets to about 3.5K, I start having more troubles with "out of program space." And yet by increasing the amount of code (sometimes just with a well-placed NOP), the problem goes away.

    I found by breaking things up into a large number of smaller subroutines I could sometimes get close to the 4K limit. So far, I've gotten up to 200 bytes free, but only by playing with the NOPs like crazy.

    As far as the original poster's problem, I believe Hugh has found something with the LCD initialization routine that was probably the troublemaker, but unrelated to the subroutine allocation business.

    It would be nice if the error message "out of program space" could give some additional feedback on where to start increasing or reducing things to make everything fit.

    Thanks for listening!

    Thomas Henry

     
  • Hugh Considine

    Hugh Considine - 2012-10-14

    I've just uploaded another update, which fixes a few problems in page selection. There were a few problems that I fixed:

    - Page selection wasn't being done properly for automatically added setup routines
    - Page selection was not being added properly in some situations where GCBASIC detects that the last line of a subroutine is a call, and replaces it with a goto to another sub to save a return later.
    - Loops of trial fits could occur with the compiler trying one arrangement of subroutines, then another, then a third, then going back to the first (as you noticed Frank!)

    I'm not particularly keen to have manual allocation of subroutines. It's something that could be implemented without too much trouble, but I think it would lead to manual reshuffling every time that some more code was added. It would also tie the program to one particular model of chip, which is something that I never want to do.

    Smaller subroutines are easier for the compiler to shuffle around, so that would certainly help the compiler to allocate memory. Thomas, if you're still having problems, please email me the code again and I'll have another look. This is definitely something that needs to be dealt with.

     
  • Anonymous

    Anonymous - 2012-10-16

    Hi Gang,

    Wow! Here's a great thanks to Hugh for the newest update. Apart from the improvements to the subroutine allocation business, I really like the rich compiler feedback page. This really gives a newcomer like me a feel for how much RAM is left, and it's interesting to see all of the subroutine dependencies laid out. Very nice!

    The new graphical LCD routines look great; I'm putting an order together tonight to get one of these things at once.

    Thanks again to Hugh for updating things like this. I'm having a real blast with the system and really appreciate all of his work.

    Thomas Henry

     
  • MBB

    MBB - 2012-10-16

    Sounds Great!!!

    What file do I download to get this update?

     
  • Hugh Considine

    Hugh Considine - 2012-10-17

    The update is at http://gcbasic.sourceforge.net/update.html, please try it and let me know what you think!

     
  • MBB

    MBB - 2012-10-24

    I finally got a chance to try the update and it worked.

    Thanks!!!

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.