Пример #1
0
    BOOL Process( UINT8 c )
    {
        while(true)
        {
            switch(m_phase)
            {
                //
                // Setup 'address' reception.
                //
            case 0:
                m_ptr = (char*)&m_address;
                m_len = sizeof(m_address);
                m_phase++;
                break;
    
                //
                // Setup 'size' reception.
                //
            case 2:
                //printf( "Got address %08x\r\n", m_address );
    
                m_ptr = (char*)&m_size;
                m_len = sizeof(m_size);
                m_phase++;
                return TRUE;
    
                //
                // Setup 'crc' reception.
                //
            case 4:
                //printf( "Got size %08x\r\n", m_size );
    
                m_ptr = (char*)&m_crc;
                m_len = sizeof(m_crc);
                m_phase++;
                return TRUE;
    
                //
                // Setup 'data' reception or jump to entrypoint.
                //
            case 6:
                //printf( "Got crc %08x\r\n", m_crc );
    
                m_crc += m_address;
                m_crc += m_size;
    
                if(m_size == 0)
                {
                    if(m_crc != 0)
                    {
                        hal_fprintf( g_State.pStreamOutput, "X crc %08x %08x\r\n", m_address, m_crc );
    
                       // bad characters! realign
                        m_phase = 0;
                        return FALSE;
                    }
    
                    hal_fprintf( g_State.pStreamOutput, "X start %08x\r\n", m_address );

#if defined(PLATFORM_ARM_MOTE2)
                    CPU_GPIO_SetPinState(LED1_GREEN, LED_OFF);        // Turn off Green LED for iMote2
#endif                
    
                    StartApplication( (void (*)())m_address );
                }
    
                if(m_size > sizeof(m_data) || (m_size % sizeof(FLASH_WORD)) != 0)
                {
                    hal_fprintf( g_State.pStreamOutput, "X size %d\r\n", m_size );
    
                    // bad characters! realign
                    m_phase = 0;
                    return FALSE;
                }
    
                m_ptr = (char*)m_data;
                m_len =        m_size;
                m_phase++;
                return TRUE;
    
            case 8:
                {
                    FLASH_WORD* src     = (FLASH_WORD*)m_data;
                    FLASH_WORD* dst     = (FLASH_WORD*)m_address;
                    BOOL        success = TRUE;
                    int         i;
                    BlockStorageDevice * pDevice;
                    ByteAddress WriteByteAddress ;
    
                    for(i=0; i<m_size; i++)
                    {
                        m_crc += m_data[i];
                    }
    
                    if(m_crc != 0)
                    {
                        hal_fprintf( g_State.pStreamOutput, "X crc %08x %08x\r\n", m_address, m_crc );
    
                        // bad characters! realign
                        m_phase = 0;
                        return FALSE;
                    }
    
                    SignalActivity();

                    // this slows things down to print every address, only print once per line
                    hal_fprintf( STREAM_LCD, "WR: 0x%08x\r", (UINT32)dst );

                    // if it not Block Device, assume it is RAM 
                    if (BlockStorageList::FindDeviceForPhysicalAddress( & pDevice, m_address, WriteByteAddress))
                    {
                        UINT32 regionIndex, rangeIndex;
                        const BlockDeviceInfo* deviceInfo = pDevice->GetDeviceInfo() ;

                        if(!(pDevice->FindRegionFromAddress(WriteByteAddress, regionIndex, rangeIndex))) 
                        {
#if !defined(BUILD_RTM)
                           hal_printf(" Invalid condition - Fail to find the block number from the ByteAddress %x \r\n",WriteByteAddress);  
#endif
                            return FALSE;
                        }

                        // start from the block where the sector sits.
                        UINT32        iRegion = regionIndex;
                        UINT32        accessPhyAddress = (UINT32)m_address;
                                
                        BYTE*         bufPtr           = (BYTE*)src;
                        BOOL          success          = TRUE;
                        INT32         writeLenInBytes  = m_size;


                        while (writeLenInBytes > 0)
                        {
                            for(; iRegion < deviceInfo->NumRegions; iRegion++)
                            {
                                const BlockRegionInfo *pRegion = &(deviceInfo->Regions[iRegion]);

                                ByteAddress blkAddr = pRegion->Start;

                                while(blkAddr < accessPhyAddress)
                                {
                                    blkAddr += pRegion->BytesPerBlock;
                                }

                                //writeMaxLength =the current largest number of bytes can be read from the block from the address to its block boundary.
                                UINT32 NumOfBytes = __min(pRegion->BytesPerBlock, writeLenInBytes);
                                if (accessPhyAddress == blkAddr && !pDevice->IsBlockErased(blkAddr, pRegion->BytesPerBlock))
                                {
                                    hal_fprintf( STREAM_LCD, "ER: 0x%08x\r", blkAddr );

                                    pDevice->EraseBlock(blkAddr);
                                    blkAddr += pRegion->BytesPerBlock;
                                }
                                success = pDevice->Write(accessPhyAddress , NumOfBytes, (BYTE *)bufPtr, FALSE);

                                writeLenInBytes -= NumOfBytes;
								
                                if ((writeLenInBytes <=0) || (!success)) break;

                                bufPtr += NumOfBytes;

                            }

                            if ((writeLenInBytes <=0) || (!success)) break;
                        }
                        
                    }
                    else
                    {
                        // must be RAM but don't verify, we write anyway, possibly causing a data abort if the address is bogus
                        memcpy( dst, src, m_size );
                    }
    
                    hal_fprintf( g_State.pStreamOutput, "X %s %08x\r\n", success ? "ack" : "nack", m_address );
    
                    m_phase = 0;
                    return FALSE;
                }
                break;
    
                //
                // Read data.
                //
            case 1:
            case 3:
            case 5:
            case 7:
                *m_ptr++ = c; if(--m_len) return TRUE;
    
                m_phase++;
                break;
            }
        }
    }
