查看: 2753|回复: 1

[原创] 【S32K146 RT-thread】之I2c bus 驱动

[复制链接]
  • TA的每日心情
    奋斗
    前天 10:11
  • 签到天数: 868 天

    连续签到: 2 天

    [LV.10]以坛为家III

    69

    主题

    3277

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    10400
    最后登录
    2025-8-22
    发表于 2024-1-3 11:21:54 | 显示全部楼层 |阅读模式
    本帖最后由 andeyqi 于 2024-1-5 22:49 编辑

    概述:
    以下链接是官方对I2C设备驱动的介绍,可以从中了解下I2C驱动模型的结构。

    RT-Thread I2C 驱动框架提供了一个结构化的方式来支持 I2C 总线通信,方便统一的接口方式访问 I2C 设备。RT-Thread I2C 驱动框架主要包括两个层次的抽象:
    • I2C 总线核心层 (i2c_core.c): 这一层提供了 I2C 总线的抽象和核心逻辑。它包含 I2C 总线的初始化、数据传输、设备注册和查找等核心功能。
    • I2C 设备驱动层 (i2c_dev.c): 这一层建立在 I2C 总线核心层之上,提供了对具体 I2C 设备的抽象。它包含 I2C 设备的初始化、打开、关闭、读写等操作,以及设备的控制和关闭。


    I2C 驱动的核心文件是i2c_core.c,对应的核心结构体为rt_i2c_bus_device, 该结构体是 RT-Thread 中定义的用于表示 I2C 总线设备的结构体。它包含了一些关键的字段,用于描述和管理具体的 I2C 总线。以下是 rt_i2c_bus_device 结构体的主要字段和功能

    1. /*for i2c bus driver*/
    2. struct rt_i2c_bus_device
    3. {
    4.     struct rt_device parent;/*  设备基类 device */
    5.     const struct rt_i2c_bus_device_ops *ops;/* I2C 下操作方法 */
    6.     rt_uint16_t  flags;/* I2C 支持的读写标志等 */
    7.     struct rt_mutex lock;/* 互斥锁,保证多线程范访问安全 */
    8.     rt_uint32_t  timeout; /* 超时时间 */
    9.     rt_uint32_t  retries; /* retry 次数 */
    10.     void *priv;/* 私有数据 */
    11. };
    复制代码

    对于适配I2C总线驱动,我们只需关注struct rt_i2c_bus_device_ops *ops成员即可,ops 成员定义了I2C 总线的访问方法定义如下:
    1. struct rt_i2c_bus_device_ops
    2. {
    3.     rt_ssize_t (*master_xfer)(struct rt_i2c_bus_device *bus,
    4.                              struct rt_i2c_msg msgs[],
    5.                              rt_uint32_t num);
    6.     rt_ssize_t (*slave_xfer)(struct rt_i2c_bus_device *bus,
    7.                             struct rt_i2c_msg msgs[],
    8.                             rt_uint32_t num);
    9.     rt_err_t (*i2c_bus_control)(struct rt_i2c_bus_device *bus,
    10.                                 int cmd,
    11.                                 void *args);
    12. };
    复制代码
    本地使用的S32K开发板是master 须实现master_xfer函数,slave_xfer/i2c_bus_control 没有实现不过不影响我们使用I2C总线访问通过RT-thread i2c 驱动框架本地实现代码如下:
    1. /*
    2. * Copyright (c) 2006-2021, RT-Thread Development Team
    3. *
    4. * SPDX-License-Identifier: Apache-2.0
    5. */

    6. #include "drv_i2c.h"
    7. #include "board.h"

    8. struct s32k_i2c
    9. {
    10.     struct rt_i2c_bus_device bus;
    11.     char *device_name;
    12.     rt_uint32_t instance;
    13.     rt_uint32_t timeout;
    14.     lpi2c_master_state_t state;
    15. };


    16. static rt_ssize_t master_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num)
    17. {
    18.     rt_ssize_t ret = (0);
    19.     rt_uint32_t index = 0;
    20.     struct s32k_i2c *i2c = RT_NULL;
    21.     struct rt_i2c_msg *msg = RT_NULL;
    22.     status_t result = STATUS_SUCCESS;
    23.     bool stop = false;
    24.    
    25.     i2c = (struct s32k_i2c *)bus;
    26.    
    27.     LPI2C_DRV_MasterSetSlaveAddr(i2c->instance,msgs[0].addr,false);
    28.    
    29.      for(index = 0; index < num; index++)
    30.     {
    31.         if(index == (num-1))
    32.           stop = true;
    33.         
    34.         msg = &msgs[index];
    35.         
    36.         if(RT_I2C_RD & msg->flags)
    37.         {
    38.            result = LPI2C_DRV_MasterReceiveDataBlocking(i2c->instance, msg->buf,msg->len, stop , i2c->timeout);
    39.         }
    40.         else
    41.         {
    42.             result = LPI2C_DRV_MasterSendDataBlocking(i2c->instance, (const uint8_t * )msg->buf,msg->len, stop , i2c->timeout);
    43.         }
    44.         
    45.         if(result != STATUS_SUCCESS)
    46.             break;
    47.     }
    48.    
    49.     if (result == STATUS_SUCCESS)
    50.     {
    51.         ret = index;
    52.     }

    53.     return ret;
    54. }

    55. static rt_ssize_t slave_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num)
    56. {
    57.     return -RT_ENOSYS;
    58. }

    59. static rt_err_t i2c_bus_control(struct rt_i2c_bus_device *bus, int cmd, void *args)
    60. {
    61.     return -RT_EINVAL;
    62. }

    63. static const struct rt_i2c_bus_device_ops ops =
    64. {
    65.     master_xfer,
    66.     slave_xfer,
    67.     i2c_bus_control,
    68. };

    69. extern void LPI2C0_Master_IRQHandler(void);

    70. void S32K14X_LPI2C0_Master_Slave_IRQHandler(void)
    71. {
    72.     /* enter interrupt */
    73.     rt_interrupt_enter();

    74.     LPI2C0_Master_IRQHandler();

    75.     /* leave interrupt */
    76.     rt_interrupt_leave();
    77. }


    78. static struct s32k_i2c i2c0 = {0};

    79. int rt_hw_i2c_init(void)
    80. {
    81.   
    82.     i2c0.device_name = "i2c0";
    83.     i2c0.bus.ops = &ops;
    84.     i2c0.instance = INST_LPI2C0;
    85.     i2c0.timeout = 500;
    86.    
    87.     INT_SYS_InstallHandler(LPI2C0_Master_IRQn,S32K14X_LPI2C0_Master_Slave_IRQHandler,NULL);
    88.    
    89.     /* init i2c0 bus */
    90.     LPI2C_DRV_MasterInit(i2c0.instance, &lpi2c0_MasterConfig0, &i2c0.state);
    91.    
    92.     rt_i2c_bus_device_register(&i2c0.bus, i2c0.device_name);

    93.     return RT_EOK;
    94. }
    95. INIT_APP_EXPORT(rt_hw_i2c_init);
    复制代码

    上面的代码里我们使用了S32 SDK 的LPI2C_DRV_MasterReceiveDataBlocking/LPI2C_DRV_MasterSendDataBlocking 的API函数,但是S32的SDK 的这些接口时跟OS 相耦合的,在 S32K Software Development Kit (SDK) 中存在一个OSIF层,OSIF (Operating System Interface) 层是一个抽象层,用于提供操作系统相关的接口,使得 S32K SDK 可以在不同的操作系统上运行。OSIF 层包含了对于操作系统的适配接口,互斥锁、信号量等。这种设计使得 S32K SDK 能够灵活地在不同的实时操作系统 (RTOS) 上运行。以下图片可以看出OS 和 接口之间夹杂了osif 我们需要实现基于RT-thread 实现osif 相关的接口。
    osif1.png

    OSIF 依赖OS 相关的接口如下。

    osif.png
    按照上面的要是求SDK OS相关的依赖。osif_rtthread.c
    1. /*
    2. * Copyright (c) 2016, Freescale Semiconductor, Inc.
    3. * Copyright 2016-2020 NXP
    4. * All rights reserved.
    5. *
    6. * NXP Confidential. This software is owned or controlled by NXP and may only be
    7. * used strictly in accordance with the applicable license terms. By expressly
    8. * accepting such terms or by downloading, installing, activating and/or otherwise
    9. * using the software, you are agreeing that you have read, and that you agree to
    10. * comply with and are bound by, such license terms. If you do not agree to be
    11. * bound by the applicable license terms, then you may not retain, install,
    12. * activate or otherwise use the software. The production use license in
    13. * Section 2.3 is expressly granted for this software.
    14. */

    15. /*!
    16. * @file osif_freertos.c
    17. *
    18. * @page misra_violations MISRA-C:2012 violations
    19. *
    20. * @section [global]
    21. * Violates MISRA 2012 Required Rule 1.3, Taking address of near auto variable
    22. * The code is not dynamically linked. An absolute stack address is obtained when
    23. * taking the address of the near auto variable. A source of error in writing
    24. * dynamic code is that the stack segment may be different from the data segment.
    25. *
    26. * @section [global]
    27. * Violates MISRA 2012 Advisory Directive 4.9, Function-like macro defined.
    28. * The macros are used to validate input parameters to driver functions.
    29. *
    30. * @section [global]
    31. * Violates MISRA 2012 Required Rule 7.2, Unsigned integer literal without a 'U' suffix
    32. * Register address defined by FreeRTOS header files.
    33. *
    34. * @section [global]
    35. * Violates MISRA 2012 Advisory Rule 8.7, External could be made static.
    36. * Function is defined for usage by application code.
    37. *
    38. * @section [global]
    39. * Violates MISRA 2012 Advisory Rule 8.13, Pointer variable could be declared as pointing to const
    40. * Type definition is done in FreeRTOS header files.
    41. *
    42. * @section [global]
    43. * Violates MISRA 2012 Advisory Rule 11.4, Conversion between a pointer and integer type.
    44. * The cast is required to initialize a pointer with an unsigned long define, representing an address.
    45. *
    46. * @section [global]
    47. * Violates MISRA 2012 Required Rule 11.6, Cast from unsigned int to pointer.
    48. * This is required for initializing pointers to the module's memory map, which is located at a
    49. * fixed address.
    50. *
    51. */

    52. #include <stdbool.h>
    53. #include "device_registers.h"
    54. #include "osif.h"
    55. #include "devassert.h"

    56. #if !defined (USING_OS_RTTHREAD)
    57. #error "Wrong OSIF selected. Please define symbol USING_OS_RTTHREAD in project settings or change the OSIF variant"
    58. #endif

    59. /*******************************************************************************
    60. * Variables
    61. ******************************************************************************/
    62. static rt_atomic_t osifid = 0;

    63. /*******************************************************************************
    64. * Private Functions
    65. ******************************************************************************/

    66. /*******************************************************************************
    67. * Code
    68. ******************************************************************************/

    69. /*FUNCTION**********************************************************************
    70. *
    71. * Function Name : OSIF_TimeDelay
    72. * Description   : This function blocks (sleep) the current thread for a number
    73. *  of milliseconds.
    74. *
    75. * Implements : OSIF_TimeDelay_freertos_Activity
    76. *END**************************************************************************/
    77. void OSIF_TimeDelay(uint32_t delay)
    78. {
    79.     /* One dependency for FreeRTOS config file */
    80.     /* INCLUDE_vTaskDelay */
    81.     rt_thread_mdelay(delay);
    82. }


    83. /*FUNCTION**********************************************************************
    84. *
    85. * Function Name : OSIF_GetMilliseconds
    86. * Description   : This function returns the number of miliseconds elapsed since
    87. *                  starting the internal timer (since scheduler was started).
    88. *
    89. * Implements : OSIF_GetMilliseconds_freertos_Activity
    90. *END**************************************************************************/
    91. uint32_t OSIF_GetMilliseconds(void)
    92. {
    93.     /*
    94.      * Return the tick count in miliseconds
    95.      * Note: if configTICK_RATE_HZ is less than 1000, the return value will be truncated
    96.      * to 32-bit wide for large values of the tick count.
    97.      */
    98.     return (uint32_t)(rt_tick_get_millisecond());
    99. }

    100. /*FUNCTION**********************************************************************
    101. *
    102. * Function Name : OSIF_MutexLock
    103. * Description   : This function obtains the mutex lock or returns error if timeout.
    104. *
    105. * Implements : OSIF_MutexLock_freertos_Activity
    106. *END**************************************************************************/
    107. status_t OSIF_MutexLock(const mutex_t * const pMutex,
    108.                         const uint32_t timeout)
    109. {
    110.     /* The (pMutex == NULL) case is a valid option, signaling that the mutex does
    111.      * not need to be locked - do not use DEV_ASSERT in this case */

    112.     status_t osif_ret_code = STATUS_SUCCESS;
    113.    
    114.     if (pMutex != NULL)
    115.     {
    116.         rt_err_t ret = rt_mutex_take(pMutex->handle,timeout);
    117.         osif_ret_code = (ret == RT_EOK) ? STATUS_SUCCESS : STATUS_ERROR;
    118.     }
    119.     return osif_ret_code;
    120. }

    121. /*FUNCTION**********************************************************************
    122. *
    123. * Function Name : OSIF_MutexUnlock
    124. * Description   : This function unlocks the mutex, fails if the current thread
    125. *  is not the mutex holder.
    126. *
    127. * Implements : OSIF_MutexUnlock_freertos_Activity
    128. *END**************************************************************************/
    129. status_t OSIF_MutexUnlock(const mutex_t * const pMutex)
    130. {
    131.     /* The (pMutex == NULL) case is a valid option, signaling that the mutex does
    132.      * not need to be unlocked - do not use DEV_ASSERT in this case */

    133.     status_t osif_ret_code = STATUS_SUCCESS;

    134.     if (pMutex != NULL)
    135.     {
    136.         rt_err_t ret = rt_mutex_release(pMutex->handle);
    137.         osif_ret_code = (ret == RT_EOK) ? STATUS_SUCCESS : STATUS_ERROR;
    138.     }
    139.    
    140.     return osif_ret_code;
    141. }

    142. /*FUNCTION**********************************************************************
    143. *
    144. * Function Name : OSIF_MutexCreate
    145. * Description   : This function creates (registers) a mutex object to the OS.
    146. *
    147. * Implements : OSIF_MutexCreate_freertos_Activity
    148. *END**************************************************************************/
    149. status_t OSIF_MutexCreate(mutex_t * const pMutex)
    150. {
    151.     /* The (pMutex == NULL) case is a valid option, signaling that the mutex does
    152.      * not need to be created - do not use DEV_ASSERT in this case */

    153.     char name[RT_NAME_MAX] = {'\0'};
    154.     rt_atomic_add(&(osifid), 1);
    155.    
    156.     rt_sprintf(name,"oi%d",osifid);   
    157.    
    158.     pMutex->handle = rt_mutex_create(name, RT_IPC_FLAG_PRIO);

    159.     return pMutex->handle ? STATUS_SUCCESS: STATUS_ERROR;
    160. }

    161. /*FUNCTION**********************************************************************
    162. *
    163. * Function Name : OSIF_MutexDestroy
    164. * Description   : This function removes the mutex from the OS (and frees memory).
    165. *
    166. * Implements : OSIF_MutexDestroy_freertos_Activity
    167. *END**************************************************************************/
    168. status_t OSIF_MutexDestroy(const mutex_t * const pMutex)
    169. {
    170.     /* The (pMutex == NULL) case is a valid option, signaling that the mutex does
    171.      * not need to be destroyed - do not use DEV_ASSERT in this case */
    172.     rt_mutex_delete(pMutex->handle);
    173.    
    174.     return STATUS_SUCCESS;
    175. }

    176. /*FUNCTION**********************************************************************
    177. *
    178. * Function Name : OSIF_SemaWait
    179. * Description   : This function performs the 'wait' (decrement) operation on a semaphore,
    180. *  returns error if operation times out.
    181. *
    182. * Implements : OSIF_SemaWait_freertos_Activity
    183. *END**************************************************************************/
    184. status_t OSIF_SemaWait(semaphore_t * const pSem,
    185.                        const uint32_t timeout)
    186. {
    187.     DEV_ASSERT(pSem);
    188.     rt_err_t ret;
    189.    
    190.     if(OSIF_WAIT_FOREVER == timeout)
    191.     {
    192.           ret = rt_sem_take(pSem->handle,RT_WAITING_FOREVER);
    193.     }
    194.     else
    195.     {
    196.           ret = rt_sem_take(pSem->handle,timeout);
    197.     }


    198.     return ret == RT_EOK ? STATUS_SUCCESS : STATUS_ERROR;
    199. }

    200. /*FUNCTION**********************************************************************
    201. *
    202. * Function Name : OSIF_SemaPost
    203. * Description   : This function performs the 'post' (increment) operation on a semaphore.
    204. *
    205. * Implements : OSIF_SemaPost_freertos_Activity
    206. *END**************************************************************************/
    207. status_t OSIF_SemaPost(semaphore_t * const pSem)
    208. {
    209.     DEV_ASSERT(pSem);

    210.     //status_t osif_ret_code;

    211.     rt_sem_release(pSem->handle);
    212.    
    213.     return STATUS_SUCCESS;
    214. }

    215. /*FUNCTION**********************************************************************
    216. *
    217. * Function Name : OSIF_SemaCreate
    218. * Description   : This function creates (registers) a semaphore object to the OS.
    219. *
    220. * Implements : OSIF_SemaCreate_freertos_Activity
    221. *END**************************************************************************/
    222. status_t OSIF_SemaCreate(semaphore_t * const pSem,
    223.                          const uint8_t initValue)
    224. {
    225.     DEV_ASSERT(pSem);
    226.     char name[RT_NAME_MAX] = {'\0'};
    227.    
    228.     rt_atomic_add(&(osifid), 1);
    229.    
    230.     rt_sprintf(name,"oi%d",osifid);
    231.    
    232.     pSem->handle = rt_sem_create((const char *)name, initValue, RT_IPC_FLAG_PRIO);

    233.     return pSem->handle ? STATUS_SUCCESS: STATUS_ERROR;
    234. }

    235. /*FUNCTION**********************************************************************
    236. *
    237. * Function Name : OSIF_SemaDestroy
    238. * Description   : This function removes a semaphore object from the OS (frees memory).
    239. *
    240. * Implements : OSIF_SemaDestroy_freertos_Activity
    241. *END**************************************************************************/
    242. status_t OSIF_SemaDestroy(const semaphore_t * const pSem)
    243. {
    244.     DEV_ASSERT(pSem);

    245.     rt_sem_delete(pSem->handle);
    246.    
    247.     return STATUS_SUCCESS;
    248. }

    249. /*******************************************************************************
    250. * EOF
    251. ******************************************************************************/
    复制代码
    osif.h更新
    1. /*
    2. * Copyright (c) 2016, Freescale Semiconductor, Inc.
    3. * Copyright 2016-2020 NXP
    4. * All rights reserved.
    5. *
    6. * NXP Confidential. This software is owned or controlled by NXP and may only be
    7. * used strictly in accordance with the applicable license terms. By expressly
    8. * accepting such terms or by downloading, installing, activating and/or otherwise
    9. * using the software, you are agreeing that you have read, and that you agree to
    10. * comply with and are bound by, such license terms. If you do not agree to be
    11. * bound by the applicable license terms, then you may not retain, install,
    12. * activate or otherwise use the software. The production use license in
    13. * Section 2.3 is expressly granted for this software.
    14. */

    15. #ifndef OSIF_H
    16. #define OSIF_H

    17. #include <stdint.h>

    18. /**
    19. * @page misra_violations MISRA-C:2012 violations
    20. *
    21. * @section [global]
    22. * Violates MISRA 2012 Advisory Rule 2.5, Global macro not referenced.
    23. * The macro defines a value that will be interpreted as an infinite timeout.
    24. *
    25. */

    26. /*! @file */

    27. /*!
    28. * @addtogroup osif
    29. * @{
    30. */

    31. /*******************************************************************************
    32. * Definitions
    33. ******************************************************************************/

    34. /*! @cond DRIVER_INTERNAL_USE_ONLY */

    35. #ifdef USING_OS_FREERTOS
    36. /* FreeRTOS implementation */
    37. #include "FreeRTOS.h"
    38. #include "semphr.h"

    39. #if configSUPPORT_STATIC_ALLOCATION == 1
    40.     typedef struct {
    41.         SemaphoreHandle_t handle;
    42.         StaticSemaphore_t buffer;
    43.     } semaphore_t;

    44.     typedef semaphore_t mutex_t;
    45. #else /* configSUPPORT_STATIC_ALLOCATION == 0, it's dynamic allocation */
    46.     /*! @brief Type for a mutex. */
    47.     typedef SemaphoreHandle_t mutex_t;
    48.     /*! @brief Type for a semaphore. */
    49.     typedef SemaphoreHandle_t semaphore_t;
    50. #endif /* configSUPPORT_STATIC_ALLOCATION == 1 */
    51.    
    52. #elif defined(USING_OS_RTTHREAD)
    53. #include <rtthread.h>
    54.     typedef struct {
    55.         rt_sem_t handle;
    56.     } semaphore_t;
    57.    
    58.     typedef struct{
    59.         rt_mutex_t handle;
    60.     }mutex_t;
    61. #else
    62. /* Bare-metal implementation */
    63. /*! @brief Type for a mutex. */
    64. typedef uint8_t mutex_t;
    65. /*! @brief Type for a semaphore. */
    66. typedef volatile uint8_t semaphore_t;
    67. #endif /* ifdef USING_OS_FREERTOS */

    68. /*! @endcond */

    69. #define OSIF_WAIT_FOREVER 0xFFFFFFFFu

    70. #include "status.h"

    71. /*******************************************************************************
    72. * API
    73. ******************************************************************************/

    74. #if defined (__cplusplus)
    75. extern "C" {
    76. #endif

    77. /*!
    78. * @brief Delays execution for a number of milliseconds.
    79. *
    80. * @param[in] delay Time delay in milliseconds.
    81. */
    82. void OSIF_TimeDelay(const uint32_t delay);

    83. /*!
    84. * @brief Returns the number of miliseconds elapsed since starting the internal timer
    85. * or starting the scheduler.
    86. *
    87. * @return the number of miliseconds elapsed
    88. */
    89. uint32_t OSIF_GetMilliseconds(void);

    90. /*!
    91. * @brief Waits for a mutex and locks it.
    92. *
    93. * @param[in] pMutex reference to the mutex object
    94. * @param[in] timeout time-out value in milliseconds
    95. * @return  One of the possible status codes:
    96. * - STATUS_SUCCESS: mutex lock operation success
    97. * - STATUS_ERROR: mutex already owned by current thread
    98. * - STATUS_TIMEOUT: mutex lock operation timed out
    99. *
    100. */
    101. status_t OSIF_MutexLock(const mutex_t * const pMutex,
    102.                         const uint32_t timeout);

    103. /*!
    104. * @brief Unlocks a previously locked mutex.
    105. *
    106. * @param[in] pMutex reference to the mutex object
    107. * @return  One of the possible status codes:
    108. * - STATUS_SUCCESS: mutex unlock operation success
    109. * - STATUS_ERROR: mutex unlock failed
    110. */
    111. status_t OSIF_MutexUnlock(const mutex_t * const pMutex);


    112. /*!
    113. * @brief Create an unlocked mutex.
    114. *
    115. * @param[in] pMutex reference to the mutex object
    116. * @return  One of the possible status codes:
    117. * - STATUS_SUCCESS: mutex created
    118. * - STATUS_ERROR: mutex could not be created
    119. */
    120. status_t OSIF_MutexCreate(mutex_t * const pMutex);

    121. /*!
    122. * @brief Destroys a previously created mutex.
    123. *
    124. * @param[in] pMutex reference to the mutex object
    125. * @return  One of the possible status codes:
    126. * - STATUS_SUCCESS: mutex destroyed
    127. */
    128. status_t OSIF_MutexDestroy(const mutex_t * const pMutex);


    129. /*!
    130. * @brief Decrement a semaphore with timeout.
    131. *
    132. * @param[in] pSem reference to the semaphore object
    133. * @param[in] timeout time-out value in milliseconds
    134. * @return  One of the possible status codes:
    135. * - STATUS_SUCCESS: semaphore wait operation success
    136. * - STATUS_TIMEOUT: semaphore wait timed out
    137. */
    138. status_t OSIF_SemaWait(semaphore_t * const pSem,
    139.                        const uint32_t timeout);


    140. /*!
    141. * @brief Increment a semaphore
    142. *
    143. * @param[in] pSem reference to the semaphore object
    144. * @return  One of the possible status codes:
    145. * - STATUS_SUCCESS: semaphore post operation success
    146. * - STATUS_ERROR: semaphore could not be incremented
    147. */
    148. status_t OSIF_SemaPost(semaphore_t * const pSem);


    149. /*!
    150. * @brief Creates a semaphore with a given value.
    151. *
    152. * @param[in] pSem reference to the semaphore object
    153. * @param[in] initValue initial value of the semaphore
    154. * @return  One of the possible status codes:
    155. * - STATUS_SUCCESS: semaphore created
    156. * - STATUS_ERROR: semaphore could not be created
    157. */
    158. status_t OSIF_SemaCreate(semaphore_t * const pSem,
    159.                          const uint8_t initValue);


    160. /*!
    161. * @brief Destroys a previously created semaphore.
    162. *
    163. * @param[in] pSem reference to the semaphore object
    164. * @return  One of the possible status codes:
    165. * - STATUS_SUCCESS: semaphore destroyed
    166. */
    167. status_t OSIF_SemaDestroy(const semaphore_t * const pSem);

    168. /*! @}*/
    169. #if defined (__cplusplus)
    170. }
    171. #endif

    172. /*! @}*/

    173. #endif /* OSIF_H */
    174. /*******************************************************************************
    175. * EOF
    176. ******************************************************************************/
    复制代码

    至此I2C 驱动程序已经适配完成,后续使用RT-thread 的I2C-tool 软件包来验证I2C总线通信状况详见(https://www.nxpic.org.cn/module/forum/thread-802558-1-1.html

    该会员没有填写今日想说内容.
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    7 天前
  • 签到天数: 1868 天

    连续签到: 2 天

    [LV.Master]伴坛终老

    203

    主题

    3万

    帖子

    64

    超级版主

    Rank: 8Rank: 8

    积分
    112694
    最后登录
    2025-8-17
    发表于 2024-1-5 08:50:02 | 显示全部楼层
    感谢大佬分享~
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

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

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

    GMT+8, 2025-8-24 04:14 , Processed in 0.083687 second(s), 21 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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