CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Example PCD bootloader doesn't work PIC 24

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
OA_mattm



Joined: 15 Feb 2017
Posts: 5

View user's profile Send private message

Example PCD bootloader doesn't work PIC 24
PostPosted: Wed Feb 15, 2017 2:05 pm     Reply with quote

PIC: 24FJ256GB206

CCS version:
IDE Version 5.062
PCD Version 5.062

I'm attempting to use the ex_pcd_bootloader.c program in PICC\Examples and no matter what I try, my application will not start.

I can confirm that the load_program() function in loader_pcd.c is in-fact receiving and properly parsing the application hex because of some debugging printf()s I put in; however, I don't know how to confirm that it is properly writing it to the flash. The only symptom is that I cannot get the application to start.

Is the bootloader perhaps loading the wrong start address for my application, and that's why my application won't start?

Here is my source code for the bootloader:
Code:

//#define DSPIC33FJ
//#define DSPIC30F
//#define PIC24FJ
#define PIC24FJ_REV2
//#define PIC24HJ
//#define PIC24EP

#if defined(DSPIC33FJ)
   #include <33FJ128GP706.h>
   #fuses NOWDT
   #use delay(crystal=12MHz)
   #use rs232(BAUD=9600,UART2,errors)
   #define PUSH_BUTTON PIN_B2
#elif defined(DSPIC30F)
   #include <30F4012.h>
   #fuses NOWDT
   #use delay(crystal=20M)
   #use rs232(BAUD=9600,UART1A,errors)
   #define PUSH_BUTTON PIN_B1
#elif defined(PIC24FJ)
   #include <24FJ128GA006.h>
   #fuses NOWDT
   #use delay(crystal=20MHz)
   #use rs232(BAUD=9600,UART1,errors)
   #define PUSH_BUTTON PIN_F6
#elif defined(PIC24FJ_REV2)
   #include <24FJ256GB206.h>
   #fuses NOWDT
   #use delay(internal=32000000)
   #pin_select U1TX=PIN_D10
   #pin_select U1RX=PIN_D11
   #use rs232(UART1, baud=115200, stream=STREAM_CONTROL,ERRORS,DISABLE_INTS)
   //#use rs232(BAUD=9600,UART1,errors)
   #define PUSH_BUTTON PIN_E0
#elif defined(PIC24HJ)
   #include <24HJ128GP306.h>
   #fuses NOWDT
   #use delay(crystal=20MHz)
   #use rs232(Baud=9600,UART1,errors)
   #define PUSH_BUTTON PIN_F6
#elif defined(PIC24EP)
   #include <24ep256gp206.h>
   #fuses NOWDT
   #use delay(crystal=20MHz)
   #pin_select U1TX = PIN_A4
   #pin_select U1RX = PIN_A9   
   #use rs232(Baud=9600,UART1,errors)
   #define PUSH_BUTTON PIN_C3
#endif

#define _bootloader
//#define BOOTLOADER_MODE2X

#include <pcd_bootloader.h>
#include "loader_pcd.c"

#org APPLICATION_START
void application(void)
{   
   while(TRUE);
}

void main(void)
{
   int inchar = 0;
   
   fprintf(STREAM_CONTROL, "P\r\n");

   inchar = fgetc(STREAM_CONTROL);
   if(inchar == 'U')
   {
      delay_ms(140); // wait for PLL
     

      // Let the user know it is ready to accept a download
      fprintf(STREAM_CONTROL, "W\r\n");

      // Load the program
      load_program();

   }
   else
   {
      fprintf(STREAM_CONTROL, "X\r\n");
      application();
   }
}

#int_default
void isr(void)
{
   jump_to_isr(LOADER_END+5);
}


Here is the source for the application I am trying to load:

Code:

#include <24FJ256GB206.h>

#device ADC=10


#fuses FRC_PLL, NOWDT, PROTECT,OSCIO

#use delay(internal=32000000)

#pin_select U1TX=PIN_D10
#pin_select U1RX=PIN_D11

#use rs232(UART1, baud=115200, stream=STREAM_CONTROL,ERRORS,DISABLE_INTS)

#include <stdio.h>


void main()
{
    fprintf(STREAM_CONTROL, "Starting\r\n");
    while (1)
    {
        delay_ms(1000);
        fprintf(STREAM_CONTROL, "Looping\r\n");
    }
}


and here is the compiled hex for my dummy application:
Code:

