Author Topic: moving uTasker  (Read 15727 times)

Offline twoerner

  • Newbie
  • *
  • Posts: 16
    • View Profile
moving uTasker
« on: July 18, 2007, 09:18:51 PM »
As shipped, the uTasker demo application for M52235 assumes it can run from flash address zero. I would like to move the application so that it resides entirely above 0x36000 and touches nothing below this address (except, of course, for the reset vectors for the stack pointer and the program counter).

Looking at the supplied *.lcf files I found that M52235_BOOT_APP_FLASH.lcf looks somewhat like what I'm looking for. So I created a new target with a copy of this *.lcf file inwhich I change the flash "ORIGIN=" value. This doesn't seem to work. So then I tried to build and run the bare_min_app_rom target (which is the target that uses the M52235_BOOT_APP_FLASH.lcf script) and it doesn't seem to work for me either.

Any idea what I'm doing wrong?

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: moving uTasker
« Reply #1 on: July 18, 2007, 09:54:56 PM »
Hi

If you link a complete project to start at a higher address (but still within FLASH) it will load to the FLASH but will only be started if code handling the reset is ALSO available. This code can simply jump to the start address of the shifted project - as long as it knows where this is;-).
Have you also loaded something to sort this out or is the reset location blank? If it is blank, no code will be able to start.

Moving to the "Bare Minimum" project. This is linked to 0x800 start address.
This is the addres which is called by the Bare-Minimum Boot Loader, which has to be loaded into FLASH at address 0x00000000 (actually it gets the start address of the application from 0x804 and then jumps to it. This makes it compatible with any software which is normally linked to 0x00000000 but simply shifted to 0x800 since the address 0x804 then contains what normally would be the reset vector). In addition, to be totally clean, it also loads the Stack pointer with the value at 0x800:

Code: [Select]
    /* If the uTaskerBoot return (without interrupt) the normal code can run */
    /* we load its SP and the PC and let it continue... */
    move.l  #0x00000800,a0
    move.l  (a0),sp
    move.l  #0x00000804,a0
    move.l  (a0),a0
    jmp (a0)


Check that you have indeed loaded BOTH of the programs to FLASH as the board can only start up when both are present. How to do this with CodeWarrior is explained in the document:
http://www.utasker.com/docs/uTasker/BM-Booloader_for_M5223X.PDF

It is interesting because you can then either debug the boot loader or the application (but not both in C). Set a break at the lines above in the boot loader project and then ensure that the jump from boot to application is working correctly. The boot loader is used by quite a lot of people and so should be fully operational as delivered.

If you would like your application to reside elsewhere simply modify the lines above to correspond to the link address of your code. Note however that your code may not have fixed interrupts in FLASH since these will not be used - it must use a vector table of its own positioned at the start of SRAM - the uTasker demo project works this way and so can be used together with the boot loader. Based on the start address which you specify (0x36000) it is correct to modify the ORIGIN value for flash1 in the linker script file - your code can however not be greater than 40k in size to fit within the 256k FLASH memory. You will not actually need the section flashconfig but maybe set it to 0x36400 to avoid any linker issues, and flash2 can be set to 0x36420 with LENGTH = 0x0009BE0 (total 40k left at end of FLASH)

Good luck

regards

Mark




« Last Edit: July 18, 2007, 11:48:54 PM by mark »

Offline twoerner

  • Newbie
  • *
  • Posts: 16
    • View Profile
Re: moving uTasker
« Reply #2 on: July 18, 2007, 11:13:34 PM »
So if I have a target and in its LCF I've defined:

Code: [Select]
MEMORY
{
    flash   (RX)   : ORIGIN = 0x0000800, LENGTH = 0x0003F800   
    vectorram(RWX) : ORIGIN = 0x20000000, LENGTH = 0x00000400
    sram (RWX)  : ORIGIN = 0x20000400, LENGTH = 0x00007C00
    ipsbar  (RWX)  : ORIGIN = 0x40000000, LENGTH = 0x0
}

I can look at the generated S-record file and see that the last line is:

Code: [Select]
S70500000808EA

Does that not mean that when the flash tool is done putting the application in FLASH, that it doesn't put the address 0x0000808 (which, according to the generated xMAP file, is the address of the "start" label and therefore the address of the first instruction of the application) into the reset vector FLASH address 0x00000004?

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: moving uTasker
« Reply #3 on: July 18, 2007, 11:48:02 PM »
A normal downloading tool will only do that which is set in the SRec file. It will therefore not set up any reset vectors!!



