CANopenNode drvTemplate/CO_driver.h hacking

/************************************************************************
 *            CANopenNode drvTemplate/CO_driver.h hacking
 * 说明:
 *     使用CANopenNode,drvTemplate/CO_driver.h说明了一些驱动编写相关的
 * 注意事项。
 *
 *                                    2017-3-24 深圳 南山平山村 曾剑锋
 ***********************************************************************/

/**
 * CAN module object for generic microcontroller.
 *
 * This file is a template for other microcontrollers.
 *
 * @file        CO_driver.h
 * @ingroup     CO_driver
 * @author      Janez Paternoster
 * @copyright   2004 - 2015 Janez Paternoster
 *
 * This file is part of CANopenNode, an opensource CANopen Stack.
 * Project home page is <https://github.com/CANopenNode/CANopenNode>.
 * For more information on CANopen see <http://www.can-cia.org/>.
 *
 * CANopenNode is free and open source software: you can redistribute
 * it and/or modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation, either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 * Following clarification and special exception to the GNU General Public
 * License is included to the distribution terms of CANopenNode:
 *
 * Linking this library statically or dynamically with other modules is
 * making a combined work based on this library. Thus, the terms and
 * conditions of the GNU General Public License cover the whole combination.
 *
 * As a special exception, the copyright holders of this library give
 * you permission to link this library with independent modules to
 * produce an executable, regardless of the license terms of these
 * independent modules, and to copy and distribute the resulting
 * executable under terms of your choice, provided that you also meet,
 * for each linked independent module, the terms and conditions of the
 * license of that module. An independent module is a module which is
 * not derived from or based on this library. If you modify this
 * library, you may extend this exception to your version of the
 * library, but you are not obliged to do so. If you do not wish
 * to do so, delete this exception statement from your version.
 */

#ifndef CO_DRIVER_H
#define CO_DRIVER_H

/* Include processor header file */
/**
 * 将这里的头文件替换成与处理器相关的头文件,譬如:
 *   1. STM32:
 *     #include "common.h"
 *     #include "stm32f10x_conf.h"
 *   2. SocketCAN:
 *      #include <stddef.h>         /* for ‘NULL‘ */
 *      #include <stdint.h>         /* for ‘int8_t‘ to ‘uint64_t‘ */
 *      #include <stdbool.h>        /* for ‘true‘, ‘false‘ */
 *      #include <unistd.h>
 *      #include <endian.h>
 *
 *      #ifndef CO_SINGLE_THREAD
 *      #include <pthread.h>
 *      #endif
 *
 *      #include <linux/can.h>
 *      #include <linux/can/raw.h>
 *      #include <linux/can/error.h>
 */
#include <stddef.h>         /* for ‘NULL‘ */
#include <stdint.h>         /* for ‘int8_t‘ to ‘uint64_t‘ */
#include <stdbool.h>        /* for ‘true‘, ‘false‘ */