:080000003E02040000000000B4
:100400005420EF00C3202000008041001040BA00BB
:100410000160EF00000006005374000061720000EC
:10042000746900006E6700000D0A00000000000003
:100430005420EF0043222000008041001040BA0009
:100440000160EF00000006004C6F00006F700000BC
:10045000696E0000670D00000A0000000000E00067
:100460004220AF00040037007B3E0900000000007E
:100470000000E900FCFF3A00000006000FF827002A
:10048000F0FF270020A0B7000000000081E0A800D6
:100490000600FC0021742000620420007305200087
:1004A000824878008348780042C7A900C0F0230042
:1004B000A4A6B70000302000C2A6B7000600FC00CA
:1004C0002174200062042000730520008248780017
:1004D0008348780042C7A80004022000243A88001C
:1004E0000028EF00040028000411880004402000C8
:1004F000141188002062A800240220004411880002
:10050000E224EF00E424EF00E624EF00EA24EF0009
:10051000EC24EF000228EF00010020000100780029
:100520000160EF0000020200000000008100E8000E
:100530002322AF00FEFF370024A2B7009000200066
:100540000008E600F5FF3700803E20002E02020082
:100550000000000001002000010078000160EF00B1
:1005600018020200000000008100E8002322AF0012
:10057000FEFF370024A2B700800020000008E6003C
:10058000F5FF3700A4020400000000000040FE0058
:020000040005F5
:1057F000FFFF00FFFFFC00FFD39900FF7F1F00FFAA
:00000001FF
;PIC24FJ256GB206
;CRC=092E  CREATED="14-Feb-17 17:17"




I also wrote the following python code for sending the application from my computer to the PIC:
Code:

import serial
import time
import sys
import string

ser = serial.Serial('COM20', 115200, timeout=0)

f = open("test.hex", "r")

mylist = []

lines = f.readlines()

f.close()

for i in range(len(lines)):
    mylist.append(lines[i].replace('\n', '\r'))

lines = mylist
print(lines)

time.sleep(1)

for line in lines:
    if line[0] == ':':
        ser.write(line)

    time.sleep(0.05)
    response = ser.read(64)
    print(response)


ser.close()
jeremiah



Joined: 20 Jul 2010
Posts: 1349

View user's profile Send private message

PostPosted: Wed Feb 15, 2017 2:58 pm     Reply with quote

I might be just missing it, but I don't see where you included the bootloader header in your application code. The bootloader code correctly has it, but I don't see it in the application. That file is necessary in both the bootloader and the application file so that memory is properly placed.

Did you try the example file for the bootloader in the example's directory?
OA_mattm



Joined: 15 Feb 2017
Posts: 5

View user's profile Send private message

PostPosted: Wed Feb 15, 2017 3:50 pm     Reply with quote

jeremiah wrote:
I might be just missing it, but I don't see where you included the bootloader header in your application code. The bootloader code correctly has it, but I don't see it in the application. That file is necessary in both the bootloader and the application file so that memory is properly placed.

Did you try the example file for the bootloader in the example's directory?


I knew it was something simple. You are correct, I did not include it in the application code. Now my application loads correctly

Here is the new application code:

Code:

#include <24FJ256GB206.h>

#device ADC=10


#fuses FRC_PLL, NOWDT, PROTECT,OSCIO

#use delay(internal=32000000)

#pin_select U1TX=PIN_D10
#pin_select U1RX=PIN_D11

#use rs232(UART1, baud=115200, stream=STREAM_CONTROL,ERRORS,DISABLE_INTS)

#include <stdio.h>
#include <pcd_bootloader.h>


void main()
{
    fprintf(STREAM_CONTROL, "Starting\r\n");
    while (1)
    {
        delay_ms(1000);
        fprintf(STREAM_CONTROL, "Looping\r\n");
    }
}


And the new application hex file:
Code:

:081000003A0A040000000000A0
:0813F8005420EF0083A0200047
:10140000008041001040BA000160EF0000000600BB
:101410005374000061720000746900006E67000080
:101420000D0A0000000000005420EF0003A220007D
:10143000008041001040BA000160EF00000006008B
:101440004C6F00006F700000696E0000670D0000B7
:101450000A0000000000E0004220AF000400370056
:101460007B3E0900000000000000E900FCFF3A009C
:10147000000006000FF82700F0FF270020A0B700AB
:101480000000000081E0A8000600FC00217420009C
:1014900062042000730520008248780083487800A9
:1014A00042C7A900C0F02300A4A6B7000030200066
:1014B000C2A6B7000600FC002174200062042000D0
:1014C00073052000824878008348780042C7A8004E
:1014D00004022000243A88000028EF0004002800BD
:1014E0000411880004402000141188002062A80024
:1014F0002402200044118800E224EF00E424EF00DD
:10150000E624EF00EA24EF00EC24EF000228EF00CD
:1015100001002000010078000160EF00FC090200DA
:10152000000000008100E8002322AF00FEFF37002A
:1015300024A2B700900020000008E600F5FF370065
:10154000803E20002A0A0200000000000100200066
:10155000010078000160EF00140A020000000000A2
:101560008100E8002322AF00FEFF370024A2B7006D
:10157000800020000008E600F5FF3700A00A040004
:08158000000000000040FE0025
:020000040005F5
:1057F000FFFF00FFFFFC00FFD39900FF7F1F00FFAA
:00000001FF
;PIC24FJ256GB206
;CRC=28F4  CREATED="15-Feb-17 13:39"

OA_mattm



Joined: 15 Feb 2017
Posts: 5

View user's profile Send private message

PostPosted: Wed Feb 15, 2017 4:26 pm     Reply with quote

Actually now, in my actual application (not just the dummy application that I posted to get the bootloader working), none of my interrupts work. Do I need to modify the linker scripts to get that going?
jeremiah



Joined: 20 Jul 2010
Posts: 1349

