CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Memory organisation trouble...

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
evan



Joined: 02 Apr 2012
Posts: 22

View user's profile Send private message

Memory organisation trouble...
PostPosted: Mon Apr 02, 2012 6:29 am     Reply with quote

Hi all, I'm a new user of the CCS compiler, and am finding it a lot of fun to use.

I am currently trying to get my bootloader working - it should live in the first block of the 16F1517 - 0x0000 to 0x07FF. The compiler reports 1136 locations used, so it should fit no problem.

I put #org 0x0005, 0x07FF before the code to try to restrict it to this area, but in the disassembly I see that the #use commands (rs232 and delay) are generating code starting at 0x0800!

Obviously this will cause a conflict as my application is supposed to live there.

Am I missing something obvious? How can I resolve this?

Thanks!
jeremiah



Joined: 20 Jul 2010
Posts: 1328

View user's profile Send private message

PostPosted: Mon Apr 02, 2012 6:55 am     Reply with quote

#org can be used a couple different ways, both to "use" and "exclude" memory locations. We would really need to see a short, compilable example of what is not working as well as know the compiler revision you are using.

For example, i tried the following in 4.130 and saw no issues:
Code:

#include <16F1517.h>
#device adc=16

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT_SW                   //No Watch Dog Timer, enabled in Software
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O


#org 0x0005,0x07FF default
#use delay(clock=20000000)
#use rs232(UART1,baud=9600,bits=8,parity=n,stop=1,ERRORS)

void main(){

   unsigned int8 value = 0;
   
   delay_ms(1000);
   value = getc();



}

#org default
evan



Joined: 02 Apr 2012
Posts: 22

View user's profile Send private message

PostPosted: Mon Apr 02, 2012 7:28 am     Reply with quote

Hi Jeremiah,

After playing about with #org, using it to exclude ranges instead of specify them, I have got it to do what I want, so thanks for the suggestion!

However, I've also cut down the original version which shows the unwanted behaviour :

Code:


#include <16F1517.h>

#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT               //No brownout reset
#FUSES MCLR                     //Master Clear pin enabled
//#FUSES NOCPD                    //No EE protection
#FUSES NOPUT                    //No Power Up Timer
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES FCMEN                    //Fail-safe clock monitor enabled

#use delay(clock=8M)


#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7, bits=8, FORCE_SW, FLOAT_HIGH)


////// BOOTLOADER!

#use fast_io (ALL)
#ORG  0x1F00, 0x1FFF {}


#org 0x0005, 0x07ff
void main()
{

    unsigned int16 reset_flags;
    unsigned int16 t;
    unsigned int16 n,i;
   char c;
   int monitor_mode=FALSE; // flag determines if monitor mode has been entered or normal run

      setup_adc_ports(NO_ANALOGS|VSS_VDD);
      setup_adc(ADC_OFF);
      setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
     setup_oscillator(OSC_8MHZ);


///////////////////////////////////// startup section


   if (input(PIN_C7)==0)
      {    
         
         for ( n=0; n<100; n++ )
         {
            delay_us(100);
            if ( input(PIN_C7) == 1 )
            {   

               break;
            }   
         }   
            


         if ( n >= 100 )
         {   

            for ( t=0; t<500; t++ )
               {
                   delay_ms(1);   
                   if ( input(PIN_C7) == 1 )
                   {             
                               


                  for ( n=0; n<10000; n++ )
                  {   

                      if ( kbhit() )
                       {   

 
                           c = getc();   

                        if ( c == 'H' ) 
                        {                 
                                 
                           while(TRUE);

                         }   
                        else if ( c == 'D' ) 
                        {   

                           delay_ms(1);     
                            putc('d');       
                           //monitor();     

                         }   
                     
                       }
                     
                  }   


                       break;
                   }   
               }
              
         }
         
      }    
   
   

//   app_main(); 

}


When this is compiled, it's clear to see the library functions beginning at 0x0800. If I try to reserve that range using #org 0x0800, 0x01eff - it fails to compile. Do you get the same thing?


