pochta 0 12 декабря, 2008 Опубликовано 12 декабря, 2008 · Жалоба В FreeRTOS работа двоичного семафора реализована в виде макросов, которые вызвают функции очереди при создании семафора, на самом деле вместо семафора создаётся очередь в 1 элемент размером в 0 байт. Другими словамии Двоичный мемафор -- очередь 1 элементx0 байт В итоге получаеться что почти все элементы структуры Очереди не используются: из двух списков (списки читателей и писателей) используеться только один. Переменные "Счётчик элементов" и "Размер элемента" всегда заведомо равны 1 и 0, так зачем их хранить в памяти???? Не знаю как создатель ОС -- Ричард Барри, но по моему тратить такое ценный ресурс как ОЗУ на двоичный семафор расточительно. В связи с этим я написал свой вариант Двоичных семафоров Он выложен на http://freertos.narod.ru. В нём в качестве двоичного семафора используеться толко Один список то есть typedef xList Semph, что позволяет экономить на памяти, и выигрывает в скорости. Особенно это может быть применено в системах где не нужны очереди сообщений, где нужны только семафоры. Если кого заинтересовало прошу скачивать и пользоваться. Если это чудо зароботает у кого ещё можно и написать что-нибудь тут! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 1 12 декабря, 2008 Опубликовано 12 декабря, 2008 · Жалоба Не знаю как создатель ОС -- Ричард Барри, но по моему тратить такое ценный ресурс как ОЗУ на двоичный семафор расточительно. На самом деле семафор эта такая сущность, задачи которой можно рещить, особенно в микроконтроллерном мире, другими способами. По этой причине реализация его ввиде макроса на очереди позволяет его в первом приближении иметь, напимер при быстром портировании чего либо готового, причем во вполне рабочем и отлаженном варианте. В связи с этим я написал свой вариант Двоичных семафоров Он выложен на http://freertos.narod.ru. В нём в качестве двоичного семафора используеться толко Один список то есть typedef xList Semph, что позволяет экономить на памяти, и выигрывает в скорости. Особенно это может быть применено в системах где не нужны очереди сообщений, где нужны только семафоры. Систем, где нужны очереди/сообщения переделал за свою жизнь немало, а вот на голых семафорах как-то не приходилось еще задач встречать. Если кого заинтересовало прошу скачивать и пользоваться. Посмотрю обязательно! P.S. Оказывается раньше уже смотрел :) Оталось проникнутся и попробовать живьем, при случае! Не знаю как создатель ОС -- Ричард Барри, но по моему тратить такое ценный ресурс как ОЗУ на двоичный семафор расточительно. Пообщаться пробовали :) :( ? Мужик сильно упертый :(, на мой взгляд. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pochta 0 13 декабря, 2008 Опубликовано 13 декабря, 2008 · Жалоба На самом деле семафор эта такая сущность, задачи которой можно рещить, особенно в микроконтроллерном мире, другими способами. Семафор -- основа основ, а другими способами, это как? -- бесконечный цикл ожидания или система управляемая событиями? -- тогда это как-то не по ОС-овски выходит. Систем, где нужны очереди/сообщения переделал за свою жизнь немало, а вот на голых семафорах как-то не приходилось еще задач встречать. Ну не знай, по моему первое и самое простое, основа основ -- семафор. Семафор используется для защиты от совместного доступа к одной и той же части устройства или одним и тем же переменным. Зачем мне тут очередь каких-то сообщений? Мне главное чтобы одновременно эту часть устройства не использовали несколько потоков. Даже там, где передаётся информация, можно обойтись семафором, если пара производитель/потребитель( читатель/писатель) в определённый момент времени существует всего лишь одна. То есть никогда нет такого, что два читателя или два писателя. Вот у меня так на атмеге написана работа с АЦП, SPI, TWI, просто и со вкусом: очень даже неплохо работает семафор + указатель на буфер + счётчик и всё тут: приложение заказывает небходимое число байт а прерывание заполняет ему буфер, пока то висит на семафоре. Множно сказать, что я и написал очередь сообщений, ан нет! то как написано на полноценную очередь сообщений не катит, так как и писатель и читатель всего лишь один, и вообще писатель не задача а прерывание. Пообщаться пробовали :) :( ? Мужик сильно упертый :( , на мой взгляд. Пробовал! Особого энтузиазизьма у него это не вызвало! И у меня немного чешуться руки "утереть ему нос" за это. На мой взгляд тоже упёртый и гнёт свою линию жёстко. У него есть своё вИденье того, как надо развивать своё ПО. Ну чтож влаг ему в руки. Мне кажеться, дело всё в том, что у него двойное лицензирование. И то, что он развивает FreeRTOS под GPL -- это просто хороший рекламный трюк. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 1 13 декабря, 2008 Опубликовано 13 декабря, 2008 · Жалоба Ну не знай, по моему первое и самое простое, основа основ -- семафор. Семафор используется для защиты от совместного доступа к одной и той же части устройства или одним и тем же переменным. Ну давайте по порядку, если это какая-то "мелкая" недолго занимемая часть устройства, то для разруливания доступа к ней совершенно незачем дергать ядро системы ввиде семафоров. Тут много более эффективнее критические секциии во всем своем разнообразии, начиная с банальных запретов прерываний. Если это действительно сложное и долго обслуживаемое "устройство", то очень часто его обслуживает свой, действительно сложный процесс - тут уже может быть буферизация, приоритеты, замораживание процессов... Даже там, где передаётся информация, можно обойтись семафором, если пара производитель/потребитель( читатель/писатель) в определённый момент времени существует Ну зачем-же обходится-то :) надо все делать наиболее бескомпромисно :) Вот у меня так на атмеге написана работа с АЦП, SPI, TWI, просто и со вкусом: очень даже неплохо работает семафор + указатель на буфер + счётчик и всё тут: приложение заказывает небходимое число байт а прерывание заполняет ему буфер, пока то висит на семафоре. Множно сказать, что я и написал очередь сообщений, ан нет! то как написано на полноценную очередь сообщений не катит, так как и писатель и читатель всего лишь один, и вообще писатель не задача а прерывание. Ну-ну... Семафор-то зачем? Задача вообще спит "вечным" сном. Обработчик прерывания получив порцию чего-то и положив в буфер поднимет задачу. Так у меня издревле, например, консолька работает - набежала командная стока - поднимаем задачу с ней разбирающуюся. static __noreturn void Console( void *param ) { ....... cbuf_parser( &cmd, &cbuf.buf[0] ); // Call Command Line parser vTaskSuspend( NULL ); } } __irq __arm void uart_isr( void ) { ...... case '\r': xTaskResumeFromISR( handle_Console ); break; ..... } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pochta 0 14 декабря, 2008 Опубликовано 14 декабря, 2008 · Жалоба Ну-ну... Семафор-то зачем? Задача вообще спит "вечным" сном. Обработчик прерывания получив порцию чего-то и положив в буфер поднимет задачу. Так у меня издревле, например, консолька работает - набежала командная стока - поднимаем задачу с ней разбирающуюся. static __noreturn void Console( void *param ) { ....... cbuf_parser( &cmd, &cbuf.buf[0] ); // Call Command Line parser vTaskSuspend( NULL ); } } __irq __arm void uart_isr( void ) { ...... case '\r': xTaskResumeFromISR( handle_Console ); break; ..... } Ну дак это вы заранее знаете какая у вас там задача консоль ждёт, а я вот не знаю заренне какая задача у меня будет ждать очередные 10 имерений с АЦП. Что мне прикажете делать? Тут я вижу два варианта 1. в особую глобальную переменую задача ложить свой handle , а потом прерывание делает xTaskResumeFromISR( эта глобальная переменная); что по сути и являеться вариантом списка ждуших задач на одном семафоре. 2. Использовать очередь сообщений, но пардонте, в очереди сообщений есть две штуки которые жрут память 1. песполезно болтаеться список процессов ждуших к отправке занимает 9 байт(не бог весть что но у меня вообще эти 10 измерений АЦП занимаю 20 байт) 2. очередь имеет буфер который на фиг мне не нужен (тоже жрёт память) 3. Вариант делать спец процесс который будет принимать заявки и что-то там кому-нибудь раздавать -- вообще не катит так как займёт ещё больше ОЗУ Ну давайте по порядку, если это какая-то "мелкая" недолго занимемая часть устройства.... Вот в том то и дело, что мелкая но долго занимаемая -- у меня например АЦП долго работает! Ну зачем-же обходится-то :) надо все делать наиболее бескомпромисно :) Вот я и стараюсь безкомпромисно, только относительно размера бесполезно затрачиваемой ОЗУ, да и по скорости простой семафор явно быстрее очереди сообщений работать будет! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 1 14 декабря, 2008 Опубликовано 14 декабря, 2008 · Жалоба 1. в особую глобальную переменую задача ложить свой handle , а потом прерывание делает xTaskResumeFromISR( эта глобальная переменная); что по сути и являеться вариантом списка ждуших задач на одном семафоре. Типа да, и без дополнительных сущностей. 2. Использовать очередь сообщений, но пардонте... Это смотря как ее использовать, например можно сладывать в нее указатели на внешний буфер. Можно ее блокировать и складывать в обработчике прерывания результаты прямо ее буфер.... 3. Вариант делать спец процесс который будет принимать заявки и что-то там кому-нибудь раздавать -- вообще не катит так как займёт ещё больше ОЗУ При этом наличие _нескольких_ процессов ждущих результатов ADC Вас не смущает. А может вместо них должен быть один тот самый процесс? Вот в том то и дело, что мелкая но долго занимаемая -- у меня например АЦП долго работает! ...простой семафор явно быстрее очереди сообщений работать будет! Простой-то он простой, но ядро системы тоже нагружает. При этом самое неприятное с моей точки зрения то, то относительно своей ОЧЕНЬ ПРОСТОЙ функции он ресурсов потребляет многовато :( Предпочитаю по мелочам не "дергаться". В общем до сих пор (совершенно не отказывая себе в чем-то) ни во FreeRTOS, ни в одной из своих систем используемых с 90x годов семафоры в сколь-нибудь явном виде не реализовавал. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pochta 0 14 декабря, 2008 Опубликовано 14 декабря, 2008 (изменено) · Жалоба При этом наличие _нескольких_ процессов ждущих результатов ADC Вас не смущает. А может вместо них должен быть один тот самый процесс? Тут нет не смущает, существующего уровня реалтайма мне хватает. Всё равно АЦП медленный и заранне мне всё равно не надо чтобы он что-то считывал. И вообще вероятность того, что будут висеть две и более задачи на семафоре очень мала, хотя и есть. Вот из-за этого мне и надо защитить минимальными средствами АЦП от одновременного доступа. Можно было бы использовать критические секции но уж он больно медленно считает по сравнению с работой самого семафора. Простой-то он простой, но ядро системы тоже нагружает. При этом самое неприятное с моей точки зрения то, то относительно своей ОЧЕНЬ ПРОСТОЙ функции он ресурсов потребляет многовато :( Предпочитаю по мелочам не "дергаться". В общем до сих пор (совершенно не отказывая себе в чем-то) ни во FreeRTOS, ни в одной из своих систем используемых с 90x годов семафоры в сколь-нибудь явном виде не реализовавал. Чтож рад за вас :yeah: что вы не юзаете семафоры, видимо я тут начитался всяких Таненбаумов и прочее , где написано, что это самое простое что должно зашищять от гонок. Изменено 14 декабря, 2008 пользователем ddiimmaa Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 1 14 декабря, 2008 Опубликовано 14 декабря, 2008 · Жалоба ...написано, что это самое простое что должно зашищять от гонок. Так ведь правда написана! Постое в применениии и очень понятное средство. Но как-то уж обычно в моих задачах "лобовым" представляется. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Terminator 0 4 февраля, 2010 Опубликовано 4 февраля, 2010 · Жалоба Интересная тема :) 1. в особую глобальную переменую задача ложить свой handle , а потом прерывание делает xTaskResumeFromISR( эта глобальная переменная); что по сути и являеться вариантом списка ждуших задач на одном семафоре.Типа да, и без дополнительных сущностей. А как быть в такой ситуации? Драйвер SPI с использованием PDC (sam7). Сейчас для информирования задачи об окончании работы PDC, используется семафор, признанный zltigo слишком тяжеловесным для этого :) Если переделать на глобальную переменную с handle, то получается вроде красиво void SPIWrite(void *buf, uint32_t size, xTaskHandle currHandle) { ... spiHandle = currHandle; startpdc; vTaskSuspend(NULL); } А если предположить что в момент startpdc запустится задача/задачи с более высоким приоритетом и займут cpu на большое время в течении которого PDC всё сделает и в прерывании выполнит xTaskResumeFromISR(spiHandle), то по логике получим остановленную без причины задачу. Конечно пример неочень хороший, но ведь такое возможно же? :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Terminator 0 5 февраля, 2010 Опубликовано 5 февраля, 2010 · Жалоба Пример выше и с семафором работать не будет, т.е. гипотетическая ситуация также приведёт к остановленной задаче. Как же тогда правильно разрулить подобную ситуацию? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Terminator 0 5 февраля, 2010 Опубликовано 5 февраля, 2010 · Жалоба Простите протупил с семафором будет работать в любом случае. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться