реклама на сайте
подробности

 
 
> Вышла TNKernel 2.7
yuri_t
сообщение Jul 6 2013, 08:46
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 163
Регистрация: 24-08-05
Пользователь №: 7 937




Эта версия посвящена ,в основном, устранению накопившихся багов.

Огромное спасибо всем участникам проекта TNKernel !!!
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
dimonomid
сообщение Sep 17 2014, 21:42
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 34
Регистрация: 16-09-14
Пользователь №: 82 835



Всем привет.

Сразу перейду к делу, после чего изложу лирику, если она кому-то интересна. Итак: в TNKernel все еще есть достаточно неприятные баги, и в течении последнего месяца я интенсивно переписываю TNKernel, исправляя найденные ошибки. Ошибки обнаруживаются с помощью подробных unit-тестов (которые я тоже аккуратно пишу), благодаря чему стабильность системы реально повышается, а вероятность добавления впоследствии новых ошибок снижается. Судя по найденным багам, оригинальная TNKernel тестировалась только "вручную", без формализованных тестов, что печально.

Текущий список найденных и исправленных багов:

* если в tn_sys_tclice_ticks() переданы неверные параметры, то возвращается TERR_WRONG_PARAM и прерывания остаются запрещенными
* есть три задачи: две низкоприоритетные с одинаковым приоритетом task_low1 и task_low2; и одна высокоприоритетная task_high. Теперь: task_low1 блокирует мютекс М1 (с алгоритмом повышения наследования приоритета), потом task_low2 пытается тоже его заблокировать и уходит в ожидание, потом task_high тоже пытается его заблокировать и тоже уходит в ожидание -> приоритет task_low1 повышается до приоритета task_high. Теперь task_low1 разблокирует мютекс, следующая задача в очереди - task_low2, она его блокирует, и ее приоритет должен быть повышен до приоритета task_high (т.к. она все еще его ждет), но этого не происходит: высокоприоритетная task_high продолжает ждать задачу task_low2, приоритет которой низкий.
* низкоприоритетная задача task_low блокирует мютекс М1 (с алгоритмом повышения наследования приоритета), высокоприоритетная задача task_high тоже пытается его заблокировать и уходит в ожидание -> приоритет task_low повышается до приоритета task_high; теперь task_high выходит из ожидания по таймауту -> приоритет task_low остается повышенным. То же самое происходит, если task_high была остановлена с помощью tn_task_terminate.
* tn_mutex_delete() - если мютекс не заблокирован, то возвращается TERR_ILUSE. То есть, чтобы удалить мютекс, нужно сначала его заблокировать. Это неправильно.

Проект размещен на bitbucket: ссылка.

Как получилось, что я вообще занялся этим: сначала я долгое время пользовался портом Alex.B для PIC32, не особо вникая в то, как работает это ядро; потом в какой-то момент меня очень расстроил тот факт, что в нормальном режиме работы контекст может быть сохранен в стек задачи два и более раз. Плюс к этому, мне уже давно надоели проблемы, связанные с тем, что для прерываний используется стек задачи, которую оно прервало (вместо отдельного стека для прерываний) - на это тратится куча RAM, которой и так вечно не хватает, и я начал искать другой порт. Нашел: это порт от Anders Montonen, в котором для прерываний используется отдельный стек, поддерживаются вложенные прерывания и shadow register set.

Но в этом порте отсутствовали некоторые вкусности, которые есть в порте Alex.B: как минимум, там не было удобных Сишных макросов для определения прерываний, и еще сам TNKernel должен быть собран в составе проекта, без возможности выделить его в отдельную либу. Таким образом, я решил допилить его для себя. Anders Montonen хочет оставить свой порт настолько близко к апстриму, насколько возможно, поэтому мне оставалось только форкнуть его.

Далее, чем больше я вникал в TNKernel, тем меньше мне нравился ее код. Подробно см. на страничке моего проекта Why refactor?, все переписывать сюда не буду, изложу кратко: очень много дублирования кода, нет централизованных методов чтобы делать многие вещи, таким образом, одно и то же реализовано в куче мест просто копи-пастом (именно это является причиной изложенных выше багов с мютексами). Почти в каждой функции есть много точек выхода, почти перед каждым оператором return - разрешение прерываний. Это нарушение очень хорошего правила: "одна точка входа - одна точка выхода". Если бы это правило соблюдалось, то ошибка в tn_sys_tclice_ticks() никогда не появилась бы.