/**
 * @defgroup CO_driver Driver
 * @ingroup CO_CANopen
 * @{
 *
 * Microcontroller specific code for CANopenNode.
 * 微控制器CANopenNode专用代码
 *
 * This file contains type definitions, functions and macros for:
 * 该文件包含为用于以下目的的类型定义,函数,宏
 *  - Basic data types.
 *    基础数据类型
 *  - Receive and transmit buffers for CANopen messages.
 *    CANopen信息发送和接收缓冲区
 *  - Interaction with CAN module on the microcontroller.
 *    在微控制器上和CAN模块进行交互
 *  - CAN receive and transmit interrupts.
 *    CAN信息接收和发送中断
 *
 * This file is not only a CAN driver. There are no classic CAN queues for CAN
 * messages. This file provides direct connection with other CANopen
 * objects. It tries to provide fast responses and tries to avoid unnecessary
 * calculations and memory consumptions.
 * 这份文件不仅仅是用于CAN驱动,这里没有典型的处理CAN消息的队列,通过直接连接其他的CANopen的对象,
 * 主要是为了提供最快的响应速度来避免不必要的计算和内存消耗
 *
 * CO_CANmodule_t contains an array of _Received message objects_ (of type
 * CO_CANrx_t) and an array of _Transmit message objects_ (of type CO_CANtx_t).
 * Each CANopen communication object owns one member in one of the arrays.
 * For example Heartbeat producer generates one CANopen transmitting object,
 * so it has reserved one member in CO_CANtx_t array.
 * SYNC module may produce sync or consume sync, so it has reserved one member
 * in CO_CANtx_t and one member in CO_CANrx_t array.
 * CO_CANmodule_t两个数组,一个是发送消息对象CO_CANrx_t,一个是接收信息的对象CO_CANtx_t,
 * 每一个CANopen通信对象在数组中拥有一个成员,例如:
 *   1. 心跳包生产者产生一个CANopen传输对象,所以他收到一个成员在CO_CANtx_t数组中。
 *   2. 同步模块可能会产生sync和消费sync,所以他保留了一个成员在CO_CANtx_t中,也
 *     保留一个在CO_CANrx_t中
 *
 * ###Reception of CAN messages.
 * Before CAN messages can be received, each member in CO_CANrx_t must be
 * initialized. CO_CANrxBufferInit() is called by CANopen module, which
 * uses specific member. For example @ref CO_HBconsumer uses multiple members
 * in CO_CANrx_t array. (It monitors multiple heartbeat messages from remote
 * nodes.) It must call CO_CANrxBufferInit() multiple times.
 * 在CAN消息被接收之前,每一个CO_CANrx_t需要先被初始化,CO_CANrxBufferInit被CANopen模块
 * 调用,有些特定的成员被使用,例如CO_HBconsumer使用了CO_CANrx_t多个成员,其监视远程节点
 * 上的多个心跳包,所以被CO_CANrxBufferInit()调用多次。
 *
 * Main arguments to the CO_CANrxBufferInit() function are CAN identifier
 * and a pointer to callback function. Those two arguments (and some others)
 * are copied to the member of the CO_CANrx_t array.
 * CO_CANrxBufferInit()主要参数是:
 *   1. CAN identifier;
 *   2. 回调的函数指针;
 * 这两个参数(也许包括其他的)都会被作为成员拷贝的CO_CANrx_t数组中。
 *
 * Callback function is a function, specified by specific CANopen module
 * (for example by @ref CO_HBconsumer). Each CANopen module defines own
 * callback function. Callback function will process the received CAN message.
 * It will copy the necessary data from CAN message to proper place. It may
 * also trigger additional task, which will further process the received message.
 * Callback function must be fast and must only make the necessary calculations
 * and copying.
 * 回调函数是一个函数,处理特定的CANopen模块相关数据,每一个CANopen模块定义了他们
 * 自己的回调函数,回调函数将处理接收到的CAN信息。他将从CAN信息中拷贝必要的数据到
 * 合适的地方,当然他也可以触发额外的任务,额外的任务会进一步处理接收到的信息。
 * 回调函数必须处理迅速,仅仅做那些必要的数据运算以及拷贝。
 *
 * Received CAN messages are processed by CAN receive interrupt function.
 * After CAN message is received, function first tries to find matching CAN
 * identifier from CO_CANrx_t array. If found, then a corresponding callback
 * function is called.
 * 接收CAN信息是由CAN接收中断函数进行处理的,在接收完数据之后,函数会尝试从CO_CANrx_t
 * 中去查找匹配的CAN identifier,如果被找到,那么正确的回调函数就会被调用。
 *
 * Callback function accepts two parameters:
 * 回调函数接收两个参数
 *  - object is pointer to object registered by CO_CANrxBufferInit().
 *    CO_CANrxBufferInit()中注册的对象指针
 *  - msg  is pointer to CAN message of type CO_CANrxMsg_t.
 *    CO_CANrxMsg_t类型的CAN信息指针
 *
 * Callback function must return #CO_ReturnError_t: CO_ERROR_NO,
 * CO_ERROR_RX_OVERFLOW, CO_ERROR_RX_PDO_OVERFLOW, CO_ERROR_RX_MSG_LENGTH or
 * CO_ERROR_RX_PDO_LENGTH.
 * 回调函数必须是返回如下CO_ReturnError_t类型的数据。
 *
 *
 * ###Transmission of CAN messages.
 * Before CAN messages can be transmitted, each member in CO_CANtx_t must be
 * initialized. CO_CANtxBufferInit() is called by CANopen module, which
 * uses specific member. For example Heartbeat producer must initialize it‘s
 * member in CO_CANtx_t array.
 * 在CAN消息被发送之前,CO_CANtx_t必须先被初始化,CO_CANtxBufferInit()被CANopen模块调用,
 * 会使用指定的成员,例如,心跳包产生者必须在CO_CANtx_t中初始化成员。
 *
 * CO_CANtxBufferInit() returns a pointer of type CO_CANtx_t, which contains buffer
 * where CAN message data can be written. CAN message is send with calling
 * CO_CANsend() function. If at that moment CAN transmit buffer inside
 * microcontroller‘s CAN module is free, message is copied directly to CAN module.
 * Otherwise CO_CANsend() function sets _bufferFull_ flag to true. Message will be
 * then sent by CAN TX interrupt as soon as CAN module is freed. Until message is
 * not copied to CAN module, its contents must not change. There may be multiple
 * _bufferFull_ flags in CO_CANtx_t array set to true. In that case messages with
 * lower index inside array will be sent first.
 * CO_CANtxBufferInit()返回CO_CANtx_t类型的指针,其中包含CAN信息可以被写入的数据缓冲区,
 * CAN信息通过CO_CANsend()函数进行发送,如果微处理器的CAN模块的CAN输出传输缓冲区被释放,
 * CAN信息将直接被拷贝进CAN模块中。
 * 另外CO_CANsend()函数设置_bufferFull_标志位true,消息将会被CAN模块尽快发送,在信息被
 * 拷贝到CAN模块之前,信息是不能被篡改的。因此,在CO_CANtx_t数组中,会有很多的_bufferFull_
 * 标志是true,在这种情况下,小的index会先被发送出去。
 */

