ARM固件开发(LPC1768启动初始化代码)
ARM固件开发(LPC1768启动初始化代码)
一、复位
ARM启动中需要配置上电复位功能,因为这样才能确保上电之后程序处于初始状态而并非程序指针未知。通常启动代码编译器自带,而程序入口基本上都是以复位中断开始。
下面这一段启动代码会自动调用两个函数,分别是
SystemInit 系统上电初始化,主要进行时钟、锁相环等核心部分的配置
main 系统上电初始化之后,调用main函数,用户无需返回main函数
; Reset HandlerReset_Handler PROCEXPORT Reset_Handler [WEAK]IMPORT SystemInitIMPORT __mainLDR R0, =SystemInitBLX R0LDR R0, =__mainBX R0ENDP
二、SystemInit系统上电初始化
SystemInit仅仅是一个函数名称,所以在不同的环境下可能名字不同。
//LPC175X-6X
#if 1
void SystemInit(void){//Flash Accelerator Configuration registerLPC_SC->FLASHCFG = ((0x05ul << 12) & (~(0x003f))) | 0x003a; //Set system timers for each component
#if (FPCLK / (FCCLK / 4)) == 1LPC_SC->PCLKSEL0 = 0x00000000; /* PCLK is 1/4 CCLK */LPC_SC->PCLKSEL1 = 0x00000000;
#endif /* (FPCLK / (FCCLK / 4)) */
#if (FPCLK / (FCCLK / 4)) == 2LPC_SC->PCLKSEL0 = 0xAAAAAAAA; /* PCLK is 1/2 CCLK */LPC_SC->PCLKSEL1 = 0xAAAAAAAA;
#endif /* (FPCLK / (FCCLK / 4)) */
#if (FPCLK / (FCCLK / 4)) == 4LPC_SC->PCLKSEL0 = 0x55555555; /* PCLK is the same as CCLK */LPC_SC->PCLKSEL1 = 0x55555555;
#endif /* (FPCLK / (FCCLK / 4)) *///Selects the CPU clock as the CLKOUT sourceLPC_SC->CLKOUTCFG = 0; /* Close PLL */if ((LPC_SC->PLL0STAT >> 24) == 1) {LPC_SC->PLL0CON = 1; // Enable PLL, disconnected LPC_SC->PLL0FEED = 0xAA;LPC_SC->PLL0FEED = 0x55;}LPC_SC->PLL0CON = 0; // Disable PLL, disconnected LPC_SC->PLL0FEED = 0xAA;LPC_SC->PLL0FEED = 0x55;while(LPC_SC->PLL0STAT & (3 << 24)); /* PLL clock *///Enable mainOSC,1MHz~20MHz LPC_SC->SCS = (LPC_SC->SCS) | 0x20;//wait for The main oscillator is readywhile ((LPC_SC->SCS & (1ul << 6)) == 0) ;LPC_SC->CLKSRCSEL = 0x01;//select main OSC as the PLL clock source LPC_SC->PLL0CFG = (((PLL_NVALUE - 1) << 16) | (PLL_MVALUE - 1)); LPC_SC->PLL0FEED = 0xAA; /* Enable but disconnect PLL */LPC_SC->PLL0FEED = 0x55; LPC_SC->PLL0CON = 1;//PLL0 EnableLPC_SC->PLL0FEED = 0xAA; // Enable but disconnect PLL LPC_SC->PLL0FEED = 0x55; while ((LPC_SC->PLL0STAT & (1ul << 26)) == 0);//CPU Clock Configuration registerLPC_SC->CCLKCFG = (FCCO / FCCLK) - 1; while (((LPC_SC->PLL0STAT & (1ul << 26)) == 0)); /* Check lock bit status */while (((LPC_SC->PLL0STAT & 0x00007FFF) != (PLL_MVALUE - 1)) && (((LPC_SC->PLL0STAT & 0x00FF0000) >> 16) != (PLL_NVALUE - 1)));LPC_SC->PLL0CON = 3; /* connect the PLL */LPC_SC->PLL0FEED = 0xAA;LPC_SC->PLL0FEED = 0x55; //Wait until the PLL is connected while ((LPC_SC->PLL0STAT & (1ul << 25)) == 0);/* USB clock */
#if FUSBCLK_EN
#if (FCCO % (FUSBCLK * 2)) == 0LPC_SC->PLL1CON = 0;LPC_SC->PLL1FEED = 0xaa;LPC_SC->PLL1FEED = 0x55; LPC_SC->USBCLKCFG = (FCCO / (FUSBCLK)) - 1;
#elseLPC_SC->PLL1CON = 1;LPC_SC->PLL1CFG = ((FUSBCLK / FOSC) - 1) | (1 << 5);LPC_SC->PLL1FEED = 0xaa;LPC_SC->PLL1FEED = 0x55;while ((LPC_SC->PLL1STAT & (1 << 10)) == 0) { }LPC_SC->PLL1CON = 3;LPC_SC->PLL1FEED = 0xaa;LPC_SC->PLL1FEED = 0x55;
#endif
#endif/* flash accesses */ //Flash accesses use 1 CPU clock. Use for up to 20 MHz CPU clock.
#if FCCLK <= 20000000 LPC_SC->FLASHCFG = ((0x01ul << 12) & (~(0x003f))) | 0x003a;
#endif //Flash accesses use 2 CPU clocks. Use for up to 40 MHz CPU clock.
#if FCCLK > 20000000 && FCCLK <= 40000000LPC_SC->FLASHCFG = ((0x02ul << 12) & (~(0x003f))) | 0x003a;
#endif //Flash accesses use 3 CPU clocks. Use for up to 60 MHz CPU clock.
#if FCCLK > 40000000 && FCCLK <= 60000000LPC_SC->FLASHCFG = ((0x03ul << 12) & (~(0x003f))) | 0x003a;
#endif //Flash accesses use 4 CPU clocks. Use for up to 80 MHz CPU clock.
#if FCCLK > 60000000 && FCCLK <= 80000000LPC_SC->FLASHCFG = ((0x04ul << 12) & (~(0x003f))) | 0x003a;
#endif //Flash accesses use 5 CPU clocks. Use for up to 100 MHz CPU clock
#if FCCLK > 80000000 && FCCLK <= 100000000LPC_SC->FLASHCFG = ((0x05ul << 12) & (~(0x003f))) | 0x003a;
#endif IO_init();NVIC_ICER0 = 0xffffffff;NVIC_ICER1 |= 0x00000007;Interrupt_Enable();
}
#endif
三、main用户函数
main函数根据用户编程,一般执行步骤是初始化各个模块资源,然后进入后台循环任务。
//最简化的main函数,没有任何任务
int main(void)
{while(1){}
}
/************************************************************************************************
*
* Description:
*
* Arguments :
* Returns : ************************************************************************************************/
int main(void)
{ErrType err;INT8U receive_buf[128],para_buf[128];u_BusPacket pkt;TKIT_MSG Msg;//TKIT init#ifdef __APP_CODE__SystemVectorRemap(0x00030000);TKIT_Init( TKITMODE_APP );#else //BOOT codeSystemVectorRemap(0x00000000);TKIT_Init( TKITMODE_BOOT );#endif //__APP_CODE__//检查文件系统以及升级文件#if TKIT_FATFS_EN && KIT_SDCARD_ENwhile( SD_Exist ){//建立系统文件夹err = t_FatSysCheck(FAT_ROOT);if( TKIT_SUCCESS==err )err = t_fat_PathCheck(FAT_ROOT_PATH, TRUE);if( TKIT_SUCCESS==err )err = t_fat_PathCheck(FAT_PATH_DEVICE, TRUE);if( TKIT_SUCCESS==err )err = t_fat_PathCheck(FAT_PATH_SYS, TRUE);//检测升级文件if( TRUE==b_FileFirmwareCheck(FAT_PATH_SYS,"AM-AM",FALSE,FALSE) ){Printf("\t<FirmwareCheck>Find available app code in disk[%s]\r\n",FAT_PATH_SYS);#ifndef __APP_CODE__b_FileFirmwareCheck(FAT_PATH_SYS,"AM-AM10",TRUE,TRUE);#endif}else{Printf("\t<FirmwareCheck>Can't find available app code in disk[%s]\r\n",FAT_PATH_SYS);}break;}#endif //TKIT_FATFS_EN//Bootloader检测是否需要跳转#ifndef __APP_CODE__Printf("\t<main>Bootloader check app code and jump...\r\n");pkt.Alt.Port = BUS_PORT_ALL;TKIT_ErrUpdate( t_TKIT_AppCheck( TKIT_DLY_3S, &pkt ) );#endif //__APP_CODE__//启动所有前台任务Printf("\t<main>TKIT task init and start.\r\n");TKIT_TaskStart();Task_Init();//创建一个任务,每隔1S执行一次TKIT_TaskCreateTimer("Task isr",Task_Isr, NULL, TKIT_DLY_1S );//创建一个消息,系统每隔1S自动触发Msg = TKIT_MsgCreate( NULL,TKIT_DLY_1S);while( 1 ){Task();//LEDif( TKIT_MsgPend(Msg,NULL,0) ){TKIT_IO_SetBurstCnt(IO_LED_CORE,1);//Pend message success}//If terminal enableif( Terminal_EnableCheck() ){if( ReadsExt(receive_buf,para_buf) ){Terminal_Handler(receive_buf,para_buf);}}//选择通信接口//接收一个帧pkt.Alt.Port = BUS_PORT_USB | BUS_PORT_AT | BUS_PORT_TCP;if( FALSE==Terminal_EnableCheck() ){pkt.Alt.Port |= BUS_PORT_UART;}if( i_ProBus_ReadPkt(&pkt,TKIT_DLY_10MS) ){//Printf("\t<main>Received command:%04X, Data len=%d\r\n",pkt.Alt.Cmd.u16,pkt.Alt.DataSize.u32 );t_ProBus_CmdHandler( &pkt );//Printf("\t<main>Received command handler finished. Return len:%d\r\n\r\n",pkt.Alt.DataSize.u32 );TKIT_IO_SetBurstCnt(IO_LED_CORE,1);}else if( BUS_PORT_UART&pkt.Alt.Port && i_ProBus_ReadPktBuffer() ){if( 0==std_StringCmpExtLen("admin%ADMIN",(char*)pkt.byte,5 ) ){Terminal_Enable(TRUE);PrintWelcome();}}#if DHCP_ENdo_dhcp(); //DHCP测试程序#endifEND FOR /}//end while
}
四、启动流程串口演示
(演示了代码启动,然后用户程序执行了手动跳转)
ARM固件开发(LPC1768启动初始化代码)相关推荐
- 【嵌入式开发】ARM 代码搬移 ( ARM 启动流程 | 代码搬移 起点 终点 | 链接地址 | 汇编代码 )
文章目录 一. ARM 启动流程 1. 各种类型开发板启动流程 ( 1 ) 2440 开发板启动流程简介 ( ① Nand Flash 拷贝 4 KB -> SRAM 垫脚石 | ② PC 指向 ...
- 【鸿蒙OS开发入门】06 - 启动流程代码分析之KernelOS:之启动Linux-4.19 Kernel内核 启动init进程
[鸿蒙OS开发入门]06 - 启动流程代码分析之KernelOS:之启动Linux-4.19 Kernel内核 一.head.S 启动start_kernel() 1.1 start_kernel() ...
- 织女星开发板能移植linux吗,织女星开发板启动模式修改——从ARM M4核启动
前言 刚开始玩织女星开发板的时候,想先从熟悉的ARM核入手,连上Jlink,打开MDK版本的Demo程序,编译OK,却检测不到芯片,仔细看了一下文档,原来RV32M1芯片默认从RISC-V核启动,如果 ...
- mssql 无法启动调试器 数据为空_织女星开发板启动模式修改——从ARM M4核启动
织女星开发板启动模式修改--从ARM M4核启动 前言 刚开始玩织女星开发板的时候,想先从熟悉的ARM核入手,连上Jlink,打开MDK版本的Demo程序,编译OK,却检测不到芯片,仔细看了一下文档, ...
- ARM Uboot经历——Uboot初始化代码解析
Uboot初始化代码主要是在Uboot重定位之前的一系列处理,起源于start.s文件,涉及crt0.s和board.c等文件,会完成最系统环境最初始的设置和结构体赋值. reset的相关处理 从_s ...
- 【鸿蒙OS开发入门】13 - 启动流程代码分析之第一个用户态进程:init 进程 之 init 任务详解
[鸿蒙OS开发入门]13 - 启动流程代码分析之第一个用户态进程:init 进程 之 init 任务详解 一. /etc/init.cfg 系统默认cfg:启动lo回环网卡 1.1 init.Hi35 ...
- Internal error: Oops: 37 [#1] PREEMPT SMP ARM。处理方法果然touchscreens被编译了,但是我的触摸屏没有接,取消此编译选项,重新编译,开发成功启动
linux kernel version: 4.4.38 hardware : exynos4412-tiny4412 起因:我向调试开发板上的网络设备驱动,需要更新kernel,更新后发现开发板无法 ...
- STM32启动文件代码解析
目录 启动流程 代码详解 启动文件使用的 ARM 汇编指令汇总 关于与启动文件有关的一些问题思考 下面是F1固件库V3.5.0的启动文件startup_stm32f10x_hd.s,以此为例做解析,其 ...
- USB设备开发---- USB固件开发
上篇介绍了基于libusb的无驱动设计,上位机没问题了,现在还留下个下位机的问题,该项目中USB下位机采用的Cypress的CY7C68013A控制芯片, 下面来仔细看如何编写下位机的固件程序(fir ...
最新文章
- totiseGit无法登录的问题
- 湖北宜昌:老太不慎落入江中 小伙奋勇救人
- 用bochs调试自己写的系统引导代码
- stdarg.h的库函数用法小结
- 查看 SELinux状态及关闭SELinu
- [数组] 连续子数组的最大和 --- LeetCode53
- 将Teams Template升级到dotnet core 3.1
- SVN更新数据和提交数据的几个疑问
- Dubbo项目简单实践
- python怎么安装pip
- 27.白纸黑点与黑纸白点
- 为什么不能完全相信自动驾驶?
- python 通过逗号分割字符串_「Python 秘籍」使用多个界定符分割字符串
- split函数 在oracle,oracle的split函数
- 扩展Windows 7内存 巧用ReadyBoost提速
- Jpress的基本使用
- 中国保险业过去五年基础数据分析
- 我不爱的那个女人[转]
- 不用重做系统,教你如何把机械硬盘上面的系统迁移到固态硬盘!
- python检索用人名查电话_ldap3 python搜索组成员并检索其sAMAcountName(Active Directory)...
热门文章
- [oeasy]python0125_汉字打印机_点阵式打字机_汉字字形码
- 还想贪小便宜?建议你先了解一下物联卡收费标准!
- 前端可视化——Canvas
- python eel 无边框_荐帮你解剖Python的一个轻量级桌面GUI开发第三方库:Eel,让它体无完肤...
- 第四届橙瓜网络文学奖《元尊》的排行竟然比《剑来》低?
- revit2018注册表删除_Revit卸载专用软件推荐及卸载方法
- 神经网络模型(TensorFlow)
- 分享几个关于geoJson的网站(乡镇级地图绘制)
- win10 激活工具 Re-LoaderByR@1n.exe
- 在苹果做了十年公关,我总结了这五条建议