2015-08-16 6 views
1

Я планирую использовать плату STM32 для отправки CAN-кадров. Я реализовал простой планировщик, который содержит 10 задач: одна задача будет отвечать за отправку фреймов.Планирование передачи кадров в RTOS

Чтобы сделать работу я объявленную структуру для CAN кадра:

typedef struct 
{ 
    unsigned int id; 
    unsigned char data[]; 
    unsigned char dlc; 
    unsigned int timeOfSend //This is the time in ms in which a frame should be sent 
}tFrame; 

А потом я объявленную таблицу кадров для отправки

aubFrames[MAX_FRAMES] = { 
    {0x12, 0xAABBCC, 4, 100}, 
    {0x12, 0xAABBCC, 4, 1000}, 
    {0x12, 0xAABBCC, 4, 2000}, 
    {0x12, 0xAABBCC, 4, 2010} 
}; 

Это сказать совет, чтобы отправить первый кадр после 100   мс, второй после 1000   мс и т. д.

Что я на самом деле делаю:

Я добавил новую задачу в планировщик с периодом 10   мс. Эта задача проверит таблицу aubFrames, и если пришло время отправить фрейм, он отправит соответствующий фрейм, иначе ничего не будет сделано. Проблема с этим решением заключается в том, что существует большая потеря времени. Например, чтобы отправить первый кадр, планировщик получит доступ к этой задаче девять раз, но ничего не делать.

Есть ли другое решение, чтобы планирование было более эффективным?

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

+0

Какие RTOS вы используете? – kkrambo

+0

Имея больше кадров, чем таймеры, не имеет значения. Один таймер может выполнить эту работу. Установите таймер для первого кадра, когда он срабатывает, сбросьте его для второго кадра и так далее. Не уверен, что так у вас уже есть настройка, но (на всякий случай у вас нет) обычно проще использовать «дифференциальные» времена, а не абсолютные. Таким образом, вместо каждого кадра, имеющего точное время с msec с начала (100, 1000, 2000, 2010), используйте «дифференциальное» время от предыдущего или «сейчас» в терминах процедуры обслуживания таймера. Пример: 100, 900, 1000, 10. Делает работу проще и текущая запись дает следующий раз. – tonypdmtr

+0

@kkrambo Я разработал ОС самостоятельно, у вас есть какие-либо предложения об операционной системе, которые могут быть полезны для меня – fedi

ответ

0

В большинстве RTOS есть несколько функций, которые кажутся им подходящими.

Один из методов заключается в том, чтобы задача приостановить себя в течение соответствующего времени (а не периодически просыпаться, чтобы опросить, будет ли это время). Например, FreeRTOS имеет функцию vTaskDelay, которая блокирует задачу в течение определенного периода времени. Ваша задача знает, что ей не нужно ничего делать за 100 или 1000 мс, поэтому она должна задерживаться на это время.

Другим методом является использование таймера программного обеспечения, а не аппаратного таймера. RTOS, по-видимому, уже получает периодический тик, поскольку он знает, что разбудил вашу задачу каждые 10 мс. Вероятно, у него также есть служба таймера программного обеспечения, например this one от FreeRTOS. Служба таймера программного обеспечения управляется аппаратным таймером, который использует планировщик RTOS. И это позволяет вам настраивать различные периодические и однозадачные таймеры программного обеспечения без необходимости использования другого аппаратного таймера. Ваша задача могла прочитать массив aubFrames и настроить таймер с одним выстрелом для каждого кадра, срок действия которого истекает в соответствующие моменты времени. Если вам не нравится идея всех этих таймеров программного обеспечения, запускаемых одновременно, установите следующий таймер с истечением предыдущего таймера.

+0

Спасибо kkrambo за разъяснение, я должен использовать таймер программного обеспечения. У меня есть дополнительный вопрос: представьте, нужно ли мне проверять, прошел ли переданный кадр (как в TCP/IP), поэтому я должен отправить фрейм и подождать некоторое время, чтобы проверить, не получил ли я оправдание. для меня я добавил обратный вызов к структуре tFrame для проверки, согласны ли вы со мной? , я думаю, что это становится немного сложнее, есть ли у вас какие-либо предложения или ссылки, которые помогают мне выйти из этой проблемы – fedi