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启动初始化代码)相关推荐

  1. 【嵌入式开发】ARM 代码搬移 ( ARM 启动流程 | 代码搬移 起点 终点 | 链接地址 | 汇编代码 )

    文章目录 一. ARM 启动流程 1. 各种类型开发板启动流程 ( 1 ) 2440 开发板启动流程简介 ( ① Nand Flash 拷贝 4 KB -> SRAM 垫脚石 | ② PC 指向 ...

  2. 【鸿蒙OS开发入门】06 - 启动流程代码分析之KernelOS:之启动Linux-4.19 Kernel内核 启动init进程

    [鸿蒙OS开发入门]06 - 启动流程代码分析之KernelOS:之启动Linux-4.19 Kernel内核 一.head.S 启动start_kernel() 1.1 start_kernel() ...

  3. 织女星开发板能移植linux吗,织女星开发板启动模式修改——从ARM M4核启动

    前言 刚开始玩织女星开发板的时候,想先从熟悉的ARM核入手,连上Jlink,打开MDK版本的Demo程序,编译OK,却检测不到芯片,仔细看了一下文档,原来RV32M1芯片默认从RISC-V核启动,如果 ...

  4. mssql 无法启动调试器 数据为空_织女星开发板启动模式修改——从ARM M4核启动

    织女星开发板启动模式修改--从ARM M4核启动 前言 刚开始玩织女星开发板的时候,想先从熟悉的ARM核入手,连上Jlink,打开MDK版本的Demo程序,编译OK,却检测不到芯片,仔细看了一下文档, ...

  5. ARM Uboot经历——Uboot初始化代码解析

    Uboot初始化代码主要是在Uboot重定位之前的一系列处理,起源于start.s文件,涉及crt0.s和board.c等文件,会完成最系统环境最初始的设置和结构体赋值. reset的相关处理 从_s ...

  6. 【鸿蒙OS开发入门】13 - 启动流程代码分析之第一个用户态进程:init 进程 之 init 任务详解

    [鸿蒙OS开发入门]13 - 启动流程代码分析之第一个用户态进程:init 进程 之 init 任务详解 一. /etc/init.cfg 系统默认cfg:启动lo回环网卡 1.1 init.Hi35 ...

  7. Internal error: Oops: 37 [#1] PREEMPT SMP ARM。处理方法果然touchscreens被编译了,但是我的触摸屏没有接,取消此编译选项,重新编译,开发成功启动

    linux kernel version: 4.4.38 hardware : exynos4412-tiny4412 起因:我向调试开发板上的网络设备驱动,需要更新kernel,更新后发现开发板无法 ...

  8. STM32启动文件代码解析

    目录 启动流程 代码详解 启动文件使用的 ARM 汇编指令汇总 关于与启动文件有关的一些问题思考 下面是F1固件库V3.5.0的启动文件startup_stm32f10x_hd.s,以此为例做解析,其 ...

  9. USB设备开发---- USB固件开发

    上篇介绍了基于libusb的无驱动设计,上位机没问题了,现在还留下个下位机的问题,该项目中USB下位机采用的Cypress的CY7C68013A控制芯片, 下面来仔细看如何编写下位机的固件程序(fir ...

最新文章

  1. totiseGit无法登录的问题
  2. 湖北宜昌:老太不慎落入江中 小伙奋勇救人
  3. 用bochs调试自己写的系统引导代码
  4. stdarg.h的库函数用法小结
  5. 查看 SELinux状态及关闭SELinu
  6. [数组] 连续子数组的最大和 --- LeetCode53
  7. 将Teams Template升级到dotnet core 3.1
  8. SVN更新数据和提交数据的几个疑问
  9. Dubbo项目简单实践
  10. python怎么安装pip
  11. 27.白纸黑点与黑纸白点
  12. 为什么不能完全相信自动驾驶?
  13. python 通过逗号分割字符串_「Python 秘籍」使用多个界定符分割字符串
  14. split函数 在oracle,oracle的split函数
  15. 扩展Windows 7内存 巧用ReadyBoost提速
  16. Jpress的基本使用
  17. 中国保险业过去五年基础数据分析
  18. 我不爱的那个女人[转]
  19. 不用重做系统,教你如何把机械硬盘上面的系统迁移到固态硬盘!
  20. python检索用人名查电话_ldap3 python搜索组成员并检索其sAMAcountName(Active Directory)...

热门文章

  1. [oeasy]python0125_汉字打印机_点阵式打字机_汉字字形码
  2. 还想贪小便宜?建议你先了解一下物联卡收费标准!
  3. 前端可视化——Canvas
  4. python eel 无边框_荐帮你解剖Python的一个轻量级桌面GUI开发第三方库:Eel,让它体无完肤...
  5. 第四届橙瓜网络文学奖《元尊》的排行竟然比《剑来》低?
  6. revit2018注册表删除_Revit卸载专用软件推荐及卸载方法
  7. 神经网络模型(TensorFlow)
  8. 分享几个关于geoJson的网站(乡镇级地图绘制)
  9. win10 激活工具 Re-LoaderByR@1n.exe
  10. 在苹果做了十年公关,我总结了这五条建议