What is the best way to access I2C in a MQX project?

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

What is the best way to access I2C in a MQX project?

1,649件の閲覧回数
mjohn
Contributor III

uPC: MK21FN1M0A

IDE: KDS 2.0.0

SDK: KSDK1.1.0_K21FA_1.0.0

Hello

I have a project that uses MQX OS with several tasks that access two I2C ports. Currently, I am using the SDK I2C component from Processor Expert for all I2C operations. I seem to run across some issues with this I2C driver when multiple tasks are trying to access the I2C ports, specifically an assert statement will fail in the driver code. In order to make sure the I2C is thread safe, I use a mutex for accessing each I2C resource. Also, the driver code seemed sensitive when preempted by another task, so I disable preemption whenever the I2C is accessed.

Considering these issues, I am wondering if this is the best method of accessing I2C in a MQX OS environment? Are there better methods of accessing the I2C than what I am doing currently?

Thanks

Matt

Here are some snippets of relevant code:

assert statement that fails: fsl_i2c_hal.c

i2c_status_t I2C_HAL_SendStop(uint32_t baseAddr)

{

    assert(BR_I2C_C1_MST(baseAddr) == 1);

    uint32_t i = 0;

    /* Start the STOP signal */

    HW_I2C_C1_CLR(baseAddr, BM_I2C_C1_MST | BM_I2C_C1_TX);

    /* Wait for the STOP signal finish. */

    while(I2C_HAL_GetStatusFlag(baseAddr, kI2CBusBusy))

    {

        if (++i == 0x400U)

        {

            /* Something is wrong because the bus is still busy. */

            return kStatus_I2C_StopSignalFail;

        }

        else

        {

            __asm("nop");

        }

    }

    return kStatus_I2C_Success;

}

Current function that accesses I2C through the I2C SDK component driver:

i2c_status_t i2c_stat;

if (instance == FSL_I2CCOM0){if (lockMutex(&i2c0_mutex) != MQX_OK){return kStatus_I2C_Fail;}}

else if (instance == FSL_I2CCOM2){if (lockMutex(&i2c2_mutex) != MQX_OK){return kStatus_I2C_Fail;}}

  else {return kStatus_I2C_Fail;}

_task_stop_preemption();

i2c_stat = I2C_DRV_MasterSendDataBlocking(instance, device, cmdBuff, cmdSize, txBuff, txSize, timeout_ms);

_task_start_preemption();

if (instance == FSL_I2CCOM0){if (unlockMutex(&i2c0_mutex) != MQX_OK){return kStatus_I2C_Fail;}}

else if (instance == FSL_I2CCOM2){if (unlockMutex(&i2c2_mutex) != MQX_OK){return kStatus_I2C_Fail;}}

return i2c_stat;

0 件の賞賛
返信
5 返答(返信)

1,279件の閲覧回数
DavidS
NXP Employee
NXP Employee

Hi Matt,

The Freescale Xtrinsic Sensor library for Kinetis (XTRINSIC_FUSION_LIB_KINMCU) has good example of using KDS+PE to access multiple sensors on I2C interface.

The software is targeted to KL46, K20D50M, K64F, KL25Z, and KL26Z Freedom boards that then plug into the FRDM-FXS-MULTI sensor board.

This should be a good reference for setting up on your K21.

Regards,

David

1,279件の閲覧回数
mjohn
Contributor III

Thanks for the reference. I'll look into that.

0 件の賞賛
返信

1,279件の閲覧回数
DavidS
NXP Employee
NXP Employee
0 件の賞賛
返信

1,279件の閲覧回数
matthewkendall
Contributor V

I am using the MQX I2C driver, as described in the "MQX I/O User's Guide" MQXIOUG. Set BSPCFG_ENABLE_I2C0 true in user_config.h to enable it in the BSP. That gets you the polled driver. You can enable the interrupt-based driver instead but I have not used that.

It installs as a standard I/O driver so the the API is the standard fopen(), read(), write(), fclose(), and ioctl(). There are some examples of how to use it in the MQX distribution.

I am using it to access a temperature sensor and an EEPROM on the same bus, in an environment where there are dozens of tasks, most of which are higher priority then those using I2C, and I have not seen any problems.

I am using CodeWarrior with MQX 4.1.1 and a K60. I know nothing about KSD or KSDK.

1,279件の閲覧回数
mjohn
Contributor III

Thanks for the help. I've been using the Processor Expert MQX component, which seems to be generated a little differently? If I don't make any headway using the PEx components, I'll give this a shot.

0 件の賞賛
返信