View user's profile Send private message

PostPosted: Wed Feb 15, 2017 4:35 pm     Reply with quote

Can you whittle it down to a small example application (That is compilable) where an interrupt doesn't work? Just a basic main with one interrupt. Verify that doesn't work and post the code.

Theoretically, the contents of pcd_bootloader.h and your #int_default in the bootloader should handle the interrupts, assuming you haven't modified them in an odd way.
OA_mattm



Joined: 15 Feb 2017
Posts: 5

View user's profile Send private message

PostPosted: Wed Feb 15, 2017 4:56 pm     Reply with quote

jeremiah wrote:
Can you whittle it down to a small example application (That is compilable) where an interrupt doesn't work? Just a basic main with one interrupt. Verify that doesn't work and post the code.

Theoretically, the contents of pcd_bootloader.h and your #int_default in the bootloader should handle the interrupts, assuming you haven't modified them in an odd way.


This is a very heavily boiled down version of my application that I have confirmed does not have working interrupts when put in through the bootloader, but still prints "Starting Program" at the beginning just fine.

Code:

#include <24FJ256GB206.h>
#device ADC=10


//#fuses FRC_PLL, WDT, PROTECT,OSCIO,
#fuses FRC_PLL, NOWDT, PROTECT,OSCIO,
//#fuses  NOWDT, NOPROTECT,OSCIO,

#use delay(internal=32000000)
#pin_select U1TX=PIN_D10
#pin_select U1RX=PIN_D11



//#use rs232(baud=38400, UART1,PARITY=N,BITS=8,)
#use rs232(UART1, baud=115200, stream=STREAM_CONTROL,ERRORS,DISABLE_INTS)

#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <pcd_bootloader.h>


//These buffers must be volatile to prevent the compiler from possibly optimizing out the memset() calls in main()
volatile char RawCommand[64];     ///< The raw, unprocessed command recieved from the UART
volatile char ProcessCommand[64]; ///< The command that is to be processed in CommandProcess()

volatile int inchar = 0; ///< Temporary variable for storing the latest character recieved from the UART
int charptr = 0;         ///< Variable for keeping track of the number of characters in the RawCommand[] array
int CommandReceived = 0; ///< Flag to indicate if a command has been recieved over serial. SerialInputISR() sets this flag, and main() clears it.

/**
 * @brief Interrupt service routine for serial input
 */
#int_RDA
void SerialInputISR()
{
    //Get the latest character from the command input UART
    inchar = fgetc(STREAM_CONTROL);

    //Copy that character to the next spot in the command input
    RawCommand[charptr] = (char) inchar & 0xFF;

    //If a carriage return is detected, then we know we are at the end of the command
    if (inchar == 13) {
        //End of command, copy RawCommand to ProcessCommand to be processed in CommandProcess
        strncpy(ProcessCommand, RawCommand, charptr);
        CommandReceived=1;
        charptr = 0;

        return;
    }

    //Increment the count of the number of recieved characters
    charptr++;

    //Impose an artificial limit of 64 characters on the command
    if (charptr > 63) {
        charptr = 0;
    }

    return;
}



/**
 * @brief Processes a command recieved in the SerialInputISR().
 *
 * When a command is recieved from UART1, it is copied to the gobal variable ProcessCommand
 * This function parses the command in the ProcessCommand variable, and takes the appropriate
 * action according to the command.
 */
void CommandProcess(void)
{
    char stest[10];
    char* locptr;

    //Test for a query command
    strcpy(stest, "$Q");
    locptr = strstr(ProcessCommand, stest);
    if (locptr > 0) {

      fprintf(STREAM_CONTROL, "Query command detected\r\n");       
        return;
    } //end $Q if statement

    //Catch-all for an unrecognized command
    fprintf(STREAM_CONTROL, "Illegal Command $RLY [%s]\r\n", ProcessCommand);
}


void main()
{
   fprintf(STREAM_CONTROL, "Starting Program");

   //Enable serial interrupt
    enable_interrupts(INT_RDA);
    enable_interrupts(INTR_GLOBAL);

    //Zero the ProcessCommand and RawCommand buffers
    memset(ProcessCommand, 0x00, sizeof(ProcessCommand));
    memset(RawCommand, 0x00, sizeof(RawCommand));
   
    //Infinite loop, do this forever
    while (1) {

        //Check to see if we've recieved a command from the RDA interrupt
        if (CommandReceived == 1) {
            CommandReceived = 0;
            CommandProcess();

            //Zero the ProcessCommand and RawCommand buffers
            memset(ProcessCommand, 0x00, sizeof(ProcessCommand));
            memset(RawCommand, 0x00, sizeof(RawCommand));
        } //end CommandReceived if statement

    } //end while (1)
} //end main()

OA_mattm



Joined: 15 Feb 2017
Posts: 5

View user's profile Send private message

PostPosted: Wed Feb 15, 2017 5:16 pm     Reply with quote

Actually, nevermind. Sorry to waste your time. My interrupts are working now with the exact code I posted. I made a change to the bootloader as an experiment and forgot to change it back.

You have been extremely helpful. My boss will be very happy we have this working now.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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