Embedder74 0 25 марта, 2010 Опубликовано 25 марта, 2010 · Жалоба Пользуясь случаем, хочу спросить у DXP. Когда примерно вы планируете выпуск мануала ОСи V3.1? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 58 26 марта, 2010 Опубликовано 26 марта, 2010 · Жалоба Пользуясь случаем, хочу спросить у DXP. Когда примерно вы планируете выпуск мануала ОСи V3.1? Определенно сказать не могу. Тот функционал, который существует сейчас, на 90% (если не больше) закрыт мануалом версии 2. Есть планы относительно новых возможностей, когда они будет реализованы, тогда и будет смысл выпускать новую документацию. По срокам ничего обещать не могу, планировал еще года полтора все это сделать, но текущая работа съедает все время. Удается только выкраивать какие-то куски на решение текущих вопросов по проекту. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jorikdima 0 26 марта, 2010 Опубликовано 26 марта, 2010 · Жалоба Ну и я что ли спрошу. Почему в проекте, написанном на С++ вы используете модификаторы доступа private а не protected, например в классах описывающих сервисы? Я вот захотел малость дополнить/изменить функционал кольцевого буфера TCbuf, унаследовавшись от него, и не получил доступа к полям private: byte* buf; byte size; volatile byte count; byte first; byte last; без изменения исходника ОС. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 58 26 марта, 2010 Опубликовано 26 марта, 2010 · Жалоба Почему в проекте, написанном на С++ вы используете модификаторы доступа private а не protected, например в классах описывающих сервисы? Я вот захотел малость дополнить/изменить функционал кольцевого буфера TCbuf, унаследовавшись от него, и не получил доступа к полям Потому, что этот класс не предназначался для того, чтобы его расширять наследованием, а только лишь как основа для сервиса TChannel. И оба класса уже давно obsolete, вместо них лучше использовать шаблоны ring_buffer и channel соответственно, которые универсальнее и функциональнее. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jorikdima 0 26 марта, 2010 Опубликовано 26 марта, 2010 · Жалоба Потому, что этот класс не предназначался для того, чтобы его расширять наследованием, а только лишь как основа для сервиса TChannel. И оба класса уже давно obsolete, вместо них лучше использовать шаблоны ring_buffer и channel соответственно, которые универсальнее и функциональнее. Сорри, я как раз ring_buffer и использовал, перепутал. Но это не имеет значение, я говорил вообще про все классы. TEventFlag например, или тот же channel. У всех есть поля private. Почему бы не предназначить эти классы в том числе для расширения наследованием? Ведь всего-то надо сделать поля не private, а protected :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 134 26 марта, 2010 Опубликовано 26 марта, 2010 · Жалоба Почему бы не предназначить эти классы в том числе для расширения наследованием? Ведь всего-то надо сделать поля не private, а protected :)Это цель новой версии, которая уже почти 2 года зреет в ветке TService репозитория - унаследовать все сервисы от одного базового класса с механизмом доступа к ядру и дать пользователю возможность самостоятельно создавать новые сервисы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 58 26 марта, 2010 Опубликовано 26 марта, 2010 · Жалоба Сорри, я как раз ring_buffer и использовал, перепутал. Но это не имеет значение, я говорил вообще про все классы. TEventFlag например, или тот же channel. У всех есть поля private. Почему бы не предназначить эти классы в том числе для расширения наследованием? Ведь всего-то надо сделать поля не private, а protected :) А что это даст? Ну, отнаследуетесь вы от TEventFlag, и что дальше? Все равно весь осезависимый функционал закрыт (доступ к функциям ядра). Т.е. если хочется слепить свой собственный сервис, то этот вариант ничем не поможет. Как раз планируемые новшества и связаны с тем, чтобы дать возможность пользователю создавать свои собственные сервисы (как сказал уже Сергей, в репе есть экспериментальная ветка, но лично мне там не все нравится, надо еще помозговать). И всегда остается возможность строить свои типы на основе включения штатных сервисов. Кстати, ring_buffer - это не сервис, а просто реализация кольцевого буфера. Что вам не хватает в его реализации, что вы хотите отнаследоваться и написать свой вариант? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jorikdima 0 27 марта, 2010 Опубликовано 27 марта, 2010 · Жалоба Кстати, ring_buffer - это не сервис, а просто реализация кольцевого буфера. Что вам не хватает в его реализации, что вы хотите отнаследоваться и написать свой вариант? Приведу конкретный пример, удачный, неудачный - неважно. Я использую кольцевой буфер для хранения данных, которые я выдаю наружу через UART, используя DMA. Для зарядки DMA нужно знать адрес, по которому хранится первый элемент и размер. Можно сделать, например так: вычитываем все что есть в буфере в переменную (массив, лучше глобальный) и даем DMA адрес этого массива. Тут всего текущего функционала достаточно. Но это требует удвоенного RAM и постоянного перекладывания "из одного кармана в другой". Я бы предпочел указывать DMA адрес, где уже хранятся даные в ring_buffer, создав наследника и добавив функцию возвращения адреса. Для этого мне нужен доступ к его private полям, который я получил бы, будь они protected, наследованием. В данном примере мне доступ к ядру не нужен. Быть может это редкий случай, когда можно применять наследование? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 58 27 марта, 2010 Опубликовано 27 марта, 2010 · Жалоба Приведу конкретный пример, удачный, неудачный - неважно. Я использую кольцевой буфер для хранения данных, которые я выдаю наружу через UART, используя DMA. А что, у вас DMA контроллер умеет читать по кольцу с произвольного адреса (делать wrap around при достижении границы пула памяти, выделенной под кольцевой буфер)? И кто будет модифицировать состояние объекта-буфера - head/tail указатели, count и т.д.? Просто так вычитать с "черного хода" данные недостаточно для корректной работы кольцевого буфера. Может я чего-то не понял, но такой вариант выглядит как грязный хак. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jorikdima 0 28 марта, 2010 Опубликовано 28 марта, 2010 · Жалоба А что, у вас DMA контроллер умеет читать по кольцу с произвольного адреса (делать wrap around при достижении границы пула памяти, выделенной под кольцевой буфер)? И кто будет модифицировать состояние объекта-буфера - head/tail указатели, count и т.д.? Просто так вычитать с "черного хода" данные недостаточно для корректной работы кольцевого буфера. Может я чего-то не понял, но такой вариант выглядит как грязный хак. Нет, DMA по кольцу не читает (про MSP430 речь). О wrap around забочусь я, если вижу, что не вычитанные данные "разрываются", то на вход DMA даю только те данные, которые идут от текущего места до конца линейного буфера, а остальное в следующий раз. Модифицирую состояние объекта-буфера - head/tail указатели, count и т.д я при таком вот чтении. Тут конечно кроется момент, связынный с тем, что сообщив на вход DMA адрес начала данных, запустив его на передачу и модифицировав count и head указатель, я по настоящему то буфер еще не освободил (пока DMA не отработал до конца). Но я сам гарантирую в своем софте, что не затру ту часть данных, которая с точки зрения кольцевого буфера свободна (а по факту еще не вычитана), новыми данными. Гарантирую это знанием о частоте прихода новых данных и размером кольцевого буфера, взятого с запасом. Собственно это конечно не есть пример грамотного программирования, быть может :), но пример наследования, где private модификатор мне пришлось поменять на protected. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 58 28 марта, 2010 Опубликовано 28 марта, 2010 · Жалоба Собственно это конечно не есть пример грамотного программирования, быть может :), но пример наследования, где private модификатор мне пришлось поменять на protected. Ну, тут, имхо, вообще тогда не стоит с этим шаблоном связываться. Какие преимущества он дает? Инкапсуляция грубо попрана, :) абстракции никакой не осталось - по сути работаете с потрохами объекта напрямую, минуя его интерфейс. Ну, и зачем тогда вообще объект? Заводите себе буфер в памяти и спокойно работаете с ним. А может удобнее было бы завести пару буферов - в один пишете, другой по DMA отдаете (если условия задачи позволяют обойтись двумя буферами). Или, например, если буфера небольшие, то завести некий пул буферов - один, который отдает данные, передать DMA, остальные в работе с источниками данных, буфера переключать... И т.д. Подход, конечно, низкоуровневый, и имеет хорошее только частное решение, но он, имхо, ничем не хуже, чем потрошить объект кольцевого буфера, сам смысл которого - скрыть от пользователя реализацию и только предоставить удобный и безопасный интерфейс. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jorikdima 0 28 марта, 2010 Опубликовано 28 марта, 2010 · Жалоба Ну, и зачем тогда вообще объект? Затем, что в нем уже реализовано 90% того, что мне надо - работа с кольцевым буфером, запись внего... Я лишь добавил один метод, который возвращает мне адрес для DMA. Ну собственно говоря ладно тогда, коль не убедил :) Придумаю более удачный пример расширения наследованием, надеюсь, убедю. Спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 15 29 марта, 2010 Опубликовано 29 марта, 2010 · Жалоба Кстати, ring_buffer - это не сервис, а просто реализация кольцевого буфера. Что вам не хватает в его реализации, что вы хотите отнаследоваться и написать свой вариант? Ну, например, я хочу сделать отладочный вариант кольцевого буфера. С выдачей дампа его содержимого. Да мало ли чего ещё:) Тут, имхо, вопрос надо ставить так: а чем может повредиить применение protected вместо private? Моё мнение здесь такое - ничем. Если человек наследует какой-то объект, то он либо знает что делает, либо сам себе злобный буратино. Запрещать всем наследоваться из-за нескольких потенциальных буратин? Имхо, это неправильно:) ЗЫ. Хочу витруальный Exec()! :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 58 29 марта, 2010 Опубликовано 29 марта, 2010 · Жалоба Затем, что в нем уже реализовано 90% того, что мне надо - работа с кольцевым буфером, запись внего... Я лишь добавил один метод, который возвращает мне адрес для DMA. Есть в вашем предложении интересное зерно. Будем подумать. Ну, например, я хочу сделать отладочный вариант кольцевого буфера. С выдачей дампа его содержимого. Да мало ли чего ещё:) Тут, имхо, вопрос надо ставить так: а чем может повредиить применение protected вместо private? Моё мнение здесь такое - ничем. Если человек наследует какой-то объект, то он либо знает что делает, либо сам себе злобный буратино. Запрещать всем наследоваться из-за нескольких потенциальных буратин? Имхо, это неправильно:) Оно исходно шло (и идет) как библиотека поддержки. Никакого расширения тут просто не предполагалось. А если так рассуждать, что вообще долой private, даешь везде protected - мало ли кому что может захотеться. ЗЫ. Хочу витруальный Exec()! :) Это ты про процесс, что-ли? :) И как ты его собрался вызывать? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 15 29 марта, 2010 Опубликовано 29 марта, 2010 · Жалоба Оно исходно шло (и идет) как библиотека поддержки. Никакого расширения тут просто не предполагалось. А если так рассуждать, что вообще долой private, даешь везде protected - мало ли кому что может захотеться. Ну а почему нет? :) Зачем заранее рубить возможные расширения? Это ж не винда:) Да и винду расковыряли, несмотря ни на что. Это ты про процесс, что-ли? :) И как ты его собрался вызывать? Дык, элементарно: Делаем TBaseProcess.Exec() виртуальной (пустой или чисто виртуальной - неважно); Добавляем в OS_Kernel.cpp новую функцию - трамплин: void OS::start_process(void) { TBaseProcess* proc = Kernel.ProcessTable[Kernel.CurProcPriority]; proc->Exec(); } Добавляем эту функцию в друзья классам TKernel и TBaseProcess (если Exec - protected); Убираем третий параметр у конструктора TBaseProcess: TBaseProcess::TBaseProcess(TStackItem* Stack, TPriority pr) { Kernel.RegisterProcess(this); ... *(--StackPointer) = reinterpret_cast<dword>(start_process); И телемаркет! © :) Имхо, весьма элегантно. Может даже и выигрыш есть... Завтра попробую в работе:) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться