Jump to content

    
pokk

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

Recommended Posts

Добрый день, переношу свой проект на  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

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.