|
|
View previous topic :: View next topic |
Author |
Message |
evan
Joined: 02 Apr 2012 Posts: 22
|
Memory organisation trouble... |
Posted: Mon Apr 02, 2012 6:29 am |
|
|
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: 1345
|
|
Posted: Mon Apr 02, 2012 6:55 am |
|
|
#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
|
|
Posted: Mon Apr 02, 2012 7:28 am |
|
|
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: 19499
|
|
Posted: Mon Apr 02, 2012 8:13 am |
|
|
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: 1345
|
|
Posted: Mon Apr 02, 2012 8:15 am |
|
|
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
|
|
Posted: Mon Apr 02, 2012 8:57 am |
|
|
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
|
|
Posted: Mon Apr 09, 2012 7:54 am |
|
|
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: 1345
|
|
Posted: Mon Apr 09, 2012 2:12 pm |
|
|
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
|
|
Posted: Tue Apr 10, 2012 3:45 am |
|
|
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: 1345
|
|
Posted: Tue Apr 10, 2012 5:00 am |
|
|
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. |
|
|
|
|
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
|