|
|
View previous topic :: View next topic |
Author |
Message |
soonc
Joined: 03 Dec 2013 Posts: 215
|
#import to combine bootloader with application code [SOLVED] |
Posted: Fri Jun 10, 2016 10:43 am |
|
|
Using Compiler Version: 5.059
PIC24FJ128GA306
Bootloader code and sample application as per CCS Example.
I can program the Bootloader and then using teraterm successfully load the real application.
Now I want to create a combined HEX file for programming with the ICDU64.
Reading this forum I think I need to use: #import
I'd like to #import the bootloader to my application ? as the bootloader should not need change.
In my application code I used this:
#include "pcd_bootloader.h" // copied to local folder
#import (FILE=C:\Source\BootloaderExample\ex_pcd_bootloader.hex, HEX, RANGE=0:LOADER_SIZE)
The error messages are:
Memory not available are requested location.
and File cannot be opened for write.
Or do I use the #import in the bootloader source and import the application. This means of course I'll be compiling both the app and the bl each time. !
Clearly I don't understand this #import directive... any help would be welcome. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Fri Jun 10, 2016 11:23 am |
|
|
The easiest way is honestly either to use MPLAB, and load the two hex files one after the other, then export the hex corresponding to the whole of memory. Some programmers also allow you to load a hex file without erasing, so again you can load the bootloader, and then the main code.
With #import, do the following:
1) Get rid of all fuses in your main. Replace with:
#fuses NONE
2) Then add the line:
#IMPORT (FILE=bootloadername.HEX,HEX)
Immediately after the fuse location etc.. With the name of your bootloader hex file.
3) Obviously make sure you are loading the bootloader.h file to set the build address etc., in the application.
This then imports the bootloader hex file into the application, which then won't complain that they are trying to use the same memory addresses (since you don't set the fuses, and the build is to different addresses). |
|
|
soonc
Joined: 03 Dec 2013 Posts: 215
|
Thanks |
Posted: Fri Jun 10, 2016 12:13 pm |
|
|
Ttelmah wrote: | The easiest way is honestly either to use MPLAB, and load the two hex files one after the other, then export the hex corresponding to the whole of memory. Some programmers also allow you to load a hex file without erasing, so again you can load the bootloader, and then the main code.
|
Thanks for the suggestion about #import
That did not work either so I'm going the MPLAB way...
I was able to get Tech. Support on the line and my original syntax is correct...
Time to give up and move one to something that works. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Fri Jun 10, 2016 12:21 pm |
|
|
Normally the error is caused by the fuses (hence my suggestion), since both the imported file, and the application contain fuses.
However the error suggests that your application may not be correctly re-locating itself to work with the bootloader. Are you sure your application build is using the same loader size settings as the bootloader?. Have you tested the application using the bootloader?.
The import _does_ work, if the settings are correct in both files. |
|
|
soonc
Joined: 03 Dec 2013 Posts: 215
|
Yes the bl works |
Posted: Fri Jun 10, 2016 1:11 pm |
|
|
Ttelmah wrote: | Normally the error is caused by the fuses (hence my suggestion), since both the imported file, and the application contain fuses.
However the error suggests that your application may not be correctly re-locating itself to work with the bootloader. Are you sure your application build is using the same loader size settings as the bootloader?. Have you tested the application using the bootloader?.
The import _does_ work, if the settings are correct in both files. |
Yes the BL works.
I was NOT able to load the application with SIOW.exe as the time out issue killed that idea.
So I used teraterm and it loaded my application, and I changed my app and that loaded OK also. The bootloader is working.
I just downloaded the monstrous mplab 575megByte and now it wants me download a compiler.
It just does not make sense all I want to do is concatenate two hex files. Arrrrgh !
As I said CCS Tech support confirmed my syntax is correct.
I also tried your suggestion #FUSES none and placed the #import where you suggested but that caused other errors and I gave up.....
I'll read the Intel spec, I've not done that for many years and then try to use notepad and do it all manually. I feel like I'm back in the early 80's I may as well be running DOS
Thanks again for your help, I'm just frustrated to distraction that such a simple task has taken 4-5 hours of my life and produced nothing for it.
I should add: I'd post the two code files but they are CCS copyright so I'm not able to do that. |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1354
|
|
Posted: Fri Jun 10, 2016 2:16 pm |
|
|
So I tried this out:
Grabbed pcd_bootloader.h and ex_pcd_bootloader.c
didn't change them, but just compiled to get a ex_pcd_bootloader.hex file
I started a separate project with my own main file, application_main.h and copied the ex_pcd_bootloader.hex file into the same directory. This is my application main:
Code: |
#include <24HJ128GP306.h>
#fuses NOWDT
#include "pcd_bootloader.h"
#use delay(crystal=20MHz)
#use rs232(Baud=9600,UART1,errors)
#IMPORT (FILE=ex_pcd_bootloader.hex,HEX,RANGE=0:LOADER_SIZE)
void main(){
delay_ms(2000);
printf("Hello World");
}
|
I used the same PIC include, fuses, and #use delay() statement as the ex_pcd_bootloader.c did, but I moved the lines around to ensure that my inclusion of pcd_bootloader.h would force the delay and rs232 code to be in the application space.
I imported right after all of that.
I got some warnings due to FUSES and main locations in the same memory space as the bootloader.hex, but the two hex files correctly mapped as far as I can tell. I verified this by comparing the bootloader's hex file to the combined hex file.
I can post the two hex files if you need, but it should be repeatable. Doing a file compare shows the only difference being between address 0x800 and 0xA58 (the application area).
I used version 5.059 |
|
|
soonc
Joined: 03 Dec 2013 Posts: 215
|
#import SOLVED |
Posted: Fri Jun 10, 2016 4:31 pm |
|
|
jeremiah wrote: | So I tried this out:
Grabbed pcd_bootloader.h and ex_pcd_bootloader.c
didn't change them, but just compiled to get a ex_pcd_bootloader.hex file
I started a separate project with my own main file, application_main.h and copied the ex_pcd_bootloader.hex file into the same directory. This is my application main:
Code: |
#include <24HJ128GP306.h>
#fuses NOWDT
#include "pcd_bootloader.h"
#use delay(crystal=20MHz)
#use rs232(Baud=9600,UART1,errors)
#IMPORT (FILE=ex_pcd_bootloader.hex,HEX,RANGE=0:LOADER_SIZE)
void main(){
delay_ms(2000);
printf("Hello World");
}
|
I used the same PIC include, fuses, and #use delay() statement as the ex_pcd_bootloader.c did, but I moved the lines around to ensure that my inclusion of pcd_bootloader.h would force the delay and rs232 code to be in the application space.
I imported right after all of that.
I got some warnings due to FUSES and main locations in the same memory space as the bootloader.hex, but the two hex files correctly mapped as far as I can tell. I verified this by comparing the bootloader's hex file to the combined hex file.
I can post the two hex files if you need, but it should be repeatable. Doing a file compare shows the only difference being between address 0x800 and 0xA58 (the application area).
I used version 5.059 |
It works... I spent a few minutes trying to find what I did wrong... !
The level of frustration with SIOW.exe and the "time-out" left a bad taste and I think I made a mistake and gave up too early !
Thanks for taking the time I really appreciate it, this has been a big help.
Now I can uninstall the MPLAB monster... |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Sat Jun 11, 2016 2:02 am |
|
|
Good.
The #fuses NONE, will get rid of the warnings about the fuses.
It's silly really. You would think, that if you include the 'import range' (as you do, and I don't), it would stop it complaining about the fuses (since you are not importing these), but it still does moan.
When you think just how large the code is, and then tot up the mSec/write time, it is terrifying just how slow the bootloader can become on larger chips. Just be glad you are not on a '512' version!... |
|
|
soonc
Joined: 03 Dec 2013 Posts: 215
|
I found the reason |
Posted: Sat Jun 11, 2016 10:47 am |
|
|
Ttelmah wrote: | Good.
The #fuses NONE, will get rid of the warnings about the fuses.
It's silly really. You would think, that if you include the 'import range' (as you do, and I don't), it would stop it complaining about the fuses (since you are not importing these), but it still does moan.
When you think just how large the code is, and then tot up the mSec/write time, it is terrifying just how slow the bootloader can become on larger chips. Just be glad you are not on a '512' version!... |
Yes I agree about the slowness. My earlier project used a PIC1867K22 and I bootloaded through the Bluetooth serial connection, but it does run at 230,400Baud but still take about 4 minutes to load.
The reason I could not get #import to work I tried using the absolute path to the .hex file because I want to keep the bootloader code in a separate folder and that did not work.
#IMPORT (FILE=..\test\ex_pcd_bootloader.hex,HEX,RANGE=0:LOADER_SIZE) // error
I also tried FILE="..\test\ex_pcd_bootloader.hex" but it failed also.
The solution for this is simply copy the ex_pcd_bootloader.hex file to the project folder and then it works...
#IMPORT (FILE=ex_pcd_bootloader.hex,HEX,RANGE=0:LOADER_SIZE) // works |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1354
|
|
Posted: Sat Jun 11, 2016 12:28 pm |
|
|
Another option to try would be to change your project settings paths to point to where ever your bootloader.hex is (like you would for code in other folders). Then you don't need to specify the path in the import statement (assuming it works).
Also, be wary of using #FUSES NONE with your particular configuration. Your import statement isn't loading the FUSES of the bootloader, so having $FUSES NONE can lead to some odd FUSE settings if your bootloader isn't using the default fuses. You either have to specify the same FUSES in your application or if you use FUSES NONE in your app, then you need to do possibly another IMPORT statement with just the fuses range from the bootloader.hex
Either way, always make sure to do a file compare between the original bootloader.hex and the combined.hex. The only code differences should be between LOADER_END and the FUSES..
FUSES NONE is definitely great when you are loading your app serially, etc. |
|
|
soonc
Joined: 03 Dec 2013 Posts: 215
|
Moving on to real world code...! |
Posted: Sat Jun 11, 2016 3:49 pm |
|
|
jeremiah wrote: | Another option to try would be to change your project settings paths to point to where ever your bootloader.hex is (like you would for code in other folders). Then you don't need to specify the path in the import statement (assuming it works).
Also, be wary of using #FUSES NONE with your particular configuration. Your import statement isn't loading the FUSES of the bootloader, so having $FUSES NONE can lead to some odd FUSE settings if your bootloader isn't using the default fuses. You either have to specify the same FUSES in your application or if you use FUSES NONE in your app, then you need to do possibly another IMPORT statement with just the fuses range from the bootloader.hex
Either way, always make sure to do a file compare between the original bootloader.hex and the combined.hex. The only code differences should be between LOADER_END and the FUSES..
FUSES NONE is definitely great when you are loading your app serially, etc. |
Thanks for the hints.
Something strange is happening now that I've #import'ed the bootloader hex, suddenly my spi (for memory card) no longer works !
My first thought was to use spi with a STREAM=MEMCARD declaration but I can't find any of the library functions that takes the STREAM name.
The CCS help for spi_read() and spi_write() make no mention of how to use the stream name!
I should not change the subject like this but it's kind-a like is the same problem path after #import'ing bootloader.
Thanks again for your help. |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1354
|
|
Posted: Sat Jun 11, 2016 5:50 pm |
|
|
for #use spi and streams you need to use spi_xfer for both reading and writing.
spi_read and spi_write are for when you use setup_spi *instead of* #use spi. Two different methods. |
|
|
soonc
Joined: 03 Dec 2013 Posts: 215
|
OK but still does not work |
Posted: Sat Jun 11, 2016 7:30 pm |
|
|
jeremiah wrote: | for #use spi and streams you need to use spi_xfer for both reading and writing.
spi_read and spi_write are for when you use setup_spi *instead of* #use spi. Two different methods. |
Right I found that shortly after posting my last response.
Without the #import bootloader hex the Hardware SPI , all four Hardware Serial Ports , hardware I2C are working,
When I add #import bootloader hex the hardware As mentioned above all stop working.
In the case of the SPI I checked the lst file and the #use SPI(....) has code and spi_xfer() calls the spi function.
If I switch the SPI to FORCE_SW the spi works. But Serial ports and IC2 are still dead.
The #fuses are the same in the bootloader and application.
Several other functions that use port pins work as expected.
Any thoughts as to why peripheral ports stop when importing the bootloader hex ? |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1354
|
|
Posted: Sat Jun 11, 2016 7:55 pm |
|
|
Can you post a small compilable example of your application? Just have spi do something in the main. Basically strip out everything but the SPI related code, make sure it still doesn't work. It should be as simple as possible and something we could copy / paste into a file and just compile out of the box.
EDIT: compilable assuming we have the bootloader.hex which we can build using the example file + the fuses/clock you have in the application.
EDIT2: If it works in software but not hardware, one thing to look at is perhaps you are trying to set the pin selects twice without enabling the FUSE that allows that? |
|
|
soonc
Joined: 03 Dec 2013 Posts: 215
|
Pure hunch |
Posted: Sat Jun 11, 2016 8:31 pm |
|
|
jeremiah wrote: | Can you post a small compilable example of your application? Just have spi do something in the main. Basically strip out everything but the SPI related code, make sure it still doesn't work. It should be as simple as possible and something we could copy / paste into a file and just compile out of the box.
EDIT: compilable assuming we have the bootloader.hex which we can build using the example file + the fuses/clock you have in the application.
EDIT2: If it works in software but not hardware, one thing to look at is perhaps you are trying to set the pin selects twice without enabling the FUSE that allows that? |
When I first started the PIC24 project I remembered Ttelmah said that all #pin_select should be early in the code.
So I figured I would I'd do it the bootloader.
But that did not help, as the application did not know anything about the pin selects that I did in the bootloader.
On a pure hunch I also declared all #pin_select the in the application also (so that's twice) and everything works.
Thanks again for the bootloader help, you have no idea how important this is to me. |
|
|
|
|
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
|