Планировщик для микроконтроллера

14/06/2014 - 10:00 Владимир Шибанов

Введение

Вопреки расхожему мнению, применение планировщиков/диспетчеров позволяет значительно ускорить разработку приложений, затратив при этом совсем немного памяти. А, как известно, время разработчика дороже последней. Средний диспетчер занимает около 1 кБ flash. Это совсем немного, учитывая те возможности, которые он предоставляет.

Сделать свои программы более организованными мне, простому любителю, хотелось достаточно давно. Я опробовал на реальных устройствах событийную систему на таблице, диспетчер ДиХальта и планировщик. Последний меньше всего мне понравился. При использовании его "как есть" он, на мой взгляд, мало пригоден для создания приложений посложнее мигания светодиодами. Но у него есть один плюс, который меня покорил. Он очень, очень простой. А значит быстрый и надежный. Поэтому его я и взял за основу.

Итак, что же, как минимум, должно быть у диспетчера для полноценного его использования? На мой взгляд необходимо следующее:

1) Возможность однократного запуска задачи;
2) Возможность циклического запуска задачи с заданным периодом;
3) Возможность однократного или циклического отложенного запуска с заданной паузой;
4) Удаление задачи.

Перечисленного вполне достаточно для реализации самых разнообразных алгоритмов. При этом, как видим, ничего лишнего нет.

Доработка планировщика

Старый планировщик умеет запускать циклические задачи отложенно (или сразу). Это уже немало. Но чтобы реализовать весь желаемый функционал, пришлось изменить практически все его функции. Теперь по порядку.

Структура задачи и очередь задач остались неизменными:


typedef struct task
{
   void (*pFunc) (void); // указатель на функцию
   u16 delay; // задержка перед первым запуском задачи
   u16 period; // период запуска задачи
   u08 run; // флаг готовности задачи к запуску
}task;

volatile static task TaskArray[MAX_TASKS]; // очередь задач


Начиная с инициализации начинаются отличия. В исходном варианте очередь очищается путем обнуления параметров задач во всей очереди. Я же ввел дополнительную переменную «хвоста» очереди и просто обнуляю ее.


inline void RTOS_Init()
{
   TCCR0 |= (1<<CS01)|(1<<CS00); // прескалер - 64
   TIFR = (1<<TOV0); // очищаем флаг прерывания таймера Т0
   TIMSK |= (1<<TOIE0); // разрешаем прерывание по переполнению
   TIMER_COUNTER = 130; // загружаем начальное зн. в счетный регистр

   arrayTail = 0; // "хвост" в 0
}


Постановщик в очередь. В старом планировщике это функция AddTask. При наличии свободного места в очереди она добавляет задачу, даже если такая уже есть в списке. Мне показалось это неудобным, поэтому задача добавляется только в том случае, если ее в списке нет. В противном случае обновляются ее параметры: пауза до выполнения и период. Поэтому функция теперь называется SetTask. Это логичней.


u08 i;

if(!taskFunc) return;

for(i = 0; i < arrayTail; i++) // поиск задачи в текущем списке
{
   if(TaskArray[i].pFunc == taskFunc) // если нашли, то обновляем переменные
   {
      DISABLE_INTERRUPT;

      TaskArray[i].delay = taskDelay;
      TaskArray[i].period = taskPeriod;
      TaskArray[i].run = 0;

      RESTORE_INTERRUPT;
      return; // обновив, выходим
   }
}

if (arrayTail < MAX_TASKS) // если такой задачи в списке нет
{ // и есть место,то добавляем
   DISABLE_INTERRUPT;

   TaskArray[arrayTail].pFunc = taskFunc;
   TaskArray[arrayTail].delay = taskDelay;
   TaskArray[arrayTail].period = taskPeriod;
   TaskArray[arrayTail].run = 0;

   arrayTail++; // увеличиваем "хвост"
   RESTORE_INTERRUPT;
}
}


Следующий шаг - удаление задачи. В старом планировщике такая функция есть, но по индексу в очереди. На практике неудобно, поэтому она была изменена. Теперь задачи удаляются по имени, причем удаление происходит не смещением всех последующих задач на шаг назад, а переносом последней задачи на место удаляемой. Это гораздо быстрее.


void RTOS_DeleteTask (void (*taskFunc)(void))
{
   u08 i,j;

   for (i=0; i<arrayTail; i++) // проходим по списку задач
   {
      if(TaskArray[i].pFunc == taskFunc) // если задача в списке найдена
      {

         DISABLE_INTERRUPT;
         if(i != (arrayTail - 1)) // переносим последнюю задачу
         { // на место удаляемой
            TaskArray[i] = TaskArray[arrayTail - 1];
         }
         arrayTail--; // уменьшаем указатель "хвоста"
         RESTORE_INTERRUPT;
         return;
      }
   }
}


Для реализации однократного запуска была изменена функция извлечения задачи из очереди. Если подошло время выполнения (флаг Run установлен), проверяется значение периода, если он равен 0, задача просто удаляется из очереди.


void RTOS_DispatchTask()
{
   u08 i;
   void (*function) (void);
   
   for (i=0; i<arrayTail; i++) // проходим по списку задач
   {
      if (TaskArray[i].run == 1) // если флаг на выполнение взведен,
      { // запоминаем задачу, т.к. во
         function = TaskArray[i].pFunc; // время выполнения может
         // измениться индекс
        if(TaskArray[i].period == 0)
        { // если период равен 0
           RTOS_DeleteTask(TaskArray[i].pFunc); // удаляем задачу из списка,
        }
        else
        {
           TaskArray[i].run = 0; // иначе снимаем флаг запуска
           if(!TaskArray[i].delay) // если задача не изменила задержку
           { // задаем ее
               TaskArray[i].delay = TaskArray[i].period-1;
           } // задача для себя может сделать паузу
        }
       
        (*function)(); // выполняем задачу
   }
}


Таймерная служба осталась почти без изменений, разве что очередь теперь сканируется не полностью, а только до "хвоста".


ISR(RTOS_ISR)
{
   u08 i;

   TIMER_COUNTER = 130; // задаем начальное значение таймера

   for (i=0; i<arrayTail; i++) // проходим по списку задач
   {
      if (TaskArray[i].delay == 0) // если время до выполнения истекло
      TaskArray[i].run = 1; // взводим флаг запуска,
      else TaskArray[i].delay--; // иначе уменьшаем время
   }
}


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

Примеры использования планировщика

1) Запуск сканирования клавиатуры 100 раз в секунду


RTOS_SetTask(KeyScan, 0, 10); // период 10 мс, неотложенный запуск


2) В паяльной станции: после включения или изменения заданной температуры одну секунду показывается заданная, затем текущая, которая обновляется 3 раза в секунду. Всего 2 строчки, смысл которых будет понятен даже не программисту.


// где-то в программе

// вывод на экран текущей температуры каждые 300 мс
RTOS_SetTask(FEN_ViewCurrentTemp, 0, 300); 
...
...

FEN_TempUp()
{
...
// пауза до вывода текущей температуры 1000 мс
RTOS_SetTask(FEN_ViewCurrentTemp, 1000, 300);

// отображение заданной температуры (1 раз) 
RTOS_SetTask(FEN_ViewTargetTemp, 0, 0); 
...
}


3) Зажигаем светодиод на 5 секунд:


RTOS_SetTask(LED_ON, 0, 0); // зажигаем
RTOS_SetTask(LED_OFF, 5000, 0); // гасим через 5 секунд


4) Смена цвета моргания светодиода при смене режима работы:


// где-то в программе
mode = GREEN; // установили режим
RTOS_SetTask(Blink_green, 0, 500); // задали цвет моргания

// изменение режима
mode = RED;
RTOS_DeleteTask(Blink_green); // выключили зеленый цвет моргания
RTOS_SetTask(Blink_red, 0, 500); // задали красный цвет моргания

Файлы

scheduler.rar 


Автор статьи: Владимир Шибанов. 

Comments   

