bootloader and vector redirect

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

bootloader and vector redirect

3,519 Views
ngsoftuser
Contributor III

Hi all,

 

I need to develop bootloader project on MC9S08DZ60 mcu (separated project).

I have few questions:

 

1. If my bootloader is not using interrupts, do I need to redirect the vector table?

2. What is the reason of redirecting the vector table? I understand that vector table redirection reason is in

    case a user app (not bootloader) wishes to modify interrupt vector information without unprotecting bootloader
    and reset vector space. How does user app can modify it? What does it mean?
    The only way I can think of modifying this is by flashing new firmware which is done by the bootloader.

3. If my bootloader size is 512 bytes, do I need to protect flash address 0xFDFF through 0xFFFF?

4. If redirection of vector table is needed, is it enough to modify the registers NVOPT.FNORED? Will this

    automatically redirect the vector table to 0xFDFF?

5. Do I need to modify NVOPT.FNORED in the common area so it takes effect on bootloader and user app?

6. In the .PRM file do I need to define new ROM segment for my user app which starts from 0xFDFF and use #pragma
    0xFDFF in all .c files of the application?

7. When the mcu reset, it will invoke _EntryPoint which will init clock and other common stuff and it will then read the
    flash (in a known location) to see if to run user app or go to bootloader. Do I need two main() one for bootloader and
    one for user app which will be in 0xFDFF segment?

 

Thank you for the help and I hope my questions were clear...

Labels (1)
0 Kudos
8 Replies

1,162 Views
ngsoftuser
Contributor III

Hi all,

In continues to question 6.

My bootloader size set to 1.5kb

1 .I modified ROM segment in prm files of bootloader and application.
According to "MC9S08DZ60.pdf" Address Area Protected is 0xFA00–0xFFFF.
This means that the ROM segment for bootloader should be
     ROM                      =  READ_ONLY 0xFA00 TO 0xFFAD;
and the ROM segment for application should be
     ROM                      =  READ_ONLY 0x1900 TO 0xF9FF;

Am i doing this right?

2. Do I need to change the two prm files in each project (Project.prm and ProcessorExpert.prm)?
Why are there two prm files?

3. I need to set my main function in s specific known address. My main function size may changed. So i can't use #pragma CODE_SEG.

Is there any way to set absolute location without size limit?

Thanks.


0 Kudos

1,162 Views
bigmac
Specialist III

Hello,

The application program should not need to know about the presence of a bootloader, and therefore the actual size of the bootloader.  Importantly, the standard vector table location should be used when compiling and linking the application program.  The program would therefore be capable of correct operation if programmed conventionally, with no bootloader already present. Except for a slightly reduced maximum allowable code size, there should be no other constraints for the programming of the application.

The placement of the application vector table at the redirected location needs to be done within the programming operations of the bootloader itself.  The bootloader alone will "know" how much space it occupies, and how much flash memory is protected, in order to determine the location of the new table.  Check whether your bootloader code already senses whenever an address corresponds to a vector address, for the application code S19 file.

If the bootloader operation uses FEI mode, the POR default, you will need to calibrate and program the non-volatile trim register setting during the programming of the bootloader code.  The bootloader code will need to write this value to the actual trim register during the initialisation process.

Regards,

Mac

0 Kudos

1,162 Views
ngsoftuser
Contributor III

Hello bigmac,

Thank you for your reply.

I must say that I am now more confused. If I won't modifythe application's prm file, then the compiler may place

these functions in the bootloader space address. same goes for bootloader. no?

I understood from your answer that the application vector table location should be on the original location and not to be moved.

In your answer you are talking about TRIM register. I never read that there's a need to modify it in any post talking about bootloader and vector redirection.

Thank you,

0 Kudos

1,162 Views
bigmac
Specialist III

Hello,

If you don't modify the application PRM, and with the bootloader code at the top of flash memory, the linker is unlikely to infringe into the bootloader block unless the application code, plus bootloader code, is too large for the MCU,  The linker will start at the lowest address, and work upwards.

