资讯
HOME
资讯
正文内容
lpc1788 nand flash 现场升级方案:NXP LPC1778采用U盘方式进行固件程序包IAP升级
发布时间 : 2024-10-15
作者 : 小编
访问数量 : 23
扫码分享至微信

现场升级方案:NXP LPC1778采用U盘方式进行固件程序包IAP升级

[本文属原创,转载请附上原文出处链接。]

闲来无事,总结一下之前做过的U盘升级项目。一个技术人员的成长之路在于善于总结,生活也是一样扯远了,我准备了两个软件环境,一个带操作系统(UCOS)的,另一个裸机版的。随后我会附上两个程序代码(头条号好像不允许发外链)。U盘升级可以分为两部分代码:U盘读取bin文件和IAP功能两部分。大概说一下实现过程,具体IAP网上都玩坏了。

硬件环境:NXP 1788

软件环境:KEIL

实现过程:上面说了我准备了两个程序,就用裸机版的代码说一下实现流程。带操作系统的原理都是一样的。只是多创建几个任务而已。USB_HOST实现IAP升级,总的思路就是:复制bin文件到U盘->目标板断电,插上U盘->目标板上电,进入升级->运行升级程序。其实可以更具体,比如说设置升级标志或者按键。

拿到一个程序先从main开始,直接贴代码,说一大堆废话有什么用。

int main(){ int32_t rc; uint32_t numBlks, blkSize; uint8_t inquiryResult[INQUIRY_LENGTH];

SystemInit();

UART_Init(57600); Host_Init(); rc = Host_EnumDev(); if (rc == OK) { rc = MS_Init( &blkSize, &numBlks, inquiryResult ); if (rc == OK) { rc = FAT_Init(); if (rc == OK) { Bin_Read(); } else { return (0); } } else { return (0); } } else { return (0); } while(1);}

下面分模块说一下, 前面的硬件初始化函数很简单,USB设备枚举和FAT文件系统NXP官网上都有,只需改硬件接口,Host_Init函数如下:

void Host_Init (void){ uint32_t HostBaseAddr;

LPC_SC->PCONP |= 0x80000000; LPC_USB->OTGClkCtrl = 0x00000019; while ((LPC_USB->OTGClkSt & 0x00000019) != 0x19); LPC_USB->StCtrl = 0x1;

LPC_IOCON->P0_29 &= ~(0x07UL << 0); LPC_IOCON->P0_30 &= ~(0x07UL << 0); LPC_IOCON->P1_28 &= ~(0x07UL << 0); LPC_IOCON->P1_29 &= ~(0x07UL << 0);

LPC_IOCON->P0_29 |= 0x01UL << 0; LPC_IOCON->P0_30 |= 0x01UL << 0; LPC_IOCON->P1_28 |= 0x01UL << 0; LPC_IOCON->P1_29 |= 0x01UL << 0; // P1.29 -- USB_SDA1 PRINT_Log("Initializing Host Stack\n");

HostBaseAddr = HOST_BASE_ADDR;

Hcca = (volatile HCCA *)(HostBaseAddr+0x000); TDHead = (volatile HCTD *)(HostBaseAddr+0x100); TDTail = (volatile HCTD *)(HostBaseAddr+0x110); EDCtrl = (volatile HCED *)(HostBaseAddr+0x120); EDBulkIn = (volatile HCED *)(HostBaseAddr+0x130); EDBulkOut = (volatile HCED *)(HostBaseAddr+0x140); TDBuffer = (volatile uint8_t *)(HostBaseAddr+0x150); FATBuffer = (volatile uint8_t *)(HostBaseAddr+0x1D0); UserBuffer = (volatile uint8_t *)(HostBaseAddr+0x1000);

Host_EDInit(EDCtrl); Host_EDInit(EDBulkIn); Host_EDInit(EDBulkOut); Host_TDInit(TDHead); Host_TDInit(TDTail); Host_HCCAInit(Hcca);

Host_DelayMS(50); LPC_USB->Control = 0; LPC_USB->ControlHeadED = 0; LPC_USB->BulkHeadED = 0; LPC_USB->CommandStatus = OR_CMD_STATUS_HCR; LPC_USB->FmInterval = DEFAULT_FMINTERVAL;

LPC_USB->Control = (LPC_USB->Control & (~OR_CONTROL_HCFS)) | OR_CONTROL_HC_OPER; LPC_USB->RhStatus = OR_RH_STATUS_LPSC; LPC_USB->HCCA = (uint32_t)Hcca; LPC_USB->InterruptStatus |= LPC_USB->InterruptStatus;

LPC_USB->InterruptEnable = OR_INTR_ENABLE_MIE | OR_INTR_ENABLE_WDH | OR_INTR_ENABLE_RHSC | OR_INTR_ENABLE_UE;

NVIC_EnableIRQ(USB_IRQn); NVIC_SetPriority (USB_IRQn, 0);

PRINT_Log("Host Initialized\n");}