# Peter 2014-06-15 06:51
Гм... А в так называемом СтаромПланировщ ике регистр TIFR очищался правильно. Как видим, новое не есть улучшенное)
Reply | Reply with quote | Quote
# demiurg 2014-06-15 07:06
Все правильно. Скобки ставим, чтобы наверняка. Потому как, если скобки не ставить, нужно помнить приоритет операций. Я, например, не желаю забивать голову всякой херней, сидеть, вспоминать, а какой там порядок приоритета? Проще скобки поставить.
Reply | Reply with quote | Quote
# Peter 2014-06-15 07:15
Да не в скобках дело. TIFR у многих AVR не любит операций |=
Reply | Reply with quote | Quote
# demiurg 2014-06-15 07:21
Раз вы так сейчас сказали, значит, вы плохо знаете архитектуру AVR... Подумайте, прежде чем ответить.
Reply | Reply with quote | Quote
# demiurg 2014-06-15 07:26
Если вы не любите кошек, значит вы не умеете их готовить...
Reply | Reply with quote | Quote
# Peter 2014-06-15 07:27
Ууууу. Тогда советую Вам повнимательнее пояитать даташит хотя бы на весьма распрочтраненну ю мегу128. А именно об недопустимости применять инструкцию SBI для сброса регистров флагов, очищающихся записью 1. Удачи!
Reply | Reply with quote | Quote
# demiurg 2014-06-15 07:33
Обоснуйте. Конкретные примеры в студию.
Reply | Reply with quote | Quote
# Peter 2014-06-15 07:43
Подозреваю, что мои примеры Вас не убедят. Вместо благодарности за науку будете ругать. Поэтому я дал Вам точную наводку где и по каким словам искать. RTFM, уважаемый. Там все описано с объяснениями.
Reply | Reply with quote | Quote
# demiurg 2014-06-15 07:47
Э-э-э, нет! Вы ничего не подозревайте. Сказали, отвечайте. А то, получается, слились вы, батенька... Если я увижу что-то новое, то только поблагодарю вас. За что же тут ругать?
Reply | Reply with quote | Quote
# Peter 2014-06-15 07:55
Вы сначала почитайте в даташЫте на мегу128 все по ключевому слову SBI. Ладно? А потом пишите сюда)).
Reply | Reply with quote | Quote
# demiurg 2014-06-15 08:04
Так что вы этим хотели сказать, что sbi, cbi не работает для этого регистра? Так нормальный компилер си будет использовать команды соответствующие этому адресному пространству. И? Так что вы хотели сказать-то, уважаемый?
Reply | Reply with quote | Quote
# Peter 2014-06-15 08:23
Она очень даже работает)) Так хорошо работает эта SBI, что может сбросить уже стоЯщие там чужие флаги. Простой пример Налюбовавшись Вашим обращением к TIFR, пользователь так же будет применять операцию |= где-нибудь в критической секции. И тем самым сбросит появившийся только что флаг таймера 0 от вашего шедулера. Вы этого хотите? Уверен что нет.
Reply | Reply with quote | Quote
# demiurg 2014-06-15 08:27
Вот это уже речь не мальчика но мужа... :) Так и пишите, как сейчас написали.
А то любит, не любит. Мы что тут, на ромашке гадаем?
Reply | Reply with quote | Quote
# Peter 2014-06-15 08:45
Рад что Вы наконец поняли. А дело свое надо именно ЛЮБИТЬ. Тогда и предмет работы будет казаться живым. Удачи!
Reply | Reply with quote | Quote
# demiurg 2014-06-15 08:53
Как бы вы не одушевляли МК, камнем он и остается. И нужно знать, как заставить этот камень правильно шевелиться. Согласен, я не сразу вкупился в чем дело. Бегло глянул, вроде отличия только в скобках. Ну и успокоился. А то что вы рассказали, я и так знал.
Ну и удивился формулировке "не любит". И наличие команд sbi cbi. Делать новый проект, чтобы убедиться, какие команды будут подставлены мне лениво. Все равно я для этих регистров делаю прямую запись. Нули-то все равно бесполезно пихать, не так ли? В крайнем случаю лишний раз гляну в даташит, чтобы уточнить как запустить периферию.
Reply | Reply with quote | Quote
# Peter 2014-06-15 08:06
Почитали? А теперь я готов ответить на Ваши вопросы, если они остались.
Reply | Reply with quote | Quote
# demiurg 2014-06-15 08:11
1 - Что вы нашли противозаконног о? Отсутствие скобок в предыдущей статье? Где команды sbi, cbi у автора?
2 - Сама ваша формулировка "МК не любит, видите ли |=" А с чего вы взяли, что будут обязательно команды sbi, cbi ?!
Reply | Reply with quote | Quote
# demiurg 2014-06-15 08:14
Тьфу, блин, кажись сообразил. Вы имели в виду, чтение модификация запись? Это что ли? Так сразу бы и сказали.
А то МК не любит... Не "не любит"!!! Это формулировка начинающего любителя, который не знает чего ждать от МК и программы...
Reply | Reply with quote | Quote
# Peter 2014-06-15 08:37
Я пейсал что TIFR не любит... Да, новые МК от этого эффекта защищены.
Reply | Reply with quote | Quote
# Peter 2014-06-15 08:32
Да что с Вами? Операция |= по установке одного бита регистра в допустимом адресном пространстве пояти наверняка заставит компилятор поставить инструкцию SBI
Reply | Reply with quote | Quote
# Владимир 2014-06-18 14:09
Скобки я ставлю только для того, чтобы стоящие рядом команды установки и снятия (тут то скобки обязательны) бита были красиво выровнены. Люблю аккуратно оформленный код)
Reply | Reply with quote | Quote
# Владимир 2014-06-18 14:21
По большому счету, диспетчер и есть флаговый автомат, просто более структурированн ый
Reply | Reply with quote | Quote
# Владимир 2014-06-18 14:22
Не туда отправил, ну да ладно
Reply | Reply with quote | Quote
# Peter 2014-06-16 07:03
Ну что ж, с очисткой флагов регистра TIFR разобрались. Теперь, перед анализом багов собственно планировщика, надо научиться правильно запускать таймер. Пользователь, поверив "продвинутому разработчику планировщика", возьмет за основу этот метод, и так и будет запускать свои таймеры в своих задачах. И может огрести кучу траблов. Для исключения этого я просто перечислю шаги запуска таймера - на примере AVR, но, наверно, и независимо от МК.
1. Остановить таймер.
2. Задать в регистрах режим работы таймера (для AVR это TCCRA, TCCRC, если они есть. А если нет - то пропустить этот шаг). Причем делать это явным присваиванием (а не пресловутой операцией |= ). Регистр, где запускается таймер - не трогать.
3. Инициализовать счетный регистр TCNTn.
4. Инициализовать регистр(ы) сравнения OCCRn
5. В регистре TIFR cбросить флаги относящиеся к таймеру-пОциенту.
6. Разрешить нужные прерывания таймера, запрещая ненужные.
7. Запустить таймер, одновременно до-задавая режим его работы - для AVR это TCCRnB(если он есть) или TCCRn. Причем тоже операцией простого присваивания, а не |=.

После такой процедуры таймер не подведет.
Готов обсудить.
Reply | Reply with quote | Quote
# demiurg 2014-06-16 07:58
Трабла есть, если используется системный тик. Скажем, 1 мс. У меня сейчас сделано так:
Массив из нужного кол-ва таймеров. Структура массива: статусный байт, 16-битный счетчик. Прерывание настроено на 1 мс. В обработчике прерывания только перезапуск таймера, для точного отбивания по 1 мс. И установка флага. В основной программе вызывается Service_Timers. Зашли, проверили флаг, не установлен, вышли. Установлен, пробежались по массиву, если в статусном байте установлен флаг TMR_UNLOCK_FLG, декремент 16-битного счетчика. Обработка следующего таймера. Если флаг не установлен, обработка следующего таймера. Время вышло (0), установка флага TIME_OUT_FLG.
Reply | Reply with quote | Quote
# demiurg 2014-06-16 07:59
Этой таймерной службы мне хватает практически для всех проектов. Точность - +- 1-10 мкс.

Но есть но: представим ситуацию. Нам нужно запустить задачу на 10 мс. И установка таймера задача произошла перед прерыванием. В итоге получится не 10 мс, а 9 с небольшим. Но так как я эти таймеры использую в задачах, где 10, даже 100 мкс погоды не играют. Абсолютно. Ну будет разброс в мкс обработки матричной клавиатуры, или обновление символьного ЖКИ. Ну и хрен на него, на это расброс.

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

Дальше планирую допилить, чтобы был флаг инкремент-декре мент. И пауза таймеров. Например, это потребуется в следующих ситуациях. Есть оборудование с режимом "Пауза". Вот в этих случаях и требуется наличие паузы в таймерах.
Reply | Reply with quote | Quote
# demiurg 2014-06-16 08:00
http://pastebin.com/4Vz96ASs
Reply | Reply with quote | Quote
# demiurg 2014-06-16 08:00
delete
Reply | Reply with quote | Quote
# demiurg 2014-06-16 08:04
delete
Reply | Reply with quote | Quote
# Peter 2014-06-17 06:42
Вот мы дошли и до анализа потенциальной уязвимости "улучшенного планировщика". Кто мне объяснит, что будет, если вызываемая в фоновом режиме функция DispatchTask() прервётся от таймера во время доступа к двухбайтовой переменной TaskArray.delay?
Да, я о проблеме атомарности, если че))
Reply | Reply with quote | Quote
# demiurg 2014-06-17 07:28
В таких планировщиках не только проблема атомарности. Взять, к примеру диспетчер DI HALT-а. В его диспетчере, в начальной версии, на асме (в сишной я еще не копался, да и нет желания) два момента. 1. Таймерная служба работает в прерывании. 2. Дамоклов меч. Представим ситуацию, мы на таком диспетчере написали программу для станка. В очереди таймеров болтается задача на исполнение. И тут бац, аварийная ситуация. Ну ладно, встали в соответствующий режим, а из прерывания таймерная служба выстрелила задачу на исполнение. Потому и назвал дамоклов меч. И вот как теперь шерстить очередь на предмет удаления задач? Если мы даже не знаем, что можно удалять, а что нельзя. Мало ли какие моменты, пусть и аварийная ситуация.
На данный момент мой опыт: пока всякие диспетчеры мне ни разу не понадобились.
void main (void)
{
func_1 ();
func_2 ();
func_3 ();
}
Все! Главные принципы: модули, автоматное программировани е. Каждая задача разбивается так, чтобы не было долгих циклов. К примеру, системный тик 1 мс. И каждый пробег main должен с запасом уложиться в 1 мс.
Ну как-то так...
Reply | Reply with quote | Quote
# САБ 2014-06-17 11:17
Quoting demiurg:
На данный момент мой опыт: пока всякие диспетчеры мне ни разу не понадобились.
На данный момент мне ни разу не понадобились: FPGA, многослойные платы, долбежный станок, картофелеубороч ный комбайн, женские прокладки и много чего еще. Предлагаете доказывать всем их ненужность?
Reply | Reply with quote | Quote
# demiurg 2014-06-17 11:28
Нет. Всему свое применение. Только прежде чем лепить что-то свое, нужно прогнать как следует. Выявить недостатки.
И не диспетчеры нужно лепить, а научиться взаимодействию модулей.
Потому что эти материалы читают начинающие. Которые вроде как нашли решение, как же, ляпаешь как попало задачи, и они блин работают. А если таким начинающим придет в голову применить эти диспетчеры и потом вляпываются по самое не балуй...
Reply | Reply with quote | Quote
# Kodex 2014-06-17 14:12
Я вот сегодня доделал для себя версию этого "старого планировщика". Добавил два уровня приоритетов. Массив задачь такой же как здесь. Задачи готовые для выполнения суются в один из двух массивов, в зависимости от приоритета. После нек. количества запуска высокоприоритет ных задачь обязятельно запускается одна низкоприоритетн ая. Одно не пойму. Нахрена мне все это...
Reply | Reply with quote | Quote
# JoJo 2014-06-17 14:19
Спортивный интерес .. только и всего
Reply | Reply with quote | Quote
# Владимир 2014-06-18 12:21
Нда, не ожидал такой дискуссии) Постараюсь ответить на все вопросы:
1) по поводу |=. Установка флага в регистре TIFR у меня происходит именно так, архив чуть устаревший отправил Паше. Уже попросил его поправить статью. Я не силен в ассемблере, но команда TIFR |= (1
Reply | Reply with quote | Quote
# Владимир 2014-06-18 12:23
плин...
1) по поводу |=. Установка флага в регистре TIFR у меня происходит именно так, архив чуть устаревший отправил Паше. Уже попросил его поправить статью. Я не силен в ассемблере, но команда TIFR |= (1 shl TOV0); транслируется в 3 асмкоманды: IN, ORI, OUT. Ни разу у меня не было конфликтов, связанных с установкой флага с помощью |=. Возможно потому, что в инициализациях я не разрешаю глобальные прерывания. Делаю это уже перед основным циклом.
Reply | Reply with quote | Quote
# _Артём_ 2014-06-18 13:57
Quoting Владимир:
транслируется в 3 асмкоманды: IN, ORI, OUT.

