Jump to content

    

Как связать задачу и обработчик прерываний I2Cx_ER_IRQHandler?

Добрый день, переношу свой проект на  FreeRTOS , начал c периферией работающей на  I2C. Есть две задачи  использующие I2C это  термодатчик LM75 и LCD hd44780 (на расширителе PCF). Остановился на обработке ошибок. Алгоритм заложил следующий:

  1.     Первый тип ошибки это если  slave  отсутствует на линии   ( ожидаем его появления и по появлению вызываем Calback на обработку, для LCD запускаем инициализацию ), соответственно так же пропажу slave с линии
  2.     Второй тип ошибки если было замыкание линии i2c (переключаем линию CLK на выход и генерируем клоки на сброс slave и запускаем переинициализацию i2c и всех задач)

Так вот  при  отсутствии slave  на линии вызывается I2Cx_ER_IRQHandler  и по флагу   I2C_SR1_AF   определяем что нету аск от  slave.

Как правильно и просто определить какой из двух задач относился вызов I2Cx_ER_IRQHandler  т.е какой из 2-3 slave не ответил ? Можно привязаться как нибудь к имени задачи или xTaskNumber?

Раньше я сохранял id "задачи" (работал без ртос) а в прерывании смотрел на этот номер, но получалось не очень хорошо (этот модуль тянул ещё дополнительные include )

Как правильно сделать  вызов Calback на обработку, событий появления/пропадания slave ?

 

 

 

 

 

 

 

 

Share this post


Link to post
Share on other sites
2 minutes ago, pokk said:

Как правильно сделать  вызов Calback на обработку, событий появления/пропадания slave ?

Вот функция для обмена с подчинёнными из моего драйвера

TRetVal Lpc43xxI2cDriver::txrx( TMsgType * msg ) {
    RET_VAL(openResult);
    TRetVal retVal;

    configASSERT(m_periphPointer[m_hdwNum]);
    configASSERT(msg);
    configASSERT(mutex[m_hdwNum]);
    if( msg == nullptr )
      retVal = rvNULL_POINTER;
    else
    {
      OsApi::Mutex mt(mutex[m_hdwNum]);
      RET_VAL(mt.take(msg->timeout_ms));

      m_tskHandles[m_hdwNum] = xTaskGetCurrentTaskHandle();


      I2C_M_SETUP_Type transferMCfg;
      /* Start I2C slave device first */
      transferMCfg.sl_addr7bit = msg->slaveAddr7Bit;
      transferMCfg.tx_data = msg->tx;
      transferMCfg.tx_length = msg->txLen;
      transferMCfg.rx_data = msg->rx;
      transferMCfg.rx_length = msg->rxLen;
      transferMCfg.retransmissions_max = 3;
      I2C_MasterTransferData(m_periphPointer[m_hdwNum], &transferMCfg, I2C_TRANSFER_INTERRUPT);

      uint32_t notify = ulTaskNotifyTake(pdTRUE, MSEC(msg->timeout_ms));
      retVal = notify ? rvOK : rvTIME_OUT;
    }

    return retVal;
}

Обратите внимание, что перед тем, как задача пытается попользоваться шиной, она берёт мьютекс

      OsApi::Mutex mt(mutex[m_hdwNum]);
      RET_VAL(mt.take(msg->timeout_ms));

Если в течение таймаута мы захватили мьютекс, то начинаем пользоваться шиной. Соответственно, все транзакции с подчинённым будут только для одной задачи.

Share this post


Link to post
Share on other sites

Понял сохранить id  можно через  xTaskGetCurrentTaskHandle() буду дальше думать  как это можно испольнозовать.

1 hour ago, haker_fox said:

transferMCfg.retransmissions_max = 3;

А этот параметр как используеться точнее повторение происходит по какому событию ? Если нету slave ? А что  дальше  делаете после трехкратного повторения ?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now