SylixOS CAN总线初始化流程解析

  1. 概述

    本文档是在AT91SAM9X25平台上进行SylixOS CAN总线驱动开发时,对CAN总线初始化流程的分析。

    适用于正在学习CAN总线开发的技术工程师。

  2. 技术实现

    CAN总线的初始化流程可以分成两个部分:

    一部分是CAN总线通道资源初始化,主要工作是对通道相关的管脚和中断以及总线编程时需要的时钟等资源的初始化;另一部分是CAN总线的硬件初始化,主要工作是对总线的波特率的设置、接收和发送数据邮箱(相当于缓存区)的初始化以及接收中断和错误中断的使能。

  3. CAN总线通道资源初始化

    在AT91SAM9X25平台上,CAN总线通道资源初始化如图 21所示。CAN总线的TX管脚、RX管脚和时钟的使能以及中断服务函数的绑定是CAN总线在初始化时必须做的工作。CAN总线的通信需要绑定CAN总线上层回调函数,这些上层回调函数由开发者实现,用做应用层和底层的通信。时钟的获取是总线工作需要用到的数据,我们在总线初始化时先将其获取存在全局结构体变量中。

    图 21 CAN总线通道资源初始化流程图

    具体的代码实现如程序清单 21所示。

    程序清单 21 CAN总线通道资源初始化

    /*********************************************************************************************************
    ** 函数名称: __canChanDataInit
    ** 功能描述: 初始化通道数据(资源)相关
    ** 输  入  : uiChannel :通道号
    ** 输  出  : ERROR_CODE
    ** 全局变量:
    ** 调用模块:
    *********************************************************************************************************/
    static INT __canChanDataInit (UINT  uiChannel)
    {
        __PCAN_CHANNEL    pChannel;
        ULONG             ulVector;
        UINT              uiInputClock;
        INT               iRet;
    
        static CPCHAR  pcCanIsrName[] = {"can_isr0", "can_isr1"};           /*  const char类型的can中断名称 */
    
        if (uiChannel >= CAN_CHAN_NUMS) {
            printk("channel invalid.\n");
            return  PX_ERROR;
        }
    
        pChannel   = &__GCanChannels[uiChannel];                            /*  定义一个全局通道类型结构体  */
    
        __canIomuxConfig(uiChannel);                                        /*  管脚复用                    */
        uiInputClock = __at91sam9X25SysClkGet(MCK);                         /*  获取系统时钟                */
    
        pChannel->CANCH_uiInputClock      = uiInputClock;
        pChannel->CANCH_canchan.pDrvFuncs = &__GCanDrvFuncs;                /*  绑定CAN 总线上层回调函数    */
        pChannel->CANCH_uiMb0Id           = 0x7FF;
        API_AtomicSet(0, &pChannel->CANCH_atomicRef);                       /*  原子赋值操作                */
    
        ulVector = pChannel->CANCH_ulVector;                                /*  中断号                      */
        iRet     = (INT)API_InterVectorConnect(ulVector,                    /*  绑定中断服务函数            */
                                               (PINT_SVR_ROUTINE)__canIrq,
                                               (PVOID)pChannel,
                                                pcCanIsrName[uiChannel]);
        if (iRet != ERROR_NONE) {
            printk("interrupt vector connect error.\n");
            return PX_ERROR;
        }
    
        API_InterVectorEnable(pChannel->CANCH_ulVector);                    /*  使能对应中断                */
    
        return ERROR_NONE;
    }
  4. CAN总线硬件初始化

    在AT91SAM9X25平台上,CAN总线硬件初始化如图 22所示。中断使能和波特率设置是每个CAN总线都需要做的工作。CAN总线波特率是根据具体使用情况和芯片的硬件特性决定的,需要配置相关寄存器来实现。消息邮箱是AT91SAM9X25平台特有的用来接收和发送消息的一组寄存器,相当于发送和接收缓存区。这些邮箱可以根据开发者的需求来配置成接收或者发送模式。

    图 22 CAN总线硬件初始化流程图

    具体代码实现如程序清单 22所示。

    程序清单 22 CAN总线硬件初始化

    /*********************************************************************************************************
    ** 函数名称: __canChanHwInit
    ** 功能描述: 硬件初始化
    ** 输  入  : pChannel :通道对象
    ** 输  出  : ERROR_CODE
    ** 全局变量:
    ** 调用模块:
    *********************************************************************************************************/
    static INT __canChanHwInit (__PCAN_CHANNEL  pChannel)
    {
        UINT  uiRegIer;
    
        writel(AT91_IRQ_ALL, REG_CAN_IDR(CHANNEL));                         /*  禁用所有中断                */
        writel(readl(REG_CAN_MR(CHANNEL)) & ~AT91_MR_CANEN,                 /*  CAN 总线失能                */
               REG_CAN_MR(CHANNEL));
        __canSetBaudRate(pChannel, CAN_MAX_BAUDRATE);                       /*  设置CAN波特率               */
        __canSetMailboxes(pChannel);                                        /*  配置消息邮箱                */
    
        writel(AT91_MR_CANEN, REG_CAN_MR(CHANNEL));                         /*  CAN 总线使能                */
    
        uiRegIer = (AT91_MB_MASK(TX_FIRST) & (~AT91_MB_MASK(TX_FIRST)))     /*  0-5邮箱中断位               */
                    | AT91_IRQ_ERRP                                         /*  被动错误中断使能            */
                    | AT91_IRQ_ERR_FRAME;                                   /*  帧错误中断使能              */
        writel(AT91_IRQ_ALL, REG_CAN_IDR(CHANNEL));                         /*  禁用所有中断                */
    
        writel(uiRegIer, REG_CAN_IER(CHANNEL));                             /*  使能错误中断和0-5邮箱中断   */
    
        return  ERROR_NONE;
    }
  5. 免责声明

    内部交流文档,仅针对AT91SAM9X25相关平台,若发现相关错误或者建议,请及时联系文档创建者进行修订和更新。