/**
 * @name Critical sections
 * CANopenNode is designed to run in different threads, as described in README.
 * Threads are implemented differently in different systems. In microcontrollers
 * threads are interrupts with different priorities, for example.
 * It is necessary to protect sections, where different threads access to the
 * same resource. In simple systems interrupts or scheduler may be temporary
 * disabled between access to the shared resource. Otherwise mutexes or
 * semaphores can be used.
 * 如同在README中描述的,CANopenNode被设计于运行于不同的线程。
 * 线程在不同的系统中,实现的方式也是不同的,在微处理器中线程采用不同的优先级的中断来完成,例如
 * 像多个线程都要访问的部分是需要被保护的,在系统中这部分共享资源在访问的时候要关闭中断和任务调度,
 * 当然想互斥和信号量也是可以使用的。
 *
 * ####Reentrant functions.
 * Functions CO_CANsend() from C_driver.h, CO_errorReport() from CO_Emergency.h
 * and CO_errorReset() from CO_Emergency.h may be called from different threads.
 * Critical sections must be protected. Eather by disabling scheduler or
 * interrupts or by mutexes or semaphores.
 * 函数CO_CANsend()是在C_driver.h中的,CO_errorReport()/CO_errorReset()是在CO_Emergency.h中,
 * 他们都可能被任何线程调用,敏感的部分必须要被保护,需要采用禁止任务切换、中断,或者
 * 采用互斥、信号量来处理。
 *
 * ####Object Dictionary variables.
 * In general, there are two threads, which accesses OD variables: mainline and
 * timer. CANopenNode initialization and SDO server runs in mainline. PDOs runs
 * in faster timer thread. Processing of PDOs must not be interrupted by
 * mainline. Mainline thread must protect sections, which accesses the same OD
 * variables as timer thread. This care must also take the application. Note
 * that not all variables are allowed to be mapped to PDOs, so they may not need
 * to be protected. SDO server protects sections with access to OD variables.
 * 通常情况下,有两个线程会访问对象字典变量:主线程和定时器。CANopenNode初始化和SDO服务
 * 运行于主线程,PDOs运行于快速定时器线程,PDO的处理不能被mainline打断。因为对象字典
 * 能够同时被主线程、定时器访问,所以需要专门被保护,在引用层也是需要注意的。不过需要
 * 注意的是,并不是所有的PDO的对象都允许被映射,可能不需要被保护。
 *
 * ####CAN receive thread.
 * It partially processes received CAN data and puts them into appropriate
 * objects. Objects are later processed. It does not need protection of
 * critical sections. There is one circumstance, where CANrx should be disabled:
 * After presence of SYNC message on CANopen bus, CANrx should be temporary
 * disabled until all receive PDOs are processed. See also CO_SYNC.h file and
 * CO_SYNC_initCallback() function.
 * 专门处理CAN数据,并将其放到合适对象里,这些对象会被稍后处理,这是不需要被特殊处理的部分。
 * 这是一个事件,CANrx应该被关闭,在获取到SYNC的信息的时候,CANrx应该被短暂的关闭直到PDO信息
 * 被处理,请查看CO_SYNC.h文件和CO_SYNC_initCallback()函数
 * @{
 */
    #define CO_LOCK_CAN_SEND()  /**< Lock critical section in CO_CANsend() */
    #define CO_UNLOCK_CAN_SEND()/**< Unlock critical section in CO_CANsend() */

    #define CO_LOCK_EMCY()      /**< Lock critical section in CO_errorReport() or CO_errorReset() */
    #define CO_UNLOCK_EMCY()    /**< Unlock critical section in CO_errorReport() or CO_errorReset() */

    #define CO_LOCK_OD()        /**< Lock critical section when accessing Object Dictionary */
    #define CO_UNLOCK_OD()      /**< Unock critical section when accessing Object Dictionary */