Должен сказать, что в своих "текущих" проектах я иногда позволяю себе вольности (хоть и знаю, что могу навлечь на себя беду), и далеко не всегда у меня получается код, который мне очень нравится. Но ядро - особый проект; и я хочу чтобы код ядра был как можно более близок к идеальному. Поэтому я решил заняться этим, хотя это отнимает сейчас все мое свободное время: работы очень много.

В данный момент большинство кода уже переписано таким образом, чтобы код дублировался как можно меньше. Если есть два похожих сервиса (например, tn_fmem_release() и tn_fmem_irelease()), то основная работа производится в одном месте, а вышеуказанные сервисы являются только обертками, совершающими соответствующие вступительные и заключительные действия.

И так во всем остальном. Больше всего путаницы с мютексами и их алгоритмами управления приоритетами задач; tn_mutex.c и tn_tasks.c переписаны, наверное, процентов на 70%.

Насчет тестов: на данный момент написаны очень подробные тесты для мютексов, чуть менее подробные тесты для управления задачами. Остальное - в скором (надеюсь) будущем.

О некоторых проблемах (например, про баг в tn_sys_tclice_ticks и про путаницу с макросом MAKE_ALIG) я писал Юрию на почту, он ничего не ответил: видимо, потерял интерес.

Некоторые детали API были изменены, т.к. они мне не нравятся; конкретно об изменениях тут: Differences from original TNKernel. Скорее всего, впоследствии API будет еще изменяться (т.к. я еще не все поправил, что мне не нравится), но по возможности оставлю слой совместимости с оригинальным TNKernel.

Вообще, изменений уже очень много (например, нет timer task - подробнее об этом по ссылке выше, хотя на API это не влияет), и будет еще больше, так что совместимость с оригинальной TNKernel будет, конечно, не абсолютная. Чтобы не вводить в заблуждение, возможно, придется выбрать новое название. Возможно, это будет TNeoKernel - и безусловная причастность к TNKernel указана (Юрий, большое спасибо вам за этот проект), и добавлена частичка Neo, которая указывает на некую новизну =)

В настоящий момент существует только порт для PIC32; Не знаю, заинтересует ли кого-то этот мой проект, но на всякий случай я написал.

Спасибо за внимание.

Сообщение отредактировал dimonomid - Sep 17 2014, 21:45
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- yuri_t   Вышла TNKernel 2.7   Jul 6 2013, 08:46
- - megajohn   благодарю, но хочу высказать свои хотелки, в целях...   Jul 9 2013, 11:11
- - Grape   Спасибо! немножко дополнений... Кодdiff -urN...   Jul 25 2013, 10:21
|- - megajohn   небольшие рекомендации от меня: не использовать pr...   Aug 7 2013, 12:26
|- - megajohn   a вce-тaки пoлeзнaя фичa peaлизoвaнa idle_user_cb ...   Oct 3 2013, 07:19
|- - megajohn   9. в фyнкциях tn_event_clear и tn_task_create пров...   Oct 4 2013, 09:04
- - Almaz_emb   Добрый день! Сразу же прошу прощения если мой ...   Jul 15 2014, 16:47
- - A. Fig Lee   Кстати, а есть сравнение TNkernel с Coocox?   Jul 15 2014, 17:00
- - Valentine Loginov   Очень интересно, спасибо! А то сейчас на pic...   Sep 18 2014, 08:16
|- - dimonomid   Цитата(Valentine Loginov @ Sep 18 2014, 12...   Sep 18 2014, 10:17
|- - megajohn   прикрутил к TnKernel систему runtime контроля стек...   Oct 27 2015, 16:18
- - Intel4004   А порт для Cortex-M0(M0+) существует?   Oct 29 2015, 23:40
- - megajohn   Цитата(Intel4004 @ Oct 30 2015, 03:40) А ...   Oct 30 2015, 09:49
- - Intel4004   Цитата(megajohn @ Oct 30 2015, 12:49) где...   Oct 30 2015, 14:09


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 28th June 2025 - 23:12
Рейтинг@Mail.ru


Страница сгенерированна за 0.01379 секунд с 7
ELECTRONIX ©2004-2016