Hi and thanks for the help so far.
The little dot to the right of the file, under the little green bug was the solution. I just had to click on all dots (or on the dot to the right of a group to configure all). I had tried all sorts of things including setting some compiler flags manually to ensure the correct format (DWARF or HIWARE) - none of which helped...
About the library size. I think that the value I was using was really not the correct size and probably represents the code size if it actually gets linked because now that I have started with the serial monitor I have seen that 24k is downloaded rather than 32k as displayed. This is very similar to the code size I get with the IAR compiler. Therefore I believe that i can use the library as it is - I don't think that the malloc functions have allocated any memory since I didn't see anything in the map file. The operating system which I use defines its own space at run time which is much more practical than having to set limits and compile libraries - it also means the heap space can be changed dynamically so that the stack has more room if not so much heap is required...
Is the simulator of any real use? My code stopped in a forever loop waiting for the PLL to lock - which was simply avoided by jumping over it but then it just ran in the operating system kernal in a forever loop. I also found that the simulator was set up quite differently (with respect to memory map) and so didn't really show me that the target was not going to work when I first tried it. I set up the memory correctly and got first signs of life.
Now I have just 3 things to adjust and then the project should also run when compiled with CodeWarrior.
1. Set up the heap space.
2. Get interrupts to work - although the peripherals are set up correctly no interrupts are arriving.
3. Force a few routines into a specific page so that they can manipulate another page (without unintentionally being located in the that page...)
1 - What I need to konw is the memory location just after the highest variable. With the GNU compiler there is a variable called _end which is set here and its address can simply be looked at using &_end. With the UAR compile it is necessary to use
#pragma segment="DATA16_Z"
pucBottomOfHeap = (unsigned char*)__segment_end("DATA16_Z");
Do you know the best way of getting this info from CodeWarrior?
By the way I did look at the structure _tagStartup which is used for initialisation of bss and data segments but didn't see that it delivered the answer in an easy fashion. Quite surprisingly I saw that it was clearing about 280 bytes in bss from 0x2c00 and then setting 6 bytes of initialised data also from 0x2c00 - meaning that the initialisation first clears all data (initialised + bss) and then writes initialised. In my case I see that the address which I am looking for is 0x2c00 + 281 but to get this from the structure woul dmean checking the structure carefully for the highest address - bss is actually after initialised here.
2 - Probably trivial - have seen that there are no entries in the interrupt vector so they are obviously being handled by the monitor's general catch interrupt. Will read the docs.
3 - To ensure that code is at a certain location I use (for example)
#pragma location="FILE_ROUTINE" where FILE_ROUTINE is declared as a segment for the linker.
I wonder whether I can simply use something equivalent to force it into the ROM_4000 segment which is already defined in my prm file?
Thanks for any last hints.
Regards
Mark Butcher
www.mjbc.ch
Hello
The linker is a smart linker. Only functions and variables really referenced in the application
will be linked to the application.
If malloc is not present in the .map file, the linker did not link it to the application.
Which HCS12 derivative are you trying to simulate?
Which derivative did you configure in the Simulator -> Derivative dialog?
1. Set up the heap space.
Do you really need dynamic memory allocation in your application?
If not there is no need to define a heap...
2. Get interrupts to work - although the peripherals are set up correctly no interrupts are arriving.
Which connection are you using?
If you are using a Multilink or Cyclone pro, you need to initialize the vector table directly.
If you are using the serial monitor, there is a mirrored vector table somewhere in Flash and you have to
initialize the corresponding entry in that mirrored table.
If you are not sure about the address of the mirrored vector table check the "Vector Table Mirroring" tab in the
"Monitor Setup" dialog.
Also make sure to allocate your interrupt function in NON_BANKED flash (in section NON_BANKED for instance)
#pragma CODE_SEG NEAR NON_BANKED
interrupt void myInt(void) {
}
#pragma CODE_SEG DEFAULT
3. Force a few routines into a specific page so that they can manipulate another page (without unintentionally being located in the that page...)
If the question is how should I define that a function should be located in NON_BANKED memory, define it in NON:BANKED section as recommended above.
I hope this helps.
CrasyCat
By the way.
I managed to get the address after the top-most variable by doing the following
1. Set stack size definition to 1.
2. Use _startupData.stackOffset as the address of the RAM loaction after the last variable.
3. In the startup code I don't use _startupData.stackOffset but rather the top of memory to set the stack pointer.
Then it operates as desired (as far as I can see).
Regards
Mark Butcher
www.mjbc.ch
Hello
Another way of doing that is to use the Linker predefined symbol __SEG_END_STACK.
Please refer to Linker manual or TN103 for more information on how to do that.
I have attached the technical note to this thread for your reference.
CrasyCat
Hi CrasyCat
Thanks for the tips. I have now been able to steer the code to the address range I wanted.
Unfortunately I had to stick with the previous solution to determine the end of the variables since the linker said it didn't know __SEG_END_STACK, or __SEG_START_STACK which is what I think that I need. I read TN103 which you posted (thanks also) and I am assuming that this feature in only available in newer CodeWarrior versions (I have 3.1) - it does say from linker v.5.0.10 (in the components list I get 5.0.9.0 so this must be the case). Never mind, I think that the 'older' solution is adequate.
By the way do you have any ideas about my download/debugging problem. The flash is deleted and the download starts until there is code at 0x8000 and then it aborts with an error, saying that there is no memory at this address. I believe it is because it believes that there is memory at 0x4000..0x7fff and 0xc000..0xffff, with pages at 0x3C8000..0x3CBFFF and 0x3D8000..0x3DBFFF, which is basically correct but at the same time not absolutely true.
My code uses a linear range from 0x4000...0xffff (48k) and then just one page for a file system at 0x3D8000..0x3DBFFF (which is controlled by the code itself rather than the compiler) - hence the need to avoid the controlling routine being in put into the range 0x8000..0xbfff since it would otherwise shut itself out when paging in the file system....
With my other debuggers and download tools I have no problem with this strategy but I haven't yet found a solution with CodeWarrior. As a last resort I could do assembler level debugging with another tool which I have but will need a file with interleaved C-code and assembler code, such as that which the GNU compiler generates with " objdump -S target.elf > target.psa". Do you know whether CodeWarrior has something suitable?
Thanks for the support!!
Regards
Mark Butcher
www.mjbc.ch
Hello
CodeWarrior for HC12 V3.1 does not support memory at address 0x8000..0xBFFF. It requires you to place the code in the real banked memory (0x3C8000..0x3CBFFF).
This is something which has been added in CodeWarrior for HC(S)12 V4.5. Extract from the V4.5 release notes:
"-Contiguous/flat flash programming support over the bank window for HCS12 devices, like programming from $4000 to $FFFF as a single flash block.
The project setup should be changed by the user, as this way of using flash resource does not take advantage of the entire size of the flash (therefore, not the default setup)."
In order to be able to use that you have to upgrade to V4.5.
CrasyCat
Hi
Thanks. That clears it up. I will update now so that my project will be possible.
Regards
Mark Butcher
www.mjbc.ch
Hi CrasyCat
1. The operating system and TCP/IP work with malloc so the heap is necessary. This is no longer a problem since I see that teh libraries version is not linked.
.2 Interrupts are working OK now - the vector table had not been added properly, which I corrected.
3. The project uses not banked memory. What I want is to force a routine to be at the address 0x4000 (to ensure that it is in the first page).
With the IAR project I do this with
#pragma location="FILE_ROUTINE"
where this is defined in the linker control file as follows:
-DFILE_ROUTINESTART=04000
-DFILE_ROUTINEEND=0407f
The code then starts at the desired location. I am sure that there is some method of doing something similar with CodeWarrior.
My biggest problem is the fact that I can not debug once the code is linked to addresses 0x8000..0xbfff - see my later posting. This is bugging me since I have a TELNET application which works fine when I compile it with the GNU compiler or the IAR compiler but crashes when I compile it with CodeWarrior. Since TELNET makes the code somewhat larger and it needs to be placed into the region which stops the debugger from working it is a real problem - how can I debug it to find out what CodeWarrior is compiling differently??
Any ideas?
Regards
Mark Butcher
www.mjbc.ch
Message Edited by Technoman64 on 04-27-200606:45 PM
Message Edited by Technoman64 on 04-27-200606:48 PM
Message Edited by Technoman64 on 04-27-200606:49 PM