Транслируется правильно, но сам алгоритм неправильный.

Quoting Владимир:
Возможно потому, что в инициализациях я не разрешаю глобальные прерывания. Делаю это уже перед основным циклом.

Видимо для ваших программ это не было важно.
Проблема может возникнуть в старых мегах - регистр TIFR зашарен между некоторыми таймерами. Поэтому в результате операции |= могут быть сброшены все флаги, а не один. В результате можно потерять прерывания или не отреагировать на нужный флаг.
И для сброса бита в TIFR достаточно записать в нужную позицию 1 - на асме это две команды:
Code:
ldi reg, 1<<BIT_POS
out TIFR, reg
Reply | Reply with quote | Quote
# Владимир 2014-06-18 14:29
Я использовал только меги8, 16, 32. Проблем не было. Как тогда правильно будет установить этот бит на С? Или только вставки делать?
Reply | Reply with quote | Quote
# JoJo 2014-06-18 14:41
Вот так
Code:TIFR = (1<<TOV0);
Без ИЛИ.
Reply | Reply with quote | Quote
# _Артём_ 2014-06-18 14:52
Quoting Владимир:
Я использовал только меги8, 16, 32. Проблем не было.

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

Quoting Владимир:
Как тогда правильно будет установить этот бит на С? Или только вставки делать?

Code:
TIFR=1<<TOV0;
Reply | Reply with quote | Quote
# Владимир 2014-06-18 15:02
Ну так в статье тогда все правильно, и в архиве тоже! Свою рабочую версию я исправил. Но все равно, учту на будущее. Спасибо!
Reply | Reply with quote | Quote
# Владимир 2014-06-18 12:23
2) Применение подобных планировщиков никогда не позволит соблюсти абсолютную временную точность выполнения задач. Погрешность может составлять до одного системного тика. И в этом нет ничего страшного, по крайней мере в большинстве приложений.
Reply | Reply with quote | Quote
# Владимир 2014-06-18 12:24
3) Атомарный доступ к переменной delay тут не обязателен. Уже говорилось в статье про исходный планировщик, что все готовые к запуску задачи (я называю это сценарий) должны уложиться в системный тик. Это довольно важный момент, который надо учитывать, если задачи требуют больших вычислительных мощностей.
Reply | Reply with quote | Quote
# Peter 2014-06-18 15:55
Гм.... ну уложились все задачив один тик. И... что, будут стоять на месте и ждать прерывания? Нет, DispatchTask() так и будет вызываться в фоновой программе(см. пример работы старого планировщика) . И таким образом опасность прерывания внутри чтения/записи двухбайтового delay сохраняется. Надо делать критическую секцию.
Reply | Reply with quote | Quote
# Владимир 2014-06-18 17:05
Да, будут стоять и ждать. К моменту, когда ожидается прерывание, все задачи с установленным флагом Run должны выполниться. В цикле только прочесывается очередь и проверяется этот флаг, который у всех (!) задач должен быть равен 0. Прерывание никак не может прервать обращение к переменной delay.
Reply | Reply with quote | Quote
# Peter 2014-06-19 07:56
Тогда зачем критические секции в SetTask() и DeleteTask(), если прерывание не пересекается с работой ни одной из задач?
Reply | Reply with quote | Quote
# Владимир 2014-06-19 13:06
Вы правы, незачем. Это следы моих экспериментов с минимальным временем системного тика. Можно убрать. Но еще раз подчеркну, очень важно, чтобы все активные задачи успевали выполняться за один тик!
Reply | Reply with quote | Quote
# Peter 2014-06-21 05:33
Но тогда зачем вообще здесь прерырвания? Будет проще после прлхода всех задач опрашивать флаг таймера - тем более точность тайминга при этом не ухудшится по сравнению с данной реализацией. Зато будет короче, понятнее и безо всяких флагов состояния задач.
Reply | Reply with quote | Quote
# Владимир 2014-06-21 06:18
Совершенствоват ь можно до бесконечности, главное вовремя остановиться. Меня устроила текущая реализация, поэтому я и остановился на ней.
Согласен с тем, о чем Вы говорите. Про опрос флага таймера в основном цикле я не думал. Возможно кто-нибудь захочет доработать этот диспетчер, добавить функциональност и. Например было бы неплохо добавить удаление задачи из списка через заданное время. Возможно сам доработаю, но уже не для avr, а для stm. Следующий проект будет на нем и планирую переводить туда этот диспетчер.
Reply | Reply with quote | Quote
# Владимир 2014-06-18 12:24
4) Применение диспетчеров не панацея от всего. И везде их совать ни к чему. Я это прекрасно понимаю. Но, уже в сотый раз, да ладно, приведу пример моей горемычной паяльной станции. Там применен этот планировщик. И мне бы очень хотелось бы сравнить код, выполняющий те же функции, что у меня реализованы, только без диспетчера, так же легко читаемый, структурированн ый, логичный. Удобство сопровождения я теперь ценю гораздо выше, чем года 3-4 назад. Станция уже почти готова, скоро выложу.
Reply | Reply with quote | Quote
# demiurg 2014-06-18 13:30
Не сочтите, что я вообще против диспетчера. Приведу пример. Не так давно я делал один проект. Блок управления, термоформовочны й станок. Типа СТА-150. Это: несколько датчиков, пульт управления (пульт оператора), символьный VFD, матричная клавиатура 4х4, выходы. В итоге получилось 3 порта дискретных входов, 1 порт клавиатура, 1 порт VFD, 2 порта выходы. Я взвесил и принял решение применить сдвиговые регистры для расширения ввода-вывода. 74HC165 и 74HC595. То есть, используется SPI. МК в DIP40 корпусе. Если что, вытащил из панельки, заменил.
Так вот никакого диспетчера у меня в помине нет. Main и список вызываемых функций. Все. А вы диспетчер в паяльную тсанцию засунули. Что у вас там? Кнопки, дисплей, неважно какой. Термодатчик, нагреватель паяльника. Ну управление питанием еще. Спрашивается, зачем в паяльной станции диспетчер? Лучше автоматным программировани ем бы занялись. И диспетчеры тогда вам еще не скоро понадобятся...
Reply | Reply with quote | Quote
# Владимир 2014-06-18 13:57
Паяльник, фен, корпус с 5-ю кнопками, два 3-символьных 7-сегментника, несколько светодиодов. Дело не в том, сколько чего вешается на порты, а в том, как разрулить все необходимые режимы работы системы. Причем так, чтобы было удобно сопровождать. Я ни в коем случае не заставляю всех использовать диспетчеры! Можно реализовать это на них, можно на автоматах или полноценных ОСРВ. Дело вкуса. Но я сделал так, мне понравилось, и решил поделиться.
Еще могу добавить по автоматному программировани ю. 2 года назад я делал контроллер управления гальванической линией металлизации печатных плат, а это: 5 ванн с терморегулирова нием и контролем уровня, 3 струйных промывки, включение источников тока и барботажа, система перемещения заготовки (2 шаговых дигателя с концевиками), дисплей. Делал на автоматах. Сейчас я даже не хочу в тот код залазить. Так вот, к чему я это? А к тому, что для каждой задачи надо выбирать оптимальное решение!
Reply | Reply with quote | Quote
# demiurg 2014-06-18 15:46
А писать надо нормально, чтобы можно было и потом в код заглядывать....

pastebin.com/Qdhdh370
Reply | Reply with quote | Quote
# Владимир 2014-06-18 17:07
Это приходит с опытом.
Reply | Reply with quote | Quote
# demiurg 2014-06-18 17:46
Вот именно. Я споткнулся на диспетчере DI HALT-а. Понимаете на тот момент у меня была проблема, взаимодействие модулей. Казалось бы, вот оно решение. Но облегчения не наступило. Но стало все наоборот. Вдобавок, я вовремя поймал засаду с дамокловым мечом. Примерно в то время на одном форуме мне указали на автоматное программировани е. Да и на асме я тогда застрял. Все слазить с него не хотел.
Когда у меня началось получаться с си, тогда я начал понимать, что мне говорили спецы на форуме.
Поэтому я и говорю, не стоит тратить время на диспетчеры, если еще не научился модульному программировани ю, автоматному программировани ю. И тогда тебе, возможно вообще не потребуются диспетчеры. RTOS - это уже иная тема...
Reply | Reply with quote | Quote
# Владимир 2014-06-19 13:20
Мне тот диспетчер тоже не понравился, но по другим причинам. Там не получится так прозрачно запустить такую простую задачу, как однократное включение нагрузки, скажем, на 1 минуту (примеры 2 и 3 в статье). Ну и куча лишних переборов очередей мне не нравится.
По поводу автоматов, когда задач становится слишком много, сложно понять структуру программы. Я ничуть не умаляю достоинств такой организации, тем более диспетчер по своей сути автоматом и является. Точнее его более структурированн ым вариантом.
Quoting demiurg:
не стоит тратить время на диспетчеры, если еще не научился модульному программированию, автоматному программированию