/** @} */

/**
 * @defgroup CO_dataTypes Data types
 * @{
 *
 * According to Misra C
 */
    /* int8_t to uint64_t are defined in stdint.h */
    typedef unsigned char           bool_t;     /**< bool_t */
    typedef float                   float32_t;  /**< float32_t */
    typedef long double             float64_t;  /**< float64_t */
    typedef char                    char_t;     /**< char_t */
    typedef unsigned char           oChar_t;    /**< oChar_t */
    typedef unsigned char           domain_t;   /**< domain_t */
/** @} */

/**
 * Return values of some CANopen functions. If function was executed
 * successfully it returns 0 otherwise it returns <0.
 */
typedef enum{
    CO_ERROR_NO                 = 0,    /**< Operation completed successfully */
    CO_ERROR_ILLEGAL_ARGUMENT   = -1,   /**< Error in function arguments */
    CO_ERROR_OUT_OF_MEMORY      = -2,   /**< Memory allocation failed */
    CO_ERROR_TIMEOUT            = -3,   /**< Function timeout */
    CO_ERROR_ILLEGAL_BAUDRATE   = -4,   /**< Illegal baudrate passed to function CO_CANmodule_init() */
    CO_ERROR_RX_OVERFLOW        = -5,   /**< Previous message was not processed yet */
    CO_ERROR_RX_PDO_OVERFLOW    = -6,   /**< previous PDO was not processed yet */
    CO_ERROR_RX_MSG_LENGTH      = -7,   /**< Wrong receive message length */
    CO_ERROR_RX_PDO_LENGTH      = -8,   /**< Wrong receive PDO length */
    CO_ERROR_TX_OVERFLOW        = -9,   /**< Previous message is still waiting, buffer full */
    CO_ERROR_TX_PDO_WINDOW      = -10,  /**< Synchronous TPDO is outside window */
    CO_ERROR_TX_UNCONFIGURED    = -11,  /**< Transmit buffer was not confugured properly */
    CO_ERROR_PARAMETERS         = -12,  /**< Error in function function parameters */
    CO_ERROR_DATA_CORRUPT       = -13,  /**< Stored data are corrupt */
    CO_ERROR_CRC                = -14   /**< CRC does not match */
}CO_ReturnError_t;

/**
 * CAN receive message structure as aligned in CAN module. It is different in
 * different microcontrollers. It usually contains other variables.
 */
typedef struct{
    /** CAN identifier. It must be read through CO_CANrxMsg_readIdent() function. */
    uint32_t            ident;
    uint8_t             DLC ;           /**< Length of CAN message */
    uint8_t             data[8];        /**< 8 data bytes */
}CO_CANrxMsg_t;

/**
 * Received message object
 */
typedef struct{
    uint16_t            ident;          /**< Standard CAN Identifier (bits 0..10) + RTR (bit 11) */
    uint16_t            mask;           /**< Standard Identifier mask with same alignment as ident */
    void               *object;         /**< From CO_CANrxBufferInit() */
    void              (*pFunct)(void *object, const CO_CANrxMsg_t *message);  /**< From CO_CANrxBufferInit() */
}CO_CANrx_t;

/**
 * Transmit message object.
 */
