S32R274 -- bootloader(一)

0、NXP没有提供S32R274的bootloader试例程序,网上也没有找到,不过NXP MPC5XXX系列芯片有bootloader的例子可以借鉴,它们都是用的z4启动核心,而且都是用的C55 FLASH。

1、开发环境是NXP官方的S32DS最新版,建立一个z4的单核工程,bootloader和用户程序要在不同的flash块,建立工程的时候地址都是从0x01000000开始,启动代码必须放到boot location块,下面是s32r274 flash相关资料
在这里插入图片描述
在这里插入图片描述
可以把bootloader放到0x00F98000,S32DS自动生成的项目起始地址是0x01000000,只能通过flash配置文件linker_flash.ld改地址,启动配置半字从F98000开始,代码起始地址从F99000开始,大小为156K,一般bootloader很小,我用到了lwip模块和串口模块,自动生成的代码有点大。

//linker_flash.ld
/* define heap and stack size */
__HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x00000400;
__STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x00004000;

/* Define FLASH */
//启动配置半字RCHW需要占用8个字节,所以代码地址从F99000开始,大小为156K
FLASH_BASE_ADDR = DEFINED(__flash_base_addr__) ? __flash_base_addr__ : 0x00F99000;
FLASH_SIZE =  DEFINED(__flash_size__) ? __flash_size__ : 156K;

/* Define SRAM */
SRAM_BASE_ADDR = DEFINED(__sram_base_addr__) ? __sram_base_addr__ : 0x40000000;
SRAM_SIZE = DEFINED(__sram_size__) ? __sram_size__ : 256K;

/* Define local data memory */
LOCAL_DMEM_BASE_ADDR = DEFINED(__local_dmem_base_addr__) ? __local_dmem_base_addr__ : 0x50800000;
LOCAL_DMEM_SIZE =  DEFINED(__local_dmem_size__) ? __local_dmem_size__ : 64K;

MEMORY
{
//启动配置半字
    flash_rchw : org = 0x00F98000, len = 0x4
    cpu0_reset_vec : org = 0x00F98000+0x04, len = 0x4

    m_text : org = FLASH_BASE_ADDR, len = FLASH_SIZE
    m_data : org = SRAM_BASE_ADDR, len = SRAM_SIZE
    local_dmem : org = LOCAL_DMEM_BASE_ADDR, len = LOCAL_DMEM_SIZE
}
...

2、flash C55模块,需要在工程内添加flash_C55模块,它提供了读写flash的接口函数,初始化、格式化、写flash代码都是官网或网上能找到的,就直接贴文件了flash.c,ProgramFlash是写烧录文件的函数,S19格式的,一条一条写

/*
 * flash.c
 *
 *  Created on: 2020年7月6日
 *      Author: 
 */
#include "flash.h"
#include "flash_c55_driver.h"
#include "Srec.h"
#include "net_conn.h"

uint32_t g_usrCnt = 0U;
flash_context_data_t pCtxData;
static uint32_t pflash_pfcr1, pflash_pfcr2;


void UserCallBack(void)
{
    /* increase g_usrCnt */
    g_usrCnt++;
}
/**************************************************************
*                          Disable Flash Cache                *
***************************************************************/
void DisableFlashControllerCache(uint32_t flashConfigReg,
                                 uint32_t disableVal,
                                 uint32_t *origin_pflash_pfcr)
{
    /* Read the values of the register of flash configuration */
    *origin_pflash_pfcr = REG_READ32(FLASH_FMC + flashConfigReg);
    /* Disable Caches */
    REG_BIT_CLEAR32(FLASH_FMC + flashConfigReg, disableVal);
}
/*****************************************************************
*               Restore configuration register of FCM            *
******************************************************************/
void RestoreFlashControllerCache(uint32_t flashConfigReg,
                                 uint32_t pflash_pfcr)
{
    REG_WRITE32(FLASH_FMC + flashConfigReg, pflash_pfcr);
}

void disable_flash_cache()
{
    DisableFlashControllerCache(FLASH_PFCR1, FLASH_FMC_BFEN_MASK, &pflash_pfcr1);
    DisableFlashControllerCache(FLASH_PFCR2, FLASH_FMC_BFEN_MASK, &pflash_pfcr2);
}

void restore_flash_cache()
{
	if(pflash_pfcr1 != 0 && pflash_pfcr2 != 0) {
		RestoreFlashControllerCache(FLASH_PFCR1, pflash_pfcr1);
	    RestoreFlashControllerCache(FLASH_PFCR2, pflash_pfcr2);
	}
}