Вот с этим абсолютно согласен.
Reply | Reply with quote | Quote
# Владимир 2014-06-18 12:25
5) Создавать нужно то, что тебе нужно. А не делать что-то, а потом думать, а зачем?! Я лично писал диспетчер для конкретной задачи, формируя только то, что нужно мне. Результат мне понравился. Настолько, что решил опубликовать. Этот планировщик был первой моей публикацией в жизни.
6) По поводу тестирования. Я очень долго прогонял его и в симуляторе, и в железе. И он претерпел немало доработок. Но если кому-то захочется целенаправленно его потестировать на баги - я только за!)
Reply | Reply with quote | Quote
# Peter 2014-06-18 16:04
Насчет атоиарности доступа к "длинным" переменным, исрользуемым в прерывании - необходимо выполнять простые правила:
а) если переменная лишь читается в прерывании, то достаточно в фоновой функции обеспечить атомарность при ее изменении.
б) если переменная изменяется в прерывании - то в фоновой функции нужно обеспечивать атомарность и при ее чтении и при ее изменении
Reply | Reply with quote | Quote
# Kodex 2014-06-19 07:10
Владимир, можешь рассказать/пока зать что конкретно менял в коде при отладке?
Reply | Reply with quote | Quote
# Владимир 2014-06-19 13:55
Всего так сразу и не вспомнишь...
Из значительного: функция DeleteTask сначала сдвигала очередь после удаляемой задачи на одну позицию. Потом один человек подсказал идею с перестановкой только последней задачи. На тот момент функция Dispatch выглядела так:
Code:
void RTOS_DispatchTask()
{
u08 i;
for (i=0; i<arrayTail; i++)
{
if (TaskArray.run == 1)
{
(TaskArray.pFunc)();
if(TaskArray.period == 0)
{
RTOS_DeleteTask(TaskArray.pFunc);
}
else
{
TaskArray.run = 0;
if(!TaskArray.delay)
{
TaskArray.delay = TaskArray.period-1;
}
}
}
}
}

Довольно быстро проявился глюк, когда задача удаляет саму себя, установка delay происходила для другой задачи, которая вставала на место удаляемой. Поэтому функция Dispatch обрела такой вид, как в статье.
Reply | Reply with quote | Quote
# Владимир 2014-06-19 14:00
блин, форматирование не получается, все смещается на начало строки
Reply | Reply with quote | Quote
# demiurg 2014-06-19 13:33
В строках RTOS_Set_Task и тд RTOS_ я бы убрал. В данном случае у нас простенький диспетчер. Set_Task Del_Task будет вполне достаточно и верно.
Reply | Reply with quote | Quote
# Владимир 2014-06-19 14:10
Дело вкуса. Просто у меня так сложилось, что если модуль представляет собой самостоятельную структуру, я добавляю префикс. Только для того, чтобы видеть, из какого именно модуля вызывается функция: RTOS_, WH1602_, WG12864_, UART_ и т.д. Согласен, бросается в глаза. Но когда подключено много модулей, как-то понятнее выглядит программа.
Reply | Reply with quote | Quote
# demiurg 2014-06-21 06:30
Quoting Peter:
Но тогда зачем вообще здесь прерырвания? Будет проще после прлхода всех задач опрашивать флаг таймера - тем более точность тайминга при этом не ухудшится по сравнению с данной реализацией.

Плюсую. Диспетчер DI HALT-а сразу же так и переделал. У него в прерывании было, я вынес в основной цикл. В прерывании взводится флаг. В основном цикле проверяется флаг, если установлен, сброс флага, прочесывание очереди. Точность в единицы, десятки мкс не критична.
Я решил все-таки собрать диспетчер. Позже выложу результат.
Reply | Reply with quote | Quote
# Peter 2014-06-21 09:10
Да. А для точности тайминга и упрощения диспетчера лучше настроить таймер в режим СТС. Более того,раз это не прерывание, то там же в шедулере и сбрасывать вачдог.
Reply | Reply with quote | Quote
# demiurg 2014-06-21 10:12
Нахер. На AVR никогда больше не вернусь к диспетчеру. Диспетчеры и RTOS хороши в системах, где код загружается с какого-либо носителя. На AVR код программы во флеш. И хоть через диспетчер, хоть в main крути функции, обвешав флагами или автоматом, суть не меняется. Только через диспетчер функции дольше переключаются.
Если использовать диспетчер, то нужно четко определить, что считать задачей? Почему-то в диспетчерах задачей считают моргалку светодиодом. Воткнули моргалку, она исправно моргает, вау! Диспетчер, задача, епт! Хорошо, а если много светодиодов? И разные световые эффекты. Как тогда быть? На автоматах легко это делается. Через диспетчер замаешься разруливать.
Вот если вытеснение, тогда уже другое дело. Простенький переключатель задач уже имеет право на существование. Но опять же, нужно четкое определение, что такое задача. Это не какая-то функция, которая запускается через определенное время.
Задача диспетчеров - распараллеливан ие задач.
Но опять же, если следовать некоторым правилам, то выясняется, что диспетчер опять не требуется.
Правила простые. Модульность. Большие функции разбиваются. Никаких долгих циклов в функциях. Зашли, выполнили код, вышли. Проверили условие, вышли. Все это делается на флагах, автоматах, какие-либо условия.
Reply | Reply with quote | Quote
# Владимир 2014-06-21 17:38
Задача диспетчеров (планировщиков) - как раз таки запуск функции через заданное время. А распараллеливан ие задач - прерогатива ОСРВ. Не надо валить все в одну кучу. Для разных задач оптимальная организация программы определяется индивидуально. Тем более, кто Вам мешает в одну из задач диспетчера включить конечный автомат, реализующий эти самые световые эффекты. А потом задать период запуска этой задачи. Конечно, если вся программа состоит только из смены эффектов, то тогда да, смысла использования диспетчера нет. Но бывают ведь случаи и посложнее.
И при чем тут avr? Какая разница какая архитектура контроллера? Дело ведь не в ней, а в структурном представлении программы. Причем модульности последней никто не отменял!
На форумах иногда попадались личности, нежелающие использовать диспетчеры на avr, основываясь только на малом объеме памяти и быстродействии. Зато переходя на эти же stm первым делом изучали например freeRTOS. Только потому, что "так все делают". Появилась какая-то тенценция применения ОСРВ на ARM'ах, особенно, если присутствует мало-мальский графический интерфейс. На мой взгляд, совершенно необоснованная. Возможности диспетчеров позволяют в большинстве случаев обойтись без ОСРВ, а разница в быстродействии с автоматами измеряется микросекундами, не думаю, что сильно критично. Более того, могут быть ситуации, когда диспетчер окажется быстрее. Зависит от количества задач и частоты их запуска.
Reply | Reply with quote | Quote
# demiurg 2014-06-21 18:04
Диспетчер не может быть быстрее по определению. В обычном цикле нет переключения. На данный момент я не вижу для себя смысла в диспетчере. Если мне требуется что-то запустить с какой-либо периодичностью, достаточно флагов или конечного автомата. Если мне потребуется запустить моргалку светодиодом, мне не нужно превращать это в отдельную задачу. На автоматах можно запустить что угодно как угодно, в диспетчере же замаешься разруливать.
Вы недавно правильно сказали, дело в опыте.
Я мучался с диспетчером, пока меня не ткнули в автоматное программировани е. Поверьте, как только я увидел преимущество КА, сразу же выкинул диспетчер.
Reply | Reply with quote | Quote
# Владимир 2014-06-22 05:56
Это бесконечный спор.
Quoting demiurg:

Я мучался с диспетчером, пока меня не ткнули в автоматное программирование

Что не устраивало Вас в том диспетчере? Когда я сформировал свои требования и реализовал их, использование диспетчера приносит только удовольствие, никаких мучений!

Quoting demiurg:
На автоматах можно запустить что угодно как угодно, в диспетчере же замаешься разруливать.

Вобще не согласен, на своем диспетчере я делал подсветку для коньков с более чем 10-ю эффектами, в большинстве из них используются переливы. При этом есть ИК-синхронизаци я между ними + пара кнопок. Очень прозрачно все написано, даже после длительного перерыва можно быстро во всем разобраться. Я не спорю, можно сделать и на автоматах. В этом случае будет даже эффективней в плане производительно сти. Но прога и так простаивает большую часть времени. А удобство восприятия программы на диспетчере с функциями SetTask(func, delay, period) мне нравится гораздо больше, чем просто список функций, непонятно как и когда вызываемых. ИМХО.
Reply | Reply with quote | Quote
# Владимир 2014-06-22 05:58
Quoting Владимир:
При этом есть ИК-синхронизация между ними

Между коньками естесственно
Reply | Reply with quote | Quote
# Владимир 2014-06-22 06:01
del
Reply | Reply with quote | Quote
# Владимир 2014-06-22 06:02
Вы наверно видели реализацию, описанную в статье. Там же я принавал, что это криво и что исправленный вариант (не привязанный к диспетчеру, можно и с автоматами использовать) в комментариях.
Reply | Reply with quote | Quote
# Владимир 2014-06-22 06:03
ну что за... Про реализацию - это мой ответ на пост ниже
Reply | Reply with quote | Quote
# demiurg 2014-06-21 18:08
Кстати, я увидел вашу реализацию с короткими и длинными нажатиями. Вы диспетчер натягиваете, как ту сову, там где надо и не надо... Дайте ваш прямой контакт. Я отправлю вам пример, как можно спокойненько сделать на КА. И удержание (длинное нажатие по вашему), и автоповтор, и много чего еще можно сделать. И нафиг диспетчер не нужен.
Reply | Reply with quote | Quote
# demiurg 2014-06-21 18:19
И кстати, автор, посмотрите в сторону micro menu. В инете найдете. Только за основу возьмите оригинал, а не как там товарищ сделал. И вы тем более поймете, что диспетчер во многих случаях не нужен.
Reply | Reply with quote | Quote
# Владимир 2014-06-22 06:07
Микроменю я использовал в контроллере управления гальваникой, у меня там было ЕМНИП 168 пунктов меню - параметры системы для 3-х технологических процессов. Диспетчера тогда еще не было.
Reply | Reply with quote | Quote
# Владимир 2014-06-22 07:01
Quoting demiurg:
И вы тем более поймете, что диспетчер во многих случаях не нужен.

