查看: 5253|回复: 11

[其他] 再问SDK1.2中的uart回调函数的用法

[复制链接]
  • TA的每日心情
    开心
    2018-7-23 21:04
  • 签到天数: 103 天

    连续签到: 1 天

    [LV.6]常住居民II

    228

    主题

    5379

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    16701
    最后登录
    1970-1-1
    发表于 2015-7-30 13:33:38 | 显示全部楼层 |阅读模式
    本帖最后由 lkl0305 于 2015-7-30 13:35 编辑

    问什么是再呢?之前问过关于相关问题。
    https://www.nxpic.org.cn/module/forum/forum.php?mod=viewthread&tid=600316&fromuid=336767
    在众网友的帮助下有了一些理解,能够简单的使用uart的回调函数。
    怎奈C语言基础没打好,还有一些问题,一定要把它搞清楚才算完事。
    ========================================================
    首先先分享一下心得吧,以串口接收数据为例。
    在SDK1.2的库中,有关uart的描述如下:
    2601.jpg
    这个是说明我们定义回调函数时的写法
    2602.jpg
    这个是要注册回调函数的函数
    在程序中可以定义自己的uart0的回调函数,里面写上需要执行的相关的代码
    2604.jpg
    在程序中,使用如下函数调用来注册我们自定义的串口回调函数
    2603.jpg
    第一个参数是串口号,第二个参数是回调函数指针,第三个参数是接收数据缓冲,第四个参数是我的问题,最后一个参数是是否每次有接收数据后触发中断。
    这样设置后,每当串口有数据接收到时,都回触发进入自定义的回调函数中执行。
    ==========================================================
    我的问题是,这个第三个参数
    void * callbackParam
    这个写法的具体含义,以及串口接收回调参数指针怎么用啊,大家能不能结合一个简单的实例来说说用法?

    先多谢指导了。



    我知道答案 目前已有11人回答

    评分

    参与人数 1NXP金币 +10 收起 理由
    小七 + 10 打赏!

    查看全部评分

    回复

    使用道具 举报

    该用户从未签到

    124

    主题

    3600

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    5781
    最后登录
    1970-1-1
    发表于 2015-7-30 15:08:57 | 显示全部楼层
    这个参数指向的参数可以给回调函数进行处理,通过以下代码和数据结构,就可以将参数的地址锁定,以备回调函数应用。代码:
    1. /*FUNCTION**********************************************************************
    2. *
    3. * Function Name : UART_DRV_InstallRxCallback
    4. * Description   : Install receive data callback function, pass in NULL pointer
    5. * as callback will unistall.
    6. *
    7. *END**************************************************************************/
    8. uart_rx_callback_t UART_DRV_InstallRxCallback(uint32_t instance,
    9.                                               uart_rx_callback_t function,
    10.                                               uint8_t * rxBuff,
    11.                                               void * callbackParam,
    12.                                               bool alwaysEnableRxIrq)
    13. {
    14.     assert(instance < UART_INSTANCE_COUNT);
    15.     UART_Type * base = g_uartBase[instance];
    16.     uart_state_t * uartState = (uart_state_t *)g_uartStatePtr[instance];

    17.     uart_rx_callback_t currentCallback = uartState->rxCallback;
    18.     uartState->rxCallback = function;
    19.     uartState->rxCallbackParam = callbackParam;
    20.     uartState->rxBuff = rxBuff;

    21.     /* Enable/Disable the receive data full interrupt */
    22.     uartState->isRxBusy = true;
    23.     UART_BWR_C2_RIE(base, alwaysEnableRxIrq);

    24.     return currentCallback;
    25. }
    复制代码
    数据结构:
    1. /*!
    2. * @brief Runtime state of the UART driver.
    3. *
    4. * This structure holds data that are used by the UART peripheral driver to
    5. * communicate between the transfer function and the interrupt handler. The
    6. * interrupt handler also uses this information to keep track of its progress.
    7. * The user passes in the memory for the run-time state structure and the
    8. * UART driver fills out the members.
    9. */
    10. typedef struct UartState {
    11.     uint8_t txFifoEntryCount;      /*!< Number of data word entries in TX FIFO. */
    12.     const uint8_t * txBuff;        /*!< The buffer of data being sent.*/
    13.     uint8_t * rxBuff;              /*!< The buffer of received data. */
    14.     volatile size_t txSize;        /*!< The remaining number of bytes to be transmitted. */
    15.     volatile size_t rxSize;        /*!< The remaining number of bytes to be received. */
    16.     volatile bool isTxBusy;        /*!< True if there is an active transmit. */
    17.     volatile bool isRxBusy;        /*!< True if there is an active receive. */
    18.     volatile bool isTxBlocking;    /*!< True if transmit is blocking transaction. */
    19.     volatile bool isRxBlocking;    /*!< True if receive is blocking transaction. */
    20.     semaphore_t txIrqSync;         /*!< Used to wait for ISR to complete its TX business. */
    21.     semaphore_t rxIrqSync;         /*!< Used to wait for ISR to complete its RX business. */
    22.     uart_rx_callback_t rxCallback; /*!< Callback to invoke after receiving byte.*/
    23.     void * rxCallbackParam;        /*!< Receive callback parameter pointer.*/
    24.     uart_tx_callback_t txCallback; /*!< Callback to invoke after transmitting byte.*/
    25.     void * txCallbackParam;        /*!< Transmit callback parameter pointer.*/
    26. } uart_state_t;
    复制代码



    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2016-11-4 16:56
  • 签到天数: 2 天

    连续签到: 1 天

    [LV.1]初来乍到

    8

    主题

    602

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    1842
    最后登录
    2020-8-25
    发表于 2015-7-30 16:29:19 | 显示全部楼层
    通过字面看,这个参数callbackParam是传给回调函数的参数,即uart0_RxCallback()中第2个参数的实参。
    一个函数可能需要处理多种数据,此时不能一味的增加函数参数(函数参数不要超过4个),这时候传入一个指向某个结构体的指针在应用时最符合实际情况。
    因为结构体可以符合多种类型的数据(结构成员),当然更重要的是:封装一个小模块。
    这样在程序处理时通过指针传入结构,在回调函数中在进行强制类型转换回来即可使用。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2016-11-24 10:19
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    50

    主题

    1028

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    2870
    最后登录
    1970-1-1
    发表于 2015-7-30 16:34:22 | 显示全部楼层
    这个指针参数之所以定义成void类型是因为这个回调函数不知道你需要用什么类型的参数,定义成VOID类型后你可以强制类型转换成任意类型,一个简单的实例:你的应用需要统计串口从开始工作共接受到了多少个字节数据,此时你的回调函数可以这样写:

    // 接收到的字节数
    uint32_t RxSizeCnt = 0;

    // 回调函数定义
    void uart0_RxCallBack(uint32_t instance,void *uartState)
    {
      // orther code
    (* (uint32_t *)uartState) ++;
    }

    // 回调函数注册
    UART_DRV_InstallRxCallback( instance, uart0_RxCallBack,rxBuff,(void *)&RxSizeCnt ,true);


    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2018-7-23 21:04
  • 签到天数: 103 天

    连续签到: 1 天

    [LV.6]常住居民II

    228

    主题

    5379

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    16701
    最后登录
    1970-1-1
     楼主| 发表于 2015-7-30 21:23:35 | 显示全部楼层
    FSL_TICS_ZP 发表于 2015-7-30 15:08
    这个参数指向的参数可以给回调函数进行处理,通过以下代码和数据结构,就可以将参数的地址锁定,以备回调函 ...

    好像明白些了,是不是说用void * callbackParam指向回调函数中要使用使用的参数,然后再回调函数中使用结构体uart_state_t的rxCallbackParam成员来使用?
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2018-7-23 21:04
  • 签到天数: 103 天

    连续签到: 1 天

    [LV.6]常住居民II

    228

    主题

    5379

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    16701
    最后登录
    1970-1-1
     楼主| 发表于 2015-7-30 21:24:37 | 显示全部楼层
    moyanming2013 发表于 2015-7-30 16:29
    通过字面看,这个参数callbackParam是传给回调函数的参数,即uart0_RxCallback()中第2个参数的实参。
    一个 ...

    回答的非常好,多谢指导了,明白了一些,回头我自己写个程序试试看
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2018-7-23 21:04
  • 签到天数: 103 天

    连续签到: 1 天

    [LV.6]常住居民II

    228

    主题

    5379

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    16701
    最后登录
    1970-1-1
     楼主| 发表于 2015-7-30 21:41:17 | 显示全部楼层
    cxtarm 发表于 2015-7-30 16:34
    这个指针参数之所以定义成void类型是因为这个回调函数不知道你需要用什么类型的参数,定义成VOID类型后你可 ...

    多谢指导,研究一下,然后测试一把
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    124

    主题

    3600

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    5781
    最后登录
    1970-1-1
    发表于 2015-7-31 08:33:24 | 显示全部楼层
    lkl0305 发表于 2015-7-30 21:23
    好像明白些了,是不是说用void * callbackParam指向回调函数中要使用使用的参数,然后再回调函数中使用结 ...

    是的
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2018-7-23 21:04
  • 签到天数: 103 天

    连续签到: 1 天

    [LV.6]常住居民II

    228

    主题

    5379

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    16701
    最后登录
    1970-1-1
     楼主| 发表于 2015-7-31 09:05:17 | 显示全部楼层

    谢谢了,在您的帮助下又解决了一个问题
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    124

    主题

    3600

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    5781
    最后登录
    1970-1-1
    发表于 2015-7-31 09:17:34 | 显示全部楼层
    lkl0305 发表于 2015-7-31 09:05
    谢谢了,在您的帮助下又解决了一个问题

    客气啊
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-7-21 00:01 , Processed in 0.120218 second(s), 32 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表