|
|
View previous topic :: View next topic |
Author |
Message |
spilz
Joined: 30 Jan 2012 Posts: 220
|
[Solved] Bootloader to program: how to share a byte |
Posted: Fri Nov 25, 2016 2:31 am |
|
|
Hello everyone,
I'm working on USB Bootloader on 18F47J53 and it works well.
But now, I would like to be able to "share" a data from the bootloader to the program :
To go into bootloader I have to press a "reset' button for 10s
in fact when I start to press, the PIC restarts, and the bootloader checks during 10s if it's still pressed.
If yes -> waiting for new program.
if not -> start normal program.
I would like to save how long the button is pressed (if less than 10s) and use it in the program (something like in normal program : if press 3s then do something).
Before with 18F2550, I used internal EEPROM, but 18F47J53 does not have it.
I just need to transfer 1 byte and use it at the beginning of the program.
What is the best way to do it ?
Thanks for your help.
regards
Last edited by spilz on Fri Nov 25, 2016 3:50 am; edited 1 time in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19569
|
|
Posted: Fri Nov 25, 2016 2:59 am |
|
|
Using the EEPROM, was going to use it's lives rather rapidly. Just make a variable 'common'. Choose a RAM location, and #locate a variable at this point. Use a global variable (but do not declare this as 'static'). A global variable, without any initialisation value, will be left unchanged when the main code starts (provided you don't use #zero_ram). You can initialise it in the bootloader, but not in the main code. |
|
|
spilz
Joined: 30 Jan 2012 Posts: 220
|
|
Posted: Fri Nov 25, 2016 3:50 am |
|
|
That works great, thanks a lot |
|
|
Rob1955
Joined: 25 Feb 2017 Posts: 6
|
|
Posted: Tue Mar 14, 2017 11:35 pm |
|
|
Ttelmah wrote: | Using the EEPROM, was going to use it's lives rather rapidly. Just make a variable 'common'. Choose a RAM location, and #locate a variable at this point. Use a global variable (but do not declare this as 'static'). A global variable, without any initialisation value, will be left unchanged when the main code starts (provided you don't use #zero_ram). You can initialise it in the bootloader, but not in the main code. |
Wanted to try #locate to get the restart_cause moved from bootloader to main application. So we use #locate twice right?
In bootloader:
Code: |
int16 reason;
#locate reason = 0x100
void main()
{
reason = restart_cause();
.
.
.
.
}
|
then in main application:
Code: |
int16 status;
#locate status = 0x100
printf....
|
Initially, i used #word status = 0x100 and that worked most of the time but the space was not 'locked'. The #locate method is also working 'most' of the time. I say 'most' as it gets corrupted (only while using bootloader!). Could it be that with bootloader, compiler uses that RAM space? Any better method?
Though the issue is more apparent when RAM and ROM utilized are >= 40% (18F65K40 with 5.070) |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19569
|
|
Posted: Wed Mar 15, 2017 2:37 am |
|
|
You are declaring 'status' as global in the actual application?. (so outside the code itself).
You show it as if the declaration might be inside the code. It needs to be outside, like the declaration in the bootloader. Otherwise it becomes only a local variable.
I'd probably suggest putting it somewhere less in the center of the memory map. So perhaps 0x7FE. Problem is that if the compiler wants to allocate a large array, it wants nice continuous blocks of memory.
Look at the .sym file generated by the bootloader, and by the main code. What does it show in the RAM area here?.
Try testing. Write a known value to the variable in the bootloader. Does it arrive successfully?. If so, then the problem is that restart_cause doesn't contain what you expect!... |
|
|
Rob1955
Joined: 25 Feb 2017 Posts: 6
|
|
Posted: Wed Mar 15, 2017 5:59 pm |
|
|
Ttelmah wrote: | You are declaring 'status' as global in the actual application?. (so outside the code itself).
You show it as if the declaration might be inside the code. It needs to be outside, like the declaration in the bootloader. Otherwise it becomes only a local variable.
I'd probably suggest putting it somewhere less in the center of the memory map. So perhaps 0x7FE. Problem is that if the compiler wants to allocate a large array, it wants nice continuous blocks of memory.
Look at the .sym file generated by the bootloader, and by the main code. What does it show in the RAM area here?.
Try testing. Write a known value to the variable in the bootloader. Does it arrive successfully?. If so, then the problem is that restart_cause doesn't contain what you expect!... |
Thanks for your reply.
Yes, status is a global variable.
Will try 0x7FE and will look at the .sym file. Thanks.
Most of the time, 'status' contains correct cause per device header file. When it gets corrupted, it shows data that i know available somewhere else at end of ROM. This is only when its being used in bootloader and when program is large. Will try to reproduce it in a smaller program so its easier to debug. Loading the same program without bootloader so it starts at 0x0000 never failed to show one of the returned values in header file.
Might as well check the debugger for the first time. I am assuming the Debugger is just like any standard high-level debugger where you can step by step run the program, see all assigned variables, halt/insert evaluation and such.
Actually i do suspect its something in the compiler and how it handles bootloader. I read 100's of posts the last week on this forum as part of the steep learning curve; i noticed a thread that someone said (with PIC24 and 5.06x compiler IIRC) that sprintf is causing his pic to restart with stack overflow.
I got that for a while when the program gets large, i traced it to sprintf, but then it was not sprintf itself per-say, it was writing any data to a character pointer. He solved his issue by doubling the stack which is something can't be done on PIC18. I've been having stack overflow while my worse stack is 5 (out of 31) per .LST file. I am learning to read the .LST file and soon .SYM and will try to see if i can figure it out. Program runs fine zero issues without bootloader. Probably the #locate issue is also related to this also. Also, changing which global variable is declared first, changes at which part of the code the pic restarts.
Thanks for your input Ttelmah. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19569
|
|
Posted: Thu Mar 16, 2017 12:37 am |
|
|
OK.
What you are describing has all the symptoms of an array used in the bootloader overflowing.
Remember there is no protection on the size of arrays, or areas used by pointers. If you have an array used to build the data up ready to write to memory, and for some reason more bytes arrive than are expected, then data can be written into areas after the array....
Look carefully at what is declared immediately below the data being corrupted. So if the sym file shows (for instance):
0xF0...0xFF buff
0x100 reason
you would need to look at what is written to 'buff'.
On the stack overflow, that is because the PIC24 and similar chips do have a 'data' stack (which the PIC12/16/18 chips don't have). Things like printf using a float use a _lot_ of stack space. The default stack size was too small for quite a lot of functions on some compiler versions. Again unlike the older PIC's, the stack is variable, and all that is needed is to increase the stack size.
To get a stack overflow on a PIC18, _you_ would have to be doing something that results in the stack becoming unbalanced. For instance, jumping out of a routine, rather than returning from it. The compiler knows how much stack it uses, and tells you this. To make this go wrong, requires deliberate action.... |
|
|
|
|
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
|