Add KBOOT.
This commit is contained in:
81
validation/embedded_host/src/image_program/SB_image.c
Normal file
81
validation/embedded_host/src/image_program/SB_image.c
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "SB_image.h"
|
||||
#include "blsh/host_command.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
static uint32_t get_SB_image_length(uint32_t image_address);
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
recordStatus_t SB_image_program(uint32_t image_address)
|
||||
{
|
||||
uint32_t image_length = get_SB_image_length(image_address);
|
||||
|
||||
if (handle_receiveSBFile_command(IMAGE_START_ADDRESS, image_length) != kStatus_Success)
|
||||
{
|
||||
return kRecordStatus_Fail;
|
||||
}
|
||||
|
||||
return kRecordStatus_Success;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief get SB image length
|
||||
*
|
||||
* @param image_address image address in target flash.
|
||||
* @return the length of sb image
|
||||
*/
|
||||
static uint32_t get_SB_image_length(uint32_t image_address)
|
||||
{
|
||||
/* uint8_t hex[4] = {0}; */
|
||||
uint32_t image_blocks = 0;
|
||||
|
||||
image_blocks = read_flash_char(image_address, SB_IMAGE_BLOCKS_OFFSET + 3) << 24;
|
||||
image_blocks |= read_flash_char(image_address, SB_IMAGE_BLOCKS_OFFSET + 2) << 16;
|
||||
image_blocks |= read_flash_char(image_address, SB_IMAGE_BLOCKS_OFFSET + 1) << 8;
|
||||
image_blocks |= read_flash_char(image_address, SB_IMAGE_BLOCKS_OFFSET);
|
||||
|
||||
/* Size of each block is 16 bytes */
|
||||
return (image_blocks << 4);
|
||||
}
|
||||
59
validation/embedded_host/src/image_program/SB_image.h
Normal file
59
validation/embedded_host/src/image_program/SB_image.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __SB_image_H__
|
||||
#define __SB_image_H__
|
||||
|
||||
#include "executable_image.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
enum
|
||||
{
|
||||
/*! Image blocks offset */
|
||||
SB_IMAGE_BLOCKS_OFFSET = 28,
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*! @brief parse SB image */
|
||||
recordStatus_t SB_image_program(uint32_t image_address);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __SB_image_H__ */
|
||||
64
validation/embedded_host/src/image_program/binary_image.c
Normal file
64
validation/embedded_host/src/image_program/binary_image.c
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "binary_image.h"
|
||||
#include "blsh/host_command.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
recordStatus_t binary_image_program(uint32_t image_address, uint32_t image_length)
|
||||
{
|
||||
for (s_image_buffer_index = 0; s_image_buffer_index < image_length; s_image_buffer_index++)
|
||||
{
|
||||
s_image_buffer[s_image_buffer_index] = read_flash_char(image_address, s_image_buffer_index);
|
||||
}
|
||||
s_image_start_address = 0x8000;
|
||||
|
||||
if (handle_writeMemory_command(s_image_start_address, s_image_buffer, s_image_buffer_index) != kStatus_Success)
|
||||
{
|
||||
return kRecordStatus_Fail;
|
||||
}
|
||||
|
||||
return kRecordStatus_Success;
|
||||
}
|
||||
54
validation/embedded_host/src/image_program/binary_image.h
Normal file
54
validation/embedded_host/src/image_program/binary_image.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __binary_image_H__
|
||||
#define __binary_image_H__
|
||||
|
||||
#include "executable_image.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* @brief parse srecord image */
|
||||
recordStatus_t binary_image_program(uint32_t image_address, uint32_t image_length);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __binary_image_H__ */
|
||||
117
validation/embedded_host/src/image_program/executable_image.c
Normal file
117
validation/embedded_host/src/image_program/executable_image.c
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "executable_image.h"
|
||||
#include "blsh/bllibc.h"
|
||||
#include "srecord_image.h"
|
||||
#include "intelhex_image.h"
|
||||
#include "binary_image.h"
|
||||
#include "SB_image.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
uint8_t s_image_buffer[IMAGE_BUFFER_SIZE] = { 0 };
|
||||
uint32_t s_image_buffer_index = 0;
|
||||
uint32_t s_image_start_address = 0;
|
||||
uint32_t s_image_next_address = 0;
|
||||
uint32_t s_image_base_address = 0;
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
uint8_t read_flash_char(uint32_t address, uint32_t index)
|
||||
{
|
||||
return *(uint8_t *)(address + index);
|
||||
}
|
||||
|
||||
uint8_t get_image_type()
|
||||
{
|
||||
if (read_flash_char(IMAGE_START_ADDRESS, SRECORD_SIGN_OFFSET) == SRECORD_SIGN)
|
||||
{
|
||||
return kImageType_Srecord;
|
||||
}
|
||||
else if (read_flash_char(IMAGE_START_ADDRESS, INTELHEX_SIGN_OFFSET) == INTELHEX_SIGN)
|
||||
{
|
||||
return kImageType_Intelhex;
|
||||
}
|
||||
else if ((read_flash_char(IMAGE_START_ADDRESS, SB_SIGN_OFFSET1) == SB_SIGN1) &&
|
||||
(read_flash_char(IMAGE_START_ADDRESS, SB_SIGN_OFFSET2) == SB_SIGN2) &&
|
||||
(read_flash_char(IMAGE_START_ADDRESS, SB_SIGN_OFFSET3) == SB_SIGN3) &&
|
||||
(read_flash_char(IMAGE_START_ADDRESS, SB_SIGN_OFFSET4) == SB_SIGN4))
|
||||
{
|
||||
return kImageType_SB;
|
||||
}
|
||||
else if ((read_flash_char(IMAGE_START_ADDRESS, 0) != 0xff) || (read_flash_char(IMAGE_START_ADDRESS, 1) != 0xff) ||
|
||||
(read_flash_char(IMAGE_START_ADDRESS, 2) != 0xff) || (read_flash_char(IMAGE_START_ADDRESS, 3) != 0xff))
|
||||
{
|
||||
return kImageType_Binary;
|
||||
}
|
||||
else
|
||||
{
|
||||
return kImageType_Invalid;
|
||||
}
|
||||
}
|
||||
|
||||
recordStatus_t flash_image(flash_image_status_t function)
|
||||
{
|
||||
uint8_t image_type = get_image_type();
|
||||
uint32_t status = kRecordStatus_InvalidStart;
|
||||
|
||||
if (image_type == kImageType_Srecord)
|
||||
{
|
||||
status = srecord_image_program(IMAGE_START_ADDRESS);
|
||||
}
|
||||
else if (image_type == kImageType_Intelhex)
|
||||
{
|
||||
status = intelhex_image_program(IMAGE_START_ADDRESS);
|
||||
}
|
||||
else if (image_type == kImageType_SB)
|
||||
{
|
||||
status = SB_image_program(IMAGE_START_ADDRESS);
|
||||
}
|
||||
else if (image_type == kImageType_Binary)
|
||||
{
|
||||
// status = binary_image_program(IMAGE_START_ADDRESS, 1788);
|
||||
status = kRecordStatus_InvalidType;
|
||||
}
|
||||
|
||||
if (function != 0)
|
||||
{
|
||||
function(status);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
127
validation/embedded_host/src/image_program/executable_image.h
Normal file
127
validation/embedded_host/src/image_program/executable_image.h
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __executable_image_H__
|
||||
#define __executable_image_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
#define IMAGE_BUFFER_SIZE 1024 * 16
|
||||
#define IMAGE_START_ADDRESS 0x00010000
|
||||
|
||||
/*! Image type value. */
|
||||
enum
|
||||
{
|
||||
kImageType_SB = 0,
|
||||
kImageType_Srecord = 1,
|
||||
kImageType_Intelhex = 2,
|
||||
kImageType_Binary = 3,
|
||||
kImageType_Invalid = 4
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
/*! The sb image sign. */
|
||||
SB_SIGN1 = 'S',
|
||||
SB_SIGN2 = 'T',
|
||||
SB_SIGN3 = 'M',
|
||||
SB_SIGN4 = 'P',
|
||||
/*! The sign offeset form start address. */
|
||||
SB_SIGN_OFFSET1 = 20,
|
||||
SB_SIGN_OFFSET2 = 21,
|
||||
SB_SIGN_OFFSET3 = 22,
|
||||
SB_SIGN_OFFSET4 = 23
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
/*! The srecord image sign. */
|
||||
SRECORD_SIGN = 'S',
|
||||
/*! The sign offeset form start address. */
|
||||
SRECORD_SIGN_OFFSET = 0
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
/*! The intelhex image sign. */
|
||||
INTELHEX_SIGN = ':',
|
||||
/*! The sign offeset form start address. */
|
||||
INTELHEX_SIGN_OFFSET = 0
|
||||
};
|
||||
|
||||
enum _recordStatus_t
|
||||
{
|
||||
kRecordStatus_Success = 0,
|
||||
kRecordStatus_Fail = 1,
|
||||
kRecordStatus_InvalidLength = 2,
|
||||
kRecordStatus_InvalidStart = 3,
|
||||
kRecordStatus_InvalidType = 4,
|
||||
kRecordStatus_InvalidChecksum = 5,
|
||||
kRecordStatus_FlashOver = 6,
|
||||
kRecordStatus_FlashPartly = 7,
|
||||
kRecordStatus_EraseOver = 8,
|
||||
kRecordStatus_ErasePartly = 9
|
||||
};
|
||||
typedef uint8_t recordStatus_t;
|
||||
|
||||
//! @brief Type of callback for flash image status
|
||||
typedef void (*flash_image_status_t)(recordStatus_t status);
|
||||
|
||||
extern uint8_t s_image_buffer[IMAGE_BUFFER_SIZE];
|
||||
extern uint32_t s_image_buffer_index;
|
||||
extern uint32_t s_image_start_address;
|
||||
extern uint32_t s_image_next_address;
|
||||
extern uint32_t s_image_base_address;
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*! @brief read a char from flash region */
|
||||
uint8_t read_flash_char(uint32_t address, uint32_t index);
|
||||
|
||||
/*! @brief get image type */
|
||||
uint8_t get_image_type();
|
||||
|
||||
/*! @brief falsh_image function */
|
||||
recordStatus_t flash_image(flash_image_status_t function);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __executable_image_H__ */
|
||||
477
validation/embedded_host/src/image_program/intelhex_image.c
Normal file
477
validation/embedded_host/src/image_program/intelhex_image.c
Normal file
@@ -0,0 +1,477 @@
|
||||
/*
|
||||
* Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "fsl_common.h"
|
||||
#include "intelhex_image.h"
|
||||
#include "blsh/bllibc.h"
|
||||
#include "blsh/host_command.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
typedef struct _intelhex_record_t
|
||||
{
|
||||
uint8_t dataCount; /*!< The number of bytes in the data field. */
|
||||
uint32_t address; /*!< The address offset of the data. */
|
||||
uint8_t type; /*!< Type of the data field. 00: Data */
|
||||
/*!< 01: End of File */
|
||||
/*!< 02: Extended Segment Address */
|
||||
/*!< 03: Start Segment Address */
|
||||
/*!< 04: Extended Linear Address */
|
||||
/*!< 05: Start Linear Address */
|
||||
uint8_t data[256]; /*!< Pointer to data, or NULL if no data for this record. */
|
||||
uint8_t checksum; /*!< The checksum byte used to verify the record. */
|
||||
} intelhex_record_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
static intelhex_record_t s_new_record = { 0 };
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
static recordStatus_t intelhex_record_parse_line(uint8_t *line, uint8_t line_length);
|
||||
static recordStatus_t intelhex_record_build_image(intelhex_record_t *new_record);
|
||||
static recordStatus_t intelhex_record_erase_target(uint32_t image_address);
|
||||
static recordStatus_t intelhex_record_erase_region(intelhex_record_t *new_record);
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
recordStatus_t intelhex_image_program(uint32_t image_address)
|
||||
{
|
||||
uint8_t image_char = 0;
|
||||
uint32_t image_index = 0;
|
||||
uint8_t line_buffer[256] = { 0 };
|
||||
uint8_t line_index = 0;
|
||||
recordStatus_t status = kRecordStatus_Fail;
|
||||
|
||||
/* Traverse the first time to erase target flash regions */
|
||||
intelhex_record_erase_target(image_address);
|
||||
|
||||
/* Clear globle variable */
|
||||
s_image_buffer_index = 0;
|
||||
s_image_start_address = 0;
|
||||
s_image_next_address = 0;
|
||||
s_image_base_address = 0;
|
||||
|
||||
/* Traverse the second time to program target */
|
||||
while (status != kRecordStatus_FlashOver)
|
||||
{
|
||||
image_char = read_flash_char(image_address, image_index);
|
||||
image_index++;
|
||||
|
||||
if (image_char == '\n')
|
||||
{
|
||||
status = intelhex_record_parse_line(line_buffer, line_index);
|
||||
if (status != kRecordStatus_Success)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
line_index = 0;
|
||||
|
||||
/* Build image and program target */
|
||||
status = intelhex_record_build_image(&s_new_record);
|
||||
|
||||
if (status == kRecordStatus_Fail)
|
||||
{
|
||||
return kStatus_Fail;
|
||||
}
|
||||
}
|
||||
else if (image_char == '\r')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
line_buffer[line_index++] = image_char;
|
||||
}
|
||||
}
|
||||
|
||||
return kRecordStatus_Success;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief parse one line of intelhex record image
|
||||
*
|
||||
* @param line one line of the intelhex record.
|
||||
* @param line_length the length of the line.
|
||||
* @return parse status
|
||||
*/
|
||||
static recordStatus_t intelhex_record_parse_line(uint8_t *line, uint8_t line_length)
|
||||
{
|
||||
uint32_t checksum = 0;
|
||||
uint32_t i = 0;
|
||||
intelhex_record_t *new_record = &s_new_record;
|
||||
|
||||
/* Must be at least a certain length */
|
||||
if (line_length < INTELHEX_MIN_LENGTH)
|
||||
{
|
||||
return kRecordStatus_InvalidLength;
|
||||
}
|
||||
|
||||
/* Start char must be ':' */
|
||||
if (line[0] != INTELHEX_START_CHAR)
|
||||
{
|
||||
return kRecordStatus_InvalidStart;
|
||||
}
|
||||
|
||||
/* Parse count field */
|
||||
new_record->dataCount = read_hex_byte(line, 1);
|
||||
checksum += new_record->dataCount;
|
||||
|
||||
/* verify the record length now that we know the count */
|
||||
if (line_length != 11 + new_record->dataCount * 2)
|
||||
{
|
||||
return kRecordStatus_InvalidLength;
|
||||
}
|
||||
|
||||
/* Read address */
|
||||
uint32_t address = 0;
|
||||
for (i = 0; i < 2; ++i)
|
||||
{
|
||||
uint8_t address_byte = read_hex_byte(line, INTELHEX_ADDRESS_START_CHAR_INDEX + i * 2);
|
||||
address = (address << 8) | address_byte;
|
||||
checksum += address_byte;
|
||||
}
|
||||
new_record->address = address;
|
||||
|
||||
/* Handle data type */
|
||||
new_record->type = read_hex_byte(line, INTELHEX_TYPE_START_CHAR_INDEX);
|
||||
checksum += new_record->type;
|
||||
switch (new_record->type)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
break;
|
||||
default:
|
||||
return kRecordStatus_InvalidType;
|
||||
}
|
||||
|
||||
/* Read data */
|
||||
if (new_record->dataCount)
|
||||
{
|
||||
for (i = 0; i < new_record->dataCount; ++i)
|
||||
{
|
||||
uint8_t data_byte = read_hex_byte(line, INTELHEX_DATA_START_CHAR_INDEX + i * 2);
|
||||
new_record->data[i] = data_byte;
|
||||
checksum += data_byte;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read and compare checksum byte */
|
||||
checksum = (~checksum + 1) & 0xff; /* low byte of one's complement of sum of other bytes */
|
||||
new_record->checksum = read_hex_byte(line, line_length - 2);
|
||||
if (checksum != new_record->checksum)
|
||||
{
|
||||
return kRecordStatus_InvalidChecksum;
|
||||
}
|
||||
|
||||
return kRecordStatus_Success;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief build intelhex srecord image and flash target
|
||||
*
|
||||
* @param new_record one line of the intelhex record.
|
||||
* @return parse status
|
||||
*/
|
||||
static recordStatus_t intelhex_record_build_image(intelhex_record_t *new_record)
|
||||
{
|
||||
uint8_t is_data_record = 0;
|
||||
uint8_t is_entry_record = 0;
|
||||
uint8_t is_address_record = 0;
|
||||
uint8_t is_eof_record = 0;
|
||||
uint32_t status = 0;
|
||||
|
||||
if (new_record->type == INTELHEX_RECORD_DATA)
|
||||
{
|
||||
is_data_record = 1;
|
||||
}
|
||||
else if ((new_record->type == INTELHEX_RECORD_START_SEGMENT_ADDRESS) ||
|
||||
(new_record->type == INTELHEX_RECORD_START_LINEAR_ADDRESS))
|
||||
{
|
||||
is_entry_record = 1;
|
||||
}
|
||||
else if ((new_record->type == INTELHEX_RECORD_EXTENDED_SEGMENT_ADDRESS) ||
|
||||
(new_record->type == INTELHEX_RECORD_EXTENDED_LINEAR_ADDRESS))
|
||||
{
|
||||
is_address_record = 1;
|
||||
}
|
||||
else if (new_record->type == INTELHEX_RECORD_END_OF_FILE)
|
||||
{
|
||||
is_eof_record = 1;
|
||||
}
|
||||
|
||||
s_image_base_address = 0;
|
||||
/* Handle 00 data record */
|
||||
if (is_data_record)
|
||||
{
|
||||
if (s_image_buffer_index)
|
||||
{
|
||||
/* If this record's data would overflow the collection buffer, or if the */
|
||||
/* record is not contiguous with the rest of the data in the collection */
|
||||
/* buffer, then flush the buffer to the target and restart. */
|
||||
if (((s_image_buffer_index + new_record->dataCount) > IMAGE_BUFFER_SIZE) ||
|
||||
(new_record->address != s_image_next_address))
|
||||
{
|
||||
/* flush the buffer to the target */
|
||||
status = handle_writeMemory_command(s_image_start_address + s_image_base_address, s_image_buffer,
|
||||
s_image_buffer_index);
|
||||
s_image_buffer_index = 0;
|
||||
|
||||
if (status == kStatus_Fail)
|
||||
{
|
||||
return kStatus_Fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Capture addresses when starting an empty buffer. */
|
||||
if (s_image_buffer_index == 0)
|
||||
{
|
||||
s_image_start_address = new_record->address;
|
||||
s_image_next_address = s_image_start_address;
|
||||
}
|
||||
|
||||
/* Copy record data into place in the collection buffer and update */
|
||||
/* size and address. */
|
||||
memcpy(&s_image_buffer[s_image_buffer_index], new_record->data, new_record->dataCount);
|
||||
s_image_buffer_index += new_record->dataCount;
|
||||
s_image_next_address += new_record->dataCount;
|
||||
}
|
||||
/* Hnadle 02, 04 record */
|
||||
else if (is_address_record)
|
||||
{
|
||||
/* If there are data in the collection buffer, then flush the buffer to the target. */
|
||||
if (s_image_buffer_index)
|
||||
{
|
||||
status = handle_writeMemory_command(s_image_start_address + s_image_base_address, s_image_buffer,
|
||||
s_image_buffer_index);
|
||||
s_image_buffer_index = 0;
|
||||
|
||||
if (status == kStatus_Fail)
|
||||
{
|
||||
return kStatus_Fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* extended address stored at data field. */
|
||||
s_image_base_address = (new_record->data[0] << 8) | new_record->data[1];
|
||||
if (new_record->type == INTELHEX_RECORD_EXTENDED_SEGMENT_ADDRESS)
|
||||
{
|
||||
s_image_base_address <<= 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_image_base_address <<= 16;
|
||||
}
|
||||
}
|
||||
/* Handle 03, 05 record */
|
||||
else if (is_entry_record)
|
||||
{
|
||||
/* Nothing to do */
|
||||
}
|
||||
/* Handle 01 record */
|
||||
else if (is_eof_record)
|
||||
{
|
||||
/* Flash any leftover data to target. */
|
||||
if (s_image_buffer_index)
|
||||
{
|
||||
status = handle_writeMemory_command(s_image_start_address, s_image_buffer, s_image_buffer_index);
|
||||
s_image_buffer_index = 0;
|
||||
|
||||
if (status == kStatus_Fail)
|
||||
{
|
||||
return kStatus_Fail;
|
||||
}
|
||||
|
||||
return kRecordStatus_FlashOver;
|
||||
}
|
||||
}
|
||||
|
||||
return kRecordStatus_Success;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief erase target flash before program target
|
||||
*
|
||||
* @param image_address address of the image in host flash.
|
||||
* @return parse status
|
||||
*/
|
||||
static recordStatus_t intelhex_record_erase_target(uint32_t image_address)
|
||||
{
|
||||
uint8_t image_char = 0;
|
||||
uint32_t image_index = 0;
|
||||
uint8_t line_buffer[256] = { 0 };
|
||||
uint8_t line_index = 0;
|
||||
recordStatus_t status = kRecordStatus_Fail;
|
||||
|
||||
while (status != kRecordStatus_EraseOver)
|
||||
{
|
||||
image_char = read_flash_char(image_address, image_index);
|
||||
image_index++;
|
||||
|
||||
if (image_char == '\n')
|
||||
{
|
||||
status = intelhex_record_parse_line(line_buffer, line_index);
|
||||
if (status != kRecordStatus_Success)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
line_index = 0;
|
||||
|
||||
/* Erase flash regions */
|
||||
status = intelhex_record_erase_region(&s_new_record);
|
||||
}
|
||||
else if (image_char == '\r')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
line_buffer[line_index++] = image_char;
|
||||
}
|
||||
}
|
||||
|
||||
return kRecordStatus_Success;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief eraset flash region based on record
|
||||
*
|
||||
* @param new_record one line of the intelhex record.
|
||||
* @return parse status
|
||||
*/
|
||||
static recordStatus_t intelhex_record_erase_region(intelhex_record_t *new_record)
|
||||
{
|
||||
uint8_t is_data_record = 0;
|
||||
uint8_t is_entry_record = 0;
|
||||
uint8_t is_address_record = 0;
|
||||
uint8_t is_eof_record = 0;
|
||||
|
||||
if (new_record->type == INTELHEX_RECORD_DATA)
|
||||
{
|
||||
is_data_record = 1;
|
||||
}
|
||||
else if ((new_record->type == INTELHEX_RECORD_START_SEGMENT_ADDRESS) ||
|
||||
(new_record->type == INTELHEX_RECORD_START_LINEAR_ADDRESS))
|
||||
{
|
||||
is_entry_record = 1;
|
||||
}
|
||||
else if ((new_record->type == INTELHEX_RECORD_EXTENDED_SEGMENT_ADDRESS) ||
|
||||
(new_record->type == INTELHEX_RECORD_EXTENDED_LINEAR_ADDRESS))
|
||||
{
|
||||
is_address_record = 1;
|
||||
}
|
||||
else if (new_record->type == INTELHEX_RECORD_END_OF_FILE)
|
||||
{
|
||||
is_eof_record = 1;
|
||||
}
|
||||
|
||||
s_image_base_address = 0;
|
||||
/* Handle 00 data record */
|
||||
if (is_data_record)
|
||||
{
|
||||
if (s_image_buffer_index)
|
||||
{
|
||||
/* If this record's data would overflow the collection buffer, or if the */
|
||||
/* record is not contiguous with the rest of the data in the collection */
|
||||
/* buffer, then erase flash region and restart. */
|
||||
if (((s_image_buffer_index + new_record->dataCount) > IMAGE_BUFFER_SIZE) ||
|
||||
(new_record->address != s_image_next_address))
|
||||
{
|
||||
/* Erase target flash region */
|
||||
handle_flashEraseRegion_command(s_image_start_address, s_image_buffer_index);
|
||||
s_image_buffer_index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Capture addresses when starting an empty buffer. */
|
||||
if (s_image_buffer_index == 0)
|
||||
{
|
||||
s_image_start_address = new_record->address;
|
||||
s_image_next_address = s_image_start_address;
|
||||
}
|
||||
|
||||
/* update size and address. */
|
||||
s_image_buffer_index += new_record->dataCount;
|
||||
s_image_next_address += new_record->dataCount;
|
||||
}
|
||||
/* Hnadle 02, 04 record */
|
||||
else if (is_address_record)
|
||||
{
|
||||
/* If there are data in the collection buffer, then flush the buffer to the executable image. */
|
||||
if (s_image_buffer_index)
|
||||
{
|
||||
/* Erase target flash region */
|
||||
handle_flashEraseRegion_command(s_image_start_address, s_image_buffer_index);
|
||||
s_image_buffer_index = 0;
|
||||
}
|
||||
|
||||
/* extended address stored at data field. */
|
||||
s_image_base_address = (new_record->data[0] << 8) | new_record->data[1];
|
||||
if (new_record->type == INTELHEX_RECORD_EXTENDED_SEGMENT_ADDRESS)
|
||||
{
|
||||
s_image_base_address <<= 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_image_base_address <<= 16;
|
||||
}
|
||||
}
|
||||
/* Handle 03, 05 record */
|
||||
else if (is_entry_record)
|
||||
{
|
||||
/* Nothing to do */
|
||||
}
|
||||
/* Handle 01 record */
|
||||
else if (is_eof_record)
|
||||
{
|
||||
/* Flash any leftover data to target. */
|
||||
if (s_image_buffer_index)
|
||||
{
|
||||
/* Erase target flash region */
|
||||
handle_flashEraseRegion_command(s_image_start_address, s_image_buffer_index);
|
||||
s_image_buffer_index = 0;
|
||||
|
||||
return kRecordStatus_EraseOver;
|
||||
}
|
||||
}
|
||||
|
||||
return kRecordStatus_Success;
|
||||
}
|
||||
95
validation/embedded_host/src/image_program/intelhex_image.h
Normal file
95
validation/embedded_host/src/image_program/intelhex_image.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __intelhex_image_H__
|
||||
#define __intelhex_image_H__
|
||||
|
||||
#include "executable_image.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
enum
|
||||
{
|
||||
/*! The required first character of a Intel Hex */
|
||||
INTELHEX_START_CHAR = ':',
|
||||
|
||||
/*! The minimum length of a Hex. This is the start char (1) + datacount (2) + addr (4) + type (2) + check sum (2).
|
||||
*/
|
||||
INTELHEX_MIN_LENGTH = 11,
|
||||
|
||||
/*! Index of the first character of the address field. */
|
||||
INTELHEX_ADDRESS_START_CHAR_INDEX = 3,
|
||||
|
||||
/*! Index of the first character of the record type field. */
|
||||
INTELHEX_TYPE_START_CHAR_INDEX = 7,
|
||||
|
||||
/*! Index of the first character of the record type field. */
|
||||
INTELHEX_DATA_START_CHAR_INDEX = 9
|
||||
};
|
||||
|
||||
/*! Intel Hex Record Type */
|
||||
enum
|
||||
{
|
||||
/*! Data Record, which contains data and a 16-bit start address for the data. */
|
||||
INTELHEX_RECORD_DATA = 0x00,
|
||||
|
||||
/*! End of File Record, which specifies the end of the hex file, and */
|
||||
/*! must occur exactly once per file in the last line of the file. */
|
||||
INTELHEX_RECORD_END_OF_FILE = 0x01,
|
||||
|
||||
/*! Extended Segment Address Record, which is used to specify bits 4- 19 of the Segment Base Address. */
|
||||
INTELHEX_RECORD_EXTENDED_SEGMENT_ADDRESS = 0x02,
|
||||
|
||||
/*! Start Segment Address Record, which is used to specify the execution start address for the object file. */
|
||||
INTELHEX_RECORD_START_SEGMENT_ADDRESS = 0x03,
|
||||
|
||||
/*! Extended Linear Address Record, which is used to specify bits 16- 31 of the Linear Base Address. */
|
||||
INTELHEX_RECORD_EXTENDED_LINEAR_ADDRESS = 0x04,
|
||||
|
||||
/*! Start Linear Address Record, which is used to specify the execution start address for the object file. */
|
||||
INTELHEX_RECORD_START_LINEAR_ADDRESS = 0x05
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*! @brief parse srecord image */
|
||||
recordStatus_t intelhex_image_program(uint32_t image_address);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __intelhex_image_H__ */
|
||||
406
validation/embedded_host/src/image_program/srecord_image.c
Normal file
406
validation/embedded_host/src/image_program/srecord_image.c
Normal file
@@ -0,0 +1,406 @@
|
||||
/*
|
||||
* Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "fsl_common.h"
|
||||
#include "srecord_image.h"
|
||||
#include "blsh/bllibc.h"
|
||||
#include "blsh/host_command.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
typedef struct _srecord_t
|
||||
{
|
||||
uint8_t type; /*!< Record number type, such as 9 for "S9", 3 for "S3" and so on.*/
|
||||
uint8_t count; /*!< Number of character pairs (bytes) from address through checksum.*/
|
||||
uint32_t address; /*!< The address specified as part of the S-record.*/
|
||||
uint8_t dataCount; /*!< Number of bytes of data.*/
|
||||
uint8_t data[256]; /*!< Pointer to data, or NULL if no data for this record type.*/
|
||||
uint8_t checksum; /*!< The checksum byte present in the S-record.*/
|
||||
} srecord_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
static srecord_t s_new_record = { 0 };
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
static recordStatus_t srecord_parse_line(uint8_t *line, uint8_t line_length);
|
||||
static recordStatus_t srecord_build_image(srecord_t *new_record);
|
||||
static recordStatus_t srecord_erase_target(uint32_t image_address);
|
||||
static recordStatus_t srecord_erase_region(srecord_t *new_record);
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
recordStatus_t srecord_image_program(uint32_t image_address)
|
||||
{
|
||||
uint8_t image_char = 0;
|
||||
uint32_t image_index = 0;
|
||||
uint8_t line_buffer[256] = { 0 };
|
||||
uint8_t line_index = 0;
|
||||
recordStatus_t status = kRecordStatus_Fail;
|
||||
|
||||
/* Traverse the first time to erase target flash regions*/
|
||||
srecord_erase_target(image_address);
|
||||
|
||||
/* Clear globle variable*/
|
||||
s_image_buffer_index = 0;
|
||||
s_image_start_address = 0;
|
||||
s_image_next_address = 0;
|
||||
s_image_base_address = 0;
|
||||
|
||||
/* Traverse the second time to program target*/
|
||||
while (status != kRecordStatus_FlashOver)
|
||||
{
|
||||
image_char = read_flash_char(image_address, image_index);
|
||||
image_index++;
|
||||
|
||||
if (image_char == '\n')
|
||||
{
|
||||
status = srecord_parse_line(line_buffer, line_index);
|
||||
if (status != kRecordStatus_Success)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
line_index = 0;
|
||||
|
||||
/* Build image and flash target*/
|
||||
status = srecord_build_image(&s_new_record);
|
||||
|
||||
if (status == kRecordStatus_Fail)
|
||||
{
|
||||
return kStatus_Fail;
|
||||
}
|
||||
}
|
||||
else if (image_char == '\r')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
line_buffer[line_index++] = image_char;
|
||||
}
|
||||
}
|
||||
|
||||
return kRecordStatus_Success;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief parse one line of srecord record image
|
||||
*
|
||||
* @param line one line of the srecord record.
|
||||
* @param line_length the length of the line.
|
||||
* @return parse status
|
||||
*/
|
||||
static recordStatus_t srecord_parse_line(uint8_t *line, uint8_t line_length)
|
||||
{
|
||||
uint32_t checksum = 0;
|
||||
uint32_t i = 0;
|
||||
srecord_t *new_record = &s_new_record;
|
||||
|
||||
if (line_length < SRECORD_MIN_LENGTH)
|
||||
{
|
||||
return kRecordStatus_InvalidLength;
|
||||
}
|
||||
|
||||
if (line[0] != SRECORD_START_CHAR)
|
||||
{
|
||||
return kRecordStatus_InvalidStart;
|
||||
}
|
||||
|
||||
/* Parse type field*/
|
||||
if ((line[1] > '9') || (line[1] < '0'))
|
||||
{
|
||||
return kRecordStatus_InvalidType;
|
||||
}
|
||||
new_record->type = line[1] - '0';
|
||||
|
||||
/* Parse count field*/
|
||||
new_record->count = read_hex_byte(line, 2);
|
||||
checksum += new_record->count;
|
||||
|
||||
/* verify the record length now that we know the count*/
|
||||
if (line_length != 4 + new_record->count * 2)
|
||||
{
|
||||
return kRecordStatus_InvalidLength;
|
||||
}
|
||||
|
||||
/* Get address length*/
|
||||
uint8_t address_length = 0;
|
||||
uint8_t has_data = 0;
|
||||
switch (new_record->type)
|
||||
{
|
||||
case 0:
|
||||
address_length = 2;
|
||||
has_data = 1;
|
||||
break;
|
||||
case 1:
|
||||
address_length = 2;
|
||||
has_data = 1;
|
||||
break;
|
||||
case 2:
|
||||
address_length = 3;
|
||||
has_data = 1;
|
||||
break;
|
||||
case 3:
|
||||
address_length = 4;
|
||||
has_data = 1;
|
||||
break;
|
||||
case 5:
|
||||
address_length = 2;
|
||||
break;
|
||||
case 7:
|
||||
address_length = 4;
|
||||
break;
|
||||
case 8:
|
||||
address_length = 3;
|
||||
break;
|
||||
case 9:
|
||||
address_length = 2;
|
||||
break;
|
||||
default:
|
||||
return kRecordStatus_InvalidType;
|
||||
}
|
||||
|
||||
/* Read address*/
|
||||
uint32_t address = 0;
|
||||
for (i = 0; i < address_length; i++)
|
||||
{
|
||||
uint8_t address_byte = read_hex_byte(line, SRECORD_ADDRESS_START_CHAR_INDEX + i * 2);
|
||||
address = (address << 8) | address_byte;
|
||||
checksum += address_byte;
|
||||
}
|
||||
new_record->address = address;
|
||||
|
||||
/* Read data*/
|
||||
if (has_data)
|
||||
{
|
||||
int32_t data_start_char_index = 4 + address_length * 2;
|
||||
int32_t data_length = new_record->count - address_length - 1;
|
||||
|
||||
for (i = 0; i < data_length; i++)
|
||||
{
|
||||
uint8_t data_byte = read_hex_byte(line, data_start_char_index + i * 2);
|
||||
new_record->data[i] = data_byte;
|
||||
checksum += data_byte;
|
||||
}
|
||||
new_record->dataCount = data_length;
|
||||
}
|
||||
|
||||
/* Read and compare checksum byte*/
|
||||
checksum = (~checksum) & 0xff; /* low byte of one's complement of sum of other bytes */
|
||||
new_record->checksum = read_hex_byte(line, line_length - 2);
|
||||
if (checksum != new_record->checksum)
|
||||
{
|
||||
return kRecordStatus_InvalidChecksum;
|
||||
}
|
||||
|
||||
return kRecordStatus_Success;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief build srecord image and flash target
|
||||
*
|
||||
* @param new_record one line of the intelhex record.
|
||||
* @return parse status
|
||||
*/
|
||||
static recordStatus_t srecord_build_image(srecord_t *new_record)
|
||||
{
|
||||
uint8_t is_data_record = 0;
|
||||
uint8_t has_data = 0;
|
||||
uint32_t status = 0;
|
||||
|
||||
/* Handle S3, 2, 1 records */
|
||||
if ((new_record->type == 3) || (new_record->type == 2) || (new_record->type == 1))
|
||||
{
|
||||
is_data_record = 1;
|
||||
}
|
||||
has_data = (new_record->data) && (new_record->dataCount);
|
||||
if (is_data_record && has_data)
|
||||
{
|
||||
if (s_image_buffer_index)
|
||||
{
|
||||
/* If this record's data would overflow the collection buffer, or if the */
|
||||
/* record is not contiguous with the rest of the data in the collection */
|
||||
/* buffer, then flush the buffer to the executable image and restart. */
|
||||
if (((s_image_buffer_index + new_record->dataCount) > IMAGE_BUFFER_SIZE) ||
|
||||
(new_record->address != s_image_next_address))
|
||||
{
|
||||
/* TO-DO flush */
|
||||
status = handle_writeMemory_command(s_image_start_address, s_image_buffer, s_image_buffer_index);
|
||||
s_image_buffer_index = 0;
|
||||
|
||||
if (status == kStatus_Fail)
|
||||
{
|
||||
return kStatus_Fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Capture addresses when starting an empty buffer. */
|
||||
if (s_image_buffer_index == 0)
|
||||
{
|
||||
s_image_start_address = new_record->address;
|
||||
s_image_next_address = s_image_start_address;
|
||||
}
|
||||
|
||||
/* Copy record data into place in the collection buffer and update */
|
||||
/* size and address. */
|
||||
memcpy(&s_image_buffer[s_image_buffer_index], new_record->data, new_record->dataCount);
|
||||
s_image_buffer_index += new_record->dataCount;
|
||||
s_image_next_address += new_record->dataCount;
|
||||
}
|
||||
else if ((new_record->type == 7) || (new_record->type == 8) || (new_record->type == 9))
|
||||
{
|
||||
/* Flash any leftover data to target. */
|
||||
if (s_image_buffer_index)
|
||||
{
|
||||
status = handle_writeMemory_command(s_image_start_address, s_image_buffer, s_image_buffer_index);
|
||||
s_image_buffer_index = 0;
|
||||
|
||||
if (status == kStatus_Fail)
|
||||
{
|
||||
return kRecordStatus_Fail;
|
||||
}
|
||||
|
||||
return kRecordStatus_FlashOver;
|
||||
}
|
||||
}
|
||||
|
||||
return kRecordStatus_Success;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief erase target flash before program target
|
||||
*
|
||||
* @param image_address address of the image in host flash.
|
||||
* @return parse status
|
||||
*/
|
||||
static recordStatus_t srecord_erase_target(uint32_t image_address)
|
||||
{
|
||||
uint8_t image_char = 0;
|
||||
uint32_t image_index = 0;
|
||||
uint8_t line_buffer[256] = { 0 };
|
||||
uint8_t line_index = 0;
|
||||
recordStatus_t status = kRecordStatus_Fail;
|
||||
|
||||
while (status != kRecordStatus_EraseOver)
|
||||
{
|
||||
image_char = read_flash_char(image_address, image_index);
|
||||
image_index++;
|
||||
|
||||
if (image_char == '\n')
|
||||
{
|
||||
status = srecord_parse_line(line_buffer, line_index);
|
||||
if (status != kRecordStatus_Success)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
line_index = 0;
|
||||
|
||||
/* Erase target */
|
||||
status = srecord_erase_region(&s_new_record);
|
||||
}
|
||||
else if (image_char == '\r')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
line_buffer[line_index++] = image_char;
|
||||
}
|
||||
}
|
||||
|
||||
return kRecordStatus_Success;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief eraset flash region based on record
|
||||
*
|
||||
* @param new_record one line of the intelhex record.
|
||||
* @return parse status
|
||||
*/
|
||||
static recordStatus_t srecord_erase_region(srecord_t *new_record)
|
||||
{
|
||||
uint8_t is_data_record = 0;
|
||||
uint8_t has_data = 0;
|
||||
|
||||
/* Handle S3, 2, 1 records */
|
||||
if ((new_record->type == 3) || (new_record->type == 2) || (new_record->type == 1))
|
||||
{
|
||||
is_data_record = 1;
|
||||
}
|
||||
has_data = (new_record->data) && (new_record->dataCount);
|
||||
if (is_data_record && has_data)
|
||||
{
|
||||
if (s_image_buffer_index)
|
||||
{
|
||||
/* If this record's data would overflow the collection buffer, or if the */
|
||||
/* record is not contiguous with the rest of the data in the collection */
|
||||
/* buffer, then erase the flash region and restart. */
|
||||
if (((s_image_buffer_index + new_record->dataCount) > IMAGE_BUFFER_SIZE) ||
|
||||
(new_record->address != s_image_next_address))
|
||||
{
|
||||
/* Erase target flash region */
|
||||
handle_flashEraseRegion_command(s_image_start_address, s_image_buffer_index);
|
||||
s_image_buffer_index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Capture addresses when starting an empty buffer. */
|
||||
if (s_image_buffer_index == 0)
|
||||
{
|
||||
s_image_start_address = new_record->address;
|
||||
s_image_next_address = s_image_start_address;
|
||||
}
|
||||
|
||||
/* Update size and address. */
|
||||
s_image_buffer_index += new_record->dataCount;
|
||||
s_image_next_address += new_record->dataCount;
|
||||
}
|
||||
else if ((new_record->type == 7) || (new_record->type == 8) || (new_record->type == 9))
|
||||
{
|
||||
/* Erase target flash region */
|
||||
if (s_image_buffer_index)
|
||||
{
|
||||
handle_flashEraseRegion_command(s_image_start_address, s_image_buffer_index);
|
||||
s_image_buffer_index = 0;
|
||||
|
||||
return kRecordStatus_EraseOver;
|
||||
}
|
||||
}
|
||||
|
||||
return kRecordStatus_Success;
|
||||
}
|
||||
65
validation/embedded_host/src/image_program/srecord_image.h
Normal file
65
validation/embedded_host/src/image_program/srecord_image.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* o Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __srecord_image_H__
|
||||
#define __srecord_image_H__
|
||||
|
||||
#include "executable_image.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
enum
|
||||
{
|
||||
/*! The required first character of an S-record. */
|
||||
SRECORD_START_CHAR = 'S',
|
||||
|
||||
/*! The minimum length of a S-record. This is the type (2) + count (2) + addr (4) + cksum (2). */
|
||||
SRECORD_MIN_LENGTH = 10,
|
||||
|
||||
/*! Index of the first character of the address field. */
|
||||
SRECORD_ADDRESS_START_CHAR_INDEX = 4
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*! @brief parse srecord image */
|
||||
recordStatus_t srecord_image_program(uint32_t image_address);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __srecord_image_H__ */
|
||||
Reference in New Issue
Block a user