[Silicon EmberZnet] 初始化流程(一)

// *******************************************************************
// * simple-main.c
// *
// * This file provides a definition for main() for non-RTOS applications.
// *
// * Copyright 2014 Silicon Laboratories, Inc.                                 *80*
// *******************************************************************

#include PLATFORM_HEADER
#include "app/framework/include/af.h"

// Our entry point is typically main(), except during testing.
#ifdef EMBER_TEST
  #define MAIN nodeMain
#else
  #define MAIN main
#endif

int MAIN(MAIN_FUNCTION_PARAMETERS)
{
  halInit();
  emberAfMainInit();
  return emberAfMain(MAIN_FUNCTION_ARGUMENTS);
}

 

在插件中会选择是否生产simple-main ,  这个便是入口函数;

主要分三段:

1、硬件初始化

2、主要是串口初始化

3、开始执行Znet

先看第一步硬件初始化:

// halInit is called on first initial boot, not on wakeup from sleep.
//这个函数只有在初始化的时候调用, 而不是唤醒之后调用
void halInit(void)
{
  //When the Cortex-M3 exits reset, interrupts are enable.  Explicitly
  //disable them for the rest of Init.
  //关闭中断
  __disable_irq();

  // Configure BASEPRI to be at the interrupts disabled level so that when we
  // turn interrupts back on nothing fires immediately.
  // 也是关闭中断, 会判断一个是否使用寄存器来关闭, __disable_irq 这个是cm3内核关闭全局中断
  INTERRUPTS_OFF();

  // Bootloader might be at the base of flash, or even in the NULL_BTL case,
  // the BAT/AAT will be at the beginning of the image.
  // Setting the vectorTable is required.
  // 设置矢量表,用STM32 OTA的应用程序段都要做矢量偏移,这个类似
  SCB->VTOR =  (uint32_t)halAppAddressTable.baseTable.vectorTable;

  // Always Configure Interrupt Priorities.  This is necessary for key behavior
  // such as fault Handlers to be serviced at the correct priority levels.
  // 设置NV中断
  #define EXCEPTION(vectorNumber, functionName, deviceIrqn, deviceIrqHandler, priorityLevel, subpriority) \
  NVIC_SetPriority(deviceIrqn, NVIC_EncodePriority(PRIGROUP_POSITION, priorityLevel, subpriority));
    #include NVIC_CONFIG
  #undef  EXCEPTION

  //Now that all the individual priority bits are set, we have to set the
  //distinction between preemptive priority and non-preemptive subpriority
  //This sets the priority grouping binary position.
  //PRIGROUP_POSITION is defined inside of nvic-config.h.
  //设置中断组
  NVIC_SetPriorityGrouping(PRIGROUP_POSITION);

  // Always Configure System Handlers Control and Configuration
  SCB->CCR |= SCB_CCR_STKALIGN_Msk; //

#if defined(SCB_CCR_DIV_0_TRP_Msk)
  SCB->CCR |= SCB_CCR_DIV_0_TRP_Msk;
#endif

#if defined(SCB_SHCSR_USGFAULTENA_Msk)
  SCB->SHCSR = (SCB_SHCSR_USGFAULTENA_Msk
                | SCB_SHCSR_BUSFAULTENA_Msk
                | SCB_SHCSR_MEMFAULTENA_Msk);
#endif

  //使能内存保护单元
  halInternalEnableMPU();

  // Determine and record the reason for the reset.  Because this code uses
  // static variables in RAM, it must be performed after RAM segements are
  // initialized, but the RESETINFO segment is left uninitialized.
  halInternalClassifyReset();

  // Zero out the EMHEAP segment.
  {
    // IAR warns about "integer conversion resulted in truncation" if
    // _EMHEAP_SEGMENT_SIZE is used directly in MEMSET().  This segment
    // should always be smaller than a 16bit size.
    MEMSET(_EMHEAP_SEGMENT_BEGIN, 0, (_EMHEAP_SEGMENT_SIZE & 0xFFFFu));
  }

  // Zero out the APP_RAM segment.
  {
    // IAR warns about "integer conversion resulted in truncation" if
    // _APP_RAM_SEGMENT_SIZE is used directly in MEMSET().  This segment
    // should always be smaller than a 16bit size.
    MEMSET(_APP_RAM_SEGMENT_BEGIN, 0, (_APP_RAM_SEGMENT_SIZE & 0xFFFFu));
  }

  __enable_irq();

  /* Configure board. Select either EBI or SPI mode. */
  CHIP_Init();
#ifdef _EFR_DEVICE
  EMU_UnlatchPinRetention();
#endif
  halConfigInit();
  RTCDRV_Init();
#ifdef _EFR_DEVICE
  #ifndef HAL_CONFIG
  halInternalInitBoard();
  #endif
  TEMPDRV_Init();
  EMU_EM4Init_TypeDef em4Init = EMU_EM4INIT_DEFAULT;
  em4Init.em4State = emuEM4Hibernate;
  EMU_EM4Init(&em4Init);
  halInternalEm4Wakeup();
#elif defined(_EZR_DEVICE)
  halInternalStartSymbolTimer();      // TODO: move to macInit or emRadioInit
#endif
  //初始化系统时钟
  halInternalStartSystemTimer();

#if     (PHY_RAIL || PHY_DUALRAIL)
  RAIL_TxPowerCurvesConfig_t txPowerCurvesConfig = { RAIL_Curves24Hp, RAIL_CurvesSg, RAIL_Curves24Lp, RAIL_PiecewiseSegments };
  RAIL_InitTxPowerCurves(&txPowerCurvesConfig);
#endif//(PHY_RAIL || PHY_DUALRAIL)
}

总的来说, 第一步主要就是初始化芯片内部的一些配置,比如中断,MPU,时钟等等,这部分建议不要修改。

 

第二步:

void emberAfMainInit(void)
{
  SETUP_FAKE_EEPROM_FOR_SIMULATION();

  INTERRUPTS_ON();  // Safe to enable interrupts at this point

  emberSerialInit(APP_SERIAL, BAUD_RATE, PARITY_NONE, 1);

  emberAfCorePrintln("Reset info: 0x%x (%p)",
                     halGetResetInfo(),
                     halGetResetString());

#if defined(EXTENDED_RESET_INFO)
  emberAfCorePrintln("Extended Reset info: 0x%2X (%p)",
                     halGetExtendedResetInfo(),
                     halGetExtendedResetString());

  if (halResetWasCrash()) {
    halPrintCrashSummary(serialPort);
    halPrintCrashDetails(serialPort);
    halPrintCrashData(serialPort);
  }
#endif
}

这不总的来说,就是初始化串口的,打印一下复位原因。

接下来才是正戏。

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值