Перейти к содержанию
    

Как связать задачу и обработчик прерываний 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 ?

 

 

 

 

 

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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));

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

1 hour ago, haker_fox said:

transferMCfg.retransmissions_max = 3;

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А нельзя в прерывании смотреть кто сейчас держит Mutex и от этого уже отталкиваться?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 07.05.2020 в 09:57, Spider сказал:

А нельзя в прерывании смотреть кто сейчас держит Mutex и от этого уже отталкиваться?

https://www.freertos.org/xSemaphoreGetMutexHolder.html

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, Andrew_Q said:

Дык я о том и говорю....

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Надо посмотреть чем отличаются fromISR функции от не fromISR и написать оберточку для обращения.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не нужно так глубоко залазить в железо, если есть HAL и RTOS. Как было правильно замечено, задача перед работой должна захватить мутекс. Потом работа идет по событиям. Пример - фрагмент драйвера KSZ9897:

void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c){
	if(hi2c == &hi2c1){
			osEventFlagsSet(I2C1EventHandle, 0x01U);
		return;
	}

}
void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c){
	if(hi2c == &hi2c1){
			osEventFlagsSet(I2C1EventHandle, 0x01U);
		return;
	}
}
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c){
	if(hi2c == &hi2c1){
			osEventFlagsSet(I2C1EventHandle, 0x02U);
		return;
	}
}


//--------------------------------------------------------------------------
uint16_t EthCtrlWrite8(uint16_t addr, uint8_t src){
	uint16_t res;
    uint32_t ret;

		abyEthCtrlTmpBuf[0] = src;

	if((res = HAL_I2C_Mem_Write_IT(&hi2c1, KSZ_I2C_ADDR, addr, KSZ_ADDR_SIZE, abyEthCtrlTmpBuf,  1)) != HAL_OK) {
		return res;
	}
		ret = osEventFlagsWait(I2C1EventHandle, osFlagsWaitAll, osFlagsWaitAny, osWaitForever);
    // TO DO 
  
	return HAL_OK;
}

Понятно, что Event нужно предварительно создать и проинициализировать.
Если девайсы на шине могут ВНЕЗАПНО пропадать и появляться, то в ожидании события osWaitForever надо заменить на определенное вменяемое значение и после срабатывания события проанализировать, чего же IRL мы таки дождались: проанализировать возврат ожидания и посмотреть флаги - кто вызвал событие. Ну и ГЛАВНОЕ - не забыть отпустить мутекс))) Тут мутекс не использован, потому что у меня девайсом монопольно рулить один процесс.
 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...