If you were to modify the application PRM file to reserve program space for the bootloader, a linker error would be generated when the code size limit was reached.  However, you should already be aware of the application code size as the development of the project proceeds, and it should already be apparent when code space is becoming tight.

For the bootloader project, the PRM modification is obviously necessary.

I can see three potential scenarios for the programming of the application code into the MCU.

  1. The application code is programmed via BDM, in the normal way, with no bootloader present.  This is likely to be the situation during the design and development of the application.
  2. The application code is programmed using already resident bootloader code.  Possibly used during upgrade of the application in the field.
  3. The application code is programmed via BDM, but with bootloader code already resident. Maybe a factory programming procedure.

For the first scenario, the vector table data would be placed at the usual position.  For the second scenario, it would be the responsibility of the boot loader, should it encounter vector data at the usual position (within the received S19 file for the application), to automatically program this data to the redirected location.  This is a fixed address shift, as determined by the bootloader.  For both these instances, the application project uses the standard format.  The various methods available for defining the interrupt vectors, i.e. vector number, vector table or PRM addition, are all available.  I was alluding to these instances within my earlier post.

The third scenario is different.  It will require a special application project arrangement, where the vector table data is specifically repositioned to the required redirected location.  This method would require a special vector table within the application code.  Obviously, this code will not execute without the bootloader.  If this code were loaded using the bootloader, it should still work (the bootloader would never encounter standard vector addresses within the S19).

There is potential problem with this last method.  Should updated versions of the bootloader be of different size to the original, the alteration would also require a corresponding modification to the application project, with the need to keep track of the bootloader version present in each device.  This may be acceptable for factory programming, but is likely to be problematic for re-programming of the application in the field.  The second method would be much safer, being independent of bootloader version.

Assuming the bootloader uses FEI mode, the NV trim register will need calibration and programming at the same time the bootloader is programmed.  If you are using the SCI module for bootloader communications, you will require a sufficiently accurate bus frequency and baud rate.  This will not be achieved without the trim calibration.

Regards,

Mac

1,162 Views
ngsoftuser
Contributor III

Hello bigmac,

thank you for your response.

I have bootloader and Application with RTC isr which invoked every 10ms.

What bothers me is that it works. :smileyhappy:

In the bootloader I used following isr for RTC

void TI1_Interrupt(void)

{

    asm ("LDHX 0xF9CC; JMP ,X");

};

taken from this post Re: Bootloader for DZ60

The guy how posted claimed that the ISR in the application doesn't return and in my situation it does.

One side effect after adding RTC ISR is that SCI2 stopped working while SCI2 does.

I am currently developing for DEMO9S08DZ60.

0 Kudos

1,162 Views
bigmac
Specialist III

Hello,

eran yasso wrote:

I have bootloader and Application with RTC isr which invoked every 10ms.

What bothers me is that it works. :smileyhappy:

In the bootloader I used following isr for RTC

void TI1_Interrupt(void)

{

    asm ("LDHX 0xF9CC; JMP ,X");

};

 

taken from this post Re: Bootloader for DZ60

The guy how posted claimed that the ISR in the application doesn't return and in my situation it does.

One side effect after adding RTC ISR is that SCI2 stopped working while SCI2 does.

I am currently developing for DEMO9S08DZ60.

The code snippet that you provide does a direct jump to address 0xF9CC.  This would require that executable code be present at this address.  However, if a vector address for the start of an ISR is present (as I might expect), the code snippet will not work.  The presence of this code would imply that you are using the bootloader to provide the redirection of each vector.  However, if you have automatic redirection enabled, which I thought you had, this code would never be executed.

With vector redirection by the bootloader, the "bridging" function for each interrupt source requires to do an indirect jump, rather than a direct jump, and this needs to be done without corrupting the H-register value.  This can be achieved by reading the individual bytes for 16-bit value at address 0xF9CC, and pushing them to the stack (LS byte first).  The "jump" is then done by executing a RTS instruction.

This code would only be required if automatic redirection could not be implemented, either because the MCU did not provide the facility, or where the bootloader itself requires to make use of one or more interrupts.  I thought that neither of these conditions was applicable to your case.

Regards,

Mac

