0

我正在使用带有编译器 XC16 的 PIC30F4011。我注意到局部变量的赋值不起作用,但是如果我将变量声明为全局变量,它就起作用了。

在下面的函数中,在赋值语句: 之后addr = b_flashStart;addr应该是0x1600,但实际上是0

uint16_t __attribute__((section("boot"))) b_calcCrc(void)
{
    uint16_t addrU = 0;
    uint16_t crcFlash;
    uint16_t index = 0;
    uint16_t addr = 0;
    
    addrU = 0x0000;
    addr = b_flashStart;
    crcFlash  = 0xFFFF;
    for(addr = b_flashStart; addr < 0x7fc0/*b_flashEnd*/; addr += 0x0040)
    {
        b_flashRowRead( addrU, addr, flashReadBuffer );  // Row of 32 pairs
        for(index = 0; index < 0x40;)
        {
            b_temp = flashReadBuffer[index++];
            crcFlash = b_crc16( crcFlash, b_temp );
            b_temp = flashReadBuffer[index++];
            crcFlash = b_crc16( crcFlash, b_temp );
            b_temp = flashReadBuffer[index++];
            crcFlash = b_crc16( crcFlash, b_temp );
            b_temp = flashReadBuffer[index++];
            crcFlash = b_crc16( crcFlash, b_temp );
        }
    }

    return crcFlash;
}

这是整个文件:



/******************************************************************************/
/* Files to Include                                                           */
/******************************************************************************/

/* Device header file */
#include <xc.h>

#include <stdint.h>        // Includes uint16_t definition
#include <stdbool.h>       // Includes true/false definition  
#define  FCY    20000000UL
#include <libpic30.h>

/******************************************************************************/
//  Programming format  Memory Map
//  -----------------
//  |    0x0000     |
//  |    0x0002     |   Boot vector
//  |    0x0004     |   Unlock & write vector
//  |               |   
//  |               |
//  |  Boot Block   |   (this program)
//  |               |
//  |    0x1000     |   Re-mapped Reset Vector
//  |    0x0600     |   Re-mapped Interrupt Vector table
//  |               |
//  |       |       |
//  |               |
//  |    0X1000     |   User program space
//  |               |
//  |       |       |
//  |               |
//  |    0xFFFE     |
//  -----------------
//


/*****************************************************************************/
#define MINOR_VERSION   0x00        // Version
#define MAJOR_VERSION   0x01

#define RC_DLE      0x01
#define RC_STX      0x02

#define STX     0x023       // use # instead
#define ETX     0x04
#define DLE     0x05

/*****************************************************************************/
#define CHKSUM      0x00        // Checksum accumulator
#define COUNTER     0x01        // General counter
#define ABTIME_H    0x02
#define ABTIME_L    0x03
#define RXDATA      0x04
#define TXDATA      0x05

#define COMMAND     0x02        // Data mapped in receive buffer
#define DATA_COUNT  0x03    
#define ADDRESS_L   0x04
#define ADDRESS_H   0x05
#define ADDRESS_UL  0x06
#define ADDRESS_UH  0x07
/*****************************************************************************/
/******************************************************************************/
/* Main Program                                                               */
/******************************************************************************/
#define pinBoot         PORTBbits.RB3       // Programming flag
//#define pinStby         PORTBbits.RB1       // CAN standby
#define bootFlag 1
#define baudConstant 129        // 9600 baud with PLL_8

bool b_processRecord(uint16_t);
uint16_t b_getRecord(void);
void b_writeUART(char ch);
char b_readUART(void);
void b_initUART(void);        // Initialize UART 2 to 115200 baud
void b_initCAN(void);         // for debugging output - watch on CANAlyzer 
void b_sendCAN(void);
void b_bootend();             // jump to application
uint16_t b_crc16(uint16_t crc, uint16_t data);
void b_crcMessage(bool flash, bool eeProm);
uint16_t b_calcCrc(void);
//unsigned int b_eeprom_read_int(unsigned int address);
//unsigned int b_eeprom_write_int(unsigned int address, unsigned int data);

#define b_flashStart  0x1600
#define b_flashEnd    0x7FFF
#define b_eepromStart 0xFC00
#define b_eepromEnd   0xFFFF
#define b_poly        0x8408    // crc16 polynoimial

union CAN
{
    uint8_t  bytes[256];
    uint16_t words[128];
}b_CAN;

union Buffer
{
    uint8_t  charBuffer[256];
    uint16_t wordBuffer[128];
}b;

