Jump to content
stubiflex

Проблема с Unified Bootloader Host Application-ом

Recommended Posts

Сгенерировал с помощью МСС код загрузчика. При попытке залить приложение с помощью Unified Bootloader Host Application, получаю сообщение, которая на скриншоте.

PIC6F18456

Как перебороть?

//******************************************************************************
//        Software License Agreement
//
// ©2016 Microchip Technology Inc. and its subsidiaries. You may use this
// software and any derivatives exclusively with Microchip products.
//
// THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER
// EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED
// WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A PARTICULAR
// PURPOSE, OR ITS INTERACTION WITH MICROCHIP PRODUCTS, COMBINATION WITH ANY
// OTHER PRODUCTS, OR USE IN ANY APPLICATION.
//
// IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
// INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND
// WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS
// BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE
// FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN
// ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
// THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
//
// MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE TERMS.
//******************************************************************************
//
//
//
// Memory Map
//   -----------------
//   |    0x0000     |   Reset vector
//   |               |
//   |    0x0004     |   Interrupt vector
//   |               |
//   |               |
//   |  Boot Block   |   (this program)
//   |               |
//   |    0x0300     |   Re-mapped Reset Vector
//   |    0x0304     |   Re-mapped High Priority Interrupt Vector
//   |               |
//   |       |       |
//   |               |
//   |  Code Space   |   User program space
//   |               |
//   |       |       |
//   |               |
//   |    0x3FFF     |
//   -----------------
//
//
//
// Definitions:
//
//   STX     -   Start of packet indicator
//   DATA    -   General data up to 255 bytes
//   COMMAND -   Base command
//   DLEN    -   Length of data associated to the command
//   ADDR    -   Address up to 24 bits
//   DATA    -   Data (if any)
//
//
// Commands:
//
//   RD_VER      0x00    Read Version Information
//   RD_MEM      0x01    Read Program Memory
//   WR_MEM      0x02    Write Program Memory
//   ER_MEM      0x03    Erase Program Memory (NOT supported by PIC16)
//   RD_EE       0x04    Read EEDATA Memory
//   WR_EE       0x05    Write EEDATA Memory
//   RD_CONFIG   0x06    Read Config Memory (NOT supported by PIC16)
//   WT_CONFIG   0x07    Write Config Memory (NOT supported by PIC16)
//   CHECKSUM    0x08    Calculate 16 bit checksum of specified region of memory
//   RESET       0x09    Reset Device and run application
//
// *****************************************************************************

#define  READ_VERSION   0
#define  READ_FLASH     1
#define  WRITE_FLASH    2
#define  ERASE_FLASH    3
#define  READ_EE_DATA   4
#define  WRITE_EE_DATA  5
#define  READ_CONFIG    6
#define  WRITE_CONFIG   7
#define  CALC_CHECKSUM  8
#define  RESET_DEVICE   9
#define  CALC_CRC       10



// *****************************************************************************
    #include "xc.h"       // Standard include
    #include <stdint.h>
    #include <stdbool.h>
    #include "bootload.h"
    #include "mcc.h"


// *****************************************************************************
void     Get_Buffer (void);     // generic comms layer
uint8_t  Get_Version_Data(void);
uint8_t  Read_Flash(void);
uint8_t  Write_Flash(void);
uint8_t  Erase_Flash(void);
uint8_t  Read_EE_Data(void);
uint8_t  Write_EE_Data(void);
uint8_t  Read_Config(void);
uint8_t  Write_Config(void);
uint8_t  Calc_Checksum(void);
void     StartWrite(void);
void     BOOTLOADER_Initialize(void);
void     Run_Bootloader(void);
bool     Bootload_Required (void);

// *****************************************************************************
#define	MINOR_VERSION   0x07       // Version
#define	MAJOR_VERSION   0x00
//#define STX             			 0x55       // Actually code 0x55 is 'U'  But this is what the autobaud feature of the PIC16F1 EUSART is looking for
#define ERROR_ADDRESS_OUT_OF_RANGE   0xFE
#define ERROR_INVALID_COMMAND        0xFF
#define COMMAND_SUCCESS              0x01

