RCN
Joined: 24 Aug 2012 Posts: 1
|
Bootloader example expansion |
Posted: Fri Aug 24, 2012 6:44 am |
|
|
The situation:
I started working on the CCS (PCM v4.129) compiler for the first time earlier this year on a PIC16F1936, and I have developed an embedded application to basically its end now. The least requirement I have to implement, is to allow for boot loading functionality.
Now, my source code is already quite involved, with various .c and .h file pairs, splitting the code up into functional units for the sake of sanity.
At first I tried to push the boot loader example into my application, but I had weird issues when calling the write_program_memory function at certain addresses, causing the firmware to stop responding (I assume it crashed, as it was non-responsive).
I managed to get the example boot loader working just fine on its own, and even managed to get two versions of it updated via the boot loader interface from my own higher level C# application.
The next step now for me would be to gradually migrate my previous code into the boot loader code, and hopefully get it to compile.
The problem:
So for each bit of functionality, I went for the modular approach and created a .h/.c pair containing their specific functions. To test if I can somehow ensure that these functions end up after my boot loader in the ROM, I took the boot loader source code as it was, and moved the "application()" function to the new file pair. The result is as follows:
bootloader.h:
Code: | #define LOADER_END 0x3D6
#define LOADER_SIZE 0x328
#ifndef _bootloader
#build(reset=LOADER_END+1, interrupt=LOADER_END+5)
#org 0, LOADER_END {}
#endif |
ISDPic.c (renamed from ex_bootloader.c)
Code: | #include "ISD.h"
#include "Test.h"
#org 0x20,0x4F
void main(void)
{
if (input(PIN_B3))
load_program();
application();
}
#ORG default
#int_global
void isr(void) {
jump_to_isr(LOADER_END+5*(getenv("BITS_PER_INSTRUCTION")/8));
} |
ISD.h contains the initialisation:
Code: | #ifndef ISD_HEADER
#define ISD_HEADER
// Device definitions
#include <16F1936.h>
#fuses NOWDT // No watchdog timer
#fuses HS // High speed Oscillator
#fuses NOBROWNOUT // No brownout reset
#fuses NOLVP // No low voltage programming
#device ADC=16 // Use B15 to B4 of the ADC
#device WRITE_EEPROM=NOINT // Allow interrupts in EPROM writes
#use DELAY(INTERNAL=8Mhz) // 8 MHz clock speed
// Global definitions
#define VER_MAJOR 2 // Major version (0-9)
#define VER_MINOR 0x02 // Minor version (00-FF)
#define _bootloader
#include <bootloader.h>
#include <loader.c>
#endif
|
Followed by my two test files:
Test.h
Code: | #ifndef TEST_HEADER
#define TEST_HEADER
#include "ISD.h"
#org LOADER_END+1,LOADER_END+20
void application(void);
#endif |
Test.c
Code: | #include "Test.h"
#org LOADER_END+1,LOADER_END+20
void application(void)
{
while(TRUE)
{
output_high(PIN_C5);
delay_ms(200);
output_low(PIN_C5);
delay_ms(200);
putchar(0x52);
}
} |
This does not build, and I end up with the following error messages:
Code: | --- Info 300 "Test.c" Line 4(1,3): More info: Segment at 00000-000AD (0000 used)
--- Info 300 "Test.c" Line 4(1,3): More info: Segment at 000AE-000B7 (0000 used) Priv
--- Info 300 "Test.c" Line 4(1,3): More info: Segment at 000B8-003D6 (0000 used) Priv
--- Info 300 "Test.c" Line 4(1,3): More info: Segment at 003D7-003EA (0000 used) Priv
--- Info 300 "Test.c" Line 4(1,3): More info: Segment at 003EB-007FF (0000 used)
--- Info 300 "Test.c" Line 4(1,3): More info: Segment at 00800-00FFF (0000 used)
--- Info 300 "Test.c" Line 4(1,3): More info: Segment at 01000-017FF (0000 used)
--- Info 300 "Test.c" Line 4(1,3): More info: Segment at 01800-01FFF (0000 used)
*** Error 126 "Test.c" Line 4(1,3): Invalid ORG range |
The funny part is that the fourth info message indicates address range 003D7 to 003EA is in use, though that is the range that I have specified for my function.
Edit: fixed an error in the Test.c file. |
|