uint16_t b_receivePointer;
unsigned char b_checksum;
unsigned char b_bufferCANb[8];
unsigned char b_bufferCANw[4];
uint16_t i;
uint16_t testSID;
bool booting = false;
uint16_t b_temp;
static uint16_t flashReadBuffer[256];
//uint16_t b_eepromRead(uint16_t adr);
//void b_eepromWrite(uint16_t adr, uint16_t data);
static uint16_t crc16_calc = 0;
static uint16_t crc16_sv = 0;
void __attribute__((section("boot"))) b_boot(void)
{
    uint16_t bufSize;
 //   uint16_t crc16_calc;
 //   uint16_t crc16_sv;
    ADPCFGbits.PCFG3 = 1;       // RB3 set to digital input
    TRISBbits.TRISB3 = 1;       // Input  - Boot Flag
    TRISDbits.TRISD0 = 0;    //LED
//    TRISBbits.TRISB1 = 0;       // Output - CAN standby
//    pinStby          = 0;       // make transceiver active
    
 //   crc16_sv = b_eeprom_read_int(EEPROM_APP_CRC_ADDR);
    crc16_calc = b_calcCrc();

    PORTDbits.RD0 = 1;
    booting = true;
    b_initUART();               // initialize the UART
    b_initCAN();
    testSID = 0x030;            // signal we are in boot mode
    b_sendCAN();
    
    b_flashRowRead( 0, 0x7fc0, flashReadBuffer ); 
    crc16_sv = flashReadBuffer[0x3e];

    if((pinBoot != bootFlag) && (crc16_sv == crc16_calc))   // if no boot flag - go to user code
        b_bootend();

    while(booting)
    {
        bufSize = b_getRecord();
        if(pinBoot != bootFlag) b_bootend();
        b_processRecord(bufSize);
    }
    b_bootend();
}

 uint16_t checkFlashCrc;
bool __attribute__((section("boot"))) b_processRecord(uint16_t bufSize)
{
 //   uint16_t flashReadBuffer[256];
    uint16_t crcFlash;
    uint16_t crcEeprom;
    uint16_t index;
    uint16_t checkFlashCrc;
    uint16_t checkEepromCrc;
    bool flashFlag = false;
    bool eePromFlag = false;

    unsigned char command = b.charBuffer[COMMAND];
    uint16_t addrU =  ((uint16_t)b.charBuffer[ADDRESS_UH] << 8) & 0xFF00 |
                 (uint16_t)b.charBuffer[ADDRESS_UL] & 0x00FF;
    uint16_t addr  = ((uint16_t)b.charBuffer[ADDRESS_H] << 8) & 0xFF00 |
                 (uint16_t)b.charBuffer[ADDRESS_L] & 0x00FF;
 
    addr  = (addr / 2) | ((addrU << 15) & 0x8000);    // make it a word address
    addrU = addrU / 2;
    
    switch(command)
    {   
        case 0x01:      // compute crc
            PORTDbits.RD0 = 1;
            testSID = 0x31;
            b_sendCAN();
            checkFlashCrc = b.wordBuffer[2];
            checkEepromCrc = b.wordBuffer[3];
           // compute eeprom checksum
            addrU = 0x007F;
            addr = 0xFC00;
            crcEeprom = 0xFFFF;
            index = b_eepromEnd - b_eepromStart + 1;
            for(addr = b_eepromStart; index > 0; index -= 2, addr += 2 )  // skip upper bytes
            {
                b_temp = b_eePromRead(addrU, addr);
                crcEeprom = b_crc16(crcEeprom, b_temp);
            }
            b_flashRowRead( 0, 0x7fc0, flashReadBuffer ); 
            flashReadBuffer[0x3E] = checkFlashCrc;
            b_flashRowWrite(0, 0x7FC0, flashReadBuffer);
            b_CAN.bytes[2] = 0xFF;
            b_CAN.bytes[3] = 0xFF;
            crcFlash = b_calcCrc();
            
            if( crcFlash == checkFlashCrc ) // set check flags
            {
  //              b_eeprom_write_int(EEPROM_APP_CRC_ADDR, crcFlash);
                flashFlag = true;
                b_CAN.bytes[2] = 0x01;
                PORTDbits.RD0 = 0;
            }
            if( crcEeprom == checkEepromCrc )
            {
                eePromFlag = true;
                b_CAN.bytes[3] = 0x01;
            }
            b_crcMessage( flashFlag, eePromFlag );
            
            b_CAN.words[2] = crcFlash;
            b_CAN.words[3] = crcEeprom;
            testSID = 0x0032;
            b_sendCAN();
            booting = false;        // we are done
            break;
        case 0x02:      // write flash
            PORTDbits.RD0 = 0;
            if( addr >= 0x1600)
            {
                b_flashRowWrite(addrU, addr, &b.wordBuffer[4]);
            }
            break;
        case 0x03:      // erase flash
            PORTDbits.RD0 = 1;
            if( addr >= 0x1600)
            {
                b_flashRowErase(addrU, addr);
            }
            break;
        case 0x04:      // erase eeprom
            b_eePromAllErase(0x007F, 0xFC00);
            break;
        case 0x05:      // write eeprom
            if( addrU == 0x007F)
            {
                b_eePromRowWrite(addrU, addr, &b.wordBuffer[4]);
            }
            break;
        default:
            break;
    }

    return true;
} 