// To be device independent, these are set by mcc in memory.h
#define  LAST_WORD_MASK          (WRITE_FLASH_BLOCKSIZE - 1)
#define  NEW_RESET_VECTOR        0x500
#define  NEW_INTERRUPT_VECTOR    0x504

#define _str(x)  #x
#define str(x)  _str(x)

// *****************************************************************************


// *****************************************************************************
    uint16_t check_sum;    // Checksum accumulator
    uint16_t counter;      // General counter
    uint8_t data_length;
    uint8_t rx_data;
    uint8_t tx_data;
    bool reset_pending = false;

// Force variables into Unbanked for 1-cycle accessibility 
    uint8_t EE_Key_1    __at(0x70);
    uint8_t EE_Key_2    __at(0x71);


frame_t  frame;

// *****************************************************************************
// The bootloader code does not use any interrupts.
// However, the application code may use interrupts.
// The interrupt vector on a PIC16F is located at
// address 0x0004. 
// The following function will be located
// at the interrupt vector and will contain a jump to
// the new application interrupt vector

    asm ("psect  intentry,global,class=CODE,delta=2");
    asm ("pagesel " str(NEW_INTERRUPT_VECTOR));
    asm ("GOTO " str(NEW_INTERRUPT_VECTOR));

void BOOTLOADER_Initialize ()
{
    EE_Key_1 = 0;
    EE_Key_2 = 0;
    
    if (Bootload_Required () == true)
    {
        Run_Bootloader ();     // generic comms layer
    }
    
    STKPTR = 0x1F;
    
    asm ("pagesel " str(NEW_RESET_VECTOR));
    asm ("goto  "  str(NEW_RESET_VECTOR));
}

// *****************************************************************************
bool Bootload_Required ()
{

// ******************************************************************
//  Check the reset vector for code to initiate bootloader
// ******************************************************************                                 

    // This section reads the application start vector to see if the location is blank
    
    NVMADRL = NEW_RESET_VECTOR & 0xFF;    // (0x3FFF) or not.  If blank, it runs the bootloader.
    NVMADRH = (NEW_RESET_VECTOR & 0xFF00UL)>> 8;                                	
    
    // Otherwise, it assumes the application is loaded and instead runs the application.
    
    NVMCON1 = 0x80;
    NVMCON1bits.RD = 1;
    NOP();
    NOP();

    if ((NVMDATH == 0x3F) && (NVMDATL == 0xFF))
    {
        return (true);
    }

    return (false);
}


// *****************************************************************************
uint8_t  ProcessBootBuffer()
{
    uint8_t   len;

    EE_Key_1 = frame.EE_key_1;
    EE_Key_2 = frame.EE_key_2;

// ***********************************************
// Test the command field and sub-command.
    switch (frame.command)
    {
    case    READ_VERSION:
        len = Get_Version_Data();
        break;
    case    READ_FLASH:
        len = Read_Flash();
        break;
    case    WRITE_FLASH:
        len = Write_Flash();
        break;
    case    ERASE_FLASH:
        len = Erase_Flash();
        break;
    case    READ_CONFIG:
        len = Read_Config();
        break;
    case    WRITE_CONFIG:
        len = Write_Config();
        break;
    case    CALC_CHECKSUM:
        len = Calc_Checksum();
        break;
    case    RESET_DEVICE:
        reset_pending = true;
        len = 9;
        break;
    default:
        frame.data[0] = ERROR_INVALID_COMMAND;
        len = 10;
    }
    return (len);
}