typedef struct{
    uint32_t            ident;          /**< CAN identifier as aligned in CAN module */
    uint8_t             DLC ;           /**< Length of CAN message. (DLC may also be part of ident) */
    uint8_t             data[8];        /**< 8 data bytes */
    volatile bool_t     bufferFull;     /**< True if previous message is still in buffer */
    /** Synchronous PDO messages has this flag set. It prevents them to be sent outside the synchronous window */
    volatile bool_t     syncFlag;
}CO_CANtx_t;

/**
 * CAN module object. It may be different in different microcontrollers.
 */
typedef struct{
    int32_t             CANbaseAddress; /**< From CO_CANmodule_init() */
    CO_CANrx_t         *rxArray;        /**< From CO_CANmodule_init() */
    uint16_t            rxSize;         /**< From CO_CANmodule_init() */
    CO_CANtx_t         *txArray;        /**< From CO_CANmodule_init() */
    uint16_t            txSize;         /**< From CO_CANmodule_init() */
    volatile bool_t     CANnormal;      /**< CAN module is in normal mode */
    /** Value different than zero indicates, that CAN module hardware filters
      * are used for CAN reception. If there is not enough hardware filters,
      * they won‘t be used. In this case will be *all* received CAN messages
      * processed by software. */
    volatile bool_t     useCANrxFilters;
    /** If flag is true, then message in transmitt buffer is synchronous PDO
      * message, which will be aborted, if CO_clearPendingSyncPDOs() function
      * will be called by application. This may be necessary if Synchronous
      * window time was expired. */
    volatile bool_t     bufferInhibitFlag;
    /** Equal to 1, when the first transmitted message (bootup message) is in CAN TX buffers */
    volatile bool_t     firstCANtxMessage;
    /** Number of messages in transmit buffer, which are waiting to be copied to the CAN module */
    volatile uint16_t   CANtxCount;
    uint32_t            errOld;         /**< Previous state of CAN errors */
    void               *em;             /**< Emergency object */
}CO_CANmodule_t;

/**
 * Endianes.
 * 大小端的问题
 *
 * Depending on processor or compiler architecture, one of the two macros must
 * be defined: CO_LITTLE_ENDIAN or CO_BIG_ENDIAN. CANopen itself is little endian.
 * 依赖于处理和编译器架构,这两个宏其中之一要被定义,cANopen本身是小端的。
 */
#define CO_LITTLE_ENDIAN

/**
 * Request CAN configuration (stopped) mode and *wait* untill it is set.
 * 请求CAN配置参数(停止)模式并直到被设置
 *
 * @param CANbaseAddress CAN module base address.
 */
void CO_CANsetConfigurationMode(int32_t CANbaseAddress);

/**
 * Request CAN normal (opearational) mode and *wait* untill it is set.
 * 请求cAN普通(操作)模式并直到被设置
 *
 * @param CANmodule This object.
 */
void CO_CANsetNormalMode(CO_CANmodule_t *CANmodule);

/**
 * Initialize CAN module object.
 * 初始化CAN模块对象
 *
 * Function must be called in the communication reset section. CAN module must
 * be in Configuration Mode before.
 *
 * @param CANmodule This object will be initialized.
 * @param CANbaseAddress CAN module base address.
 * @param rxArray Array for handling received CAN messages
 * @param rxSize Size of the above array. Must be equal to number of receiving CAN objects.
 * @param txArray Array for handling transmitting CAN messages
 * @param txSize Size of the above array. Must be equal to number of transmitting CAN objects.
 * @param CANbitRate Valid values are (in kbps): 10, 20, 50, 125, 250, 500, 800, 1000.
 * If value is illegal, bitrate defaults to 125.
 *
 * Return #CO_ReturnError_t: CO_ERROR_NO or CO_ERROR_ILLEGAL_ARGUMENT.
 */
CO_ReturnError_t CO_CANmodule_init(
        CO_CANmodule_t         *CANmodule,
        int32_t                 CANbaseAddress,
        CO_CANrx_t              rxArray[],
        uint16_t                rxSize,
        CO_CANtx_t              txArray[],
        uint16_t                txSize,
        uint16_t                CANbitRate);

/**
 * Switch off CANmodule. Call at program exit.
 * 关闭CAN模块,程序的最后需要被调用
 *
 * @param CANmodule CAN module object.
 */
void CO_CANmodule_disable(CO_CANmodule_t *CANmodule);