uint16_t __attribute__((section("boot"))) b_calcCrc(void)
{
    uint16_t addrU = 0;
    uint16_t crcFlash;
    uint16_t index = 0;
    uint16_t addr = 0;
    
    addrU = 0x0000;
    addr = b_flashStart;
    crcFlash  = 0xFFFF;
    for(addr = b_flashStart; addr < 0x7fc0/*b_flashEnd*/; addr += 0x0040)
    {
        b_flashRowRead( addrU, addr, flashReadBuffer );  // Row of 32 pairs
        for(index = 0; index < 0x40;)
        {
            b_temp = flashReadBuffer[index++];
            crcFlash = b_crc16( crcFlash, b_temp );
            b_temp = flashReadBuffer[index++];
            crcFlash = b_crc16( crcFlash, b_temp );
            b_temp = flashReadBuffer[index++];
            crcFlash = b_crc16( crcFlash, b_temp );
            b_temp = flashReadBuffer[index++];
            crcFlash = b_crc16( crcFlash, b_temp );
        }
    }
#if 0
    b_flashRowRead( addrU, addr, flashReadBuffer );  // Row of 32 pairs
    for(index = 0; index < 0x3D;)
    {
        b_temp = flashReadBuffer[index++];
        crcFlash = b_crc16( crcFlash, b_temp );
        b_temp = flashReadBuffer[index++];
        crcFlash = b_crc16( crcFlash, b_temp );
    }
#endif
    return crcFlash;
}
//#endif
uint16_t __attribute__((section("boot"))) b_getRecord()
{
    // find two consecutive STX characters
    char currentChar = ETX;
    char previousChar = STX;

    while((currentChar != STX) || (previousChar != STX) )
    {
        previousChar = currentChar;
        currentChar = b_readUART();
    }
    b_CAN.bytes[0] = previousChar;
    b_CAN.bytes[1] = currentChar;
    b_receivePointer = 2;
    while( b_receivePointer < 8 )
    {
        currentChar  = b_readUART();
        b.charBuffer[b_receivePointer++] = currentChar;
    }
    b_CAN.words[1] = b.wordBuffer[1];
    b_CAN.words[2] = b.wordBuffer[2];
    b_CAN.words[3] = b.wordBuffer[3];
    b_CAN.words[4] = b.wordBuffer[4];
   
    uint16_t length =  b.charBuffer[b_receivePointer - 5]; // data length
    for( i = 0; i < length; i++)
    {
        currentChar  = b_readUART();
        b.charBuffer[b_receivePointer++] = currentChar;
       
    }
    return b_receivePointer; 
}

void __attribute__((section("boot"))) b_crcMessage(bool flash, bool eeProm)
{
    if(flash)
    {
        b_writeUART('A');
        b_writeUART('C');
        b_writeUART('K');       
    }
    else
    {
        b_writeUART('N');
        b_writeUART('A');
        b_writeUART('K');       
    }
    b_writeUART(',');
    if(eeProm)
    {
        b_writeUART('A');
        b_writeUART('C');
        b_writeUART('K');       
    }
    else
    {
        b_writeUART('N');
        b_writeUART('A');
        b_writeUART('K');       
    }
    b_writeUART('\r');
    b_writeUART('\n');
}

void __attribute__((section("boot"))) b_writeUART(char ch)
{
    while(U2STAbits.TRMT == 0);         // Wait for transmit register empty
    U2TXREG = ch;                       // send character
}

char __attribute__((section("boot"))) b_readUART()
{
    while(U2STAbits.URXDA == 0); //&&         // Wait for receive register not empty
            //(pinBoot == bootFlag) );        // abort if boot flag is reset
    if(pinBoot != bootFlag) b_bootend();
    char chr = U2RXREG;
    return chr;
}

