Вопрос или проблема
Я новичок в протоколе LIN и на данный момент изучил коммуникацию LIN и внедрил стек, который работает хорошо. Теперь я хочу реализовать таймауты N_CR и N_AS. Я хочу узнать, где этот таймаут реализуется и в каких условиях. Таймаут составляет 1000 мс.
В моем CAPL мастер-запрос (3C) и время следующего запроса составляет 50 мс.
Я использую таймер2 с 1000 мс.
Когда я использую TIMER_Enable(TIM2) в основной функции и отправляю несколько MasterReq из CAPL, отладка прерывается здесь в середине передачи.
void TIM2_IRQHandler()
{
if(timeout_type == N_CR_TIMEOUT)
{
timout_type = N_CR_ERROR;
}
Так где мне следует включить таймер: после получения FirstFrame или после получения следующего последовательного кадра?
Ответ или решение
В LIN-протоколе управление тайм-аутами, таким как N_CR (Timeout после передачи запроса управления) и N_AS (Timeout на ответ), является ключевым элементом для обеспечения надежности и синхронизации связи между мастером и слейвами.
Объяснение N_CR и N_AS таймаутов
-
N_CR (Control Request Timeout):
- Этот таймаут определяет максимальное время ожидания ответа от слейва на запрос управляющего кадра (Master Request). Если ответ не получен в течение установленного времени (в вашем случае 1000 мс), инициируется обработка ошибки таймаута.
- N_AS (Answer Timeout):
- Этот таймаут применяется, когда мастер ожидает ответа от слейва после отправки определённого запроса. Он также может быть установлен на 1000 мс. Если ответ не получен в течение указанного времени, это интерпретируется как ошибка.
Имплементация таймаутов
Для вашей реализации, вы должны правильно управлять запуском и остановкой таймера в зависимости от состояния обмена данными. Вот пример того, как это можно реализовать:
-
Инициализация таймера:
- Таймер должен быть инициализирован в вашем основном цикле или в начале связи. Например, используйте
TIMER_Enable(TIM2)
вmain
.
- Таймер должен быть инициализирован в вашем основном цикле или в начале связи. Например, используйте
- Использование таймера:
- Запуск таймера N_CR: Выполняйте это каждый раз, когда отправляете запрос управляющего кадра.
- Остановка таймера N_CR: Остановите таймер, когда получите ответ от слейва, либо когда будете готовы отправить следующий управляющий кадр.
- Сброс таймера N_AS: Запустите этот таймер сразу после отправки запроса и остановите его после получения ответа.
Пример кода
Вот пример того, как можно управлять таймерами внутри вашего прерывания:
void TIM2_IRQHandler() {
if (timeout_type == N_CR_TIMEOUT) {
timeout_type = N_CR_ERROR;
// Здесь можно обработать ошибку N_CR
}
else if (timeout_type == N_AS_TIMEOUT) {
timeout_type = N_AS_ERROR;
// Здесь можно обработать ошибку N_AS
}
}
void sendMasterRequest() {
// Отправка управляющего кадра
TIMER_Enable(TIM2); // Запустить таймер для N_CR
}
void receiveResponse() {
// Обработка полученного ответа
TIMER_Disable(TIM2); // Остановить таймер для N_CR
}
Правила управления таймерами
-
Таймер для N_CR:
- Активируйте его сразу после отправки управляющего кадра.
- Деактивируйте его как только получите ответ или отправите следующий запрос.
- Таймер для N_AS:
- Активируйте его сразу после отправки запроса слейву.
- Деактивируйте его, когда получите ответ от слейва.
Заключение
Таким образом, для корректной работы таймаутов в LIN-протоколе, необходимо правильно управлять запуском и остановкой таймеров в зависимости от конкретной ситуации в процессе обмена данными. Убедитесь, что таймеры и типы ошибок обрабатываются корректно, чтобы ваше приложение было более надежным.