In fact the line which you have copied is not code. S7 signifies some information which looks to be the start up address of the code (entry point). This is useful for a debugger since it can set the PC to this address and then start up from there.

Here are the first three lines of the Srec which my compiler is generating (CW6.3)
S0030000FC
S32100000800200080000000080846FC2700203C200000000680000000214E7B0C05C0
S3210000081C2E7C20008000203C4000000006800000000123C040000000203C0000CE

The first is S0 and I don't actually know what it is saying - it can be ignored when loading code to FLASH.
S3 is a line of code with a 32bit address (00000800) and total length of 0x21. The last byte (0xc0) is the check sum of the line.
The target data is thus:
0x00000800 = 0x20008000 (the top of SRAM - will be loaded to SP)
0x00000804 = 0x00000808 (the start location of the code - the PC would be loaded with it at reset)
0x00000804 = 46FC2700 which is assembler code        move.w   #0x2700,sr
I can't actually read assembler, but this is the first line in Startup.s!!

Therefore loading this code to FLASH will not result in any thing which can run., There are 2 possible reasons.
1. This is quite obvious (but not the real reason!). 0x00000004 is 0xffffffff and so the reset will load the PC with this value and the processor will immediately crash when trying to access 0xffffffff.
2. The less obvious. The addresses 0x400..0x418 are 0xffffffff. The FLASH controller in the M5223X loads these also at reset to configure the FLASH controller. These values give the CPU no rights to access FLASH. Therefore the CPU will exception when it tries to load 0x00000000!!

Either way it means instant death and so best to be avoided!!

If you load this code PLUS the boot loader the boot loader will supply everthing which is otherwise missing and both can operate as a team...


Cheers

Mark

« Last Edit: July 18, 2007, 11:51:52 PM by mark »

Offline twoerner

  • Newbie
  • *
  • Posts: 16
    • View Profile
Re: moving uTasker
« Reply #4 on: July 19, 2007, 07:25:58 PM »
I have an application based on the uTasker sample application and I'm trying to minimize the amount of code in FLASH below 0x00030000; ideally I'd like there to be no code below this address, except for:

1) the initial SP value at 0x00000000
2) the initial PC value at 0x00000004
3) the FLASH controller config at 0x00000400 - 0x00000418

I modified the LCF file so that the ORIGIN of FLASH2 is 0x00030000, and this works fine.

I then edited Startup.c to remove all the functions except for "start" (e.g. mcf5xxx_wr_vbr, asm_int_off, asm_int_on, ) and placed them in Startup2.c which, in the LCF, I placed into FLASH2. Looking through the xMAP file I can see that the code for these routines is in fact located above 0x00030000. Everything still works fine.

At this point:
1) initial SP (from Startup.c) is 0x20008000 in location 0x00000000
2) initial PC (from Startup.c) is 0x00000008 in location 0x00000004
3) FLASH controller config is zeroed
4) I'm using about 80 bytes starting at 0x00000008 for the code of the "start" routine

Code: [Select]
S0030000FC
S32100000000200080000000000846FC2700203C200000000680000000214E7B0C05D0
S3210000001C2E7C20008000203C4000000006800000000123C040000000203C0000D6
S31D0000003800000680000000614E7B0C044EB9000317144EB9000300505B
S31D00000400000000000000000000000000000000000000000000000000DE
S32100030000

Then I tried to move more code from below 0x00300000. I edited "start" in Startup.c to just include a "jsr start2" and moved the actual code of the "start" routine to Startup2.c in a routine called "start2". After compiling I end up with an S-record that looks like:

Code: [Select]
S0030000FC
S3150000000020008000000000084EB900030000000038
S31D00000400000000000000000000000000000000000000000000000000DE
S32100030000

But this does not work. Any ideas why? The initial SP and PC are still set correctly. The "jsr start2" is the first instruction executed after a reset, and the FLASH config registers are still setup properly. Any idea why this code (with the "start" routine essentially at 0x00030000) is wrong but the previous (with the "start" routine at 0x00000008) is fine?

I guess another way to ask the question is: of the 5 things done in "start" why must they be done in low FLASH memory? Can't they be done somewhere else?

The 5 things I'm referring to are:
1) set SR to 0x2700
2) init RAMBAR1 to __SRAM + 0x21
3) init SP to __SP_INIT
4) init IPSBAR to __IPSBAR + 0x1
5) init RAMBAR0 to __FLASH + 0x61