void __attribute__((section("boot"))) b_initUART(void)
{
    U2MODEbits.UARTEN = 1;              // Enable UART pins
    U2BRG             = baudConstant;   // 9600 0r 115200 Baud - w/PLL_8
    U2MODEbits.PDSEL  = 0;              // 8 bit, no parity
    U2MODEbits.STSEL  = 0;              // 1 stop bit
    U2STAbits.UTXISEL = 0;              // Interrupt when char transferred to Transmit Shift register
    U2STAbits.UTXEN   = 1;              // Enable transmitter
    U2STAbits.URXISEL = 1;              // Interrupt for each char received
    IEC1bits.U2RXIE   = 0;              // Disable receive interrupts
    IEC1bits.U2TXIE   = 0;              // Disable transmit interrupts
}

void __attribute__((section("boot"))) b_sendCAN() // for testing output
{
//    while(C1TX2CONbits.TXREQ != 0);   // overwrite if not send yet
    C1TX2CONbits.TXREQ = 0;             // only used for diagnostic messages
    C1TX2B1 = b_CAN.words[0];
    C1TX2B2 = b_CAN.words[1];
    C1TX2B3 = b_CAN.words[2];
    C1TX2B4 = b_CAN.words[3];
    C1TX2SIDbits.SID10_6 = (testSID >> 6) & 0x001F;
    C1TX2SIDbits.SID5_0  =  testSID & 0x003F;
    C1TX2DLCbits.DLC   = 8;
    C1TX2SIDbits.SRR = 0;           // Normal message
    C1TX2CONbits.TXPRI = 0;             // Lowest transmission priority
    C1TX2SIDbits.TXIDE = 0;             // Standard Identifier
    C1TX2CONbits.TXREQ = 1;             // Transmit the message
    return;
}

void __attribute__((section("boot"))) b_initCAN(void) // for testing output
{
    C1CTRLbits.CANCAP    = 0;           // Disable CAN Capture
    C1CTRLbits.CANSIDL   = 1;           // Stop CAN in Idle mode
    C1CTRLbits.ABAT      = 1;           // Abort any transmit operations
    C1CTRLbits.CANCKS    = 0;           // CAN clock is 4 Fcy
    C1CTRLbits.REQOP     = 4;           // Set configuration mode
    while(C1CTRLbits.OPMODE != 4);      // wait for Configuration mode

    C1CFG1bits.SJW       = 0;           // Synchronized jump width 1 x Tq
    
    C1CFG1bits.BRP       = 0x03;        // Baud rate pre-scaler - PLL_8
    C1CFG2bits.WAKFIL    = 0;           // Filter not used for wakeup
    C1CFG2bits.SEG2PH    = 2;           // SEG2 - 3
    C1CFG2bits.SEG2PHTS  = 1;           // Freely programmable
    C1CFG2bits.SAM       = 1;           // Sample 3 times
    C1CFG2bits.SEG1PH    = 3;           // SEG1 1 - 4
    C1CFG2bits.PRSEG     = 1;           // PROP 5

    C1CTRLbits.REQOP     = 0;           // Change to normal mode
    while(C1CTRLbits.OPMODE != 0);      // wait for Normal mode
    C1INTEbits.RX0IE     = 0;           // Disable RX 0 Interrupt
    C1INTEbits.RX1IE     = 0;           // Disable RX 1 Interrupt
    C1INTEbits.TX0IE     = 0;           // Disable TX 0 Interrupt
    C1INTEbits.TX1IE     = 0;           // Disable TX 1 Interrupt
    C1INTEbits.TX2IE     = 0;           // Disable TX 2 Interrupt
    IPC6bits.C1IP        = 3;           // CAN Interrupt priority
    IEC1bits.C1IE        = 0;           // Disable CAN Interrupts
    
    C1CTRLbits.ABAT      = 1;           // Abort any transmit operations
    
    // zero CAN buffer
    int i;
    for(i=0;i<4;i++)
    {
        b_bufferCANb[i]   = 0x00;
        b_bufferCANb[i*2] = 0x00;
        b_bufferCANw[i]   = 0x0000;
    }
}

uint16_t __attribute__((section("boot"))) b_crc16(uint16_t crc, uint16_t data)
{
    int i;
    for(i = 0; i < 16; i++, data >>= 1)
    {
        if((( crc & 0x0001 ) ^ ( data & 0x0001 )) == 0x0001 )
        {
            crc = (crc >> 1) ^ b_poly;
        }
        else
        {
            crc = crc >> 1;
        }
    }
    return crc;
}


void __attribute__((section("boot"))) b_bootend(void)
{
    asm ("goto __resetPRI");
}
4

1 回答 1

1

您将一个值分配给addr两次并且不使用两个分配之间的变量,因此编译器将优化第一个分配:

第一个任务:

addr = b_flashStart;

第二次作业;

for(addr = b_flashStart; addr < 0x7fc0/*b_flashEnd*/; addr += 0x0040)
于 2021-02-24T05:41:09.890 回答