时间: 2024-11-08 17:25:22

SylixOS CAN总线初始化流程解析的相关文章

SylixOS 基于AT91SAM9X25的CAN总线传输流程解析

概述 本文档是在AT91SAM9X25平台上进行SylixOS CAN总线驱动开发时,对CAN总线底层传输流程的解析. 适用于正在学习CAN总线驱动的技术工程师. 技术实现 CAN总线的传输流程可以分成两个部分: 一部分是CAN总线的发送流程,主要工作是将准备发送的数据填充到对应的寄存器,并使能开始传输位和邮箱中断位:另一部分是CAN总线的中断处理流程,主要工作是对触发中断的中断源进行判断,并对不同的中断进行相关处理. CAN总线的发送流程 在AT91SAM9X25平台上,CAN总线发送流程如图

SylixOS BSP tick驱动流程

SylixOS BSP tick驱动流程 1. 开发环境 - 操作系统:SylixOS - 编程环境:RealEvo-IDE3.1 - 硬件平台:IMX6Q实验箱 2.技术实现 时钟节拍(clock tick)是特定的周期性中断.这个中断可以看做是系统心脏的脉动.时钟的节拍式中断使得内核可以将任务延时若干个整数时钟节拍,同时当任务等待事件发生时,提供等待超时的依据. 2.1 Tick的频率设置 Tick的频率需要根据具体的硬件性能来设置.频率越快,系统的额外开销也会越大.SylixOS中频率通

libev 默认事件循环初始化的解析

libev第一次进入的是默认的事件循环,这里将源码中执行的默认循环流程解析一下,要进入事件循环,如下例子 int main (void) { // use the default event loop unless you have special needs struct ev_loop *loop = EV_DEFAULT; // initialise an io watcher, then start it // this one will watch for stdin to becom

MediaPlayer本地播放流程解析(二)

上一篇MediaPlayer本地播放流程解析(一)讲了MediaPlayer的setDataSource流程,本篇将接着讲MediaPlayer的prepare流程. Prepare前面的流程一直到AwesomePlayer,和setDataSource都基本上一样,这里直接略掉.下面将从AwesomePlayer开始. status_t AwesomePlayer::prepare() { ATRACE_CALL(); Mutex::Autolock autoLock(mLock); retu

SylixOS SylixOS CAN总线驱动之三

SylixOS CAN报文传送流程 CAN报文传送流程框图 在SylixOS中CAN报文的传输框图如图 11所示. 图 11 SylixOS CAN报文传输框图 (注:此文档承接之前的文档编写,之前文档中详细介绍过的报文,传输结构体在此文档中不做详细介绍.) SylixOS CAN报文缓存机制 在SylixOS中CAN报文的传输不是底层和上层应用的直接传输.而是在底层和应用层中间加了一层系统缓存队列.所有收发的CAN报文都要先经过一个系统缓存机制传输到真正调用到它的地方. 系统CAN发送报文缓存

【开源】OSharp3.3框架解说系列(7.1):初始化流程概述

本文已同步到系列目录:OSharp快速开发框架解说系列 框架初始化 相对于OSharp 3.0,3.3版本最大的更新,就是从框架级别定义了初始化流程,对初始化功能进行了抽象与封装,不依赖于第三方实现,第三方实现仅作为可替换的服务实现方案存在. 例如,依赖注入功能中,接口与其实现类的映射配置,对象容器的构建,对象的解析获取,都将通过框架定义的API来完成,而Autofac,仅作为这些功能的实现方存在,如果不想使用Autofac,则可以很方便的切换成别的IoC组件. 具体的初始化功能是怎样抽象与定义

深入浅出高性能服务发现、配置框架Nacos系列 3: 服务发现:Nacos客户端初始化流程

上一章节,我们从全局了解了一下Nacos项目的模块架构,做到了心中有数,现在,我们去逐步去挖掘里面的代码细节,很多人在学习开源的时候,无从下手,代码那么多,从哪个地方开始看呢?我们可以从一个接口开始入手,这个接口是你使用过的,知道它大概做什么事,有体感的,大家还记得第一章时,我们写的HelloWorld吗,对,就从里面的接口开始剥洋葱. 这个是Nacos的github代码地址,开始之前先start关注一下,加上watch,后续Nacos的邮件列表也会通知到你,可以关注到Nacos的最新实时消息,

Shiro权限管理框架(三):Shiro中权限过滤器的初始化流程和实现原理

本篇是Shiro系列第三篇,Shiro中的过滤器初始化流程和实现原理.Shiro基于URL的权限控制是通过Filter实现的,本篇从我们注入的ShiroFilterFactoryBean开始入手,翻看源码追寻Shiro中的过滤器的实现原理. 初始化流程 ShiroFilterFactoryBean实现了FactoryBean接口,那么Spring在初始化的时候必然会调用ShiroFilterFactoryBean的getObject()获取实例,而ShiroFilterFactoryBean也在

EurekaClient自动装配及启动流程解析

在上篇文章中,我们简单介绍了EurekaServer自动装配及启动流程解析,本篇文章则继续研究EurekaClient的相关代码 老规矩,先看spring.factories文件,其中引入了一个配置类EurekaDiscoveryClientConfigServiceBootstrapConfiguration @ConditionalOnClass(ConfigServicePropertySourceLocator.class) @ConditionalOnProperty(value =