// **************************************************************************************
// Commands
//
//        Cmd     Length----------------   Address---------------
// In:   [<0x00> <0x00><0x00><0x00><0x00> <0x00><0x00><0x00><0x00>]
// OUT:  [<0x00> <0x00><0x00><0x00><0x00> <0x00><0x00><0x00><0x00> <VERL><VERH>]
uint8_t  Get_Version_Data()
{
    frame.data[0] = MINOR_VERSION;
    frame.data[1] = MAJOR_VERSION;
    frame.data[2] = 0;       // Max packet size (256)
    frame.data[3] = 1;
    frame.data[4] = 0;
    frame.data[5] = 0;
    NVMADRL = 0x06;               // Get device ID
    NVMADRH = 0x00;
    NVMCON1bits.NVMREGS = 1;
    NVMCON1bits.RD = 1;
    NOP();
    NOP();
    frame.data[6] = NVMDATL;
    frame.data[7] = NVMDATH;
    frame.data[8] = 0;
    frame.data[9] = 0;

    frame.data[10] = ERASE_FLASH_BLOCKSIZE;
    frame.data[11] = WRITE_FLASH_BLOCKSIZE;

    NVMADRL = 0x00;
    NVMADRH = 0x00;
    NVMCON1bits.NVMREGS = 1;
    
    for (uint8_t  i= 12; i < 16; i++)
    {
        NVMCON1bits.RD = 1;
        NOP();
        NOP();
        frame.data[i] = NVMDATL;
        
        if ((++ NVMADRL) == 0x00)
        {
            ++ NVMADRH;
        }
    }

    return  25;   // total length to send back 9 byte header + 16 byte payload
}

// **************************************************************************************
// Read Flash
// In:	[<0x01><DLEN><ADDRL><ADDRH><ADDRU>]
// OUT:	[<0x01><DLEN><ADDRL><ADDRH><ADDRU><DATA>...]
uint8_t Read_Flash()
{
    NVMADRL = frame.address_L;
    NVMADRH = frame.address_H;
    NVMCON1 = 0x80;
    
    for (uint16_t i = 0; i < frame.data_length; i += 2)
    {
        NVMCON1bits.RD = 1;
        NOP();
        NOP();
        frame.data[i]  = NVMDATL;
        frame.data[i+1] = NVMDATH;
        
        if ((++ NVMADRL) == 0x00)
        {
            ++ NVMADRH;
        }
    }

    return (frame.data_length + 9);
}

// **************************************************************************************
// Write Flash
// In:	[<0x02><DLENBLOCK><0x55><0xAA><ADDRL><ADDRH><ADDRU><DATA>...]
// OUT:	[<0x02>]
uint8_t Write_Flash()
{
    NVMADRL = frame.address_L;
    NVMADRH = frame.address_H;
    NVMCON1 = 0xA4;       // Setup writes
    
    for (uint16_t  i= 0; i < frame.data_length; i += 2)
    {
        if (((NVMADRL & LAST_WORD_MASK) == LAST_WORD_MASK)|| (i == frame.data_length - 2))
            
        NVMCON1bits.LWLO = 0;
        NVMDATL = frame.data[i];
        NVMDATH = frame.data[i+1];

        StartWrite();
        
        if ((++ NVMADRL) == 0x00)
        {
            ++ NVMADRH;
        }
    }
    
    frame.data[0] = COMMAND_SUCCESS;
    EE_Key_1 = 0x00;  // erase EE Keys
    EE_Key_2 = 0x00;
    
    return (10);
}

// **************************************************************************************
// Erase Program Memory
// Erases data_length rows from program memory
uint8_t Erase_Flash ()
{
    NVMADRL = frame.address_L;
    NVMADRH = frame.address_H;
    
    for (uint16_t i=0; i < frame.data_length; i++)
    {
        if ((NVMADRH & 0x7F) >= ((END_FLASH & 0xFF00) >> 8))
        {
            frame.data[0] = ERROR_ADDRESS_OUT_OF_RANGE;
            return (10);
        }
        
        NVMCON1 = 0x94;       // Setup writes
        
        StartWrite();
        
        if ((NVMADRL += ERASE_FLASH_BLOCKSIZE) == 0x00)
        {
            ++ NVMADRH;
        }
    }
    
    frame.data[0]  = COMMAND_SUCCESS;
    frame.EE_key_1 = 0x00;  // erase EE Keys
    frame.EE_key_2 = 0x00;
    
    return (10);
}