status_t FlashInit()
{
	status_t ret = STATUS_SUCCESS;
	uint32_t blkLockState;
    /* Flash Initialization */
    ret = FLASH_DRV_Init();
    DEV_ASSERT(ret == STATUS_SUCCESS);

    /**************************************************************************/
    /* Lock to protect UTest address space                                    */
    /**************************************************************************/
    ret = FLASH_DRV_GetLock(C55_BLOCK_UTEST, &blkLockState);
    if (!(blkLockState & 0x00000001U))
    {
        ret = FLASH_DRV_SetLock(C55_BLOCK_UTEST, 0x1U);
        if (STATUS_SUCCESS != ret)
        {
            return ret;
        }
    }
    /**************************************************************************/
    /* Unlock all blocks in low address space                                 */
    /**************************************************************************/
    ret = FLASH_DRV_SetLock(C55_BLOCK_LOW, UNLOCK_LOW_BLOCKS);
    if (STATUS_SUCCESS != ret)
    {
        return ret;
    }
    /**************************************************************************/
    /* Unlock all blocks in mid address space                                 */
    /**************************************************************************/
    ret = FLASH_DRV_SetLock(C55_BLOCK_MID, UNLOCK_MID_BLOCKS);
    if (STATUS_SUCCESS != ret)
    {
        return ret;
    }
    /**************************************************************************/
    /* Unlock all blocks in 256K blocks                                       */
    /**************************************************************************/
    ret = FLASH_DRV_SetLock(C55_BLOCK_256K_FIRST, UNLOCK_FIRST256_BLOCKS);
    return ret;
}

status_t EraseFlash()
{
	status_t ret = STATUS_SUCCESS;
	flash_block_select_t blockSelect;
	flash_state_t opResult;
    //选择需要擦除的块,是用户代码块0x01000000开始
    blockSelect.lowBlockSelect = 0x0U;
    blockSelect.midBlockSelect = 0x0U;
    blockSelect.highBlockSelect = 0x0U;
    blockSelect.first256KBlockSelect = 0x3U;
    blockSelect.second256KBlockSelect = 0x0U;

    ret = FlashInit();
    if (STATUS_SUCCESS != ret)
    {
    	return ret;
    }
    /* Erase block */
    ret = FLASH_DRV_Erase(ERS_OPT_MAIN_SPACE, &blockSelect);
    if (STATUS_SUCCESS == ret)
    {
        do
        {
            /* The user can do any tasks while check status function is still in progress */
            UserCallBack();
            ret = FLASH_DRV_CheckEraseStatus(&opResult);
        }while(ret == STATUS_FLASH_INPROGRESS);
    }

    return ret;
}