Offline twoerner

  • Newbie
  • *
  • Posts: 16
    • View Profile
Re: moving uTasker
« Reply #5 on: July 19, 2007, 09:24:01 PM »
Wow! I got it working! I created a "Hello, world!"-type simple program using the M52235 stationary from Metrowerks and by seeing what they're doing I was able to move the entire application to start at 0x00030000 and set the reset boot vector to point there so when the board is RESET it executes all the code starting from that location.

I modified the LCF to look like:
Code: [Select]
MEMORY
{
    flash1  (RX)   : ORIGIN = 0x00000000, LENGTH = 0x00420
    flash2  (RX)   : ORIGIN = 0x00030000, LENGTH = 0x000FFFF
    vectorram(RWX) : ORIGIN = 0x20000000, LENGTH = 0x00000400
    sram    (RWX)  : ORIGIN = 0x20000400, LENGTH = 0x00007C00
    ipsbar  (RWX)  : ORIGIN = 0x40000000, LENGTH = 0x0
}

You'll notice that I removed the flash_config.s stuff and instead wrapped it all up in Startup.s. Taking a page from the project stationary my Startup.s now looks like:

Code: [Select]
.text

/*
 * Exception Vector Table
 */
VECTOR_TABLE:
_VECTOR_TABLE:
INITSP: .long ___SP_INIT /* Initial SP */
INITPC: .long start        /* Initial PC */
vector002: .long asm_exception_handler /* Access Error */
vector003: .long asm_exception_handler /* Address Error */
vector004: .long asm_exception_handler /* Illegal Instruction */
vector005: .long asm_exception_handler /* Reserved */
vector006: .long asm_exception_handler /* Reserved */
vector007: .long asm_exception_handler /* Reserved */
vector008: .long asm_exception_handler /* Privilege Violation */
vector009: .long asm_exception_handler /* Trace */
vector010: .long asm_exception_handler /* Unimplemented A-Line */
vector011: .long asm_exception_handler /* Unimplemented F-Line */
vector012: .long asm_exception_handler /* Debug Interrupt */
vector013: .long asm_exception_handler /* Reserved */
...
vector251: .long asm_exception_handler
vector252: .long asm_exception_handler
vector253: .long asm_exception_handler
vector254: .long asm_exception_handler
vector255: .long asm_exception_handler

CFM_FLASH_CONFIG:
_CFM_FLASH_CONFIG:
/*
 * CFM Flash Configuration Field
 */
KEY_UPPER:  .long   0x00000000
KEY_LOWER:  .long   0x00000000
CFMPROT:    .long   0x00000000
CFMSACC:    .long   0x00000000
CFMDACC:    .long   0x00000000
CFMSEC:     .long   0x00000000

To ensure that the above is not deadstripped I've modified M5223X.c -> mcf52235_init() to contain:
Code: [Select]
extern unsigned long VECTOR_TABLE[];
volatile unsigned long someValue;
...
someValue = VECTOR_TABLE[0];

The volatile is extremely important.

I then removed all references to flash_config, and added a simple asm_interrupt_handler() and it works.

The handler looks like the following and was added to Startup2.s:
Code: [Select]
asm_exception_handler:
    rte

The start of my S-record file looks like:
Code: [Select]
S0030000FC
S32100000000200080000003000000030090000300900003009000030090000300905C
S3210000001C00030090000300900003009000030090000300900003009000030090BD
S3210000003800030090000300900003009000030090000300900003009000030090A1
...
S321000003D40003009000030090000300900003009000030090000300900003009002
S321000003F0000300900003009000030090000300900000000000000000000000009F
S3190000040C0000000000000000000000000000000000000000D6
S3210003000046FC2700203C200000000680000000214E7B0C052E7C20008000203CCF

Notice how the FLASH config registers are set to 0 as needed.
Awesome! :-)

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: moving uTasker
« Reply #6 on: July 19, 2007, 10:47:29 PM »
Hi

You seem to be getting the hang of all this!!

Just one comment about why you originally needed more instructions than expected. It was possibly due to the fact that you were calling the code with jsr rather than jmp. Since jsr pushes the return address onto the stack the stack must also exist. This means that the SP will  have to be set set up to point to a location in RAM and also the RAM will have had to be set up using RAMBAR. Trying to push to an non-existent RAM location would result in an exception.

Just putting the start location at 0x0000004 is very much like a jmp to that address and so no further set up is needed for it to function.

Mark

« Last Edit: August 13, 2007, 11:12:03 AM by mark »