NXP i.MX RT106x系列官方SDK库之Enet时钟BUG

        最近,在调试RT1064芯片的双以太网时,发现每次在初始化第二个以太网时,程序直接跑飞了。通过仿真器进行DBUG发现,程序卡在初始化第二路以太网的时钟地方,于是进一步查看寄存器值,发现头文件的宏定义有问题。

        首先,我们来看下NXP 的SDK源码:

        这是一个基本的可重入初始化函数,ENET1和ENET2均使用此函数来配置。关键问题出现在如下的  uint32_t instance = ENET_GetInstance(base);和(void)CLOCK_EnableClock(s_enetClock[instance]);这两句上面。

status_t ENET_Init(ENET_Type *base,
                   enet_handle_t *handle,
                   const enet_config_t *config,
                   const enet_buffer_config_t *bufferConfig,
                   uint8_t *macAddr,
                   uint32_t srcClock_Hz)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
    uint32_t instance = ENET_GetInstance(base);

    /* Ungate ENET clock. */
    (void)CLOCK_EnableClock(s_enetClock[instance]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
    /* Reset ENET module. */
    ENET_Reset(base);

    return ENET_Up(base, handle, config, bufferConfig, macAddr, srcClock_Hz);
}

我们来剖析下ENET_GetInstance函数,通过for循环计算出instance为1(见ENET_BASE_PTRS),因此初始化ENET2时函数返回1。


#define ENET_BASE_PTRS                           { ENET, ENET2 }

/*! @brief Pointers to enet bases for each instance. */
static ENET_Type *const s_enetBases[] = ENET_BASE_PTRS;


uint32_t ENET_GetInstance(ENET_Type *base)
{
    uint32_t instance;

    /* Find the instance index from base address mappings. */
    for (instance = 0; instance < ARRAY_SIZE(s_enetBases); instance++)
    {
        if (s_enetBases[instance] == base)
        {
            break;
        }
    }

    assert(instance < ARRAY_SIZE(s_enetBases));

    return instance;
}

我们继续看(void)CLOCK_EnableClock(s_enetClock[instance]);函数,当instance等于1时,s_enetClock[instance]为kCLOCK_IpInvalid,继续执行,将错误的值写入控制时钟的寄存器,将产生错误,问题因此出在这儿,下面函数就没必要展开了。我是将kCLOCK_IpInvalid替换成kCLOCK_Enet2,检查这个不会对其他程序造成影响,问题得到解决。

#define ENET_CLOCKS                                 \
    {                                               \
        kCLOCK_Enet, kCLOCK_IpInvalid, kCLOCK_Enet2\
    }

const clock_ip_name_t s_enetClock[] = ENET_CLOCKS;


(void)CLOCK_EnableClock(s_enetClock[instance]);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值