/**
 * Read CAN identifier from received message
 * 获取CAN identifier从接受到的信息中
 *
 * @param rxMsg Pointer to received message
 * @return 11-bit CAN standard identifier.
 */
uint16_t CO_CANrxMsg_readIdent(const CO_CANrxMsg_t *rxMsg);

/**
 * Configure CAN message receive buffer.
 * 配置CAN信息接收缓冲区
 *
 * Function configures specific CAN receive buffer. It sets CAN identifier
 * and connects buffer with specific object. Function must be called for each
 * member in _rxArray_ from CO_CANmodule_t.
 *
 * @param CANmodule This object.
 * @param index Index of the specific buffer in _rxArray_.
 * @param ident 11-bit standard CAN Identifier.
 * @param mask 11-bit mask for identifier. Most usually set to 0x7FF.
 * Received message (rcvMsg) will be accepted if the following
 * condition is true: (((rcvMsgId ^ ident) & mask) == 0).
 * @param rtr If true, ‘Remote Transmit Request‘ messages will be accepted.
 * @param object CANopen object, to which buffer is connected. It will be used as
 * an argument to pFunct. Its type is (void), pFunct will change its
 * type back to the correct object type.
 * @param pFunct Pointer to function, which will be called, if received CAN
 * message matches the identifier. It must be fast function.
 *
 * Return #CO_ReturnError_t: CO_ERROR_NO CO_ERROR_ILLEGAL_ARGUMENT or
 * CO_ERROR_OUT_OF_MEMORY (not enough masks for configuration).
 */
CO_ReturnError_t CO_CANrxBufferInit(
        CO_CANmodule_t         *CANmodule,
        uint16_t                index,
        uint16_t                ident,
        uint16_t                mask,
        bool_t                  rtr,
        void                   *object,
        void                  (*pFunct)(void *object, const CO_CANrxMsg_t *message));

/**
 * Configure CAN message transmit buffer.
 * 配置CAN信息发送缓冲区
 *
 * Function configures specific CAN transmit buffer. Function must be called for
 * each member in _txArray_ from CO_CANmodule_t.
 *
 * @param CANmodule This object.
 * @param index Index of the specific buffer in _txArray_.
 * @param ident 11-bit standard CAN Identifier.
 * @param rtr If true, ‘Remote Transmit Request‘ messages will be transmitted.
 * @param noOfBytes Length of CAN message in bytes (0 to 8 bytes).
 * @param syncFlag This flag bit is used for synchronous TPDO messages. If it is set,
 * message will not be sent, if curent time is outside synchronous window.
 *
 * @return Pointer to CAN transmit message buffer. 8 bytes data array inside
 * buffer should be written, before CO_CANsend() function is called.
 * Zero is returned in case of wrong arguments.
 */
CO_CANtx_t *CO_CANtxBufferInit(
        CO_CANmodule_t         *CANmodule,
        uint16_t                index,
        uint16_t                ident,
        bool_t                  rtr,
        uint8_t                 noOfBytes,
        bool_t                  syncFlag);

/**
 * Send CAN message.
 * 发送信息函数
 *
 * @param CANmodule This object.
 * @param buffer Pointer to transmit buffer, returned by CO_CANtxBufferInit().
 * Data bytes must be written in buffer before function call.
 *
 * @return #CO_ReturnError_t: CO_ERROR_NO, CO_ERROR_TX_OVERFLOW or
 * CO_ERROR_TX_PDO_WINDOW (Synchronous TPDO is outside window).
 */
CO_ReturnError_t CO_CANsend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer);

/**
 * Clear all synchronous TPDOs from CAN module transmit buffers.
 * 在CAN模块中的发送缓冲区清除所有的同步TPDO
 *
 * CANopen allows synchronous PDO communication only inside time between SYNC
 * message and SYNC Window. If time is outside this window, new synchronous PDOs
 * must not be sent and all pending sync TPDOs, which may be on CAN TX buffers,
 * must be cleared.
 *
 * This function checks (and aborts transmission if necessary) CAN TX buffers
 * when it is called. Function should be called by the stack in the moment,
 * when SYNC time was just passed out of synchronous window.
 *
 * @param CANmodule This object.
 */
void CO_CANclearPendingSyncPDOs(CO_CANmodule_t *CANmodule);