Так я с этим и не спорил. Даже наоборот, говорил что для каждой задачи организация программы выбирается индивидуально! Я не имею ничего против автоматов!
Reply | Reply with quote | Quote
# demiurg 2014-06-22 08:47
Вот вам ссылка is.ifmo.ru/works/ Цикл статей Татарчевского. Для поиска. Татарчевский В. Применение SWITCH-технолог ии при разработке прикладного программного обеспечения для микроконтроллер ов. Часть 1
Ну и там много еще чего интересного.
К примеру у Татарчевского рассказано, как можно реализовать опрос клавиатуры.
Вкратце: перед вызовом автомата сканируются кнопки. В зависимости от того, какая клавиатура, пишется соответствующая функция. Матричная клавиатура, на одном порту, на нескольких портах. Дальше работает конечный автомат. Главная идея: сколько бы кнопок не было, они обрабатываются, как одна. И вам не нужно извращаться с диспетчером. Лично у меня опрос клавиатуры идет в модуле вывода информации на дисплей. Ну а если уж так приспичило использовать диспетчер, смотрите по программе, как вам запускать. Или как самостоятельную задачу, или в составе модуля.
pastebin.com/URMd767u
Идем дальше. Как дальше использовать. Отсканировали, распознали кнопки. В буфере у нас код кнопки.
У меня это сделано так:
В конечном автомате:
Code:
void Tui_Service_Main_Init (void)
{
set_menu (L_OUT_MODE);
}

void Tui_Service_Main_Out_Mode (void) { if (proc_menu_keys ()) return; // Если была обработка кнопок - выход.
Reply | Reply with quote | Quote
# Владимир 2014-06-22 12:56
На контроллере гальваники я примерно так и делал, только железно, почти без дефайнов. Опыта маловато было. Была матрица 3х4.
Code:
key_code = 0;
SetPortKeys = 0x08;
PortKeys = 0x77;

if ((PinPortKeys&0x01)==0x00) key_code=HEAT_key;
if ((PinPortKeys&0x02)==0x00) key_code=PREV_key;
if ((PinPortKeys&0x04)==0x00) key_code=START_key;

SetPortKeys = 0x10;
PortKeys = 0x6F;

if ((PinPortKeys&0x01)==0x00) key_code=ESC_key;
if ((PinPortKeys&0x02)==0x00) key_code=SET_key;
if ((PinPortKeys&0x04)==0x00) key_code=ENTER_key;

SetPortKeys = 0x20;
PortKeys = 0x5F;

if ((PinPortKeys&0x01)==0x00) key_code=PAUSE_key;
if ((PinPortKeys&0x02)==0x00) key_code=NEXT_key;
if ((PinPortKeys&0x04)==0x00) key_code=STOP_key;

SetPortKeys = 0;
PortKeys = 0x40;

Потом в основном цикле проверял код кнопки.
В паяльной станции я сделал по другому, т.к. всего 5 кнопок.
Code:
void BUT_Scan()
{
// define | counter | short press | long press
TestButton (BUT_FEN_SET, &fenSetPressed, FEN_SetMode, FEN_Off);
TestButton (BUT_FEN_DOWN, &fenDownPressed, FEN_TempDown, NULL);
TestButton (BUT_FEN_UP, &fenUpPressed, FEN_TempUp, FEN_SaveTemp);
TestButton (BUT_SOLD_DOWN, &soldDownPressed, SOLD_TempDown, SOLD_Off);
TestButton (BUT_SOLD_UP, &soldUpPressed, SOLD_TempUp, SOLD_SaveTemp);
}

Согласитесь, приведенный фрагмент (если его выровнять, получится таблица) раскрывает весь функционал программы. К этому я и стремился.
Reply | Reply with quote | Quote
# Владимир 2014-06-22 13:12
Да, и какой это у меня изврат с опросом кнопок? Вызов его (опроса) каждые 10 мс осуществляется одной строчкой:
Code:
RTOS_SetTask(BUT_Scan, 0, 10);

Остальное разрулит фрагмент, приведенный выше. А он к диспетчеру можно сказать не имеет отношения.
Reply | Reply with quote | Quote
# Casper 2014-06-30 09:56
День добрый. А под ардуино такой планировщик сложно будет переписать? Его очень не хватает мне для проекта)) Постепенно ухожу конечно я с ардуино, но самый большой проект всетаки на нем остался...
Reply | Reply with quote | Quote
# Владимир 2014-06-30 13:44
Никогда не интересовался ардуиной, даже не знаю, какой там контроллер используется. Переделать несложно: поправить инициализацию аппаратного таймера в функции RTOS_Init, не забыть обновить счетчик в прерывании таймера (у меня это ISR(RTOS_ISR)). Разрешить глобальные прерывания. Все.
Reply | Reply with quote | Quote
# Casper 2014-06-30 17:30
Там проц atmega328 используется, но он сишный язык как я понял не понимает, надо под с++ переписывать..
Reply | Reply with quote | Quote
# _Артём_ 2014-07-01 08:37
Quoting Casper:
Там проц atmega328 используется, но он сишный язык как я понял не понимает, надо под с++ переписывать..

Как так? Что там переписывать нужно?
Если плюсы понимает, то си наверняка поймёт.
Reply | Reply with quote | Quote
# Владимир 2014-07-01 13:37
скорей всего компилятор ругается на функции авр студии. уберите из функций диспетчера DISABLE_INTERRU PT и RESTORE_INTERRU PT (они не обязательны). Затем уберите инклуды из файла commons.h. Там же удалите ENABLE_, DISABLE_ и RESTORE_INTERRU PT. После этого оформите программу по правилам вашей среды разработки.
Reply | Reply with quote | Quote
# Владимир 2014-07-01 13:39
Еще возможно потребуется изменить в главном файле .с строку
Code:
#include <rtos.h>

на
Code:
#include "rtos.h"
Reply | Reply with quote | Quote
# Casper 2014-07-01 16:34
Жалуется на это
Code:rtos.c: In function 'RTOS_Init':
rtos.c:15: error: 'TCCR0' undeclared (first use in this function)
rtos.c:15: error: (Each undeclared identifier is reported only once
rtos.c:15: error: for each function it appears in.)
rtos.c:16: error: 'TIFR' undeclared (first use in this function)
rtos.c:17: error: 'TIMSK' undeclared (first use in this function)
Reply | Reply with quote | Quote
# _Артём_ 2014-07-02 14:22
Quoting Casper:
Жалуется на это
Code:rtos.c: In function 'RTOS_Init':
rtos.c:15: error: 'TCCR0' undeclared (first use in this function)
rtos.c:15: error: (Each undeclared identifier is reported only once
rtos.c:15: error: for each function it appears in.)
rtos.c:16: error: 'TIFR' undeclared (first use in this function)
rtos.c:17: error: 'TIMSK' undeclared (first use in this function)

В mega328 нет таких регистров, вот и выдаёт ошибку. Там TIMSK соответствует TIMSK0, TIFR - TIFR0 и так далее.
Reply | Reply with quote | Quote
# Vlad 2014-07-21 06:57
Успешно прикрутил к STM8L.
Кому интересно -- пишите.
Reply | Reply with quote | Quote
# megannnn98 2014-08-01 09:44
Спасибо огромное за планировщика. :D реально нужная штука
Reply | Reply with quote | Quote
# megannnn98 2014-08-08 12:26
Единственное, что мне не хватило функции очистки очереди

void RTOS_Reset()
{
arrayTail = 0; // "хвост" в 0
}
Reply | Reply with quote | Quote
# Владимир 2014-08-16 09:03
Пожалуйста! А в каких случаях используете эту функцию?
Reply | Reply with quote | Quote
# demiurg 2014-09-02 10:47
Владимир. Что вы скажете насчет такого варианта? ссылка
Reply | Reply with quote | Quote
# Владимир 2014-09-02 12:33
Ответил в сообществе
Reply | Reply with quote | Quote
# Chugun 2014-09-17 20:35
Можно ли передавать параметры в задачу при добавлении её в очередь, как при работе с функциями ???
Reply | Reply with quote | Quote
# Владимир 2014-09-19 11:15
Нет, нельзя. Как вариант - использовать глобальные переменные.
Reply | Reply with quote | Quote
# Анатолий 2016-01-05 00:28
Спасибо за планировщик. Все работает четко.
Запустил на LED матрице 8х8. Параметр ПЕРИОД очень пригодился, позволил визуально проверить последовательно сть зажигания светодиодов и работу кода.
Маленькая поправка. В коде заголовочные файлы в угловых скобках (а не кавычках), поэтому компилятор ругается. Или это только у меня?!.
И еще было бы не плохо написать процедуру запуска с одной тестовой задачей (TskTest). Легче сразу разобраться.
Reply | Reply with quote | Quote
# Владимир 2016-01-09 08:12
Пожалуйста.
В свойствах проекта надо прописать корневой каталог проекта, тогда угловые скобки будут работать. Ну или переделать на кавычки.
Как пример можно посмотреть код моей станции. Там много файлов, но для начала надо смотреть ssf.c и buttons.c
Reply | Reply with quote | Quote
# Анатолий 2016-01-10 13:40
Quoting Владимир:
В свойствах проекта надо прописать корневой каталог проекта, тогда угловые скобки будут работать.