Cheers
Evan

edit: version 4.129 of everything, built inside MPLAB
Ttelmah



Joined: 11 Mar 2010
Posts: 19360

View user's profile Send private message

PostPosted: Mon Apr 02, 2012 8:13 am     Reply with quote

The 'compiler' code, is stuff like RS232 routines, delay, etc.. The keyword controlling this, is 'default'. If you specify a memory range for code, using #org, and include the keyword 'default', then compiler generated routines, will also use this range. Otherwise, it'll explicitly _avoid_ this range.

Best Wishes
jeremiah



Joined: 20 Jul 2010
Posts: 1328

View user's profile Send private message

PostPosted: Mon Apr 02, 2012 8:15 am     Reply with quote

It's because of how you specify the #org statements. Look at my example and specifically observe the following things:

1. the "default" keyword I use in both of my #org statements
2. the location of my #use with respect to the #org statements
3. the location of my delay_ms() and getc() calls with respect to the #org statements

The use of "default" and the placement of the statements is key here. Default tells the compiler that EVERYTHING between this and the next "#org default" needs to fall in this range.
evan



Joined: 02 Apr 2012
Posts: 22

View user's profile Send private message

PostPosted: Mon Apr 02, 2012 8:57 am     Reply with quote

Great - I did experiment with DEFAULT but wasn't entirely clear about what it was meant to be doing. Now it's clear. Thanks, both.
evan



Joined: 02 Apr 2012
Posts: 22

View user's profile Send private message

PostPosted: Mon Apr 09, 2012 7:54 am     Reply with quote

Closely related question:
Now that I've placed the "default" and #use section at the beginning of my source, the address of main() is no longer at the start but is in a random location, i.e. it can change after making any change to the code.

Can I nail it down to a fixed address as well as having all the code constrained to this section?
jeremiah



Joined: 20 Jul 2010
Posts: 1328

View user's profile Send private message

PostPosted: Mon Apr 09, 2012 2:12 pm     Reply with quote

If you are wanting your application main (not the bootloader main) to be in a specific location, then just use:

Code:

#define NEW_RESET_VECTOR 0x0E00  //you pick this value
#BUILD(reset=NEW_RESET_VECTOR)  //moves the compiled reset vector


By itself in the application source. In this scenario, just make sure the bootloader calls GOTO NEW_RESET_VECTOR when it is ready to run the app, and the compiler handles populating the reset vector for you.

If you are wanting your bootloader main to be in a specific location, can you give a reason why? Just want to make sure it's actually necessary.
evan



Joined: 02 Apr 2012
Posts: 22

View user's profile Send private message

PostPosted: Tue Apr 10, 2012 3:45 am     Reply with quote

The bootloader. It's not strictly absolutely necessary, but the previous version of the bootloader (on a different PIC and different compiler) had it at a fixed address, so the reset vector can be always be the same, which keeps things simple.

To tie in with the design documents it would be nice to do it the same way, but if it's not straightforward then so be it.
jeremiah



Joined: 20 Jul 2010
Posts: 1328

View user's profile Send private message

PostPosted: Tue Apr 10, 2012 5:00 am     Reply with quote

The reason I ask is that the compiler loads the reset vector with the correct bootloader main address, so a fixed one typically isn't needed. No matter where you move it, the compiler computes the correct address.

If you really really want it in say spot 0x0200 for example, put something like:

Code:

#ORG 0x0800,0x0BFF default
#use delay(clock=/*whatever your clock equals*/)
#use rs232(/*place your options here*/)
/*place functions that use rs232 calls here*/
#ORG default

#ORG 0x0200,0x2FF     //these values are specified by you
void main(){
   //put code here.  Do not use delay_ms, getc, putc, etc directly here
   //or it will generate those ahead of main in some cases.   Use the
   //calls you made (wrapper functions) instead, so they are placed
   //in the above ORG statement
}



If you still have trouble after that, post a small complete code example of what fails. Maybe we can spot an error.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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