/**
 * Verify all errors of CAN module.
 * 校验所有的额错误CAN模块
 *
 * Function is called directly from CO_EM_process() function.
 *
 * @param CANmodule This object.
 */
void CO_CANverifyErrors(CO_CANmodule_t *CANmodule);

/**
 * Receives and transmits CAN messages.
 * 接收、发送CAN信息
 *
 * Function must be called directly from high priority CAN interrupt.
 *
 * @param CANmodule This object.
 */
void CO_CANinterrupt(CO_CANmodule_t *CANmodule);

/** @} */
#endif
时间: 2024-10-13 10:47:07

CANopenNode drvTemplate/CO_driver.h hacking的相关文章

CANopenSocket CANopenCGI.c hacking

/**************************************************************************************** * CANopenSocket CANopenCGI.c hacking * 说明: * 分析一下CANopenSocket中的CANopenCGI部分是怎么工作的. * * 2017-3-23 深圳 南山平山村 曾剑锋 *************************************************

移动安全初探:窃取微信聊天记录、Hacking Android with Metasploit

在这篇文章中我们将讨论如何获取安卓.苹果设备中的微信聊天记录,并演示如何利用后门通过Metasploit对安卓设备进行控制.文章比较基础.可动手性强,有设备的童鞋不妨边阅读文章边操作,希望能激发大家对移动终端的安全兴趣. (文章内容存在一定攻击性,目的在于普及终端安全知识.提高安全意识,如有非法使用,后果自负) “如何获取Android.iPhone手机上的微信聊天记录? ” 0×00 条件: 安卓设备已获取root权限,安装SSHDroid(通过ssh.ftp连接手机) Apple设备越狱,安

Redis代码阅读之Hacking Strings

Hacking Strings The implementation of Redis strings is contained in sds.c ( sds stands for Simple Dynamic Strings ).The C structure sdshdr declared in sds.h represents a Redis string: struct sdshdr { long len; long free; char buf[]; }; The buf charac

Rootkit Hacking Technology &amp;&amp; Defence Strategy Research

目录 1. The Purpose Of Rootkit 2. Syscall Hijack 3. LKM Module Hidden 4. Network Communication Hidden 5. File Hidden 6. Process Hidden 7. Hidden Port Remote Reverse Connections 8. Programe Replacing 1. The Purpose Of Rootkit Basically, the purpose of r

I.MX6 android BatteryService jni hacking

/**************************************************************************** * I.MX6 android BatteryService jni hacking * 声明: * 本文主要是为了知道Android的获取的电源管理的数据的jni是从Linux系统的 * 什么位置获取的,获取的机制是什么. * * 2016-2-22 深圳 南山平山村 曾剑锋 ********************************

AM335x Android eMMC mkmmc-android.sh hacking

# AM335x Android eMMC mkmmc-android.sh hacking # # 1. 有空解读一下android的分区文件. # 2. 代码来源:https://github.com/hendersa/bbbandroid-external-ti_android_utilities/blob/master/am335x/mk-mmc/mkmmc-android.sh # # 2016-9-8 深圳 南山平山村 曾剑锋 #!/bin/bash # 如果参数只有一个,这里就会直

OK335xS Qt network hacking

/********************************************************************** * OK335xS Qt network hacking * 说明: * 应该半年前尝试过来解读这个程序,但是那时候对有些东西不是很理解, * 最后不了了之了,这次因为需要,所以重新对network的mainwindow.cpp进行 * 一下解读. * * 2016-4-8 深圳 南山平山村 曾剑锋 ***************************

I.MX6 U-Boot mkconfig hacking

/**************************************************************************** * I.MX6 U-Boot mkconfig hacking * 声明: * 本文主要是为了知道U-Boot中的mkconfig是如何工作的,是如何将配置 * 中的内容进行汇总,同时又将这些内容放在了什么地方. * * 2015-12-19 深圳 南山区平山村 曾剑锋 ************************************

mkbootimg hacking

1 /********************************************************************** 2 * mkbootimg hacking 3 * 声明: 4 * 1. 本文源代码来自myzr_android4_2_2_1_1_0.tar.bz2中的mkbootimg.c; 5 * 2. 通过阅读该源码,可知Android的boot.img合成原理; 6 * 7 * 深圳 南山平山村 曾剑鋒 Mon May 4 13:09:49 CST 201