这段主要是USB引脚配置和USB主机初始化。Bin_Read()函数如下:

void Bin_Read (void){ int32_t fdr; uint32_t bytes_read,writelen; uint32_t dstaddr; SelSector(APP_START_SECTOR,APP_END_SECTOR); //选择扇区 EraseSector(APP_START_SECTOR,APP_END_SECTOR); BlankCHK(APP_START_SECTOR,APP_END_SECTOR); SelSector(APP_START_SECTOR,APP_END_SECTOR); PRINT_Log("\r\nstart file operations...\r\n");

fdr = FILE_Open(FILENAME_R, RDONLY); if (fdr > 0) { PRINT_Log("Reading from %s...\n", FILENAME_R); for(writelen=0;writelen<(APP_END_ADDR-APP_START_ADDR)/1024;writelen++) { bytes_read = FILE_Read(fdr, UserBuffer, MAX_BUFFER_SIZE); dstaddr = (uint32_t)(APP_START_ADDR + (writelen)*1024);//dst address. SelSector(APP_START_SECTOR,APP_END_SECTOR); RamToFlash(dstaddr,(uint32_t)UserBuffer, 1024); Compare(dstaddr, (uint32_t)UserBuffer, 1024); } // printf("%x",writelen); PRINT_Log("\r\n write file successful\r\n"); SCB->VTOR = APP_START_ADDR; ExceuteApplication(); FILE_Close(fdr); } else { PRINT_Log("\r\n write file failed\r\n"); }}

上面的代码可以分为两部分:1.从U盘读取bin文件2.IAP功能。先说IAP部分,IAP实现方法有UART,GPRS,USB等方式。要进行IAP设计,先划分FLASH扇区。LPC1788的FLASH划分如下:

将flash划分为两个区,bootloader和APP区,bootloader存放升级引导程序,即我们的USB_HOST_IAP代码,根据具体的Code大小确定bootloader的扇区,APP就是用户程序即需要升级的程序代码。APP需要配置后面再说。这是我的扇区划分:

#define IAP_START_ADDR 0x00000000 // IAP开始地址#define IAP_LOCATION 0x1FFF1FF1 #define APP_START_ADDR 0x00A000 // 用户程序起始地址#define APP_END_ADDR 0x78000 //LPC1788 512K Flash //#define APP_SIZE 0x10000 #define APP_START_SECTOR 10#define APP_END_SECTOR 29 // LPC1788 512K Flash扇区

下面分别概括一下实现IAP命令的函数,IAP功能命令有准备编程扇区,复制RAM到FLASH,擦除扇区,扇区查空,读器件ID,读BOOT代码版本,比较等指令。程序要进行IAP升级,必须要先选择扇区擦除扇区之后才能写进Flash。先需要定义系统时钟,参数和一些变量。

#define IAP_FCCLK 48000

uint32_t paramin[8]; uint32_t paramout[8]; unsigned long command[5];unsigned long result[5];typedef void (*IAP) (unsigned int [ ] , unsigned int [ ]);

写数据之前,必须要选择需要写入的扇区,选择扇区部分代码:

uint32_t SelSector(uint8_t sec1,uint8_t sec2){ paramin[0] = IAP_SELECTOR; paramin[1] = sec1; paramin[2] = sec2; (*(void(*)())IAP_LOCATION)(paramin,paramout); return(paramout[0]); }

选中扇区之后,要检查该扇区是否已经有数据,所以要擦除扇区,附代码:

uint32_t EraseSector(uint32_t sec1, uint32_t sec2){ paramin[0] = IAP_ERASESECTOR; paramin[1] = sec1; paramin[2] = sec2; paramin[3] = IAP_FCCLK; (*(void(*)())IAP_LOCATION)(paramin,paramout); return(paramout[0]); }

下来就是向flash写入数据,flash起始地址必须以256字节为分界,调用函数

uint32_t RamToFlash(uint32_t dst, uint32_t src, uint32_t no){ paramin[0] = IAP_RAMTOFLASH; paramin[1] = dst; paramin[2] = src; paramin[3] = no; paramin[4] = IAP_FCCLK; (*(void(*)())IAP_LOCATION)(paramin,paramout); return(paramout[0]); }

写完之后要进行比较,将RAM读出来的数据和写入到flash的数据进行比较,注意flash起始地址必须字对齐,字节个数必须能被4整除,当源或目标地址包含从地址 0 开始的前 64 个字节中的任意一个地址时, 比较的结果可能不准确。因为前 64 个字节可被重新映射到 RAM:

uint32_t Compare(uint32_t dst, uint32_t src, uint32_t no){ paramin[0] = IAP_COMPARE; paramin[1] = dst; paramin[2] = src; paramin[3] = no; (*(void(*)())IAP_LOCATION)(paramin,paramout); return(paramout[0]); }

还有ExceuteApplication()部分的代码,程序写入flash之后,要重新映射向量表,从bootloader跳转到APP执行,这就要获取程序的入口地址和SP堆栈的值。如下:

__asm void ExceuteApplication(void){ ldr r0, =0x00A000 ldr r0, [r0] mov sp, r0 ldr r0, =0x00A004 ldr r0, [r0] BX r0}

最后关闭文件系统,main里面最主要读取bin文件调用IAP功能的Bin_Read()函数说完了。最后说一下APP程序产生bin文件的配置。关于KEIL中Target Options配置:1.将程序入口定位到App即用户程序的入口地址;

2.User选项:Run #1填写产生bin文件路径:C:\Keil\ARM\ARMCC\bin\fromelf.exe--bin --output output\FLASH\test.bin output\FLASH\LPC177x_8x.axf;

3.C/c++选项:Optimization选择高优先级:Level3;

4.Asm选项:Define填NO_CRP,即不产生空文件夹;

5.Linker选项:勾选Use Memory layout from Target Dialog.整个工程就算建立起来了。

LPC1788FBD208K微控制器的性能特点-启苜微科技

LPC1788FBD208K是一款由NXP半导体公司制造的高性能微控制器,它具有强大的ARM Cortex-M4内核,高速运行,高品质音效,以及丰富的外设接口,在工业控制、安防监控、车载导航等领域有着广泛的应用前景。

LPC1788FBD208K微控制器的性能特点-启苜微科技

一、产品特性

LPC1788FBD208K的主要特性包括:

1.内核:采用ARM Cortex-M4核心,主频高达72MHz,能够满足复杂的应用需求。2.内存:内置了高速的Flash存储器和SRAM,同时还有EEPROM,可用于存储程序和数据。3.封装:采用标准的QFN-100封装,方便集成和布局。

二、性能特点

LPC1788FBD208K的性能特点主要体现在以下几个方面:

1.高速运行:主频高达72MHz的ARM Cortex-M4内核,可以高速处理各种计算和数据处理任务。2.高品质音效:LPC1788FBD208K内置了高性能的音频处理器,可以实现高品质的音频处理。3.丰富功能:除了基本的GPIO、UART、SPI、I2C等接口外,还具有ADC、DAC、定时器、PWM输出等功能,可以满足各种应用的需求。

三、应用场景

LPC1788FBD208K主要应用于以下场景:

1.工业控制:作为主控制器,可以用于各种工业控制系统的控制和监测。2.安防监控:可用于各种安防监控系统的图像处理和控制。3.车载导航:可用于车载导航系统的主控芯片,实现导航、娱乐等功能。

四、优势与挑战

LPC1788FBD208K的优势主要体现在其高性能、丰富的外设接口和高品质的音频处理能力。然而,它也面临一些挑战,主要包括成本、功耗和可靠性等方面。为了充分发挥LPC1788FBD208K的优势并解决其挑战,建议在应用时注意以下几点:

1.优化程序设计:通过优化程序设计,减少不必要的功耗消耗,提高系统可靠性。2.选择合适的封装形式:针对不同的应用场景,选择合适的封装形式,以满足不同需求。3.考虑配套设施:在使用LPC1788FBD208K时,应考虑配套设施的性能和兼容性,以确保整个系统的性能和稳定性。4.注重产品选型:针对具体应用场景,需注重产品选型,选择符合实际需求的产品型号,以确保系统的可靠性。

五、结论

LPC1788FBD208K是一款具有高速与高品质的微控制器,它采用ARM Cortex-M4核心,内置高速Flash存储器和SRAM,同时具有丰富的外设接口和高品质的音频处理能力。在工业控制、安防监控、车载导航等领域有着广泛的应用前景。虽然LPC1788FBD208K的成本、功耗和可靠性等方面仍存在一定的挑战,但通过优化程序设计、选择合适的封装形式和注重产品选型等措施,可以充分发挥其高性能、丰富功能和高品质音效的优势,为各种嵌入式应用提供稳定可靠、高效节能的控制解决方案。

相关问答

笔记本外接屏幕闪烁!笔记本本身屏幕不闪!-ZOL问答

4、外接显示也存在类似故障,则需要考虑更新显卡驱动、Flash插件或重新恢复系统。5、软件问题不能排除故障,替换cpu测试,来确定故障是由于cpu导致还是主板...

为何电脑重启后发出警报的声音,进入不了系统?-ZOL问答

1长9短:主板FlashRAM或EPROM错误,BIOS损坏。换块FlashRAM试试。不断地响(长声):内存条未插紧或损坏。重插内存条,若还是不行,只有更换一条内存。不停地...

大小最大的笔记本电脑?目前市面上大小最大的笔记本电脑是18.4...

目前最高配置的AlienwareM18X是(ALW18D-1788),报价35999屏幕尺寸:18.4英寸1920x1080CPU型号:酷睿i74900MQ,4核8线程,初始主频2.8GHz...

相机内存卡在哪里-ZOL问答

6人讨论1788次围观关注问题写回答讨论回答(6)dsuekqtilfsc卖相机的地方就有不过价格偏贵随便找个电子市场或手机市场都有SD卡比较通用SONY的记忆棒价...

通达信和mt4的外汇行情一样吗- 汇财吧专业问答test

[回答]通达信免费的就能看外汇了,你这边是在操作外汇吗?其实外汇的MT4软件我感觉是比较好而且很方便的。你要做分析还是用MT4好点,我这边是做Rinfx,以后可...

 金 卡黛珊  台风森拉克生成 
王经理: 180-0000-0000(微信同号)
10086@qq.com
北京海淀区西三旗街道国际大厦08A座
©2024  上海羊羽卓进出口贸易有限公司  版权所有.All Rights Reserved.  |  程序由Z-BlogPHP强力驱动
网站首页
电话咨询
微信号

QQ

在线咨询真诚为您提供专业解答服务

热线

188-0000-0000
专属服务热线

微信

二维码扫一扫微信交流
顶部