Спасибо буду знать
Reply | Reply with quote | Quote
# *Dim 2016-07-23 10:15
А нет ли полного проекта с этим планировщиком? Нужен пример "правильного" построения программы.
Reply | Reply with quote | Quote
# *Dim 2016-07-23 10:18
:-) Увидел ссыль на паяльную станцию, буду разбираться, спасибо.
Reply | Reply with quote | Quote
# Владимир_ 2016-07-26 09:46
Будут вопросы - спрашивайте. Я сюда периодически заглядываю.
Reply | Reply with quote | Quote
# arhiv6 2016-10-01 11:46
А зачем в функции void RTOS_DispatchTa sk() в строчке TaskArray.delay = TaskArray.perio d-1; отнимается единица?
Reply | Reply with quote | Quote
# Владимир_ 2016-10-12 04:34
Чтобы заданный период соответствовал действительност и. А иначе задачи будут выполняться через количество системных тиков period+1.
Reply | Reply with quote | Quote
# demiurg 2016-10-01 12:01
Мы с Владимиром уже обсуждали это творение. Остались при своих.
Этот планировщик и ему подобные не имеют никакого смысла. Потому что начинающие программисты считают, что подобные планировщики и диспетчеры якобы решают их проблемы. Но на самом деле приобретают лишний геморрой.
Решение главной проблемы (взаимодействие модулей и своевременное выполнение программного кода) следующее:
Исключение долгих циклов программных модулей, дробление выполнения модулями программного кода. Программные таймеры. Автоматное программировани е. Конечные автоматы.
Reply | Reply with quote | Quote
# ujin 2016-10-03 15:32
под разные задачи разные реализации...вы ше уже это говорили...поэт ому планировщику в этом мире есть свое место....с небольшой адаптацией вполне себе взлетел под CVAVrом
вполне нормально так работает...нагр евалки-мигалки аля подобное ак раз вполне это для него...
автору спасибо что делитесь своими знаниями ,и подробные объяснения по коду.
Reply | Reply with quote | Quote
# arhiv6 2016-10-24 04:14
Автор, я перенес планировщик на ARM и немного его доработал. Используются встроенные в ядро системный таймер SysTick и прерывание PendSV, что позволяет использовать планировщик на любом Cortex микроконтроллер е. Т.к. вся обработка сделана в прерываниях, в main вместо бесконечного вызова DispatchTask() можно оставить пустой цикл или заменить его на for(;;){idle()} ; - вызов какой-нибудь фоновой задачи, которую допускается в любой момент прервать остальными. Ещё добавил приоритеты задачам - если в один момент времени пришло время выполнить несколько задач одновременно - они выполняются в порядке, определённом их приоритетами. Собственно вопрос - у Вас в статье не указана лицензия проекта. Если я выложу код на github, достаточно того, что я укажу ссылку на эту статью и Вас в качестве автора изначального кода, на основе которого сделаны правки?
Reply | Reply with quote | Quote
# Владимир_ 2016-10-24 05:44
Более чем достаточно. Это 100%-ный OpenSource. Если не затруднит, оставьте здесь ссылку на гит. Интересно будет посмотреть.
Reply | Reply with quote | Quote
# arhiv6 2016-10-24 06:09
Вот, выложил: https://github.com/arhiv6/arm-task-sheduler
Reply | Reply with quote | Quote
# Владимир_ 2016-10-25 06:24
На практике уже пробовали его или просто ради удовольствия сделали?
Reply | Reply with quote | Quote
# arhiv6 2016-10-25 06:29
Ваш на практике пробовал в одном проекте. Свой - пока только пару тестов запускал. В ближайшее время буду небольшой проект делать - там попробую. Если какие-то правки/исправле ния вносить буду - внесу исправления в репозиторий и тут в комментариях напишу.
Reply | Reply with quote | Quote
# Антон_Ш 2016-11-20 05:05
Представляю вашему вниманию утилиту которая визуализирует выполнение задач данным планировщиком.

https://drive.google.com/file/d/0B6yun0FRTB-DalJhUmpFSF80Y28/view
Reply | Reply with quote | Quote
# Владимир_ 2016-12-13 04:15
С точки зрения программиста программа написана на высоком уровне. Она полностью самодостаточка. Приятно полазить, понажимать кнопки... Оценил график (делал нечто подобное), наверняка пришлось порядком повозиться.
С прикладной точки зрения все не так однозначно. Главная проблема - необходимость определять время выполнения каждой функции (знаю, в симуляторе AVR это легко). Для небольших проектов реально, но в ряде случаев это может стать проблемой.
В целом интересная утилитка. Мне понравилась.
Reply | Reply with quote | Quote
# mikhail 2017-10-11 16:02
Спасибо за интересную публикацию!
Читал с удовольствием как саму статью так и разгоревшуюся дискуссию в комментариях
Reply | Reply with quote | Quote
# Jonah 2017-10-12 12:02
Create Trackers for Twitter, Instagram and Facebook.


My web-site: best time to post
on social media: https://www.4shared.com/web/preview/pdf/H9p8vvU7ca?
Reply | Reply with quote | Quote
# Rashad 2017-10-15 09:53
Patriot Care is happy to provide the qualified sufferers of Massachusetts with a wide-variety of
medicine-grade, naturally produced marijuana products for
medical use with the best quality customer support
available. Some states have processes for certifying
and registering eligible folks. Some have additionally designated dispensaries, or medical marijuana facilities, the place
individuals can get the product and advice on dosing and what type
to make use of for his or her condition. Research
report that marijuana has doable profit for several conditions.
State legal guidelines range in which situations qualify individuals for treatment with medical marijuana.

If you happen to're contemplating marijuana for medical use, verify your state's regulations.
Nausea, vomiting or extreme wasting related to most cancers remedy.

If you're experiencing uncomfortable symptoms or unintended effects of medical remedy, particularly ache and nausea, speak with your physician about all your choices before attempting marijuana.


The state had nearly 10,800 registered patients as of the top of
last yr. Craig West, the dispensary operations supervisor, stated Thursday
the most important cause is that Compassionate Sciences is the
only one in the state to offer cannabis extract s to its
patients. In all probability between 20 and 30 p.c of our patients buy extracts,” he said, including that
a whole lot of sufferers journey two hours from the tippy-prime of the state” to obtain the extracts.
The primary cannabis-infuse d lozenges have been accredited for sale within the
state final October. At that time, the dispensary was selling a bottle of 30 grape- or
cherry-flavor lozenges for $75, or $60 if sufferers qualify for financial help, in response
to a discover despatched out to sufferers.

Which means the Egg Harbor-based mostly dispensary in Atlantic County is the second to the final in the state in terms
of patients and gross sales. According to the report,
about 4,seven hundred new sufferers registered for the program
final year, nearly doubling the number from the previous year.
WebMD describes spasticity as a muscle control dysfunction that
is characterised by tight or stiff muscle tissue and an incapability to manage
these muscle groups.” About 39 percent of patients who are
eligible for marijuana are recognized with this
situation. The second most common ailment was listed as severe or power pain,” based
on the Health Division report.

The brand new heart had some hiccups early Friday in the form of some laptop issues associated to the state's new customer monitoring system for ensuring patients don't exceed a
limit of 3 ounces in a 14-day period. But those hold-ups were nothing compared with the gradual
progress of Delaware's foray into medical marijuana , a point of frustration for many sufferers.
Marijuana is still unlawful below federal legislation, even for medicinal use.
But under state regulation, Delawareans can apply for a medical marijuana card to purchase cannabis at a dispensary so long as a physician has licensed that they
have sure qualifying situations, together with cancer, Alzheimer's illness, a number of sclerosis, HIV and illnesses that cause severe ache and nausea.



Legal points and construction delays pushed First State's opening in Wilmington back to mid-2015 - around the same time lawmakers
voted to decriminaliz e marijuana, downgrading possession of
1 ounce from a felony offense to a civil violation, like a parking ticket.
By then, greater than 300 Delawareans have been licensed to make use
of medical marijuana. At present, more than three,000 patients statewide are licensed to buy cannabis.
First State Compassion Middle, a new medical marijuana dispensary near Lewes.
As a substitute, the New Castle County dispensary has nearly doubled its crop production to accommodate
the Sussex County operation and growing demand close to Wilmington.

Columbia's facility is slated to open this fall, although
an exact location has not yet been disclosed. Shari Mosley, a
fifty seven-year-old Dover resident who makes use of medical marijuana to help
treat her multiple sclerosis, said she's trying
forward to with the ability to purchase cannabis nearer to residence.
The within of the Columbia Care medical marijuana dispensary is seen in New York
January 7, 2016.Shannon Stapleton. THE BIG APPLE (Reuters)
- New York state opened its first medical marijuana dispensaries on Thursday, launching one of the most conservative and tightly
monitored applications of its form within the United States.



Not like all the opposite states that permit medical marijuana except Minnesota, New
York prohibits marijuana for smoking. It permits the drug to be offered solely in liquid or oil form to be used in vaporizers and inhalers, or
capsules taken orally. In addition, New York requires a 4-hour mandatory training course for physicians before they can certify sufferers
and for pharmacists earlier than they will dispense the drug,
a requirement not mandated by different state applications, based on the National Convention of State Legislatures.
By allowing solely refined marijuana extracts, not smokable
crude plant or so-referred to as edibles, the state is
permitting for larger dosing standardization and purity,
Bednarczyk mentioned.

We're additionally proud to perpetuate the Cannabis
motion by way of our efforts in local and nationwide business and
affected person outreach programs. We strive to present the widest variety of regionally sourced and in home strains for our sufferers.
Signal up to obtain the most recent news and deals from The Clinic Nevada!

Nonetheless, we're too busy swooning over the plush interiors of America's rising dispensary architecture to care about any of those things.
The rising authorized marijuana industry is the quickest-growin g trade in the United States.
Indeed, there are even structure and design corporations that
specialize in the design of dispensaries and develop rooms.


Jensen stated the durability and security
of a financial institution added to the constructing's enchantment as a house for the
potential dispensary. Jensen, an lawyer turned entrepreneur who has worked as a mentor with the Maryland Middle for Entrepreneurshi p, Howard County's business incubator, mentioned his experience as a most
cancers survivor was one thing that led him to the medical cannabis
trade, which is simply getting its begin within the state.
The business' team also contains Melanie Galloway, the previous director of Crownsville's
Serenity Acres drug rehabilitation clinic. Evolution Wellness was certainly one of 12 businesses awarded
a dispensary license in December to function in Anne Arundel.


Rising Medical Marijuana Card Doctor and the Studio City Easy
Clinic in Valley Village additionally moved across the road to the easily accessible Starbucks shopping middle.

The Studio Metropolis Simple clinic is now at the nook of Laurel Canyon and Riverside
Dr at 12045 Riverside Dr Los Angeles CA, 91607. Open since 2009, Hollywood Easy Clinic and Medical Marijuana Card
Physician concentrate on medical hashish evaluations, recommendations , renewals, playing cards
and cultivation licenses for growing marijuana.
Cannabis in Hollywood Los Angeles has its biggest advocate with Medical Marijuana Card Physician of the Hollywood Simple Clinic.