// **************************************************************************************
// Read Config Words
// In:	[<0x06><DataLengthL><unused> <unused><unused> <ADDRL><ADDRH><ADDRU><unused>...]
// OUT:	[9 byte header + 4 bytes config1 + config 2]
uint8_t Read_Config ()
{
    NVMADRL = frame.address_L;
    NVMADRH = frame.address_H;
    NVMCON1 = 0x40;      // can these be combined?
    
    for (uint8_t  i= 0; i < frame.data_length; i += 2)
    {

        NVMCON1bits.RD = 1;
        NOP();
        NOP();
        frame.data[i]   = NVMDATL;
        frame.data[i+1] = NVMDATH;
        ++ NVMADRL;
    }
    
    return (13);           // 9 byte header + 4 bytes config words
}
// **************************************************************************************
// Write Config Words
uint8_t Write_Config ()
{
    NVMADRL = frame.address_L;
    NVMADRH = frame.address_H;
    NVMCON1 = 0xC4;       // Setup writes
    
    for (uint8_t  i = 0; i < frame.data_length; i += 2)
    {
        NVMDATL = frame.data[i];
        NVMDATH = frame.data[i+1];

        StartWrite();
        
        if ((++ NVMADRL) == 0x00)
        {
            ++ NVMADRH;
        }
    }
    frame.data[0] = COMMAND_SUCCESS;
    EE_Key_1 = 0x00;  // erase EE Keys
    EE_Key_2 = 0x00;
    
    return (10);
}


// **************************************************************************************
// Calculate Checksum
// In:	[<0x08><DataLengthL><DataLengthH> <unused><unused> <ADDRL><ADDRH><ADDRU><unused>...]
// OUT:	[9 byte header + ChecksumL + ChecksumH]
uint8_t Calc_Checksum()
{
    NVMADRL = frame.address_L;
    NVMADRH = frame.address_H;
    NVMCON1 = 0x80;
    check_sum = 0;
    
    for (uint16_t i = 0;i < frame.data_length; i += 2)
    {
        NVMCON1bits.RD = 1;
        NOP();
        NOP();
        check_sum += (uint16_t)NVMDATL;
        check_sum += ((uint16_t)NVMDATH) << 8;
        
        if ((++ NVMADRL) == 0x00)
        {
            ++ NVMADRH;
        }
    }
    
     frame.data[0] = (uint8_t) (check_sum & 0x00FF);
     frame.data[1] = (uint8_t)((check_sum & 0xFF00) >> 8);
     
     return (11);
}


// In: [<0x08><DataLengthL><DataLengthH> <unused><unused> <ADDRL><ADDRH><ADDRU><unused>...]
// OUT: [9 byte header + ChecksumL + ChecksumH]
/*uint8_t Calc_Checksum()
{
 uint16_t addr = (frame.address_H << 8) | frame.address_L; 
 check_sum = 0;
 for (uint16_t i = 0;i < frame.data_length; i += 2)
 {
 check_sum += FLASH_ReadWord(addr);
 ++ addr;
 }
 frame.data[0] = (uint8_t) (check_sum & 0x00FF);
 frame.data[1] = (uint8_t)((check_sum & 0xFF00) >> 8);
 return (11);
}*/




// *****************************************************************************
// Unlock and start the write or erase sequence.

void StartWrite()
{
    CLRWDT();
//    NVMCON2 = EE_Key_1;
//    NVMCON2 = EE_Key_2;
//    NVMCON1bits.WR = 1;       // Start the write
// had to switch to assembly - compiler doesn't comprehend no need for bank switch
    asm ("movf " str(_EE_Key_1) ",w");
    asm ("movwf " str(BANKMASK(NVMCON2)));
    asm ("movf  " str(_EE_Key_2) ",w");
    asm ("movwf " str(BANKMASK(NVMCON2)));
    asm ("bsf  "  str(BANKMASK(NVMCON1)) ",1");       // Start the write

    NOP();
    NOP();
    return;
}


// *****************************************************************************
// Check to see if a device reset had been requested.  We can't just reset when
// the reset command is issued.  Instead we have to wait until the acknowledgement
// is finished sending back to the host.  Then we reset the device.
void Check_Device_Reset ()
{
    if (reset_pending == true)
    {

        RESET();
    }
}




// *****************************************************************************
// *****************************************************************************

 

 

bootloader3.png

Share this post


Link to post
Share on other sites