status_t ProgramFlash(int sock, char * data, uint32_t len)
{
	status_t ret = STATUS_SUCCESS;
	flash_block_select_t blockSelect;
	flash_state_t opResult;
	uint32_t numOfWordCycle;
	uint32_t sum;
	uint32_t failedAddress;
    uint32_t dest;                 /* destination address */
    uint32_t size;                 /* size applicable */
    uint32_t source;               /* source address for program and verify */
    SRecDataRec ProgSRec;

	/* go get an S-Record, return if there was an error */
    uint8_t Error = RcvSRecord(sock, &ProgSRec, data, len);
	if (Error != 0) {
		return Error;
	}

	if (ProgSRec.RecType == EndRec)	/* S7, S8 or S9 record? */
	{
		restore_flash_cache();
		return (0x006U);			/* yes. return */
	}

	else if (ProgSRec.RecType == HeaderRec)	/* S0 record? */
	{
		return STATUS_SUCCESS;			/* yes. just ignore it */
	}
	/* a data record was received */
	else
	{
		//write(sock, ProgSRec.Data, MaxSRecLen);
	    if ((ProgSRec.LoadAddr & 0x0000000FUL) != 0) /* S-Record address aligned? */
	    {
	    	return(101);	/* address not aligned. return */
	    }
	    if (ProgSRec.NumBytes != 16)/* S-Record constant length 16? */
	    {
	    	return(102);	/* length different from 16. Return */
	    }

	    /* Prepare data for programming */
	    dest = ProgSRec.LoadAddr;
	    source = (uint32_t)ProgSRec.Data;
	    size = 16;
	    ret = FLASH_DRV_Program(&pCtxData,dest, size, source);
	    if (STATUS_SUCCESS == ret)
	    {
	        do
	        {
	            /* The user can do any tasks while check status function is still in progress */
	            UserCallBack();
	            ret = FLASH_DRV_CheckProgramStatus(&pCtxData, &opResult);
	        }while(ret == STATUS_FLASH_INPROGRESS);
	    }

	    if (STATUS_SUCCESS != ret)
	    {

	        return ret;
	    }

	    numOfWordCycle = NUMBER_OF_WORD_PGM_VERIFY;
	    /* Program verify */
	    ret = FLASH_DRV_ProgramVerify(dest,
	                                  size,
	                                  source,
	                                  numOfWordCycle,
	                                  &failedAddress,
	                                  NULL_CALLBACK);
	    if (STATUS_SUCCESS != ret)
	    {
	        return ret;
	    }
	    numOfWordCycle = NUMBER_OF_WORD_CHECK_SUM;
	    /* Check sum */
	    ret = FLASH_DRV_CheckSum(dest,
	                             size,
	                             numOfWordCycle,
	                             &sum,
	                             NULL_CALLBACK);
	    if ((STATUS_SUCCESS != ret) && (sum != 0U))
	    {
	        return ret;
	    }
	}

    return ret;
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是S32K144-EVB开发板CAN实例代码,供参考: ```c #include "S32K144.h" #define CAN0_TX_PIN 16U /* PTC16 */ #define CAN0_RX_PIN 17U /* PTC17 */ void CAN0_Init(void) { /* Enable the clock to the module */ PCC->PCCn[PCC_PORTC_INDEX] |= PCC_PCCn_CGC_MASK; PCC->PCCn[PCC_FlexCAN0_INDEX] |= PCC_PCCn_CGC_MASK; /* Configure the pins for CAN0 */ PORTC->PCR[CAN0_TX_PIN] &= ~PORT_PCR_MUX_MASK; PORTC->PCR[CAN0_TX_PIN] |= PORT_PCR_MUX(2); PORTC->PCR[CAN0_RX_PIN] &= ~PORT_PCR_MUX_MASK; PORTC->PCR[CAN0_RX_PIN] |= PORT_PCR_MUX(2); /* Reset the module */ FLEXCAN0->MCR |= FLEXCAN_MCR_SOFTRST_MASK; while (FLEXCAN0->MCR & FLEXCAN_MCR_SOFTRST_MASK); /* Configure the module */ FLEXCAN0->MCR |= FLEXCAN_MCR_FRZ_MASK; FLEXCAN0->MCR |= FLEXCAN_MCR_MDIS_MASK; FLEXCAN0->CTRL1 |= FLEXCAN_CTRL1_CLKSRC_MASK; FLEXCAN0->CTRL1 |= FLEXCAN_CTRL1_PRESDIV(0x01); FLEXCAN0->CTRL1 &= ~FLEXCAN_CTRL1_LBUF_MASK; FLEXCAN0->MCR &= ~FLEXCAN_MCR_MDIS_MASK; while (FLEXCAN0->MCR & FLEXCAN_MCR_LPMACK_MASK); while (!(FLEXCAN0->MCR & FLEXCAN_MCR_FRZACK_MASK)); FLEXCAN0->MCR &= ~FLEXCAN_MCR_FRZ_MASK; /* Configure the mailbox */ FLEXCAN0->MB[0].CS |= FLEXCAN_MB_CS_IDE_MASK; FLEXCAN0->MB[0].ID |= FLEXCAN_MB_ID_IDSTD(0x123); FLEXCAN0->MB[0].CS |= FLEXCAN_MB_CS_RTR_MASK; FLEXCAN0->MB[0].CS |= FLEXCAN_MB_CS_DLC(8); FLEXCAN0->MB[0].CS |= FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_INACTIVE); } void CAN0_Send(uint8_t *data) { uint32_t i; /* Copy data to mailbox */ for (i = 0; i < 8; i++) { FLEXCAN0->MB[0].DATA[i] = data[i]; } /* Send the message */ FLEXCAN0->MB[0].CS &= ~FLEXCAN_MB_CS_CODE_MASK; FLEXCAN0->MB[0].CS |= FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_ONCE); } int main(void) { uint8_t data[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; CAN0_Init(); CAN0_Send(data); return 0; } ``` 注意,以上代码仅供参考,具体实现需要根据实际情况进行修改。例如,需要根据实际需求设置CAN的波特率、ID等参数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值