California marijuana patients of Medical Marijuana
Card Physician on the Hollywood Simple Clinic are the best advocates for
how you can get a medical marijuana card.
You should use this advice alone to get access
to a cannabis club. However, a medical marijuana card is
offered via our clinic for $20. Solely after you might have a valid and verified medical hashish suggestion are you able to receive a
California State Verified medical marijuana identification card administered by your native
county Division of Public Well being. If you are at the moment ready over an hour at
one other docs workplace that looks just like the DMV, name and ask our cannabis clinic workers how simple
it's to get a medical cannabis card at one in every of our clinics.


These articles are thought of the California authority on medical
hashish.Medical Marijuana Card Doctor and his consulting marijuana physicians
comparable to Rising Medical Marijuana Doctor also work
at the Studio Metropolis Simple Clinic. Studio Metropolis Simple Clinic, open since 2011, serves the sufferers of Sherman Oaks, North
Hollywood, Van Nuys, Reseda. Our medical cannabis medical doctors train our
patients about the advantages of organic meals, train and pure medicine as
a complement to present medical care. Medical hashish patients as far west as Ventura County, Santa Barbara and Pismo Beach
come to see if cannabis could be a protected part of their therapy plan.

Renewals $forty five (renewal worth only counts if your suggestion hasn't expired prior to now 6 months) Full Bundle $eighty five.

Often called the California Compassionate Use Act,” Proposition 215 was
enacted by California voters and took effect on November sixth, 1996.

Marijuana Dispensaries are fashioned by these collectives or
teams of medical marijuana patients. Medical hashish in California has given energy again to the patient and made medical marijuana medical doctors objective observers to help patients in managing the advantages
of marijuana with the negative effects of marijuana.Medic al
marijuana card necessities have turn out to be higher defined because the
legalization of medical marijuana.

Alternative suggestions are $30 and includes a miniature advice so you're much less more likely to lose it
again. Medical Marijuana Card San Francisco Doctor is a local Californian with a family history of farmers from Sonoma County
in Northern California. He has worked with many different doctor's workplaces that specialize in medical marijuana and was dissatisfied
with the level of disregard for affected person nicely being.
However, he has utilized all of the greatest rules from each medical marijuana docs
office into his personal apply with the Hollywood Easy Clinic.
Hollywood Easy Clinic is a medical doctor's office that is situated in Los Angeles County, California specializing in medical
marijuana cards, evaluations, suggestions and renewals.


Our staff supplies steerage based on the affected person's needs and
most sufferers uncover sure strains that provide the very best aid for his or her individual symptoms.
Medical marijuana dispensaries are open in Nevada.

Anyone with a medical marijuana card (even from out-of-state) is allowed to possess as
much as 2.5 oz of hashish. Leisure and medical marijuana dispensaries are up and running in Nevada.
Nevada recognizes reciprocity with different medical marijuana states,
which means your medical card from out-of-state
is valid at any Nevada dispensary. The Easiest Method to Get a Medical Marijuana
Card from Medical doctors Who Care.

You'll even be issued a medical marijuana card and literature containing California's medical marijuana
legal guidelines. Your medical marijuana card
permits you access to holistic drugs all through the state, whether you
live in Downtown Los Angeles, Long Beach,
CA, Culver Metropolis, CA, South Gate, CA, Inglewood, CA, Huntington Park, CA or anywhere else.
Patients who have accomplished our medical examination with
a qualifying condition will receive a durable, plastic affected person ID card containing your
photograph, name, patient ID number, and your birthdate.
This card could also be presented to regulation enforcement and incorporates necessary information about California's medical marijuana
legal guidelines.

Also visit my blog ... marijuana clinic - www.smartmylife.fr: https://www.smartmylife.fr/smartnews/groups/california-is-the-first-state-to-cross-marijuana-legal-guidelines-to-permit-california-sufferers-to-satisfy-with-medical-doctors-in-clinic-or-online-by-way-of-tele-medicine-to-visit-with-420-docs-for/members/ -
Reply | Reply with quote | Quote
# Keisha 2017-10-15 15:00
I have noticed that your page needs some fresh
content. Writing manually takes a lot of time, but there is tool for this boring
task, search for: Wrastain's tools for content

Feel free to surf to my homepage PatX: https://Roy2009.blogspot.com
Reply | Reply with quote | Quote
# Margarita 2018-05-25 04:54
I'm ցone to say to my little brotһer, that he should also visit this webpage ߋn rеgular basis to obtain updated from latest repoгts.



My web-site: Parkwood Residences: http://www.showflatlocation.com/parkwood-residences-oxley/
Reply | Reply with quote | Quote
# Mona 2018-05-25 07:30
It gives fast file transfer with USB 3.zero
connectivity and you'll easily create scheduled backup plans with included software.


Feel free to visit my blog post :: usb backup windows: http://www.newkeys.co.kr/index.php?mid=app_review&document_srl=1058
Reply | Reply with quote | Quote
# Tina 2018-05-25 09:16
It's remarkable to ggo to see this web page
and reading the views of all colleagues concerning this piece of writing, while I
am also keen of getting familiarity.

Stop by my site Dollie: https://twitter.com/slumberserenity
Reply | Reply with quote | Quote
# Alecia 2018-05-25 10:54
I have checked your blog and i've found some duplicate content, that's why you don't rank high in google's search results, but there is a tool that can help you to create 100% unique
articles, search for: SSundee advices unlimited content
for your blog

Here is my web-site; LeiaBold: https://AliceTalks.jimdo.com
Reply | Reply with quote | Quote
# Terrence 2018-05-25 12:14
Fantastic blog you have here but I was curious if you knew of any discussion boards that cover the same topics talked about in this article?
I'd really like to be a part of online community where I can get
opinions from other knowledgeable people that share
the same interest. If you have any recommendations , please let me know.

Bless you!

my web page: Estella: https://Twitter.com/slumberserenity
Reply | Reply with quote | Quote
# Kara 2018-05-25 18:03
At US$3.four billion, NEO ( NEO ), is now the sixth largest among cryptocurrencie s and belongings.

RDNs, the team famous, are not needed on the core of the protocol, what
means anybody can use the Raiden Community with out having
the tokens. Offering: That is the ultimate version of the white paper, setting
out the phrases of a contract for the benefit of the buyers, made on behalf of the company entering into the ICO.
The ICONOMI Open Fund Administration (OFM) platform is
an easy management instrument where traders with knowledge
and experience create their very own funding funds.
His experience varies from online inventory market platforms to totally
integrated custom CRM methods.

TokenMarket is a marketplace for tokens, digital assets and blockchain based mostly investing.
At launch, weavechain will have the ability to process exchanges between Bitcoin, Ethereum, NXT, Counterparty, New Economy Motion, and Lisk.

Part of the information offered in the doc is nothing more than a business research with a monetary strategy primarily based on futuristic forecasting and different subjective information.
He joined the workforce in September 2016, bringing with him over 20 years
of engineering and enterprise experience from a variety of firms, including Points
International, NeoEdge Networks and AOL Time Warner.

On Nov 11, 2016 Golem's crowdfunding campaign raised 820 000 ETH (eight 8,600,000 USD on the time),
making it the second largest crowdfunding event on the Ethereum platform and sixteenth largest ever.
With Ambisafe you'll be able to quickly problem any type
of asset on the blockchain, and add it to cryptocurrency exchanges
worldwide. Altcoins - propped up by ERC20 tokens and ICOs - have
solely lately change into major market players.
It is towards this backdrop that we consider LALA World, the
blockchain company that seeks to make use of revolutionary expertise to assist unbanked populations obtain monetary inclusion.

Rising the entire quantity of mineable OneCoins from 10 000 coins
per block in the outdated blockchain to 50 000 coins per block in the
new blockchain, adding up to a complete of one hundred twenty billion cash,
allow OneCoin to broaden its consumer base and turn its plans for creating a robust global service provider network into a
reality. Digital native with 14+ years of International Advertising, Enterprise Development and Advertising experience.
With the October 22 ICO launch and change to be
unveiled in early 2018, Blockbid is expected to bear future growth,
enabled by way of the proceeds raised by person participation and progress.



Almost 72 million USD value of bitcoin (119,756 bitcoins) was stolen from from customers' accounts in one of the
largest alternate platforms in Hong Kong, Reuters
experiences. Digital asset,” asset,” coin,” digital forex,” good,” ledger entry,” altcoin,” and token” confer with
blockchain-base d mostly software ledger knowledge entries.
GlobeNewswire, a Nasdaq company, is among the world's largest
newswire distribution networks, specializing within the delivery of company press releases financial disclosures and multimedia content
to the media, funding group, particular person traders and
the general public.

What I've read to this point is that the value has modified to $1.
When the market decides the value, why wouldn't
the earlier investors take their earnings and cause a panic promote for the
people who bought in at ICO worth of $1, causing the
worth to plummet again to new help and there's always a
possibility that it will drop to $0.10USD or decrease.
This was announced at The Sensible Contract Market Platform in London and attended by trade giants similar to Miko
Matsumura of Pantera Capital, Renny Navaez of BNY Mellon, Angelique
Mohring, Founder CEO of GainX, Professor Olinga Ta'eed, Director of the not-for-revenue Suppose Tank, the Centre for
Citizenship, Enterprise and Governance (x Pedagog Limited and Hyper Solid) as well
as Nick Williamson, Founding father of Qadre, along with leaders
of industries.

SAFTLaunch, a US-based firm is dedicated to providing investors
a secure and compliant ICO platform. The method of
transferring funds to the manager is carried out by
shopping for a supervisor's cryptocurrency on the inner
trade. Institutional investors don't enter the cryptocurrency market attributable to legal restrictions.
This publish is a part of the ICO Highlight, a sequence of posts
with the groups behind the different tasks covered by Coinschedule.
Coin ICOs typically sell participation in an financial system, whereas token ICOs sell a proper
of ownership or royalties to a project or DAO.

Moreover, the funds will be spent on different initiatives, together with the event of decentralized apps
based on the Raiden know-how. In whole, 2.5bn BNK tokens have
been sold for 25M EUR, making it one of the largest pre-ICOs ever.
Vital: Digital currencies, tokens, and digital belongings are, by their
nature, typically irreversible, and their alternate charges are
extremely risky and transitory. Monetary information is launched as per the
principles of the trade on which the IPO happened, whilst for
ICOs, these will either be public by the use of the blockchain or as outlined inside
the white paper and agreement with the traders.

Buyers can ask for his or her funds to be returned at
any level after the ICO ends. 65% of all funds raised will
go instantly into development and increasing the staff behind Nexus.

5,000 Tokens and one bonus. The aim of this ICO
is to boost enough capital to establish a de-facto cost platform in the cryptocurrency world
and changing into a leading Fintech startup in digital funds.
Wanchain seeks to create a new distributed monetary infrastructure, connecting completely different blockchain networks together to alternate
value.

My site - zcash mining wallet (pas.agapecare. net: http://pas.agapecare.net/UserProfile/tabid/57/userId/1083475/Default.aspx)
Reply | Reply with quote | Quote
# Adelaide 2018-05-25 19:55
Development started September 18th, 2017, on 265 new, inexpensive flats at Concourse Village West within the
Fleetwood - Concourse Village neighborhood of the Bronx.

Utilizing our fast search you can search for properties by tackle, internet ID, or building title.
Revealed tax charges may differ slightly from
the average efficient rates utilized by NeighborhoodSco ut, the place NeighborhoodSco ut's tax rates extra intently follow the taxes paid by property house owners.

The true property data and related content displayed on this website is offered for shoppers'
private, non-business use and is probably not used for any objective apart from to determine prospective properties consumers could also be involved in purchasing.
Inbuilt 1910, this 4-story walkup constructing with 6 flats and three
stores has 7,520± SF.

Walk a few blocks west of the Grand Concourse and discover Macomb Dam Park,
a new state-of-the-ar t recreation area built on the rooftop of the two story Ruppert Plaza
Storage, throughout the street from Yankees Stadium.

Kamber is anxious that the current residents of the Bronx will get left behind in the actual property shuffle, whether or
not it instantly impacts their buildings or not, and that the neighborhood still will
not have the vital companies that residents really want.
If you'd like to talk to one in all our friendly real estate brokers about
homes and property on the market or hire in Australia, contact Century 21
McCann Alliance (Beaumaris) at the moment.

Discovering the perfect location and house means discovering the suitable
real estate agent to help you, one who fully understands each step of the method, from
navigating the market, to negotiation, to closing.
Your search for Real Estate Listings for Sale in Fleetwood - Concourse Village returned no outcomes together with your selected standards.
Uncooked crime incidents are sourced from all 18,000+ native law enforcement agencies - municipal,
county, transit, park, port, university, tribal and more, assigned to localities, then built into NeighborhoodSco ut's proprietary predictive fashions to provide a complete crime danger profile for each
neighborhood and tackle-vicinity in the U.S.


Discover your dream house in Concourse Village Elementary School utilizing the instruments above.
1749 Grand Concourse, known as the Lewis Morris building, was purchased by an un-named Brookl yn primarily based non-public investor in an off-market deal brokered by Steven Vegh of
Westwood Realty Associates. For house patrons, our information of the Brooklyn New York real estate market is second to none.
In the final 180 days, 8 industrial actual property
listings have come available on the market, which means new listings
is perhaps going fast. Deals within the South Bronx, comprising neighborhoods such
as Mott Haven, Morrisania, Melrose, Port Morris and
Hunts Point, accounted for half that figure.

For less than $300,000, you can get this two-bed room, one-toilet co-op at 1100 Grand Concourse.
Situated mid-block on the north facet of Canal Avenue between West Broadway
and Wooster Avenue, the ground ground retail space enjoys large foot-site visitors all through the neighborhood and features a 3,500± SF
rentable basement. With Point2 Homes, you may simply flick thru Concourse Village, Bronx, NY single household houses
for sale, townhouses, condos and industrial properties, and shortly get a basic perspective on the true estate costs.
Concourse Village is the 57th most walkable neighborhood in New York with
a Stroll Rating of ninety six.

Located in the SoHo Forged Iron Historic District, the 21,000± square foot constructing incorporates 6 residential lofts,
1 retail retailer and a sub-basement. The BQE, this isn't:
 The Grand Concourse, which stretches four miles all through the Bronx, is much out of your
average freeway. three - Similar Value (Similar value per square foot to different neighborhoods nearby).
As not too long ago famous by the New York Occasions, a number of young families are pouring in from
Manhattan and other areas of Brooklyn, benefiting from the
presently low real estate prices. Model new building: accomplished in 2016
with 421A approval sixteen unit residential 7-story elevator constructing with 1 giant retail tenant All flats are luxurious with modern kitchens and heated
rest room flooring 14,600 SF constructing with over 5% Cap Price.


In-built 1933, this single story retail building with retailer has roughly 10,000 SF. Between Vanderveer Place and Ditmas Avenue.
PORTFOLIO ABSTRACT: 14-18 Gabriel Drive, Bronx, NY 10469 (The Properties”) includes three 2-story walk-up buildings with 6 residences, and totals 7,
920 SF. The properties are located between Allerton Avenue and Mace Avenue
in the Pelham Gardens neighborhood of the Bronx. The decrease concourse, which runs from 149th Avenue to the
tip at 138th Avenue, is generally residential, with extra co-op buildings.
In 2011, the Landmarks Preservation Commission designated a historic
district alongside the Grand Concourse from 153rd to 167th Avenue.


10,000 SF with 100' of frontage on South 11th Avenue. Unit 3F at 1075 Grand Concourse was obtainable at $251
per sq. foot. Awaye Realty presents unparalleled service to ALL shoppers within the Brooklyn New York real
property market. Inbuilt 1929, this property has approximately 6,799 ±SF.

Awaye Realty serves your entire Brooklyn New York real estate market
including the encompassing communities such as the Bronx, Manhattan, Queens, and Staten Island area.
Fill out the form beneath and we'll send you listings that match your property search the
second they hit the market. In-built 1900, this 5-story walkup
building with 20 apartments has approximately 6,490 SF. Cap Charge (%) 4.three.
Roof has been up to date with aluminum coating; fireplace
escape has been repainted and maintained; and all
electrical work has been redone.

Built in 2006, this 7-story elevator constructing with 20 residences, 2 stores, 15 indoor parking
spaces and has roughly 31,909 SF. The Bronx County Bar Affiliation referral service
shouldn't be-for-revenue and can get you a screened, for quality, effectiveness,
and repute, legal professional that represents purchasers in Actual Property matters in New York State, including New York Metropolis and Bronx County.

800 Grand Concourse is a full-service constructing on Grand Concourse
and East 158th Avenue- a just lately landmarked neighborhood.

This is likely one of the nicest buildings on the Grand Concourse.

2866 Marion Avenue, Bronx, NY 10458, models 3J,
5J, 6E, and L2 (The Property”) is a 7-story elevator
cooperative building with 67 apartments, which totals seventy
one,652 SF. The property is positioned between East 199th Avenue and Bedford Park Boulevard in the Jerome Park neighborhood of the Bronx.


In terms of stock, the variety of houses for sale increased marginally year-over-year by 12.5 %, a positive development for future house
hunters trying to buy a bit of this vicinity's actual estate.

Previous performance takes into consideration the
last 10 years of noticed house worth appreciation and present fundamentals embrace key components that NeighborhoodSco ut's analyses have discovered to ensure
properties maintain worth in a downturn. The 36,000± SF property consists of two adjacent 4-story walkup buildings containing 32 residences, of
which 21 have been fully renovated with rental-quality finishes.


Neighborhood adjustments will not be simply confined to real
estate prices. 811 Walton Road, right off the Grand Concourse, can also be identified for
its impressive foyer, while 1150 Grand Concourse has an impressive facade with a coloration mosaic of undersea creatures flanking the primary entrance.
View Coldwell Banker Residential Brokerage Bronx actual property agents
or workplaces and let us assist you to find the perfect property.
Solely NeighborhoodSco ut® has nationally comparable school
scores that facilitate accurate comparison among colleges, school
districts, and neighborhoods in the identical (or totally different) cities, and even between colleges in several states.


Also in Pennsylvania are the 225,000-sf Larkin Middle in Boothwyn, anchored by Super Recent and Wal-Mart, and the 132,000-sf Retailers at Cedar Point in Allentown, with grocery anchor Weis Markets.

There weren't any fires breaking out along the Grand Concourse,” says
García Conde, although the neighborhood misplaced its repute
of grandeur and many house owners stopped investing
within the upkeep of their buildings. He envisioned the Grand Concourse as New York's model of the Champs-Élysées— solely longer—and
the venture would span one hundred eighty ft throughout, with bicycle
paths, pedestrian sidewalks and three distinct roadways
split by lush landscaping.

At this time we're making a long run investment in the
South Bronx, with permanent affordability locked-in for more than a hundred of these 265 reasonably priced
properties, along with new retail and neighborhood facility area,” mentioned Eric
Enderlin, president of the New York Metropolis
Housing Growth Corp. In-built 1929, this 4-story corner walkup constructing
with 30 apartments has roughly 27,520 SF. Near Brookdale Hospital Medical Middle.

Besen  a single-story retail building with approximately 2,852± SF on the ground flooring and a 2,852± SF selling basement with double stair
case and 14' feet ceilings.

In-built 1926, the Property consists of three contiguous four-story plus
basement walkup buildings with 39 residences totaling 25,578± SF.
The Burke Avenue subway station 2, 5 trains present convenient
access to the Property. In case you're on the lookout for properties and houses on the market or hire in Melbourne - Inside South, Victoria, Century 21 McCann Alliance (Beaumaris) has a broad number of residential and industrial actual estate to go well with all budgets.

The information regarding real property for
sale on this web site comes in half from Hudson Gateway Multiple Itemizing Service, Inc.
Fleetwood - Concourse Village is situated in Bronx, New York.



3000 Valentine Avenue, Bronx, NY 10458, models 1E, and 6E (The Property”) is a 6-story elevator cooperative building with fifty seven flats, which totals
fifty five,800 SF. The property is positioned between East 201st Road and East 202nd Avenue in the Jerome Park neighborhood of the Bronx.
In-built 2003, this 2 unit retail condo with three,650± SF on the bottom floor of a 7-story condominium con structing additionally has a
2,700± SF basement. Besen additional reading: http://www.tucsonjamz.com/phpbb3/viewtopic.php?f=4&t=1175776
Reply | Reply with quote | Quote

Add comment