0 Kudos

1,162 Views
ngsoftuser
Contributor III

I have more updates.

Now i set vector redirection using HW (clearing bit FNORED in FOPT reg) instead of manually and it works.

However, SCI2 still doesn't give any output.

One of the things i also did was to preserve memory in eclipse (the application from 0x1900-0xfa1f).

When i disable memory preservation, SCI2 outputs, However, there is no application to jump to since its space

is erased when burning bootloader.

This leads me to think that there might be a bug in memory preservation in CW 10.2. One of the bugs is that

when I set memory preservation from 0x1900 - 0xfa00, eclispe automatically changes it to 0x1900 - 0xfa1f.

maybe the extra 0x1f bytes causes SCI2 to stop working.

0 Kudos

1,162 Views
tonyp
Senior Contributor II

> 1. If my bootloader is not using interrupts, do I need to redirect the vector table?

Since a bootloader is (normally) write-protected, the default vector area located in the same protected sectors will not be changeable.  This means you need to redirect the vectors your app uses.  This can be done in three main ways (with several variations):

a. Use hardware vector redirection, when available.

b. Use software vector redirection.  Each vector in the bootloader points to code in the bootloader that loads the address from the corresponding redirected vector and jumps to it.

c. Each vector in the bootloader points to code in the bootloader that jumps to the corresponding entry of a JMP table in the app.  (The difference with [b] is that each app vector now needs 3 bytes, instead of 2, but on the plus side, the interrupt latency is somewhat smaller.)

>2. What is the reason of redirecting the vector table? I understand that vector table redirection reason is in

>    case a user app (not bootloader) wishes to modify interrupt vector information without unprotecting bootloader
>    and reset vector space. How does user app can modify it? What does it mean?
>    The only way I can think of modifying this is by flashing new firmware which is done by the bootloader.

The app vectors are modified each time you load a new app (via the bootloader).  Since your app interrupt handlers normally change location from version to version, the corresponding vectors must also be updated to point to the correct entry locations for each ISR.

>3. If my bootloader size is 512 bytes, do I need to protect flash address 0xFDFF through 0xFFFF?

You need to protect the minimum for your MCU variant.  For some MCUs, this is a multiple of 512 (like QE's 1024), for others, like the DZ it's multiples of 768, etc.

>4. If redirection of vector table is needed, is it enough to modify the registers NVOPT.FNORED? Will this

>    automatically redirect the vector table to 0xFDFF?

For hardware redirection, yes.  (I assume you have some Flash protected, though, or redirection won't happen.)  The actual address of the vector table depends on how much Flash is protected.

>5. Do I need to modify NVOPT.FNORED in the common area so it takes effect on bootloader and user app?

I'm not sure what you mean by this.  FNORED is fixed during installation of the bootloader.  It cannot be changed later by your app.

>6. In the .PRM file do I need to define new ROM segment for my user app which starts from 0xFDFF and use >#pragma     0xFDFF in all .c files of the application?

C users will help you with that...

>7. When the mcu reset, it will invoke _EntryPoint which will init clock and other common stuff and it will then read the
>    flash (in a known location) to see if to run user app or go to bootloader. Do I need two main() one for bootloader and
>    one for user app which will be in 0xFDFF segment?

Unless you're dealing with specific hardware requirements, I would avoid doing any irreversible setup from within the bootloader.  Some registers are write-once.  For me, the best approach is to defer all such setup to the actual app.  That way, if a different requirement is needed after initial deployment, it can be handled in the updated app.

So, I would prefer to use the default startup settings, which among other things it means the bootloader always uses the internal oscillator. Run a check for a valid app being present (by CRC calculation, or other method).  My own bootloader even sets all affected registers (like those used by the SCI for the firmware update) back to the default settings before executing the app.  That way, my app will start running as if straight out of reset.

In some cases, however, (for example, when you need to keep certain pins in a specific default state,) the bootloader should do this setup upon startup, even if an app is not available.  For example, a door security system should keep the doors locked (or unlocked, for fail-safe systems) during the firmware update, especially if such update can be performed from a remote location, and not on-site.