Пример #2
0
    BOOL ParseLine( const char* SRECLine )
    {
        UINT32               Address;
        int                  i;
        UINT32               BytesRemaining = 0;
        UINT32               Temp           = 0;
        UINT32               Data32;
        UINT32               RecordType;
        UINT32               CheckSum;
        UINT32               WordCount = 0;
        UINT32               ByteCount = 0;
        FLASH_WORD           WordData[16/sizeof(FLASH_WORD)];     // we support 16 bytes of data per record max, 4 words, 8 shorts
        UINT8                ByteData[16];                        // we support 16 bytes of data per record max, 4 words, 8 shorts

        BlockStorageDevice         *pDevice;
        UINT32               m_size;
        ByteAddress WriteByteAddress;


        RecordType = *SRECLine++;

        SRECLine = htoi( SRECLine, 2, BytesRemaining ); if(!SRECLine) return FALSE;

        // start the checksum with this byte
        CheckSum = BytesRemaining;

        // get the destination address
        // do bytes only to make checksum calc easier
        Data32 = 0;
        for(i = 0; i < 4; i++)
        {
            SRECLine = htoi( SRECLine, 2, Temp ); if(!SRECLine) return FALSE;

            CheckSum += Temp;

            Data32 <<= 8;
            Data32  |= Temp;

            BytesRemaining -= 1;
        }
        Address = Data32;

        // take off one byte for CRC;
        m_size = BytesRemaining -1;

        switch(RecordType)
        {
        case '3':
            {

                while(BytesRemaining > 1)
                {
                    // get bytes into words, and checksum
                    Data32 = 0;
                    for(i = 0; i < sizeof(FLASH_WORD); i++)
                    {
                        SRECLine = htoi( SRECLine, 2, Temp ); if(!SRECLine) return FALSE;

                        CheckSum += Temp;

                        Data32 |= Temp << (i*8);    // little endian format

                        ByteData[ByteCount++] = Temp;

                        BytesRemaining -= 1;

                        // leave the checksum in place
                        if(1 == BytesRemaining) break;
                    }

                    ASSERT(WordCount < (16/sizeof(FLASH_WORD)));

                    WordData[WordCount++] = Data32;
                }
            }
            break;

        case '7':
            // just a return address (starting location)
            m_StartAddress = (UINT32)Address;
            break;

        default:
            // we only support S3 and S7 records, for now
            return FALSE;
        }

        // get the checksum
        SRECLine = htoi( SRECLine, 2, Temp ); if(!SRECLine) return FALSE;

        CheckSum += Temp;

        BytesRemaining -= 1;

        ASSERT(0 == BytesRemaining);

        // make sure we had a NULL terminator for line, and not more characters
        if(*SRECLine != 0)
        {
            return FALSE;
        }

        if(0xff != (CheckSum & 0xff))
        {
            return FALSE;
        }
        else
        {
            // only write if we succeeded the checksum entirely for whole line

            if(m_size > 0)
            {
                SignalActivity();

                // this slows things down to print every address, only print once per line

                hal_fprintf( STREAM_LCD, "WR: 0x%08x\r", (UINT32)Address );

                if (BlockStorageList::FindDeviceForPhysicalAddress( &pDevice, Address, WriteByteAddress)) 
                {

                        UINT32 regionIndex, rangeIndex;
                        const BlockDeviceInfo* deviceInfo = pDevice->GetDeviceInfo() ;

                        if(!(pDevice->FindRegionFromAddress(WriteByteAddress, regionIndex, rangeIndex))) 
                        {
#if !defined(BUILD_RTM)
                            hal_printf(" Invalid condition - Fail to find the block number from the ByteAddress %x \r\n",WriteByteAddress);  
#endif
                            return FALSE;
                        }

                        // start from the block where the sector sits.
                        UINT32        iRegion = regionIndex;
                        UINT32        accessPhyAddress = (UINT32)Address;
                                
                        BYTE*         bufPtr           = (BYTE*)ByteData;
                        BOOL          success          = TRUE;
                        INT32         writeLenInBytes  = m_size;


                        while (writeLenInBytes > 0)
                        {
                            for(; iRegion < deviceInfo->NumRegions; iRegion++)
                            {
                                const BlockRegionInfo *pRegion = &(deviceInfo->Regions[iRegion]);

                                ByteAddress blkAddr = pRegion->Start;

                                while(blkAddr < accessPhyAddress)
                                {
                                    blkAddr += pRegion->BytesPerBlock;
                                }

                                //writeMaxLength =the current largest number of bytes can be read from the block from the address to its block boundary.
                                UINT32 NumOfBytes = __min(pRegion->BytesPerBlock, writeLenInBytes);
                                if (accessPhyAddress == blkAddr && !pDevice->IsBlockErased(blkAddr, pRegion->BytesPerBlock))
                                {
                                    hal_fprintf( STREAM_LCD, "ER: 0x%08x\r", blkAddr );
                                    pDevice->EraseBlock(blkAddr);
                                    blkAddr += pRegion->BytesPerBlock;
                                }
                                success = pDevice->Write(accessPhyAddress , NumOfBytes, (BYTE *)bufPtr, FALSE);

                                writeLenInBytes -= NumOfBytes;

                                if ((writeLenInBytes <=0) || (!success)) break;

                                bufPtr += NumOfBytes;

                            }

                            if ((writeLenInBytes <=0) || (!success)) break;
                        }
                        
                    }
                else
                {
                    FLASH_WORD *Addr = (FLASH_WORD *) Address;
                    for(i = 0; i < WordCount; i++)
                    {
                        // must be RAM but don't verify, we write anyway, possibly causing a data abort if the address is bogus
                         *Addr++ = WordData[i];
                    }
                }
            }
        }

        return TRUE;
    }