Если я Вас правильно понял, вы вначале bootloader нашли на свои мк прошивка .asm,  потом настроили ее допустим шьем в конец flash памяти не с нулевого адреса мк и скомпилировали еe в .hex и прошили нормальным прогграматором и только потом можно заливать свою прошивку программу через uart переходник допустим. Если это было сделанно не так вы нарушили все инструкций адрес вот читаем http://proiot.ru/blog/posts/2012/10/03/zamechatelnyi-bootloader-ot-microchip-dlia-pic16-pic18/ или я дурак вас не понял).

Share this post


Link to post
Share on other sites

Написано же выше, что я сгенерировал (создал прошивку) бутлоудера. Конечно же сгенерированную прошивку залил в PIC с помощью PICkit3. Потом пытался залить прошивку аппликации через уже залитого бутлоудера и программы на ПК. Результаты на скриншотах.

 

А замечательный бутлоадер, на которого дали ссылку, меня давно уже работает. Но тема сейчас не этот.

Share this post


Link to post
Share on other sites

Приглашаем на вебинар «Новинки и уникальные решения Molex. На что обратить внимание и почему»

15 апреля приглашаем на вебинар, который будет интересен разработчикам и инженерам-схемотехникам, интересующимся тенденциями рынка, новыми перспективными решениями для соединений «провод-провод», «провод-плата», «плата-плата». Для инженеров КИПиА и IT будут освещены уникальные решения Molex для «удлинения» интерфейсов HDMI, DisplayPort и USB даже в условиях сильного зашумления, а также семейство бесконтактных датчиков Contrinex. Помимо этого, будет уделено внимание дальнейшему развитию направления антенн, где Molex имеет ряд интересных и уникальных решений.

Подробнее

Мне только одно интересно через приложение AN1310 которое можно тоже самое проделать тоже ошибку выдает?

Share this post


Link to post
Share on other sites

Залитая прошивка бутлоудера не способен сотрудничать с AN1310, по этому не может быть выдаваться тот же ошибка. 

Share this post


Link to post
Share on other sites
                     

Выбираем преобразователь для портативных устройств

Портативные устройства могут различаться по типам элементов питания, а также по разным функциям. В статье на примере 3-х устройств демонстрируется, как многоканальные SIMO-преобразователи помогают эффективно реализовывать потенциал системы питания и первичного элемента, а также гибко подстраиваться под требуемый функционал.

Читать статью

Ну если для данного мк, после установки приложения  AN1310  нет бутлоадера .asm в списках поддержки то наверно не будет работать с вашей прошивкой данное приложение. Тогда посмотрите здесь намеки https://www.microchip.com/forums/m988264-p2.aspx может поможет и внимательно проидите по ссылкам которые там похоже ответ на вашу проблему есть, mcc не совсем корректно генерирует загрузчик с определенными данными.

Share this post


Link to post
Share on other sites

5-ый раз говорю, что на МК залит прошивка бутлоудера, сгенерированная с помощью МСС. Это все не имеет никакого отношения к АN1310.

Share this post


Link to post
Share on other sites

Тогда вас ждут танцы с бубном с загрузчиком сгенерированным с помощью мсс, его надо подгонять под приложение Unified Bootloader Host Application чтобы заработало как надо. Об этом явно пишут на форуме по ссылкам которые давал. То что бут залит в мк вас не спасет. Колдовать придется с самим бутом кода генерированным мсс еще раньше прежде чем прошивть его в мк.

Edited by Securety

Share this post


Link to post
Share on other sites

А на вопрос, которую я задал в стартовом посте, ничего конкретного? Просто постите, увеличивая количество постов? После 100 бесполезных постов дают тут грамоту?

Share this post


Link to post
Share on other sites

А вы на том форуме хоть были? В котором с переводом лично насчитал около 6+ решений именно с вашей проблемой unified bootloader application. Тут нет телепатов потому что, нужно иметь ваш мк с железом чтоб точно помочь вам, вы же не о коде спрашивайте и какие там ошибки которую легко в proteus проверить на правильность. Я лично на 100%  что там на том форуме вы не были и не пробывали варианты, а сразу здесь спросили и написали.

Share this post


Link to post
Share on other sites

Здравствуйте. Что сразу вижу:

1. Попробуйте в настройках поставить скорость 19200. На 9600 у меня почему-то тоже не было связи.

2. Память под программу, как я понимаю, должна начинаться с 0х0300, у Вас в настройках 0х1000.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...