<?xml version="1.0" encoding="utf-8"?>
<!-- generator="FeedCreator 1.7.2-ppt DokuWiki" -->
<?xml-stylesheet href="http://wiki.pic24.ru/lib/exe/css.php?s=feed" type="text/css"?>
<rdf:RDF
    xmlns="http://purl.org/rss/1.0/"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
    xmlns:dc="http://purl.org/dc/elements/1.1/">
    <channel rdf:about="http://wiki.pic24.ru/feed.php">
        <title>PIC24 tnkernel</title>
        <description></description>
        <link>http://wiki.pic24.ru/</link>
        <image rdf:resource="http://wiki.pic24.ru/lib/images/favicon.ico" />
       <dc:date>2023-02-10T20:40:16+03:00</dc:date>
        <items>
            <rdf:Seq>
                <rdf:li rdf:resource="http://wiki.pic24.ru/doku.php/tnkernel/faq?rev=1296640340"/>
                <rdf:li rdf:resource="http://wiki.pic24.ru/doku.php/tnkernel/mchp_c30_16bit_port?rev=1297879069"/>
                <rdf:li rdf:resource="http://wiki.pic24.ru/doku.php/tnkernel/ports?rev=1208439711"/>
            </rdf:Seq>
        </items>
    </channel>
    <image rdf:about="http://wiki.pic24.ru/lib/images/favicon.ico">
        <title>PIC24</title>
        <link>http://wiki.pic24.ru/</link>
        <url>http://wiki.pic24.ru/lib/images/favicon.ico</url>
    </image>
    <item rdf:about="http://wiki.pic24.ru/doku.php/tnkernel/faq?rev=1296640340">
        <dc:format>text/html</dc:format>
        <dc:date>2011-02-02T12:52:20+03:00</dc:date>
        <title>TNKernel : Часто задаваемые вопросы</title>
        <link>http://wiki.pic24.ru/doku.php/tnkernel/faq?rev=1296640340</link>
        <description>


&lt;h1&gt;&lt;a name=&quot;tnkernel_часто_задаваемые_вопросы&quot; id=&quot;tnkernel_часто_задаваемые_вопросы&quot;&gt;TNKernel : Часто задаваемые вопросы&lt;/a&gt;&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;

Где их можно задать:
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://www.microchip.su&quot; class=&quot;urlextern&quot; title=&quot;http://www.microchip.su&quot;  rel=&quot;nofollow&quot;&gt;Форум по продукции Microchip&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://caxapa.ru&quot; class=&quot;urlextern&quot; title=&quot;http://caxapa.ru&quot;  rel=&quot;nofollow&quot;&gt;Форум САХАРА&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;TNKernel : Часто задаваемые вопросы&quot; [2-239] --&gt;
&lt;h2&gt;&lt;a name=&quot;документация&quot; id=&quot;документация&quot;&gt;Документация&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;

&lt;p&gt;&lt;div class=&quot;noteclassic&quot;&gt;
Где скачать документацию в &lt;acronym title=&quot;Portable Document Format&quot;&gt;PDF&lt;/acronym&gt;?

&lt;/div&gt;&lt;/p&gt;
Документацию &lt;acronym title=&quot;Portable Document Format&quot;&gt;PDF&lt;/acronym&gt; можно скачать по &lt;a href=&quot;http://wiki.pic24.ru/lib/exe/fetch.php/tnkernel/tnkernel_rus_20110125.pdf&quot; class=&quot;media mediafile mf_pdf&quot; title=&quot;tnkernel:tnkernel_rus_20110125.pdf&quot;&gt;ссылке&lt;/a&gt;
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Документация&quot; [240-462] --&gt;
&lt;h2&gt;&lt;a name=&quot;объем_стека_задачи&quot; id=&quot;объем_стека_задачи&quot;&gt;Объем стека задачи&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;

&lt;p&gt;&lt;div class=&quot;noteclassic&quot;&gt;
Какими средствами возможно просчитать необходимый объем стека для задачи?

&lt;/div&gt;&lt;/p&gt;
&lt;/p&gt;

&lt;p&gt;
Только эмпирически, исходя из конфигурации системы. Можно выделить для начала стек побольше, а потом в ходе работы контролировать его заполняемость отладчиком (стек перед запуском задачи инициализируется значениями 0xFFFF, в ходе работы видно как он заполняется).
&lt;/p&gt;

&lt;p&gt;
Надо понимать, что чем больше вложенных функций в задаче, чем больше у них локальных переменных, чем больше параметров передается в функции – тем больше должен быть стек. Так же не надо забывать о прерываниях – допустим, задача на самом низком уровне вложенности и стека вроде бы хватает – а тут возникает прерывание. Естественно в стек будет сохраняться контекст. Если стека не хватит – возникнет исключение, в котором нужно отметить событие переполнения стека в логе (если он есть) и сбросить контроллер.
&lt;/p&gt;

&lt;p&gt;
Если используются &amp;quot;тяжелые&amp;quot; функции из стандартных библиотек (&lt;code&gt;printf()&lt;/code&gt; и т. п.) - обязательно нужно контролировать, какой объем стека требуют они. Как правило, довольно много.
&lt;/p&gt;

&lt;p&gt;
Если говорить о TNKernel, то для среднего приложения можно установить размер стека задачи, равный 128 слов (256 байт). Исходя из контроля стека в ходе отладки, обычно эта цифра уменьшается.

&lt;/p&gt;
&lt;div class=&quot;plugin_uparrow&quot;&gt;
  &lt;a href=&quot;#&quot; title=&quot;Наверх&quot;&gt;
    &lt;img src=&quot;http://wiki.pic24.ru/lib/plugins/uparrow/images/blue_arrow.png&quot; alt=&quot;Наверх&quot;/&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Объем стека задачи&quot; [463-2725] --&gt;
&lt;h2&gt;&lt;a name=&quot;переполнение_стека&quot; id=&quot;переполнение_стека&quot;&gt;Переполнение стека&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;

&lt;p&gt;&lt;div class=&quot;noteclassic&quot;&gt;
Отслеживается ли ситуация, когда задача «вылезла» за отведенную для нее область стека? Если да, то что будет 1) с этой задачей. 2) с другими задачами?

&lt;/div&gt;&lt;/p&gt;
&lt;/p&gt;

&lt;p&gt;
У микроконтроллеров PIC24/dsPIC есть механизм аппаратного контроля указателя стека – если значение указателя становится больше чем величина регистра &lt;code&gt;SPLIM&lt;/code&gt;, возникает немаскируемое исключение (прерывание).
&lt;/p&gt;

&lt;p&gt;
В TNKernel &lt;code&gt;SPLIM&lt;/code&gt; сохраняется индивидуально для каждой задачи, что позволяет в реальном времени отслеживать переполнение стека. Отслеживания опустошения стека нет, да оно и не нужно, так как может возникнуть только если само ядро работает неправильно (а тогда контроль стека не нужен вовсе). Ну или при ручной манипуляции с указателем стека, что на языке Си сделать не просто.
&lt;/p&gt;

&lt;p&gt;
Переполнение стека может возникнуть, если для задачи выделен недостаточный объем стека. Поэтому ответ на вопрос 1) - возникнет немаскируемое исключение (если обработчик исключения в коде отсутствует - произойдет сброс контроллера). Ответ на вопрос 2) - уже все равно что будет с другими задачами. Переполнение стека - аварийная ситуация которая не может быть решена без перезапуска системы (сброса контроллера). Отслеживание переполнения - это скорее диагностическая, отладочная функция.

&lt;/p&gt;
&lt;div class=&quot;plugin_uparrow&quot;&gt;
  &lt;a href=&quot;#&quot; title=&quot;Наверх&quot;&gt;
    &lt;img src=&quot;http://wiki.pic24.ru/lib/plugins/uparrow/images/blue_arrow.png&quot; alt=&quot;Наверх&quot;/&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Переполнение стека&quot; [2726-5008] --&gt;
&lt;h2&gt;&lt;a name=&quot;использование_sleep&quot; id=&quot;использование_sleep&quot;&gt;Использование SLEEP&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;

&lt;p&gt;&lt;div class=&quot;noteclassic&quot;&gt;
Уст-во на PIC24F с применением TNKernel работает в 2-х режимах - питание от батарейки и нормальное функционирование. Интересует процесс перехода на батарейное питание. 
&lt;/p&gt;

&lt;p&gt;
&lt;br/&gt;
 
Сейчас делаю так - на ноге INT1 отображается состояние (подача внешнего питания)… если в процессе работы от внешнего питания оно выключается, я в прерывании переключаю режим тактирования на 32768 Гц, (завершаю высокоприоритетные задачи, низкоприоритетные (которые можно просто выключить)), отключаю системный тик TNKernel и засыпаю, периодически просыпаясь для определения - не подали ли питание. Если подали питание, то через программный сброс и полную инициализацию TNKernel продолжаю работать.
&lt;/p&gt;

&lt;p&gt;
Правильно ли я делаю и каковы рекомендации по работе в таких режимах?

&lt;/div&gt;&lt;/p&gt;
&lt;/p&gt;

&lt;p&gt;
Смысла делать полный сброс нет.
&lt;/p&gt;

&lt;p&gt;
Принцип простой – по прерыванию от INT1 (пропало питание) меняется фронт по которому прерывание будет возникать. Далее выполняется переход в SLEEP напрямую в прерывании. При этом нужно не забыть отключить все &lt;strong&gt;пользовательские&lt;/strong&gt; прерывания (которые имеют приоритет выше чем &lt;code&gt;TN_INTERRUPT_LEVEL&lt;/code&gt; и не используют сервисы RTOS). Задачи можно не останавливать, так система находится в &lt;strong&gt;системном&lt;/strong&gt; прерывании, а прерывания которые могут переключить контекст имеют тот же приоритет.
&lt;/p&gt;

&lt;p&gt;
Как только напряжение питания появится, контроллер выйдет из режима SLEEP на следующей инструкции после входа, так как приоритет ядра равен приоритету прерывания. Необходимо проверить - если это прерывание от INT1 (контроллер могут разбудить несколько прерываний), опять меняется фронт прерывания INT1. Ну а потом функционирование системы нормально продолжается.
&lt;/p&gt;

&lt;p&gt;
Если контроллер разбудило другое прерывание - проще всего опять заснуть. Впрочем, можно выполнить и какие-нибудь полезные действия, например, поработать с часами реального времени, если контроллер разбудило прерывание от таймера TMR1 с внешним кварцем.
&lt;/p&gt;

&lt;p&gt;
Еще рекомендация по уменьшению потребления – в рабочем режиме можно засыпать в функции, которая вызывается из задачи &lt;code&gt;tn_idle_task()&lt;/code&gt;. Если выполняется задача idle, то полезных задач, готовых к выполнению нет, они могут появиться только в прерывании от системного таймера или в &lt;strong&gt;системном&lt;/strong&gt; прерывании, поэтому можно спокойно спать – прерывание само кинет контроллер на свой вектор, так как его приоритет выше чем приоритет ядра в контексте задач.

&lt;/p&gt;
&lt;div class=&quot;plugin_uparrow&quot;&gt;
  &lt;a href=&quot;#&quot; title=&quot;Наверх&quot;&gt;
    &lt;img src=&quot;http://wiki.pic24.ru/lib/plugins/uparrow/images/blue_arrow.png&quot; alt=&quot;Наверх&quot;/&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Использование SLEEP&quot; [5009-9227] --&gt;
&lt;h2&gt;&lt;a name=&quot;tn_no_error_checking&quot; id=&quot;tn_no_error_checking&quot;&gt;TN_NO_ERROR_CHECKING&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;

&lt;p&gt;&lt;div class=&quot;noteclassic&quot;&gt;
Для чего нужен &lt;code&gt;TN_NO_ERROR_CHECKING&lt;/code&gt;?

&lt;/div&gt;&lt;/p&gt;
&lt;/p&gt;

&lt;p&gt;
Об этом можно почитать &lt;a href=&quot;http://wiki.pic24.ru/doku.php/tnkernel/mchp_c30_16bit_port#варианты_сервисов_без_проверки_параметров&quot; class=&quot;wikilink1&quot; title=&quot;tnkernel:mchp_c30_16bit_port&quot;&gt;тут&lt;/a&gt;.

&lt;/p&gt;
&lt;div class=&quot;plugin_uparrow&quot;&gt;
  &lt;a href=&quot;#&quot; title=&quot;Наверх&quot;&gt;
    &lt;img src=&quot;http://wiki.pic24.ru/lib/plugins/uparrow/images/blue_arrow.png&quot; alt=&quot;Наверх&quot;/&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;TN_NO_ERROR_CHECKING&quot; [9228-9503] --&gt;
&lt;h2&gt;&lt;a name=&quot;tn_debug&quot; id=&quot;tn_debug&quot;&gt;TN_DEBUG&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;

&lt;p&gt;&lt;div class=&quot;noteclassic&quot;&gt;
Для чего нужен &lt;code&gt;TN_DEBUG&lt;/code&gt;?

&lt;/div&gt;&lt;/p&gt;
&lt;/p&gt;

&lt;p&gt;
Об этом можно почитать &lt;a href=&quot;http://wiki.pic24.ru/doku.php/tnkernel/mchp_c30_16bit_port#отладка&quot; class=&quot;wikilink1&quot; title=&quot;tnkernel:mchp_c30_16bit_port&quot;&gt;тут&lt;/a&gt;.

&lt;/p&gt;
&lt;div class=&quot;plugin_uparrow&quot;&gt;
  &lt;a href=&quot;#&quot; title=&quot;Наверх&quot;&gt;
    &lt;img src=&quot;http://wiki.pic24.ru/lib/plugins/uparrow/images/blue_arrow.png&quot; alt=&quot;Наверх&quot;/&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;TN_DEBUG&quot; [9504-9695] --&gt;
&lt;h2&gt;&lt;a name=&quot;разделяемые_ресурсы&quot; id=&quot;разделяемые_ресурсы&quot;&gt;Разделяемые ресурсы&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;

&lt;p&gt;&lt;div class=&quot;noteclassic&quot;&gt;
Пытаюсь прочувствовать механизм вытеснения:  
&lt;/p&gt;

&lt;p&gt;
&lt;br/&gt;
  

&lt;/p&gt;
&lt;pre class=&quot;cpp code cpp&quot; style=&quot;font-family:monospace;&quot;&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; TN_TASK Task1 &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;sy2&quot;&gt;*&lt;/span&gt;par&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;;;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
    &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
        LATBbits.&lt;span class=&quot;me1&quot;&gt;LATB1&lt;/span&gt; &lt;span class=&quot;sy1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nu19&quot;&gt;0&lt;/span&gt;;
        tn_task_sleep&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;
        LATBbits.&lt;span class=&quot;me1&quot;&gt;LATB1&lt;/span&gt; &lt;span class=&quot;sy1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;;
    &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; TN_TASK Task2 &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;sy2&quot;&gt;*&lt;/span&gt;par&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;;;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
    &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
        LATBbits.&lt;span class=&quot;me1&quot;&gt;LATB2&lt;/span&gt; &lt;span class=&quot;sy1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sy3&quot;&gt;!&lt;/span&gt;PORTBbits.&lt;span class=&quot;me1&quot;&gt;RB2&lt;/span&gt;;
    &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
tn_sys_interrupt &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;_T2Interrupt&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    IFS0bits.&lt;span class=&quot;me1&quot;&gt;T2IF&lt;/span&gt; &lt;span class=&quot;sy1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nu19&quot;&gt;0&lt;/span&gt;;
    tn_tick_int_processing&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;
    LATBbits.&lt;span class=&quot;me1&quot;&gt;LATB4&lt;/span&gt; &lt;span class=&quot;sy1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sy3&quot;&gt;!&lt;/span&gt;PORTBbits.&lt;span class=&quot;me1&quot;&gt;RB4&lt;/span&gt;;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
Смутило поведение выводов - оно не соответствует тому, которое можно предположить. В чем дело?

&lt;/div&gt;&lt;/p&gt;
&lt;/p&gt;

&lt;p&gt;
Дело в том, что в этом примере в разных задачах используется один и тот же ресурс (порт), и этот ресурс не блокируется.
&lt;/p&gt;

&lt;p&gt;
Для вытесняющих RTOS существует такое понятие как &lt;strong&gt;разделяемый ресурс&lt;/strong&gt; - данные или периферия, которые используют две (или более) задачи. Так как вытеснение может произойти в любой момент времени (внешнее прерывание, прерывание системного таймера), то следует очень аккуратно относится к использованию аппаратных модулей и общей памяти в нескольких задачах. 
&lt;/p&gt;

&lt;p&gt;
Способов решения проблемы всего два:
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; использовать мютексы, которые для этого и предназначены&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; работать с разделяемым ресурсом в критической секции (часть программы, в которой запрещено переключение контекста)&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;

Первый вариант лучше использовать для более развитой периферии, нежели порты, так как защита десятка инструкций мютексом даст ощутимый оверхед. Например, если несколько задач выводят данные на ЖКИ (одна - часы, другая - меню, третья - статус) - тут без мютекса не обойтись.
&lt;/p&gt;

&lt;p&gt;
Второй вариант хорош тем, что не дает заметного оверхеда - по сути запрещение переключения контекста это запрещение прерываний. Однако, критическая секция - это серьезное вмешательство программиста в работу планировщика. Делать это нужно как можно реже, а критическая секция должна выполняться как можно быстрее.
&lt;/p&gt;

&lt;p&gt;
В приведенном примере в две задачи используют один и тот же порт - &lt;code&gt;PORTB&lt;/code&gt;. При этом задача &lt;code&gt;Task2&lt;/code&gt; выполняет &lt;strong&gt;не атомарную&lt;/strong&gt; операцию с портом. Такая же не атомарная операция видна и в системном прерывании. Вот что получим, скомпилировав исходник:
&lt;/p&gt;
&lt;pre class=&quot;code&quot;&gt;    mov.b   #PORTB,    0x0000
    ze.b    0x0000,    0x0000
    lsr     0x0000,    #2,  0x0000
    btg     0x0000,    #0
    and.b   0x0000,    #1,  0x0000
    sl      0x0000,    #2,  0x0000
    mov.w   #LATB,     0x0002
    mov.b   [0x0002],  0x0002
    bclr    0x0002,    #2
    ior.b   0x0002,    0x0000,0x0002
    mov.w   0x0002,    0x0000
    mov.b   0x0000,    #LATB&lt;/pre&gt;
&lt;p&gt;
Если вытеснение произойдет между считыванием значения регистра &lt;code&gt;PORTB&lt;/code&gt; и записью результата в &lt;code&gt;LATB&lt;/code&gt;, то вполне возможно, что задача получит управление, когда &lt;code&gt;PORTB&lt;/code&gt; будет иметь совсем другое значение…
&lt;/p&gt;

&lt;p&gt;
Если изменить пример, защитив действия с портом критической секцией, то все будет работать правильно:
&lt;/p&gt;
&lt;pre class=&quot;cpp code cpp&quot; style=&quot;font-family:monospace;&quot;&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; TN_TASK Task1 &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;sy2&quot;&gt;*&lt;/span&gt;par&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;;;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
    &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
        tn_sys_enter_critical&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;
        LATBbits.&lt;span class=&quot;me1&quot;&gt;LATB1&lt;/span&gt; &lt;span class=&quot;sy1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nu19&quot;&gt;0&lt;/span&gt;;
        tn_sys_exit_critical&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;
&amp;nbsp;
        tn_task_sleep&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;
&amp;nbsp;
        tn_sys_enter_critical&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;
        LATBbits.&lt;span class=&quot;me1&quot;&gt;LATB1&lt;/span&gt; &lt;span class=&quot;sy1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;;
        tn_sys_exit_critical&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;
    &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; TN_TASK Task2 &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;sy2&quot;&gt;*&lt;/span&gt;par&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;;;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
    &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
        tn_sys_enter_critical&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;
        LATBbits.&lt;span class=&quot;me1&quot;&gt;LATB2&lt;/span&gt; &lt;span class=&quot;sy1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sy3&quot;&gt;!&lt;/span&gt;PORTBbits.&lt;span class=&quot;me1&quot;&gt;RB2&lt;/span&gt;;
        tn_sys_exit_critical&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;
    &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
tn_sys_interrupt &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;_T2Interrupt&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    IFS0bits.&lt;span class=&quot;me1&quot;&gt;T2IF&lt;/span&gt; &lt;span class=&quot;sy1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nu19&quot;&gt;0&lt;/span&gt;;
    tn_tick_int_processing&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;
&amp;nbsp;
    LATBbits.&lt;span class=&quot;me1&quot;&gt;LATB4&lt;/span&gt; &lt;span class=&quot;sy1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sy3&quot;&gt;!&lt;/span&gt;PORTBbits.&lt;span class=&quot;me1&quot;&gt;RB4&lt;/span&gt;;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
Кстати, запись &lt;code&gt;LATBbits.LATB4 = !PORTBbits.RB4;&lt;/code&gt; гораздо лучше будет выглядеть вот так:
&lt;/p&gt;
&lt;pre class=&quot;cpp code cpp&quot; style=&quot;font-family:monospace;&quot;&gt;LATB &lt;span class=&quot;sy3&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;sy1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;sy1&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/pre&gt;
&lt;p&gt;
Скорей всего, получим следующее:
&lt;/p&gt;
&lt;pre class=&quot;code&quot;&gt;    btg     0x02CA,    #4&lt;/pre&gt;&lt;div class=&quot;plugin_uparrow&quot;&gt;
  &lt;a href=&quot;#&quot; title=&quot;Наверх&quot;&gt;
    &lt;img src=&quot;http://wiki.pic24.ru/lib/plugins/uparrow/images/blue_arrow.png&quot; alt=&quot;Наверх&quot;/&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Разделяемые ресурсы&quot; [9696-15020] --&gt;
&lt;h2&gt;&lt;a name=&quot;вызов_функций&quot; id=&quot;вызов_функций&quot;&gt;Вызов функций&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;

&lt;p&gt;&lt;div class=&quot;noteclassic&quot;&gt;…можно ли вызывать из разных задач одну и ту же функцию, или же нужно работать как с разделяемыми ресурсами. Предполагаю, что можно, но хотелось бы уверенности.
&lt;/div&gt;&lt;/p&gt;
&lt;/p&gt;

&lt;p&gt;
Можно, если функция из разряда &lt;strong&gt;thread-safe&lt;/strong&gt; (по-русски длинно - допускает многопотоковое выполнение), т.е. если функция уже написана таким образом, что допускает безопасный вызов из разных задач без использования мютексов или иных методов, реализующих атомарное выполнение.
&lt;/p&gt;

&lt;p&gt;
Тут нужно еще ввести такое понятие как &lt;strong&gt;реентерабельная&lt;/strong&gt; функция - такая функция которая может допускает вложенность вызовов - т.е. может быть вызвана из основного кода и из прерывания (или несколькими ядрами процессора).
&lt;/p&gt;

&lt;p&gt;
Реентерабельная функция никогда не использует глобальных переменных, не использует статических переменных - т.е. работает только с теми данными, которые переданы через параметры. Понятное дело, что реентерабельная фунция не должна вызывать нереентерабельные.
&lt;/p&gt;

&lt;p&gt;
Thread-safe - примерно то же самое, т.е. можно сказать, что любую реентерабельную функцию можно вызывать как thread-safe - из любой задачи RTOS без использования методов синхронизации.
Тем не менее, это не одно и тоже. Любую НЕ thread-safe функцию можно превратить в thread-safe используя мютексы, критические секции и пр. С нереентерабельными такой фокус не пройдет - нужно менять реализацию таким образом, чтоб она не использовала сторонних данных - только те, которые предоставляются вызывающей функцией.
&lt;/p&gt;

&lt;p&gt;
Таким образом термин thread-safe относится только к приложениям, в которых используется операционная система, в то время как реентерабельность - свойство функции вне зависимости от контекста использования.
&lt;/p&gt;

&lt;p&gt;
&lt;p&gt;&lt;div class=&quot;noteimportant&quot;&gt;Короче, для начала нужно помнить, что большинство стандартных функций НЕ thread-safe. Например, если используешь динамическое выделение памяти или &lt;code&gt;sprintf()&lt;/code&gt; в разных задачах - всегда оборачивай их вызов в мютекс.
&lt;/div&gt;&lt;/p&gt;
&lt;/p&gt;
&lt;div class=&quot;plugin_uparrow&quot;&gt;
  &lt;a href=&quot;#&quot; title=&quot;Наверх&quot;&gt;
    &lt;img src=&quot;http://wiki.pic24.ru/lib/plugins/uparrow/images/blue_arrow.png&quot; alt=&quot;Наверх&quot;/&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Вызов функций&quot; [15021-18406] --&gt;
&lt;h2&gt;&lt;a name=&quot;тонкости_round-robin&quot; id=&quot;тонкости_round-robin&quot;&gt;Тонкости Round-Robin&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;

&lt;p&gt;&lt;div class=&quot;noteclassic&quot;&gt;Заметил такую особенность: создаю четыре задачи - в последовательности Task1, Task2, Task3 и Task4.
При старте системы первой начинает работу задача Task1, потом Task4, следом Task3 и, соответственно, после Task3 переключается на Task2.
&lt;/p&gt;

&lt;p&gt;
Я думал, что задачи должны были крутиться по порядку создания Task1, Task2, Task3 и потом только Task4. Если создать три задачи - аналогичная ситуация: запускается сперва Task1 потом Task3 и после Task3 - задача Task2. Чем это объясняется?
&lt;/div&gt;&lt;/p&gt;
&lt;/p&gt;

&lt;p&gt;
Все очень просто. Задачи действительно ставятся в очередь в порядке создания. Но когда у первой задачи заканчивается ее квант времени - запускается задача из конца очереди (т.е. Task4) - точнее она забирается из конца и ставится в начало очереди. По большому счету без разницы - можно было бы первую задачу перемещать в конец, но автор сделал так.
&lt;/p&gt;

&lt;p&gt;
А вообще round-robin не специфицирует очередность запуска задач. Оно немного для другого предназначено. Если хочешь обеспечить точную последовательность запуска, нужно использовать объекты синхронизации (семафоры и пр.)
&lt;/p&gt;
&lt;div class=&quot;plugin_uparrow&quot;&gt;
  &lt;a href=&quot;#&quot; title=&quot;Наверх&quot;&gt;
    &lt;img src=&quot;http://wiki.pic24.ru/lib/plugins/uparrow/images/blue_arrow.png&quot; alt=&quot;Наверх&quot;/&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Тонкости Round-Robin&quot; [18407-] --&gt;</description>
    </item>
    <item rdf:about="http://wiki.pic24.ru/doku.php/tnkernel/mchp_c30_16bit_port?rev=1297879069">
        <dc:format>text/html</dc:format>
        <dc:date>2011-02-16T20:57:49+03:00</dc:date>
        <title>Порт TNKernel для PIC24/dsPIC и PIC32</title>
        <link>http://wiki.pic24.ru/doku.php/tnkernel/mchp_c30_16bit_port?rev=1297879069</link>
        <description>


&lt;h1&gt;&lt;a name=&quot;порт_tnkernel_для_pic24dspic_и_pic32&quot; id=&quot;порт_tnkernel_для_pic24dspic_и_pic32&quot;&gt;Порт TNKernel для PIC24/dsPIC и PIC32&lt;/a&gt;&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Порт TNKernel для PIC24/dsPIC и PIC32&quot; [1-62] --&gt;
&lt;h2&gt;&lt;a name=&quot;скачать&quot; id=&quot;скачать&quot;&gt;Скачать&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Скачать&quot; [63-97] --&gt;
&lt;h3&gt;&lt;a name=&quot;актуальная_версия&quot; id=&quot;актуальная_версия&quot;&gt;Актуальная версия&lt;/a&gt;&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt;  &lt;strong&gt;2.5.908&lt;/strong&gt; (16 февраля 2011)  &lt;a href=&quot;http://wiki.pic24.ru/lib/exe/fetch.php/tnkernel/tnkernel_2_5_908.rar&quot; class=&quot;media mediafile mf_rar&quot; title=&quot;tnkernel:tnkernel_2_5_908.rar&quot;&gt;скачать&lt;/a&gt; @ 550 кБ&lt;/div&gt;
&lt;ul&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; Исправлена ошибка в порте Cortex-M3, которая приводила к некорректной работе программы при вызове сервисов &lt;code&gt;tn_sys_time_get()&lt;/code&gt; и &lt;code&gt;tn_sys_time_set()&lt;/code&gt;. Спасибо Дмитрию Кривецкову.&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;

&lt;br/&gt;
 

&lt;/p&gt;
&lt;hr /&gt;
&lt;div class=&quot;plugin_uparrow&quot;&gt;
  &lt;a href=&quot;#&quot; title=&quot;Наверх&quot;&gt;
    &lt;img src=&quot;http://wiki.pic24.ru/lib/plugins/uparrow/images/blue_arrow.png&quot; alt=&quot;Наверх&quot;/&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Актуальная версия&quot; [98-563] --&gt;
&lt;h3&gt;&lt;a name=&quot;предыдущие_версии&quot; id=&quot;предыдущие_версии&quot;&gt;Предыдущие версии&lt;/a&gt;&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt;  &lt;strong&gt;2.5.716&lt;/strong&gt; (17 сентября 2010) &lt;a href=&quot;http://wiki.pic24.ru/lib/exe/fetch.php/tnkernel/tnkernel_2_5_716.rar&quot; class=&quot;media mediafile mf_rar&quot; title=&quot;tnkernel:tnkernel_2_5_716.rar&quot;&gt;скачать&lt;/a&gt; @ 550 кБ&lt;/div&gt;
&lt;ul&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;strong&gt;&lt;span style='color:red; '&gt;Добавлен порт для ARM Cortex-M3 (для компилятора Keil RealView)&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; Найдены и исправлены ошибка во внутренних функциях &lt;code&gt;try_lock_mutex()&lt;/code&gt; и &lt;code&gt;do_unlock_mutex()&lt;/code&gt;. При использовании мютексов с протоколом увеличения приоритетов мог возникнуть exception (взятие значения по нулевому адресу). Спасибо &lt;a href=&quot;http://www.microchip.su/showthread.php?t=9951&quot; class=&quot;urlextern&quot; title=&quot;http://www.microchip.su/showthread.php?t=9951&quot;  rel=&quot;nofollow&quot;&gt;Vanizma&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; Найдена и исправлена ошибка в порте для PIC32 (смена контекста не защищалась критической секцией). Спасибо Ивану Федотову.&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; Все определения, зависящие от архитектуры, под которую производится сборка, перенесены в файлы &lt;code&gt;port_defs.h&lt;/code&gt; каждой архитектуры.&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; Переделана структура примера. В пример добавлена задача, использующая UART (работает на Explorer16 как для PIC24, так и для PIC32). Задача принимает 10 байт (с таймаутом 2 мс на скорости 19200 бит/с) и пересылает их обратно. Для разных архитектур используются разные файлы bsp.c&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
&lt;strong&gt;Настоятельно рекомендую обновиться&lt;/strong&gt;
&lt;/p&gt;

&lt;p&gt;
&lt;br/&gt;
 

&lt;/p&gt;
&lt;hr /&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt;  &lt;strong&gt;2.5.601&lt;/strong&gt; (14 июля 2010) &lt;a href=&quot;http://wiki.pic24.ru/lib/exe/fetch.php/tnkernel/tnkernel_2_5_601.rar&quot; class=&quot;media mediafile mf_rar&quot; title=&quot;tnkernel:tnkernel_2_5_601.rar&quot;&gt;скачать&lt;/a&gt; @ 400 кБ&lt;/div&gt;
&lt;ul&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;strong&gt;&lt;span style='color:red; '&gt;Добавлен порт TNKernel для PIC32&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li class=&quot;level3&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;span style='color:grey; '&gt;Рекомендую почитать &lt;span class=&quot;curid&quot;&gt;&lt;a href=&quot;http://wiki.pic24.ru/doku.php/tnkernel/mchp_c30_16bit_port#отличия_порта_для_pic32_от_порта_для_pic24dspic&quot; class=&quot;wikilink1&quot; title=&quot;tnkernel:mchp_c30_16bit_port&quot;&gt;список отличий&lt;/a&gt;&lt;/span&gt; и пройтись поиском по этой странице. Искать &lt;code&gt;PIC32&lt;/code&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; Множество платформозависимых ассемблерных файлов сведено в один &lt;code&gt;port.S&lt;/code&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; Переработан пример. Теперь его можно запускать в железе (Explorer 16 + PIC24FJ256GB110 или PIC32MX360F512L) и смотреть как моргают светодиоды, нажимать на кнопку, крутить потенциометр&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; Конфигурация сборки (&lt;code&gt;TN_DEBUG&lt;/code&gt;) определяется во внешнем файле &lt;code&gt;tnkernel_conf.h&lt;/code&gt; - см. пункт &lt;span class=&quot;curid&quot;&gt;&lt;a href=&quot;http://wiki.pic24.ru/doku.php/tnkernel/mchp_c30_16bit_port#файл_конфигурации&quot; class=&quot;wikilink1&quot; title=&quot;tnkernel:mchp_c30_16bit_port&quot;&gt;&amp;quot;11. Файл конфигурации&amp;quot;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; Для всех функций &lt;em&gt;без&lt;/em&gt; проверки параметров добавлена проверка, создан объект или нет. В противном случае можно нарваться на неприятные проблемы, типа отсылки сообщения через очередь, которая еще не создана. Это очень важный фикс, &lt;strong&gt;рекомендую обновиться&lt;/strong&gt;.&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;

&lt;br/&gt;
 

&lt;/p&gt;
&lt;hr /&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt;  &lt;strong&gt;2.5.455&lt;/strong&gt; (07 апреля 2010) &lt;a href=&quot;http://wiki.pic24.ru/lib/exe/fetch.php/tnkernel/tnkernel_mchp_c30_16bit_2_5_455.rar&quot; class=&quot;media mediafile mf_rar&quot; title=&quot;tnkernel:tnkernel_mchp_c30_16bit_2_5_455.rar&quot;&gt;скачать&lt;/a&gt; @ 530 кБ&lt;/div&gt;
&lt;ul&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; Исправлена ошибка в функции &lt;a href=&quot;http://wiki.pic24.ru/doku.php/tnkernel/ref/task/tn_task_exit&quot; class=&quot;wikilink1&quot; title=&quot;tnkernel:ref:task:tn_task_exit&quot;&gt;tn_task_exit()&lt;/a&gt;. Неладное заметил и настойчиво просил разобраться &lt;a href=&quot;http://www.microchip.su/showthread.php?t=8710&quot; class=&quot;urlextern&quot; title=&quot;http://www.microchip.su/showthread.php?t=8710&quot;  rel=&quot;nofollow&quot;&gt;Daniil&lt;/a&gt;, за что ему большое спасибо.&lt;/div&gt;
&lt;ul&gt;
&lt;li class=&quot;level3&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;span style='color:grey; '&gt;Ошибка тянется еще издавна, когда были попытки использовать все приоритеты для реализации системных прерываний. Ошибка проявляла себя только в случае, если после вызова &lt;a href=&quot;http://wiki.pic24.ru/doku.php/tnkernel/ref/task/tn_task_exit&quot; class=&quot;wikilink1&quot; title=&quot;tnkernel:ref:task:tn_task_exit&quot;&gt;tn_task_exit()&lt;/a&gt; возникало системное прерывание, которое переключало контекст. Так как сервис &lt;code&gt;tn_task_exit()&lt;/code&gt; вообще не очень популярный, то баг был замечен только сейчас&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;

&lt;p&gt;

&lt;br/&gt;
 
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt;  &lt;strong&gt;2.5.298&lt;/strong&gt; (15 января 2010) &lt;a href=&quot;http://wiki.pic24.ru/lib/exe/fetch.php/tnkernel/tnkernel_mchp_c30_16bit_2_5_298.rar&quot; class=&quot;media mediafile mf_rar&quot; title=&quot;tnkernel:tnkernel_mchp_c30_16bit_2_5_298.rar&quot;&gt;скачать&lt;/a&gt; @ 530 кБ&lt;/div&gt;
&lt;ul&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; Исправлена ошибка в функциях &lt;a href=&quot;http://wiki.pic24.ru/doku.php/tnkernel/ref/sys/tn_sys_time_get&quot; class=&quot;wikilink1&quot; title=&quot;tnkernel:ref:sys:tn_sys_time_get&quot;&gt;tn_sys_time_get()&lt;/a&gt; и &lt;a href=&quot;http://wiki.pic24.ru/doku.php/tnkernel/ref/sys/tn_sys_time_set&quot; class=&quot;wikilink1&quot; title=&quot;tnkernel:ref:sys:tn_sys_time_set&quot;&gt;tn_sys_time_set()&lt;/a&gt;. Проблему нашел &lt;a href=&quot;http://www.microchip.su/showpost.php?p=85901&amp;amp;postcount=114&quot; class=&quot;urlextern&quot; title=&quot;http://www.microchip.su/showpost.php?p=85901&amp;amp;postcount=114&quot;  rel=&quot;nofollow&quot;&gt;vitalka&lt;/a&gt;, локализовал &lt;a href=&quot;http://www.microchip.su/showpost.php?p=88269&amp;amp;postcount=172&quot; class=&quot;urlextern&quot; title=&quot;http://www.microchip.su/showpost.php?p=88269&amp;amp;postcount=172&quot;  rel=&quot;nofollow&quot;&gt;tester&lt;/a&gt; - гран мерси!&lt;/div&gt;
&lt;ul&gt;
&lt;li class=&quot;level3&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;span style='color:grey; '&gt;Использование этих функций разрешено как в задачах, так и в системных прерываниях. Однако функции запрещали и сбрасывали флаг приоритета ядра, не проверяя, в каком контексте находятся. При использовании этих функций в системном прерывании, приоритет ядра сбрасывался на 0&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;

&lt;p&gt;

&lt;br/&gt;
 
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt;  &lt;strong&gt;2.5.182&lt;/strong&gt; (15 ноября 2009) &lt;a href=&quot;http://wiki.pic24.ru/lib/exe/fetch.php/tnkernel/tnkernel_mchp_c30_16bit_2_5_182.rar&quot; class=&quot;media mediafile mf_rar&quot; title=&quot;tnkernel:tnkernel_mchp_c30_16bit_2_5_182.rar&quot;&gt;скачать&lt;/a&gt; @ 530 кБ&lt;/div&gt;
&lt;ul&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; Исправлена ошибка в макросе &lt;code&gt;MAKE_ALIG()&lt;/code&gt;, который используется для выделения пула блоков памяти фиксированного размера. Спасибо &lt;strong&gt;vitalka&lt;/strong&gt;!&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;

&lt;p&gt;

&lt;br/&gt;
 
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt;  &lt;strong&gt;2.5.62&lt;/strong&gt; (24 июня 2009) &lt;a href=&quot;http://wiki.pic24.ru/lib/exe/fetch.php/tnkernel/tnkernel_mchp_c30_16bit_2_5_62.rar&quot; class=&quot;media mediafile mf_rar&quot; title=&quot;tnkernel:tnkernel_mchp_c30_16bit_2_5_62.rar&quot;&gt;скачать&lt;/a&gt; @ 530 кБ&lt;/div&gt;
&lt;ul&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; Тип параметра, передаваемый в функции &lt;a href=&quot;http://wiki.pic24.ru/doku.php/tnkernel/ref/task/tn_task_reference&quot; class=&quot;wikilink1&quot; title=&quot;tnkernel:ref:task:tn_task_reference&quot;&gt;tn_task_reference()&lt;/a&gt; и &lt;a href=&quot;http://wiki.pic24.ru/doku.php/tnkernel/ref/task/tn_task_ireference&quot; class=&quot;wikilink1&quot; title=&quot;tnkernel:ref:task:tn_task_ireference&quot;&gt;tn_task_ireference()&lt;/a&gt; изменен с &lt;code&gt;TN_TCB_S&lt;/code&gt; на &lt;code&gt;TN_TCB&lt;/code&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li class=&quot;level3&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;span style='color:grey; '&gt;компилятор выдавал предупреждение о несоответствии типов. Спасибо &lt;a href=&quot;http://www.microchip.su/showpost.php?p=68376&amp;amp;postcount=3&quot; class=&quot;urlextern&quot; title=&quot;http://www.microchip.su/showpost.php?p=68376&amp;amp;postcount=3&quot;  rel=&quot;nofollow&quot;&gt;Vanizma&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;

&lt;p&gt;

&lt;br/&gt;
 
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt;  &lt;strong&gt;2.5.28&lt;/strong&gt; (23 апреля 2009) &lt;a href=&quot;http://wiki.pic24.ru/lib/exe/fetch.php/tnkernel/tnkernel_mchp_c30_16bit_2_5_28.rar&quot; class=&quot;media mediafile mf_rar&quot; title=&quot;tnkernel:tnkernel_mchp_c30_16bit_2_5_28.rar&quot;&gt;скачать&lt;/a&gt; @ 530 кБ&lt;/div&gt;
&lt;ul&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; Исправлена ошибка в механизме карусельного (round-robin) планирования (&lt;a href=&quot;http://www.microchip.su/showthread.php?t=5760&quot; class=&quot;urlextern&quot; title=&quot;http://www.microchip.su/showthread.php?t=5760&quot;  rel=&quot;nofollow&quot;&gt;обнаружил&lt;/a&gt; &lt;strong&gt;VXDRV&lt;/strong&gt;, спасибо)&lt;/div&gt;
&lt;ul&gt;
&lt;li class=&quot;level3&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;span style='color:grey; '&gt;Карусельное планирование позволяет выделять задачам с фиксированным приоритетом временные кванты, длительность которых задается с помощью функции &lt;a href=&quot;http://wiki.pic24.ru/doku.php/tnkernel/ref/sys/tn_sys_tslice_ticks&quot; class=&quot;wikilink1&quot; title=&quot;tnkernel:ref:sys:tn_sys_tslice_ticks&quot;&gt;tn_sys_tslice_ticks()&lt;/a&gt;. Ошибка в системной функции &lt;a href=&quot;http://wiki.pic24.ru/doku.php/tnkernel/ref/sys/tn_tick_int_processing&quot; class=&quot;wikilink1&quot; title=&quot;tnkernel:ref:sys:tn_tick_int_processing&quot;&gt;tn_tick_int_processing()&lt;/a&gt; увеличивала этот интервал на один системный тик&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;

&lt;p&gt;

&lt;br/&gt;
 
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt;  &lt;strong&gt;2.5.10&lt;/strong&gt; (8 декабря 2008) &lt;a href=&quot;http://wiki.pic24.ru/lib/exe/fetch.php/tnkernel/tnkernel_mchp_c30_16bit_2_5_10.rar&quot; class=&quot;media mediafile mf_rar&quot; title=&quot;tnkernel:tnkernel_mchp_c30_16bit_2_5_10.rar&quot;&gt;скачать&lt;/a&gt; @ 532 кБ&lt;/div&gt;
&lt;ul&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; Обновлено до &lt;a href=&quot;http://www.tnkernel.com/news.html&quot; class=&quot;urlextern&quot; title=&quot;http://www.tnkernel.com/news.html&quot;  rel=&quot;nofollow&quot;&gt;официальной версии&lt;/a&gt; &lt;strong&gt;2.5&lt;/strong&gt; &lt;/div&gt;
&lt;ul&gt;
&lt;li class=&quot;level3&quot;&gt;&lt;div class=&quot;li&quot;&gt; Исправлена ошибка в задаче системного таймера &lt;code&gt;tn_timer_task_func()&lt;/code&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li class=&quot;level4&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;span style='color:grey; '&gt;В предыдущих версиях была следующая ошибка - если в момент выполнения задачи таймера &lt;code&gt;tn_timer_task_func()&lt;/code&gt; возникало системное прерывание, в котором разблокировалась одна из задач (устанавливался ожидаемый семафор, и т.п.), то при выходе их этого прерывания запускалась разблокированная задача. Таким образом, в определенных ситуациях, было возможно непроизвольное увеличение таймаутов ожидающих событие задач&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li class=&quot;level3&quot;&gt;&lt;div class=&quot;li&quot;&gt; Исправлена ошибка в функции &lt;code&gt;task_wait_complete()&lt;/code&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li class=&quot;level4&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;span style='color:grey; '&gt;Ошибка в обработке задач, использующих ceiling мютекс&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; Добавлено определение &lt;code&gt;__TNKERNEL_VERSION&lt;/code&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li class=&quot;level3&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;span style='color:grey; '&gt;В связи с переездом на новый SVN хостинг номера ревизий будут меньше чем у предыдущих версий. Введено определение &lt;code&gt;__TNKERNEL_VERSION&lt;/code&gt;, которое будет обозначать номер текущей версии (2.5)&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;

&lt;p&gt;

&lt;br/&gt;
 
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt;  &lt;strong&gt;2.4.1037&lt;/strong&gt; (25 июня 2008) &lt;a href=&quot;http://wiki.pic24.ru/lib/exe/fetch.php/tnkernel/tnkernel_mchp_c30_16bit_2_4_1037.rar&quot; class=&quot;media mediafile mf_rar&quot; title=&quot;tnkernel:tnkernel_mchp_c30_16bit_2_4_1037.rar&quot;&gt;скачать&lt;/a&gt; @ 530 кБ&lt;/div&gt;
&lt;ul&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; исправлена ошибка в порте для dsPIC (нашел &lt;strong&gt;Vlad&lt;/strong&gt;, спасибо)&lt;/div&gt;
&lt;ul&gt;
&lt;li class=&quot;level3&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;span style='color:grey; '&gt;код с библиотекой просто не собирался&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;

&lt;p&gt;

&lt;br/&gt;
 
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt;  &lt;strong&gt;2.4.1034&lt;/strong&gt; (20 июня 2008) &lt;a href=&quot;http://wiki.pic24.ru/lib/exe/fetch.php/tnkernel/tnkernel_mchp_c30_16bit_2_4_1034.rar&quot; class=&quot;media mediafile mf_rar&quot; title=&quot;tnkernel:tnkernel_mchp_c30_16bit_2_4_1034.rar&quot;&gt;скачать&lt;/a&gt; @ 494 кБ &lt;/div&gt;
&lt;ul&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; добавлены сервисы получения информации о задаче &lt;a href=&quot;http://wiki.pic24.ru/doku.php/tnkernel/ref/task/tn_task_reference&quot; class=&quot;wikilink1&quot; title=&quot;tnkernel:ref:task:tn_task_reference&quot;&gt;tn_task_reference()&lt;/a&gt; и &lt;a href=&quot;http://wiki.pic24.ru/doku.php/tnkernel/ref/task/tn_task_ireference&quot; class=&quot;wikilink1&quot; title=&quot;tnkernel:ref:task:tn_task_ireference&quot;&gt;tn_task_ireference()&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; добавлен сервис получения текущего контекста системы &lt;a href=&quot;http://wiki.pic24.ru/doku.php/tnkernel/ref/sys/tn_sys_context_get&quot; class=&quot;wikilink1&quot; title=&quot;tnkernel:ref:sys:tn_sys_context_get&quot;&gt;tn_sys_context_get()&lt;/a&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li class=&quot;level3&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;span style='color:grey; '&gt;можно использовать в функциях, которые вызываются как из задач, так и из обработчиков прерываний и при этом используют системные сервисы&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; введен тип &lt;code&gt;TN_TIMEOUT&lt;/code&gt; для параметров сервисов с таймаутами&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;

&lt;p&gt;

&lt;br/&gt;
 

&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt;  &lt;strong&gt;2.4.1000&lt;/strong&gt; (17 апреля 2008) &lt;a href=&quot;http://wiki.pic24.ru/lib/exe/fetch.php/tnkernel/tnkernel_mchp_c30_16bit_2_4_1000.rar&quot; class=&quot;media mediafile mf_rar&quot; title=&quot;tnkernel:tnkernel_mchp_c30_16bit_2_4_1000.rar&quot;&gt;скачать&lt;/a&gt; @ 458 кБ &lt;/div&gt;
&lt;ul&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; изменен способ проверки контекста в сервисах&lt;/div&gt;
&lt;ul&gt;
&lt;li class=&quot;level3&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;span style='color:grey; '&gt;увеличена скорость выполнения системных сервисов в среднем на 15%&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; добавлен &lt;span class=&quot;curid&quot;&gt;&lt;a href=&quot;http://wiki.pic24.ru/doku.php/tnkernel/mchp_c30_16bit_port#системный_таймер&quot; class=&quot;wikilink1&quot; title=&quot;tnkernel:mchp_c30_16bit_port&quot;&gt;системный таймер&lt;/a&gt;&lt;/span&gt; и функции &lt;code&gt;tn_sys_time_get()&lt;/code&gt; и &lt;code&gt;tn_sys_time_set()&lt;/code&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; изменен способ нумерации версий&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; изменена структура исходников&lt;/div&gt;
&lt;ul&gt;
&lt;li class=&quot;level3&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;span style='color:grey; '&gt;начиная с этой версии для использования TNKernel достаточно подключить к проекту библиотеку &lt;code&gt;xxx.lib&lt;/code&gt; и включить в модули, использующие сервисы RTOS файл &lt;code&gt;tnkernel.h&lt;/code&gt;. Файл &lt;code&gt;tnkernel_rev.h&lt;/code&gt; должен находиться в одной папке с &lt;code&gt;tnkernel.h&lt;/code&gt;, другие заголовочные файлы не требуются&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;

&lt;p&gt;

&lt;br/&gt;
 

&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt;  &lt;strong&gt;2.4.977&lt;/strong&gt; (8 апреля 2008) &lt;a href=&quot;http://wiki.pic24.ru/lib/exe/fetch.php/tnkernel/tnkernel_mchp_c30_16bit_2_4_977.rar&quot; class=&quot;media mediafile mf_rar&quot; title=&quot;tnkernel:tnkernel_mchp_c30_16bit_2_4_977.rar&quot;&gt;скачать&lt;/a&gt; @ 550 кБ &lt;/div&gt;
&lt;ul&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; добавлен код возврата &lt;span class=&quot;curid&quot;&gt;&lt;a href=&quot;http://wiki.pic24.ru/doku.php/tnkernel/mchp_c30_16bit_port#код_возврата_terr_exs&quot; class=&quot;wikilink1&quot; title=&quot;tnkernel:mchp_c30_16bit_port&quot;&gt;TNERR_EXS&lt;/a&gt;&lt;/span&gt; - все сервисы создания объектов возвращают этот код, если объект уже создан&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; добавлен файл &lt;span class=&quot;curid&quot;&gt;&lt;a href=&quot;http://wiki.pic24.ru/doku.php/tnkernel/mchp_c30_16bit_port#получение_ревизии_tnkernel&quot; class=&quot;wikilink1&quot; title=&quot;tnkernel:mchp_c30_16bit_port&quot;&gt;tnkernel_rev.h&lt;/a&gt;&lt;/span&gt;, в котором объявлена текущая ревизия и дата сборки библиотеки&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;

&lt;p&gt;

&lt;br/&gt;
 

&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt;  &lt;strong&gt;2.4.780&lt;/strong&gt; (6 января 2008) &lt;a href=&quot;http://wiki.pic24.ru/lib/exe/fetch.php/tnkernel/tnkernel_mchp_c30_16bit_2_4_780.rar&quot; class=&quot;media mediafile mf_rar&quot; title=&quot;tnkernel:tnkernel_mchp_c30_16bit_2_4_780.rar&quot;&gt;скачать&lt;/a&gt; @ 545 кБ &lt;/div&gt;
&lt;ul&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; исправлена &lt;a href=&quot;http://www.microchip.su/showpost.php?p=20225&amp;amp;postcount=57&quot; class=&quot;urlextern&quot; title=&quot;http://www.microchip.su/showpost.php?p=20225&amp;amp;postcount=57&quot;  rel=&quot;nofollow&quot;&gt;ошибка&lt;/a&gt; возникающая в режиме модульной и битреверсивной адресации в dsPIC (спасибо &lt;strong&gt;qas&lt;/strong&gt;)&lt;/div&gt;
&lt;ul&gt;
&lt;li class=&quot;level3&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;span style='color:grey; '&gt;Если во время выполнения библиотечной функции, которая использует модульную или битреверсивную адресацию возникает системное прерывание, регистры &lt;code&gt;MODCON&lt;/code&gt; и &lt;code&gt;XBREV&lt;/code&gt; не сохраняются и не обнуляются. При этом косвенная адресация по прежнему подчиняется правилам модульной или битреверсивной адресации, что однозначно приведет к краху системы. &lt;br/&gt;
 В ревизии 780 введены два target-а - PIC24 и dsPIC. Для dsPIC в стеке задачи сохраняются регистры &lt;code&gt;MODCON&lt;/code&gt; и &lt;code&gt;XBREV&lt;/code&gt;. Соответственно изменены файлы сборки библиотеки. В архиве четыре варианта - PIC24 coff/elf и dsPIC coff/elf с оптимизацией Os. В проект нужно просто подключить соответствующую библиотеку. &lt;br/&gt;
 Тем не менее, ядро DSP до сих пор является разделяемым ресурсом и при его использовании нужно применять мютекс.&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; изменен способ проверки контекста в сервисах&lt;/div&gt;
&lt;ul&gt;
&lt;li class=&quot;level3&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;span style='color:grey; '&gt;увеличена скорость выполнения системных сервисов на 10-15%&lt;/span&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; исправлена ошибка проверки контекста в функции &lt;code&gt;tn_task_exit()&lt;/code&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;

&lt;p&gt;

&lt;br/&gt;
 

&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt;  &lt;strong&gt;2.4.653&lt;/strong&gt; (7 декабря 2007) &lt;a href=&quot;http://wiki.pic24.ru/lib/exe/fetch.php/tnkernel/tnkernel_mchp_c30_16bit_2_4_653.rar&quot; class=&quot;media mediafile mf_rar&quot; title=&quot;tnkernel:tnkernel_mchp_c30_16bit_2_4_653.rar&quot;&gt;скачать&lt;/a&gt; @ 442 кБ&lt;/div&gt;
&lt;ul&gt;
&lt;li class=&quot;level2&quot;&gt;&lt;div class=&quot;li&quot;&gt; добавлены сервисы &lt;a href=&quot;http://wiki.pic24.ru/doku.php/tnkernel/ref/task/tn_task_iresume&quot; class=&quot;wikilink1&quot; title=&quot;tnkernel:ref:task:tn_task_iresume&quot;&gt;tn_task_iresume()&lt;/a&gt; и &lt;a href=&quot;http://wiki.pic24.ru/doku.php/tnkernel/ref/task/tn_task_isuspend&quot; class=&quot;wikilink1&quot; title=&quot;tnkernel:ref:task:tn_task_isuspend&quot;&gt;tn_task_isuspend()&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;div class=&quot;plugin_uparrow&quot;&gt;
  &lt;a href=&quot;#&quot; title=&quot;Наверх&quot;&gt;
    &lt;img src=&quot;http://wiki.pic24.ru/lib/plugins/uparrow/images/blue_arrow.png&quot; alt=&quot;Наверх&quot;/&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Предыдущие версии&quot; [564-15149] --&gt;
&lt;h3&gt;&lt;a name=&quot;thread-metric_test_suite&quot; id=&quot;thread-metric_test_suite&quot;&gt;Thread-Metric Test Suite&lt;/a&gt;&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt;  Thread-Metric Test Suite TNKernel для PIC24/dsPIC (17 апреля 2008) &lt;a href=&quot;http://wiki.pic24.ru/lib/exe/fetch.php/tnkernel/tnkernel_mchp_c30_16bit_2_4_1000_tms.rar&quot; class=&quot;media mediafile mf_rar&quot; title=&quot;tnkernel:tnkernel_mchp_c30_16bit_2_4_1000_tms.rar&quot;&gt;скачать&lt;/a&gt; @ 130 кБ&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;div class=&quot;plugin_uparrow&quot;&gt;
  &lt;a href=&quot;#&quot; title=&quot;Наверх&quot;&gt;
    &lt;img src=&quot;http://wiki.pic24.ru/lib/plugins/uparrow/images/blue_arrow.png&quot; alt=&quot;Наверх&quot;/&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Thread-Metric Test Suite&quot; [15150-15360] --&gt;
&lt;h3&gt;&lt;a name=&quot;документация&quot; id=&quot;документация&quot;&gt;Документация&lt;/a&gt;&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt;  Оригинальная документация TNKernel 2.4 (&lt;a href=&quot;http://wiki.pic24.ru/lib/exe/fetch.php/tnkernel/tnkernel_user_guide.pdf&quot; class=&quot;media mediafile mf_pdf&quot; title=&quot;tnkernel:tnkernel_user_guide.pdf&quot;&gt;скачать&lt;/a&gt; @ 390 кБ)&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;div class=&quot;plugin_uparrow&quot;&gt;
  &lt;a href=&quot;#&quot; title=&quot;Наверх&quot;&gt;
    &lt;img src=&quot;http://wiki.pic24.ru/lib/plugins/uparrow/images/blue_arrow.png&quot; alt=&quot;Наверх&quot;/&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Документация&quot; [15361-15545] --&gt;
&lt;h2&gt;&lt;a name=&quot;почему_tnkernel&quot; id=&quot;почему_tnkernel&quot;&gt;Почему TNKernel?&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;

&lt;strong&gt;TNKernel&lt;/strong&gt; (&lt;a href=&quot;http://www.tnkernel.com&quot; class=&quot;urlextern&quot; title=&quot;http://www.tnkernel.com&quot;  rel=&quot;nofollow&quot;&gt;http://www.tnkernel.com&lt;/a&gt;) - вытесняющая RTOS, изначально разработанная для микроконтроллеров с ядром ARM7, имеющая ряд достоинств по сравнению с аналогичными некоммерческими и коммерческими продуктами. TNKernel распространяется по FreeBSD-like лицензии и написана в основном на языке Си, что сделало возможным ее портирование как на 16-битную архитектуру Microchip &lt;a href=&quot;http://www.microchip.com/16bit/&quot; class=&quot;urlextern&quot; title=&quot;http://www.microchip.com/16bit/&quot;  rel=&quot;nofollow&quot;&gt;PIC24/dsPIC&lt;/a&gt; (для компилятора &lt;a href=&quot;http://www.microchip.com/c30/&quot; class=&quot;urlextern&quot; title=&quot;http://www.microchip.com/c30/&quot;  rel=&quot;nofollow&quot;&gt;Microchip C30&lt;/a&gt;) так и на 32-битные &lt;a href=&quot;http://www.microchip.com/pic32&quot; class=&quot;urlextern&quot; title=&quot;http://www.microchip.com/pic32&quot;  rel=&quot;nofollow&quot;&gt;PIC32&lt;/a&gt; (архитектура MIPS32 M4K, компилятор &lt;a href=&quot;http://www.microchip.com/c32&quot; class=&quot;urlextern&quot; title=&quot;http://www.microchip.com/c32&quot;  rel=&quot;nofollow&quot;&gt;Microchip C32&lt;/a&gt;)
&lt;/p&gt;

&lt;p&gt;
При выборе RTOS для применения в проектах с PIC24/dsPIC рассматривались различные варианты: &lt;a href=&quot;http://www.micrium.com/&quot; class=&quot;urlextern&quot; title=&quot;http://www.micrium.com/&quot;  rel=&quot;nofollow&quot;&gt;uC/OS-II&lt;/a&gt;, как наиболее распространенная коммерческая RTOS для однокристалльных контроллеров, &lt;a href=&quot;http://www.freertos.org&quot; class=&quot;urlextern&quot; title=&quot;http://www.freertos.org&quot;  rel=&quot;nofollow&quot;&gt;freeRTOS&lt;/a&gt; - широко известная и бесплатная RTOS. Рассматривались варианты портирования &lt;a href=&quot;http://www.rtos.com&quot; class=&quot;urlextern&quot; title=&quot;http://www.rtos.com&quot;  rel=&quot;nofollow&quot;&gt;ThreadX&lt;/a&gt; (оригинального порта тогда еще не было) и других платных и бесплатных &amp;quot;легких&amp;quot; планировщиков. Операционные системы с кооперативным планировщиком (&lt;a href=&quot;http://www.pumpkininc.com/&quot; class=&quot;urlextern&quot; title=&quot;http://www.pumpkininc.com/&quot;  rel=&quot;nofollow&quot;&gt;Salvo&lt;/a&gt;, &lt;a href=&quot;http://jacos.narod.ru/&quot; class=&quot;urlextern&quot; title=&quot;http://jacos.narod.ru/&quot;  rel=&quot;nofollow&quot;&gt;jacOS&lt;/a&gt;) были откинуты сразу, так как даже первые линейки PIC24/dsPIC имели достаточный объем оперативной памяти для реализации вытеснения.
&lt;/p&gt;

&lt;p&gt;
Основные критерии выбора были следующие:
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; наличие исходных текстов и разрешение на коммерческое использование&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; простое портирование на другие архитектуры, понятный и масштабируемый код на языке Си&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; наличие дополнительных библиотек - файловой системы, tcp/ip стека и т.п.&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; объем программной памяти и памяти данных, используемый ядром&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; время реакции на внешнее событие&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;

TNKernel изначально удовлетворяла всем критериям, поэтому и была выбрана за основу, несмотря на то что оригинальная версия разработана для контроллеров с ядром ARM7. 

&lt;/p&gt;
&lt;div class=&quot;plugin_uparrow&quot;&gt;
  &lt;a href=&quot;#&quot; title=&quot;Наверх&quot;&gt;
    &lt;img src=&quot;http://wiki.pic24.ru/lib/plugins/uparrow/images/blue_arrow.png&quot; alt=&quot;Наверх&quot;/&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Почему TNKernel?&quot; [15546-18633] --&gt;
&lt;h3&gt;&lt;a name=&quot;наличие_исходных_текстов&quot; id=&quot;наличие_исходных_текстов&quot;&gt;Наличие исходных текстов&lt;/a&gt;&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;

Существует большое количество коммерческих и бесплатных &amp;quot;легких&amp;quot; RTOS для однокристальных контроллеров, исходные коды которых либо выложены в свободном доступе (freeRTOS), либо доступны только для ознакомительных целей (uC/&lt;acronym title=&quot;Operating System&quot;&gt;OS&lt;/acronym&gt;-II), либо можно найти в файлообменных сетях (ThreadX).
&lt;/p&gt;

&lt;p&gt;
TNKernel распространяется по лицензии, допускающей модификацию исходников и коммерческое использование при сохранении копирайта. Это стало одним из решающих аргументов. 
&lt;/p&gt;

&lt;p&gt;
Несмотря на то, что лицензия freeRTOS так же допускает изменение исходных кодов и коммерческое использование, freeRTOS не удовлетворяет многим другим критериям (с моей точки зрения).

&lt;/p&gt;
&lt;div class=&quot;plugin_uparrow&quot;&gt;
  &lt;a href=&quot;#&quot; title=&quot;Наверх&quot;&gt;
    &lt;img src=&quot;http://wiki.pic24.ru/lib/plugins/uparrow/images/blue_arrow.png&quot; alt=&quot;Наверх&quot;/&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Наличие исходных текстов&quot; [18634-19820] --&gt;
&lt;h3&gt;&lt;a name=&quot;простое_портирование_понятный_код&quot; id=&quot;простое_портирование_понятный_код&quot;&gt;Простое портирование, понятный код&lt;/a&gt;&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;

Простое портирование или существование портов для других популярных архитектур - так же очень важный критерий, так как бессмыслено постоянно менять (а значит и осваивать) инструментарий при переходе с одного семейства на другое.
&lt;/p&gt;

&lt;p&gt;
Под &amp;quot;простым&amp;quot; портированием я понимаю &lt;em&gt;четкое&lt;/em&gt; разделение собственно ядра системы (которое должно быть написано на С/С++) и модулей, зависящих от архитектуры (переключение контекста, работа с прерываниями и т.п.). Большинство известных RTOS для однокристальных контроллеров имеют как большое количество портов, так и сформировавшуюся структуру, которая позволяет быстро порты добавлять.
&lt;/p&gt;

&lt;p&gt;
На момент выбора системы порты для 16-битных контроллеров Microchip имели только freeRTOS и uC/&lt;acronym title=&quot;Operating System&quot;&gt;OS&lt;/acronym&gt;-II. Однако, порт для uC/&lt;acronym title=&quot;Operating System&quot;&gt;OS&lt;/acronym&gt;-II не работал (ошибка в ассемблерном модуле - первый релиз, спишем на это), а в порте freeRTOS был найден комментарий типа &amp;quot;в этом месте может зависнуть, почему - пока не понятно…&amp;quot;. Все это ставило под сомнение использование этих систем (тем более, что uC/&lt;acronym title=&quot;Operating System&quot;&gt;OS&lt;/acronym&gt;-II еще и коммерческая). Сейчас ситуация изменилась - выходят обновления портов, обновления самих систем. Поэтому выбор может быть не столь очевидным, и, возможно, даже не в пользу TNKernel (если вы, например, уже используете freeRTOS).
&lt;/p&gt;

&lt;p&gt;
Понятный код - еще один момент на котором стоит остановиться. Несомненно, что каждый программист или коллектив имеет сложившийся стиль, поэтому трудно оценивать чужой код - понятный он или нет. Мне наиболее ближе TNKernel - по такому критерию это несомненный лидер.

&lt;/p&gt;
&lt;div class=&quot;plugin_uparrow&quot;&gt;
  &lt;a href=&quot;#&quot; title=&quot;Наверх&quot;&gt;
    &lt;img src=&quot;http://wiki.pic24.ru/lib/plugins/uparrow/images/blue_arrow.png&quot; alt=&quot;Наверх&quot;/&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Простое портирование, понятный код&quot; [19821-22563] --&gt;
&lt;h3&gt;&lt;a name=&quot;наличие_дополнительных_библиотек&quot; id=&quot;наличие_дополнительных_библиотек&quot;&gt;Наличие дополнительных библиотек&lt;/a&gt;&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;

В этом случае явным лидером является uC/&lt;acronym title=&quot;Operating System&quot;&gt;OS&lt;/acronym&gt;-II, так как имеет огромное количество дополнительного софта (за дополнительные же деньги): файловую систему, стек tcp/ip, библиотеку обслуживания USB, &lt;acronym title=&quot;Graphical User Interface&quot;&gt;GUI&lt;/acronym&gt; и т.д. freeRTOS может включать в себя порт открытого tcp/ip стека uIP и большое количество &lt;a href=&quot;http://www.freertos.org/embeddedtcp.html&quot; class=&quot;urlextern&quot; title=&quot;http://www.freertos.org/embeddedtcp.html&quot;  rel=&quot;nofollow&quot;&gt;примеров&lt;/a&gt;, построенных на его основе.
&lt;/p&gt;

&lt;p&gt;
Оригинальная версия TNKernel имеет библиотеку &lt;a href=&quot;http://www.tnkernel.com/usb_bulk.html&quot; class=&quot;urlextern&quot; title=&quot;http://www.tnkernel.com/usb_bulk.html&quot;  rel=&quot;nofollow&quot;&gt;USB Bulk Firmware&lt;/a&gt; для контроллеров NXP LPC2100 и урезанный порт &lt;a href=&quot;http://www.tnkernel.com/tnmw.html&quot; class=&quot;urlextern&quot; title=&quot;http://www.tnkernel.com/tnmw.html&quot;  rel=&quot;nofollow&quot;&gt;Nano-X GUI&lt;/a&gt;. Если первое не может использоваться совместно с 16-битными контроллерами Microchip в силу понятных причин, то второе вполне можно успешно применять в проектах на PIC24/dsPIC и PIC32. Недавно автором TNKernel был выпущен &lt;a href=&quot;http://www.tnkernel.com/tn_net_1.html&quot; class=&quot;urlextern&quot; title=&quot;http://www.tnkernel.com/tn_net_1.html&quot;  rel=&quot;nofollow&quot;&gt;TCP/IP стек&lt;/a&gt;, который, возможно будет работать и на PIC32.

&lt;/p&gt;
&lt;div class=&quot;plugin_uparrow&quot;&gt;
  &lt;a href=&quot;#&quot; title=&quot;Наверх&quot;&gt;
    &lt;img src=&quot;http://wiki.pic24.ru/lib/plugins/uparrow/images/blue_arrow.png&quot; alt=&quot;Наверх&quot;/&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Наличие дополнительных библиотек&quot; [22564-24020] --&gt;
&lt;h3&gt;&lt;a name=&quot;используемые_ресурсы&quot; id=&quot;используемые_ресурсы&quot;&gt;Используемые ресурсы&lt;/a&gt;&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;

По этому критерию TNKernel вне конкуренции - uC/&lt;acronym title=&quot;Operating System&quot;&gt;OS&lt;/acronym&gt;-II и freeRTOS требовали почти в два раза больше программной памяти и в полтора раза больше ОЗУ (не считая стеков задач). Возможно сейчас ситуация изменилась, но в начале это произвело впечатление.
&lt;/p&gt;

&lt;p&gt;
Следует заметить, что и uC/&lt;acronym title=&quot;Operating System&quot;&gt;OS&lt;/acronym&gt;-II и freeRTOS требуют компиляции в составе проекта, а линкер Microchip C30 пока не умеет игнорировать неиспользуемые секции кода, подключая на выход целиком весь объектный файл, даже если из него используется одна функция, лежащая в отдельной секции. Поэтому в проект с использованием  freeRTOS и uC/&lt;acronym title=&quot;Operating System&quot;&gt;OS&lt;/acronym&gt;-II будет включаться весь исполняемый код RTOS. 
&lt;/p&gt;

&lt;p&gt;
Конечно это не является недостатком вышеназванных RTOS - это проблема компилятора Microchip C30. Частично она решается заголовочными файлами конфигурации, в которых указано, какие сервисы и объекты будут использоваться. Тем не менее даже полный вариант TNKernel использует меньше программной памяти чем freeRTOS или uC/&lt;acronym title=&quot;Operating System&quot;&gt;OS&lt;/acronym&gt;-II.
&lt;/p&gt;

&lt;p&gt;
Компилятор Microchip C32 основан на новой версии GCC и умеет игнорировать неиспользуемые функции в объектном файле, однако для совместимости с портом для PIC24/dsPIC структура системы оставлена прежней.
&lt;/p&gt;
&lt;div class=&quot;plugin_uparrow&quot;&gt;
  &lt;a href=&quot;#&quot; title=&quot;Наверх&quot;&gt;
    &lt;img src=&quot;http://wiki.pic24.ru/lib/plugins/uparrow/images/blue_arrow.png&quot; alt=&quot;Наверх&quot;/&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Используемые ресурсы&quot; [24021-26093] --&gt;
&lt;h3&gt;&lt;a name=&quot;время_реакции&quot; id=&quot;время_реакции&quot;&gt;Время реакции&lt;/a&gt;&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;

Под временем реакции будем понимать время, необходимое для входа в задачу ожидающую событие с момента наступления этого события. Как правило это время измеряется следующим образом: в задаче вызывается сервис ожидания семафора, а семафор освобождается в обработчике внешнего прерывания. Временем между возникновением прерывания и выходом из сервиса ожидания и будет время реакции.
&lt;/p&gt;

&lt;p&gt;
Оценить время реакции и другие &amp;quot;скоростные&amp;quot; параметры RTOS, можно используя набор тестов известного производителя Express Logic Corp. (автора ThreadX), который называется Thread-Metric Test Suite. Результаты тестов для наиболее известных RTOS для PIC24/dsPIC приведены в таблице.

&lt;/p&gt;
&lt;table class=&quot;inline&quot;&gt;
	&lt;tr class=&quot;row0&quot;&gt;
		&lt;td class=&quot;col0 rightalign&quot;&gt;      &lt;/td&gt;&lt;th class=&quot;col1&quot;&gt; Cooperative Scheduling &lt;/th&gt;&lt;th class=&quot;col2&quot;&gt; Preemptive Scheduling &lt;/th&gt;&lt;th class=&quot;col3&quot;&gt; Interrupt Processing &lt;/th&gt;&lt;th class=&quot;col4&quot;&gt; Interrupt Preemption &lt;/th&gt;&lt;th class=&quot;col5&quot;&gt; Message Processing &lt;/th&gt;&lt;th class=&quot;col6&quot;&gt; Sync Processing &lt;/th&gt;&lt;th class=&quot;col7&quot;&gt; Memory Processing &lt;/th&gt;
	&lt;/tr&gt;
	&lt;tr class=&quot;row1&quot;&gt;
		&lt;th class=&quot;col0&quot;&gt; TNKernel &lt;/th&gt;&lt;td class=&quot;col1 rightalign&quot;&gt;  &lt;strong&gt;(1)&lt;/strong&gt; &lt;/td&gt;&lt;td class=&quot;col2 rightalign&quot;&gt;  4,139,983 &lt;/td&gt;&lt;td class=&quot;col3 rightalign&quot;&gt;  &lt;strong&gt;7,784,007&lt;/strong&gt; &lt;/td&gt;&lt;td class=&quot;col4 rightalign&quot;&gt;  3,179,511 &lt;/td&gt;&lt;td class=&quot;col5 rightalign&quot;&gt;  5,721,174 &lt;/td&gt;&lt;td class=&quot;col6 rightalign&quot;&gt;  13,621,698 &lt;/td&gt;&lt;td class=&quot;col7 rightalign&quot;&gt;  9,746,870 &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr class=&quot;row2&quot;&gt;
		&lt;th class=&quot;col0&quot;&gt; AVIX &lt;/th&gt;&lt;td class=&quot;col1 rightalign&quot;&gt;  9,069,625 &lt;/td&gt;&lt;td class=&quot;col2 rightalign&quot;&gt;  &lt;strong&gt;5,100,589&lt;/strong&gt; &lt;/td&gt;&lt;td class=&quot;col3 rightalign&quot;&gt;  7,400,858 &lt;/td&gt;&lt;td class=&quot;col4 rightalign&quot;&gt;  &lt;strong&gt;3,293,937&lt;/strong&gt; &lt;/td&gt;&lt;td class=&quot;col5 rightalign&quot;&gt;  5,020,698 &lt;/td&gt;&lt;td class=&quot;col6 rightalign&quot;&gt;  &lt;strong&gt;19,030,131&lt;/strong&gt; &lt;/td&gt;&lt;td class=&quot;col7 rightalign&quot;&gt;  10,609,717 &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr class=&quot;row3&quot;&gt;
		&lt;th class=&quot;col0 leftalign&quot;&gt; ThreadX  &lt;/th&gt;&lt;td class=&quot;col1 rightalign&quot;&gt;  &lt;strong&gt;11,848,815&lt;/strong&gt; &lt;/td&gt;&lt;td class=&quot;col2 rightalign&quot;&gt;  5,032,710 &lt;/td&gt;&lt;td class=&quot;col3 rightalign&quot;&gt;  7,342,967 &lt;/td&gt;&lt;td class=&quot;col4 rightalign&quot;&gt;  3,132,150 &lt;/td&gt;&lt;td class=&quot;col5 rightalign&quot;&gt;  7,354,317 &lt;/td&gt;&lt;td class=&quot;col6 rightalign&quot;&gt;  17,592,956 &lt;/td&gt;&lt;td class=&quot;col7 rightalign&quot;&gt;  &lt;strong&gt;14,413,455&lt;/strong&gt; &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr class=&quot;row4&quot;&gt;
		&lt;th class=&quot;col0&quot;&gt; uc/&lt;acronym title=&quot;Operating System&quot;&gt;OS&lt;/acronym&gt;-II &lt;/th&gt;&lt;td class=&quot;col1 rightalign&quot;&gt;  &lt;strong&gt;(1)&lt;/strong&gt; &lt;/td&gt;&lt;td class=&quot;col2 rightalign&quot;&gt;  3,909,085 &lt;/td&gt;&lt;td class=&quot;col3 rightalign&quot;&gt;  5,259,998 &lt;/td&gt;&lt;td class=&quot;col4 rightalign&quot;&gt;  &lt;strong&gt;(1)&lt;/strong&gt; &lt;/td&gt;&lt;td class=&quot;col5 rightalign&quot;&gt;  &lt;strong&gt;7,387,612&lt;/strong&gt; &lt;/td&gt;&lt;td class=&quot;col6 rightalign&quot;&gt;  10,293,318 &lt;/td&gt;&lt;td class=&quot;col7 rightalign&quot;&gt;  6,814,817 &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr class=&quot;row5&quot;&gt;
		&lt;th class=&quot;col0&quot;&gt; FreeRTOS &lt;/th&gt;&lt;td class=&quot;col1 rightalign&quot;&gt;  &lt;strong&gt;(2)&lt;/strong&gt; &lt;/td&gt;&lt;td class=&quot;col2 rightalign&quot;&gt;  3,717,913 &lt;/td&gt;&lt;td class=&quot;col3 rightalign&quot;&gt;  1,881,892 &lt;/td&gt;&lt;td class=&quot;col4 rightalign&quot;&gt;  2,400,967 &lt;/td&gt;&lt;td class=&quot;col5 rightalign&quot;&gt;  0,484,691 &lt;/td&gt;&lt;td class=&quot;col6 rightalign&quot;&gt;  1,989,999 &lt;/td&gt;&lt;td class=&quot;col7 rightalign&quot;&gt;  &lt;strong&gt;(1)&lt;/strong&gt; &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr class=&quot;row6&quot;&gt;
		&lt;th class=&quot;col0 leftalign&quot;&gt; AVA      &lt;/th&gt;&lt;td class=&quot;col1 rightalign&quot;&gt;  &lt;strong&gt;(1)&lt;/strong&gt; &lt;/td&gt;&lt;td class=&quot;col2 rightalign&quot;&gt;  1,724,948 &lt;/td&gt;&lt;td class=&quot;col3 rightalign&quot;&gt;  5,207,762 &lt;/td&gt;&lt;td class=&quot;col4 rightalign&quot;&gt;  1,260,190 &lt;/td&gt;&lt;td class=&quot;col5 rightalign&quot;&gt;  2,761,154 &lt;/td&gt;&lt;td class=&quot;col6 rightalign&quot;&gt;  7,514,799 &lt;/td&gt;&lt;td class=&quot;col7 rightalign&quot;&gt;  10,235,182 &lt;/td&gt;
	&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;

&lt;strong&gt;(1)&lt;/strong&gt; Функция или объект не поддерживается &lt;br/&gt;
 
&lt;strong&gt;(2)&lt;/strong&gt; Ошибка выполнения теста
&lt;/p&gt;

&lt;p&gt;
&lt;a href=&quot;http://wiki.pic24.ru/lib/exe/detail.php/tnkernel/rtos_contest_result.png?id=tnkernel%3Amchp_c30_16bit_port&quot; class=&quot;media&quot; title=&quot;tnkernel:rtos_contest_result.png&quot;&gt;&lt;img src=&quot;http://wiki.pic24.ru/lib/exe/fetch.php/tnkernel/rtos_contest_result.png&quot; class=&quot;mediacenter&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
Проект с тестовым приложением для TNKernel можно скачать по &lt;span class=&quot;curid&quot;&gt;&lt;a href=&quot;http://wiki.pic24.ru/doku.php/tnkernel/mchp_c30_16bit_port#thread-metric_test_suite&quot; class=&quot;wikilink1&quot; title=&quot;tnkernel:mchp_c30_16bit_port&quot;&gt;ссылке&lt;/a&gt;&lt;/span&gt;.
&lt;/p&gt;

&lt;p&gt;
В таблице присутствуют RTOS, которые раньше не упоминались, поэтому дадим краткую характеристику каждой из них:

&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://www.avix-rt.com/&quot; class=&quot;urlextern&quot; title=&quot;http://www.avix-rt.com/&quot;  rel=&quot;nofollow&quot;&gt;AVIX&lt;/a&gt; - коммерческая RTOS специально разработанная для микроконтроллеров PIC24/dsPIC (в начале 2008 г. появился порт для 32-битных контроллеров PIC32). По утверждению автора это первая в мире RTOS для однокристальных контроллеров, которая имеет &amp;quot;нулевую&amp;quot; программную задержку входа в обработчик прерывания, то есть системные сервисы прерывания не запрещают. Кроме того, для контекста прерываний AVIX использует отдельный системный стек.&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://www.rtos.com/&quot; class=&quot;urlextern&quot; title=&quot;http://www.rtos.com/&quot;  rel=&quot;nofollow&quot;&gt;ThreadX&lt;/a&gt; - порт известной коммерческой RTOS для контроллеров PIC24/dsPIC.&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://www.lassarsystems.com/&quot; class=&quot;urlextern&quot; title=&quot;http://www.lassarsystems.com/&quot;  rel=&quot;nofollow&quot;&gt;AVA&lt;/a&gt; - еще одна коммерческая RTOS, разработанная специально для 16-битных контроллеров Microchip. Судя по результатам теста и критическим ошибкам в первых релизах ничего хорошего из себя не представляет.&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;

Тестирование TNKernel и AVIX можно повторить самостоятельно, скачав проекты. Остальные результаты взяты с форума &lt;a href=&quot;http://forum.microchip.com/tm.aspx?m=279201&amp;amp;mpage=1&amp;amp;key=&amp;amp;#279201&quot; class=&quot;urlextern&quot; title=&quot;http://forum.microchip.com/tm.aspx?m=279201&amp;amp;mpage=1&amp;amp;key=&amp;amp;#279201&quot;  rel=&quot;nofollow&quot;&gt;microchip.com&lt;/a&gt;. Результаты тестов так же опубликованы на сайте &lt;a href=&quot;http://www.avix-rt.com/html/performance.html&quot; class=&quot;urlextern&quot; title=&quot;http://www.avix-rt.com/html/performance.html&quot;  rel=&quot;nofollow&quot;&gt;AVIX&lt;/a&gt;, однако они &lt;a href=&quot;http://www.reuters.com/article/pressRelease/idUS135644+21-Jan-2008+BW20080121&quot; class=&quot;urlextern&quot; title=&quot;http://www.reuters.com/article/pressRelease/idUS135644+21-Jan-2008+BW20080121&quot;  rel=&quot;nofollow&quot;&gt;устаревшие&lt;/a&gt; и неполные.
&lt;/p&gt;

&lt;p&gt;
Если за первое место в тесте начислять 3 балла, за второе - 2 балла и за третье - 1 балл, то AVIX займет лидирующую позицию, ThreadX - второе место, а TNKernel - третье.
&lt;/p&gt;

&lt;p&gt;
Самая популярная freeware RTOS для однокристальных микроконтроллеров - freeRTOS оказалась по совокупности результатов на одном из последних мест. По просьбе автора, freeRTOS удалена из таблицы сравнения на странице &lt;a href=&quot;http://www.avix-rt.com/html/performance.html&quot; class=&quot;urlextern&quot; title=&quot;http://www.avix-rt.com/html/performance.html&quot;  rel=&quot;nofollow&quot;&gt;AVIX&lt;/a&gt; - по его утверждению результаты тестов сильно отличаются от реальности. Однако, до сих пор результаты автор freeRTOS не привел, поэтому в этом документе опубликовано то, что было получено в изначальной дискуссии. Вполне возможно, что на самом деле freeRTOS ведет себя гораздо лучше…
&lt;/p&gt;

&lt;p&gt;
Таким образом, можно сказать, что TNKernel является лучшим из вытесняющих планировщиков, распространяемых с открытыми исходными кодами и допускающих использование в коммерческих разработках.

&lt;/p&gt;
&lt;div class=&quot;plugin_uparrow&quot;&gt;
  &lt;a href=&quot;#&quot; title=&quot;Наверх&quot;&gt;
    &lt;img src=&quot;http://wiki.pic24.ru/lib/plugins/uparrow/images/blue_arrow.png&quot; alt=&quot;Наверх&quot;/&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Время реакции&quot; [26094-32114] --&gt;
&lt;h2&gt;&lt;a name=&quot;отличия_tnkernel_для_pic24dspic_и_pic32&quot; id=&quot;отличия_tnkernel_для_pic24dspic_и_pic32&quot;&gt;Отличия TNKernel для PIC24/dsPIC и PIC32&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Отличия TNKernel для PIC24/dsPIC и PIC32&quot; [32115-32179] --&gt;
&lt;h3&gt;&lt;a name=&quot;исходные_коды&quot; id=&quot;исходные_коды&quot;&gt;Исходные коды&lt;/a&gt;&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;

Структура исходных текстов TNKernel значительно изменена по сравнению с оригинальной. Основное отличие  - каждая функция находится в отдельном файле. Таким образом обходится проблема линкера C30, который не может игнорировать неиспользуемые секции кода.
&lt;/p&gt;

&lt;p&gt;
При сборке проекта в исполняемый файл линкер добавляет только те функции, которые используются в пользовательском приложении. Это позволяет значительно сократить объем программной памяти, используемый ядром. Например, все сервисы требуют порядка 15 кБ программной памяти, тогда как в среднем приложении ядро RTOS занимает примерно 6-7 кБ.
&lt;/p&gt;

&lt;p&gt;
Кроме разделения исходных кодов на файлы была предпринята попытка сделать TNKernel еще более портируемой - все основные типы переопределяются, все машинозависимые функции вынесены в отдельные модули (префикс &lt;code&gt;port_&lt;/code&gt;). Это позволило в свое время достаточно просто добавить порт для PIC32.
&lt;/p&gt;

&lt;p&gt;
Итак, скачав архив с проектом вы увидите католог &lt;code&gt;source&lt;/code&gt; в котором и находятся исходные тексты TNKernel для PIC24/dsPIC. Файл &lt;code&gt;_build_mchp_c30.bat&lt;/code&gt; предназначен для сборки библиотеки. Его можно отредактировать для сборки файла с требуемыми параметрами - другим уровнем оптимизации, моделью памяти и пр. Текущая версия командного файла собирает четыре библиотеки - две для PIC24 с оптимизацией &lt;code&gt;Os&lt;/code&gt; и форматом &lt;code&gt;coff&lt;/code&gt; и &lt;code&gt;elf&lt;/code&gt; и две для dsPIC. То же самое и для PIC32, командный файл называется &lt;code&gt;_build_mchp_c32.bat&lt;/code&gt;
&lt;/p&gt;

&lt;p&gt;
Для сборки необходимо, чтобы в системе был прописан путь к исполняемому файлу компилятора.

&lt;/p&gt;
&lt;div class=&quot;plugin_uparrow&quot;&gt;
  &lt;a href=&quot;#&quot; title=&quot;Наверх&quot;&gt;
    &lt;img src=&quot;http://wiki.pic24.ru/lib/plugins/uparrow/images/blue_arrow.png&quot; alt=&quot;Наверх&quot;/&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Исходные коды&quot; [32180-34845] --&gt;
&lt;h3&gt;&lt;a name=&quot;порт_для_pic24dspic&quot; id=&quot;порт_для_pic24dspic&quot;&gt;Порт для PIC24/dsPIC&lt;/a&gt;&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;

Компания Microchip имеет две основные линейки 16-битных контроллеров: &lt;a href=&quot;http://www.microchip.com/pic24/&quot; class=&quot;urlextern&quot; title=&quot;http://www.microchip.com/pic24/&quot;  rel=&quot;nofollow&quot;&gt;PIC24&lt;/a&gt; - микроконтроллеры общего назначения и &lt;a href=&quot;http://www.microchip.com/dspic/&quot; class=&quot;urlextern&quot; title=&quot;http://www.microchip.com/dspic/&quot;  rel=&quot;nofollow&quot;&gt;dsPIC&lt;/a&gt; - контроллеры цифровой обработки сигналов. По сути PIC24 являются усеченной версией dsPIC - в них отсутствует DSP ядро и специальные методы адресации.
&lt;/p&gt;

&lt;p&gt;
Изначально TNKernel портировалась как под PIC24, так и под dsPIC, причем в версии для последнего в стеке задачи кроме всего прочего, сохранялся контекст DSP-ядра. Но как выяснилось это не имело большого смысла, потому, что полностью восстановить контекст DSP простыми способами невозможно - большинство статусных флагов DSP-ядра имеют доступ только для чтения, да и с аппаратным циклом DO все не так просто. Поэтому от отдельного порта для dsPIC было решено отказаться - в следующих вариантах TNKernel для PIC24/dsPIC DSP-ядро было предложено рассматривать как разделяемые ресурс и использовать для доступа к нему из разных задач мютекс.
&lt;/p&gt;

&lt;p&gt;
Но как выяснилось напрасно. Благодаря камраду &lt;strong&gt;qas&lt;/strong&gt; был найден серьезный &lt;a href=&quot;http://www.microchip.su/showpost.php?p=20225&amp;amp;postcount=57&quot; class=&quot;urlextern&quot; title=&quot;http://www.microchip.su/showpost.php?p=20225&amp;amp;postcount=57&quot;  rel=&quot;nofollow&quot;&gt; баг&lt;/a&gt;, который мог однозначно порушить систему при использовании модульной или бит-реверсивной адресации DSP-ядра. Баг исправлен, но опять появилось две версии TNKernel - для PIC24 и для dsPIC.
&lt;/p&gt;

&lt;p&gt;
Тем не менее ситуация с DSP-ядром прежняя - его контекст не сохраняется и его следует рассматривать как разделяемый ресурс, используя для доступа из разных задач мютекс.

&lt;/p&gt;
&lt;div class=&quot;plugin_uparrow&quot;&gt;
  &lt;a href=&quot;#&quot; title=&quot;Наверх&quot;&gt;
    &lt;img src=&quot;http://wiki.pic24.ru/lib/plugins/uparrow/images/blue_arrow.png&quot; alt=&quot;Наверх&quot;/&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Порт для PIC24/dsPIC&quot; [34846-37377] --&gt;
&lt;h3&gt;&lt;a name=&quot;порт_для_pic32&quot; id=&quot;порт_для_pic32&quot;&gt;Порт для PIC32&lt;/a&gt;&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;

Порт для PIC32 был реализован весной 2010 года по просьбам трудящихся. По сути он мало чем отличается от порта для PIC24/dsPIC. Начиная с версии 2.5.600 в комплекте идет пример, который может быть скомпилирован как под PIC24 так и под PIC32 без изменений.
&lt;/p&gt;
&lt;div class=&quot;plugin_uparrow&quot;&gt;
  &lt;a href=&quot;#&quot; title=&quot;Наверх&quot;&gt;
    &lt;img src=&quot;http://wiki.pic24.ru/lib/plugins/uparrow/images/blue_arrow.png&quot; alt=&quot;Наверх&quot;/&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Порт для PIC32&quot; [37378-37848] --&gt;
&lt;h3&gt;&lt;a name=&quot;основные_отличия_от_оригинальной_версии&quot; id=&quot;основные_отличия_от_оригинальной_версии&quot;&gt;Основные отличия от оригинальной версии&lt;/a&gt;&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;/div&gt;

&lt;h4&gt;&lt;a name=&quot;типы_данных&quot; id=&quot;типы_данных&quot;&gt;1. Типы данных&lt;/a&gt;&lt;/h4&gt;
&lt;div class=&quot;level4&quot;&gt;

&lt;p&gt;

Все стандартные типы данных (кроме &lt;code&gt;void&lt;/code&gt;) переопределены:
&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;span class='term'&gt; &lt;code&gt;TN_CHAR&lt;/code&gt;&lt;/span&gt;&lt;/dt&gt;
&lt;dd&gt;для всех архитектур соответствует &lt;code&gt;signed char&lt;/code&gt;. Под &lt;code&gt;char&lt;/code&gt; в данном случае подразумевается 1 байт.&lt;/dd&gt;
&lt;dt&gt;&lt;span class='term'&gt; &lt;code&gt;TN_UCHAR&lt;/code&gt;&lt;/span&gt;&lt;/dt&gt;
&lt;dd&gt;для всех архитектур соответствует &lt;code&gt;unsigned char&lt;/code&gt;&lt;/dd&gt;
&lt;dt&gt;&lt;span class='term'&gt; &lt;code&gt;TN_WORD&lt;/code&gt;&lt;/span&gt;&lt;/dt&gt;
&lt;dd&gt;для PIC24/dsPIC (компилятор C30) соответствует &lt;code&gt;signed int&lt;/code&gt;, то есть 16-битному целому со знаком&lt;/dd&gt;
&lt;dd&gt;для ARM (Keil RV) и PIC32 (C32) соответствует &lt;code&gt;signed int&lt;/code&gt;, то есть 32-битному целому со знаком&lt;/dd&gt;
&lt;dt&gt;&lt;span class='term'&gt; &lt;code&gt;TN_UWORD&lt;/code&gt;&lt;/span&gt;&lt;/dt&gt;
&lt;dd&gt;размер машинного слова. Этот тип рекомендуется использовать для объявления стеков задач&lt;/dd&gt;
&lt;dd&gt;для PIC24/dsPIC (компилятор C30) соответствует &lt;code&gt;unsigned int&lt;/code&gt;, то есть беззнаковому 16-битному целому&lt;/dd&gt;
&lt;dd&gt;для ARM (Keil RV) и PIC32 (C32) соответствует &lt;code&gt;unsigned int&lt;/code&gt;, то есть беззнаковому 32-битному целому&lt;/dd&gt;
&lt;dt&gt;&lt;span class='term'&gt; &lt;code&gt;TN_SYS_TIM_T&lt;/code&gt;&lt;/span&gt;&lt;/dt&gt;
&lt;dd&gt;тип счетчика &lt;a href=&quot;http://wiki.pic24.ru/doku.php/tnkernel/ref/sys/intro#системное_время&quot; class=&quot;wikilink1&quot; title=&quot;tnkernel:ref:sys:intro&quot;&gt;системного времени&lt;/a&gt;. Для PIC24/dsPIC это 32-битный счетчик, для ARM/PIC32 - 64-битный &lt;/dd&gt;
&lt;dt&gt;&lt;span class='term'&gt; &lt;code&gt;TN_TIMEOUT&lt;/code&gt;&lt;/span&gt;&lt;/dt&gt;
&lt;dd&gt;тип таймаута&lt;/dd&gt;
&lt;dd&gt;для PIC24/dsPIC (компилятор C30) соответствует &lt;code&gt;unsigned int&lt;/code&gt;, то есть беззнаковому 16-битному целому&lt;/dd&gt;
&lt;dd&gt;для ARM (Keil RV) и PIC32 (C32) соответствует &lt;code&gt;unsigned int&lt;/code&gt;, то есть беззнаковому 32-битному целому&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;
Рекомендуется употреблять эти типы для объявления переменных и массивов, связанных непосредственно с системой - стеков задач, блоков памяти фиксированного размера, очередей сообщений и др.:
&lt;/p&gt;
&lt;pre class=&quot;cpp code cpp&quot; style=&quot;font-family:monospace;&quot;&gt;TN_UWORD task_1_stack&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; TN_DATA;&lt;/pre&gt;
&lt;/div&gt;

&lt;h4&gt;&lt;a name=&quot;приоритеты_задач&quot; id=&quot;приоритеты_задач&quot;&gt;2. Приоритеты задач&lt;/a&gt;&lt;/h4&gt;
&lt;div class=&quot;level4&quot;&gt;

&lt;p&gt;

В оригинальной версии TNKernel задачи могут иметь приоритет от &lt;strong&gt;1&lt;/strong&gt; до &lt;strong&gt;30&lt;/strong&gt; (&lt;strong&gt;0&lt;/strong&gt; и &lt;strong&gt;31&lt;/strong&gt; приоритет имеют системные задачи). В версии TNKernel для PIC24/dsPIC пользовательские задачи могут иметь приоритет от &lt;strong&gt;1&lt;/strong&gt; до &lt;strong&gt;14&lt;/strong&gt; (&lt;strong&gt;0&lt;/strong&gt; и &lt;strong&gt;15&lt;/strong&gt; приоритет имеют системные задачи). Это связано с разрядностью слова контроллера и стремлением сократить время поиска следующей задачи, т.е. по сути время переключения контекста.
&lt;/p&gt;

&lt;p&gt;
Следует сказать, что такого количества приоритетов вполне достаточно, так как опционально TNKernel обеспечивает карусельное (round-robin) переключение между задачами с одинаковым приоритетом.
&lt;/p&gt;

&lt;p&gt;
&lt;p&gt;&lt;div class=&quot;noteclassic&quot;&gt;В версии TNKernel для PIC32 задачи могут иметь такие же приоритеты как и в оригинальной: &lt;strong&gt;1&lt;/strong&gt; до &lt;strong&gt;30&lt;/strong&gt;.
&lt;/div&gt;&lt;/p&gt;
&lt;/p&gt;

&lt;/div&gt;

&lt;h4&gt;&lt;a name=&quot;инициализация_системы&quot; id=&quot;инициализация_системы&quot;&gt;3. Инициализация системы&lt;/a&gt;&lt;/h4&gt;
&lt;div class=&quot;level4&quot;&gt;

&lt;p&gt;

Инициализация системы в оригинальной версии TNKernel выполняется с помощью функции &lt;code&gt;tn_start_system()&lt;/code&gt;, которая не имеет параметров. В порте TNKernel для PIC24/dsPIC и PIC32 эта функция выглядит следующим образом:
&lt;/p&gt;

&lt;p&gt;
&lt;strong&gt;Вызов:&lt;/strong&gt;
&lt;/p&gt;
&lt;pre class=&quot;cpp code cpp&quot; style=&quot;font-family:monospace;&quot;&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; tn_start_system &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;TN_UWORD &lt;span class=&quot;sy2&quot;&gt;*&lt;/span&gt;timer_task_stack,
                      TN_UWORD  timer_task_stack_size,
                      TN_UWORD &lt;span class=&quot;sy2&quot;&gt;*&lt;/span&gt;idle_task_stack,
                      TN_UWORD  idle_task_stack_size,
                      &lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;      &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy2&quot;&gt;*&lt;/span&gt;app_in_cb&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,
                      &lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;      &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy2&quot;&gt;*&lt;/span&gt;cpu_int_en&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,
                      &lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;      &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy2&quot;&gt;*&lt;/span&gt;idle_user_cb&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
                     &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/pre&gt;
&lt;p&gt;
&lt;strong&gt;Разрешен вызов:&lt;/strong&gt; &lt;br/&gt;
 
&lt;/p&gt;

&lt;p&gt;
В контексте задачи
&lt;/p&gt;

&lt;p&gt;
&lt;strong&gt;Параметры функции:&lt;/strong&gt;
&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;span class='term'&gt; &lt;code&gt;timer_task_stack&lt;/code&gt;&lt;/span&gt;&lt;/dt&gt;
&lt;dd&gt;указатель на стек системной задачи таймера&lt;/dd&gt;
&lt;dt&gt;&lt;span class='term'&gt; &lt;code&gt;timer_task_stack_size&lt;/code&gt;&lt;/span&gt;&lt;/dt&gt;
&lt;dd&gt;размер стека системной задачи таймера (в машинных словах)&lt;/dd&gt;
&lt;dt&gt;&lt;span class='term'&gt; &lt;code&gt;idle_task_stack&lt;/code&gt;&lt;/span&gt;&lt;/dt&gt;
&lt;dd&gt;указатель на стек системной задачи простоя&lt;/dd&gt;
&lt;dt&gt;&lt;span class='term'&gt; &lt;code&gt;idle_task_stack_size&lt;/code&gt;&lt;/span&gt;&lt;/dt&gt;
&lt;dd&gt;размер стека системной задачи простоя (в машинных словах)&lt;/dd&gt;
&lt;dt&gt;&lt;span class='term'&gt; &lt;code&gt;app_in_cb&lt;/code&gt;&lt;/span&gt;&lt;/dt&gt;
&lt;dd&gt;указатель на функцию инициализации приложения. Эта функция вызывается после того как системные задачи будут созданы, а планировщик запущен&lt;/dd&gt;
&lt;dt&gt;&lt;span class='term'&gt; &lt;code&gt;cpu_int_en&lt;/code&gt;&lt;/span&gt;&lt;/dt&gt;
&lt;dd&gt;указатель на функцию конфигурации прерываний. Эта функция вызывается сразу после функции &lt;code&gt;app_in_cb&lt;/code&gt;&lt;/dd&gt;
&lt;dt&gt;&lt;span class='term'&gt; &lt;code&gt;idle_user_cb&lt;/code&gt;&lt;/span&gt;&lt;/dt&gt;
&lt;dd&gt;указатель на функцию, циклически вызываемую из задачи простоя. В этой функции можно, например, инкрементировать счетчик загрузки или уводить контроллер в состояние пониженного энергопотребления (Sleep или Idle) &lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;
&lt;strong&gt;Возвращаемые значения:&lt;/strong&gt; 
&lt;/p&gt;

&lt;p&gt;
нет
&lt;/p&gt;

&lt;p&gt;
&lt;strong&gt;Пример вызова:&lt;/strong&gt;  

&lt;/p&gt;
&lt;pre class=&quot;cpp code cpp&quot; style=&quot;font-family:monospace;&quot;&gt;&lt;span class=&quot;co2&quot;&gt;#define TMR_TASK_STACK_SIZE    128&lt;/span&gt;
&lt;span class=&quot;co2&quot;&gt;#define IDL_TASK_STACK_SIZE    128&lt;/span&gt;
&amp;nbsp;
TN_UWORD stk_tmr&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;TMR_TASK_STACK_SIZE&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; TN_DATA;  &lt;span class=&quot;coMULTI&quot;&gt;/* стек задачи таймера */&lt;/span&gt;
TN_UWORD stk_idl&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;IDL_TASK_STACK_SIZE&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; TN_DATA;  &lt;span class=&quot;coMULTI&quot;&gt;/* стек задачи простоя */&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; appl_init&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;
&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; intr_init&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;
&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; idle_user&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;
&amp;nbsp;
&lt;span class=&quot;kw4&quot;&gt;int&lt;/span&gt; main &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    tn_start_system&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;stk_tmr,
                    TMR_TASK_STACK_SIZE,
                    stk_idl,
                    IDL_TASK_STACK_SIZE,
                    appl_init,
                    intr_init,
                    idle_user
                   &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; appl_init &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span class=&quot;coMULTI&quot;&gt;/* инициализация */&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; intr_init &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span class=&quot;coMULTI&quot;&gt;/* инициализация и разрешение прерываний */&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; idle_user &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span class=&quot;coMULTI&quot;&gt;/* когда нечего делать мы тут */&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
Функции &lt;code&gt;app_in_cb&lt;/code&gt; и &lt;code&gt;cpu_int_en&lt;/code&gt; заменяют &lt;code&gt;tn_app_init()&lt;/code&gt; и &lt;code&gt;tn_cpu_int_enable()&lt;/code&gt; в оригинальной версии TNKernel.
&lt;/p&gt;

&lt;p&gt;
Введение параметров в функцию &lt;code&gt;tn_start_system()&lt;/code&gt; позволило более гибко настраивать систему, в частности, выбирать размеры стеков системных задач и выполнять полезные действия в задаче простоя (&lt;code&gt;tn_task_idle()&lt;/code&gt;).
&lt;/p&gt;

&lt;p&gt;
По сути в точке входа приложения - функции &lt;code&gt;main()&lt;/code&gt; должен вызываться только сервис &lt;code&gt;tn_start_system()&lt;/code&gt;.
&lt;/p&gt;

&lt;/div&gt;

&lt;h4&gt;&lt;a name=&quot;создание_задачи&quot; id=&quot;создание_задачи&quot;&gt;4. Создание задачи&lt;/a&gt;&lt;/h4&gt;
&lt;div class=&quot;level4&quot;&gt;

&lt;p&gt;

Изменен вызов сервиса создания задачи &lt;code&gt;tn_task_create()&lt;/code&gt;:

&lt;/p&gt;
&lt;pre class=&quot;cpp code cpp&quot; style=&quot;font-family:monospace;&quot;&gt;TN_RETVAL tn_task_create &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;TN_TCB    &lt;span class=&quot;sy2&quot;&gt;*&lt;/span&gt;task,
                          &lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;     &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy2&quot;&gt;*&lt;/span&gt;task_func&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;sy2&quot;&gt;*&lt;/span&gt;param&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;,
                          TN_UWORD  priority,
                          TN_UWORD  &lt;span class=&quot;sy2&quot;&gt;*&lt;/span&gt;task_stack_start,
                          TN_UWORD  task_stack_size,
                          &lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;      &lt;span class=&quot;sy2&quot;&gt;*&lt;/span&gt;param,
                          TN_UWORD  option
                         &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/pre&gt;
&lt;p&gt;
Параметр &lt;code&gt;task_stack_start&lt;/code&gt; указывает на вершину (младший адрес) стека задачи, тогда как в оригинальной версии, &lt;code&gt;task_stack_start&lt;/code&gt; указывает на старший адрес стека. Это связано с тем, что в PIC24/dsPIC стек растет от младшего адреса к старшему.
&lt;p&gt;&lt;div class=&quot;notewarning&quot;&gt;
В версии TNKernel для PIC32 в функцию создания задачи так же должен передаваться адрес вершины стека, несмотря на то, что у MIPS32 стек растет от старшего адреса к младшему.

&lt;/div&gt;&lt;/p&gt;

&lt;/p&gt;
&lt;div class=&quot;plugin_uparrow&quot;&gt;
  &lt;a href=&quot;#&quot; title=&quot;Наверх&quot;&gt;
    &lt;img src=&quot;http://wiki.pic24.ru/lib/plugins/uparrow/images/blue_arrow.png&quot; alt=&quot;Наверх&quot;/&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Основные отличия от оригинальной версии&quot; [37849-46706] --&gt;
&lt;h3&gt;&lt;a name=&quot;нововведения&quot; id=&quot;нововведения&quot;&gt;Нововведения&lt;/a&gt;&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;/div&gt;

&lt;h4&gt;&lt;a name=&quot;критические_секции&quot; id=&quot;критические_секции&quot;&gt;1. Критические секции&lt;/a&gt;&lt;/h4&gt;
&lt;div class=&quot;level4&quot;&gt;

&lt;p&gt;

Добавлены функции &lt;code&gt;tn_sys_enter_critical()&lt;/code&gt; и &lt;code&gt;tn_sys_exit_critical()&lt;/code&gt;, которые аналогичны используемым в оригинальной версии &lt;code&gt;tn_disable_interrupt()&lt;/code&gt; и &lt;code&gt;tn_enable_interrupt()&lt;/code&gt;. Функции используются следующим образом:

&lt;/p&gt;
&lt;pre class=&quot;cpp code cpp&quot; style=&quot;font-family:monospace;&quot;&gt;&lt;span class=&quot;coMULTI&quot;&gt;/* ... */&lt;/span&gt;
&amp;nbsp;
tn_sys_enter_critical&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;
    &lt;span class=&quot;coMULTI&quot;&gt;/*
      критическая секция кода, в которой запрещено переключение контекста
    */&lt;/span&gt;
tn_sys_exit_critical&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;
&amp;nbsp;
&lt;span class=&quot;coMULTI&quot;&gt;/* ... */&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
Названия функций отражают их назначение - выделение части кода в критическую секцию в которой запрещено переключение контекста. &lt;code&gt;tn_disable_interrupt()&lt;/code&gt; и &lt;code&gt;tn_enable_interrupt()&lt;/code&gt; - не совсем корректное название для PIC24/dsPIC, которые имеют векторный приоритетный контроллер прерываний.
&lt;p&gt;&lt;div class=&quot;notewarning&quot;&gt;
В версии TNKernel PIC32 функция &lt;code&gt;tn_sys_enter_critical()&lt;/code&gt; запрещает все прерывания!

&lt;/div&gt;&lt;/p&gt;
&lt;/p&gt;

&lt;/div&gt;

&lt;h4&gt;&lt;a name=&quot;новые_сервисы&quot; id=&quot;новые_сервисы&quot;&gt;2. Новые сервисы&lt;/a&gt;&lt;/h4&gt;
&lt;div class=&quot;level4&quot;&gt;

&lt;p&gt;

Добавлены следующие сервисы:

&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.pic24.ru/doku.php/tnkernel/ref/task/tn_task_isuspend&quot; class=&quot;wikilink1&quot; title=&quot;tnkernel:ref:task:tn_task_isuspend&quot;&gt;tn_task_isuspend()&lt;/a&gt; - останов задачи в прерывании&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.pic24.ru/doku.php/tnkernel/ref/task/tn_task_iresume&quot; class=&quot;wikilink1&quot; title=&quot;tnkernel:ref:task:tn_task_iresume&quot;&gt;tn_task_iresume()&lt;/a&gt; - восстановление задачи из прерывания&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.pic24.ru/doku.php/tnkernel/ref/sys/tn_sys_context_get&quot; class=&quot;wikilink1&quot; title=&quot;tnkernel:ref:sys:tn_sys_context_get&quot;&gt;tn_sys_context_get()&lt;/a&gt; - получение текущего контекста системы&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.pic24.ru/doku.php/tnkernel/ref/task/tn_task_reference&quot; class=&quot;wikilink1&quot; title=&quot;tnkernel:ref:task:tn_task_reference&quot;&gt;tn_task_reference()&lt;/a&gt; - получение информации о задаче&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.pic24.ru/doku.php/tnkernel/ref/task/tn_task_ireference&quot; class=&quot;wikilink1&quot; title=&quot;tnkernel:ref:task:tn_task_ireference&quot;&gt;tn_task_ireference()&lt;/a&gt; - получение информации о задаче в прерывании&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;

&lt;h4&gt;&lt;a name=&quot;атрибут_задачи&quot; id=&quot;атрибут_задачи&quot;&gt;3. Атрибут задачи&lt;/a&gt;&lt;/h4&gt;
&lt;div class=&quot;level4&quot;&gt;

&lt;p&gt;

Функции задач могут объявляться с атрибутом &lt;code&gt;TN_TASK&lt;/code&gt;. Этот атрибут сообщает компилятору о том, что функция имеет бесконечный цикл и выхода из нее не будет. В большинстве случаев это позволяет уменьшить размер стека задачи. Пример:
&lt;/p&gt;
&lt;pre class=&quot;cpp code cpp&quot; style=&quot;font-family:monospace;&quot;&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; TN_TASK Task &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;sy2&quot;&gt;*&lt;/span&gt;par&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;;;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
    &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
        tn_task_sleep&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;
    &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h4&gt;&lt;a name=&quot;атрибут_данных&quot; id=&quot;атрибут_данных&quot;&gt;4. Атрибут данных&lt;/a&gt;&lt;/h4&gt;
&lt;div class=&quot;level4&quot;&gt;

&lt;p&gt;

Объекты и стеки задач могут объявляться с атрибутом &lt;code&gt;TN_DATA&lt;/code&gt;. По сути он размещает переменные в отдельной секции ОЗУ - это позволяет контролировать объем памяти, занимаемой объектами RTOS и стеками задач. Для этого в скрипт линкера необходимо добавить следующие строки (см., например, файл &lt;code&gt;..\example1\p24FJ128GA006.gld&lt;/code&gt;):
&lt;/p&gt;
&lt;pre class=&quot;code&quot;&gt;.tnk_data :
{
      *(tnk_data);
} &amp;#62; data&lt;/pre&gt;
&lt;p&gt;
Пример использования атрибута:
&lt;/p&gt;
&lt;pre class=&quot;cpp code cpp&quot; style=&quot;font-family:monospace;&quot;&gt;TN_SEM   Sem_From_IRQ TN_DATA;
TN_DQUE  que_test     TN_DATA;&lt;/pre&gt;
&lt;p&gt;
Все сервисы TNKernel размещаются в отдельную секцию кода. Это позволяет контролировать объем программной памяти, которую занимает ядро. Для этого в скрипт линкера необходимо добавить следующие строки (см., например, файл &lt;code&gt;..\example1\p24FJ128GA006.gld&lt;/code&gt;):
&lt;/p&gt;
&lt;pre class=&quot;code&quot;&gt;.tnk_code :
{
      *(tnk_code);
} &amp;#62;program&lt;/pre&gt;
&lt;p&gt;
&lt;p&gt;&lt;div class=&quot;noteclassic&quot;&gt;
В версии TNKernel для PIC32 именованные секции кода пока не поддерживаются.

&lt;/div&gt;&lt;/p&gt;
&lt;/p&gt;

&lt;/div&gt;

&lt;h4&gt;&lt;a name=&quot;отладка&quot; id=&quot;отладка&quot;&gt;5. Отладка&lt;/a&gt;&lt;/h4&gt;
&lt;div class=&quot;level4&quot;&gt;

&lt;p&gt;

Если в заголовочном файле &lt;code&gt;tnkernel_conf.h&lt;/code&gt; не объявить &lt;code&gt;TN_DEBUG&lt;/code&gt;, внутренняя структура всех объектов будет скрыта от пользователя, и структура объектов в окне Watch отладчика будет отображена в виде байтового массива.
&lt;/p&gt;

&lt;p&gt;
Если &lt;code&gt;TN_DEBUG&lt;/code&gt; будет объявлен, структуры объектов будут раскрыты. Это позволит отлаживать приложение контролируя значения полей структур.
&lt;/p&gt;

&lt;/div&gt;

&lt;h4&gt;&lt;a name=&quot;варианты_сервисов_без_проверки_параметров&quot; id=&quot;варианты_сервисов_без_проверки_параметров&quot;&gt;6. Варианты сервисов без проверки параметров&lt;/a&gt;&lt;/h4&gt;
&lt;div class=&quot;level4&quot;&gt;

&lt;p&gt;

В порте TNKernel для PIC24/dsPIC и PIC32 имеется два набора сервисов - с проверкой параметров и без проверки параметров. Естественно, последние будут занимать меньше программной памяти и будут быстрее выполняться. 
&lt;/p&gt;

&lt;p&gt;
Объявление &lt;code&gt;TN_NO_ERROR_CHECKING&lt;/code&gt;  в файле конфигурации системы &lt;code&gt;tnkernel_conf.h&lt;/code&gt; позволяет использовать более компактные и быстрые варианты сервисов без проверки параметров.
&lt;/p&gt;

&lt;/div&gt;

&lt;h4&gt;&lt;a name=&quot;контроль_переполнения_стеков_задач&quot; id=&quot;контроль_переполнения_стеков_задач&quot;&gt;7. Контроль переполнения стеков задач&lt;/a&gt;&lt;/h4&gt;
&lt;div class=&quot;level4&quot;&gt;

&lt;p&gt;

Микроконтроллеры PIC24/dsPIC имеют аппаратный механизм контроля переполнения стека, который полностью задействован в TNKernel для PIC24/dsPIC. Для того чтобы контролировать переполнение, необходимо объявить в коде исключение (trap) по ошибке стека:
&lt;/p&gt;
&lt;pre class=&quot;cpp code cpp&quot; style=&quot;font-family:monospace;&quot;&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; __attribute__&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;interrupt, no_auto_psv&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; _StackError &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;;;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;   &lt;span class=&quot;coMULTI&quot;&gt;/* при переполнении стека задачи попадем сюда */&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
&lt;p&gt;&lt;div class=&quot;noteclassic&quot;&gt;
В версии TNKernel для PIC32 контроль переполнения стека не поддерживается

&lt;/div&gt;&lt;/p&gt;
&lt;/p&gt;

&lt;/div&gt;

&lt;h4&gt;&lt;a name=&quot;код_возврата_terr_exs&quot; id=&quot;код_возврата_terr_exs&quot;&gt;8. Код возврата TERR_EXS&lt;/a&gt;&lt;/h4&gt;
&lt;div class=&quot;level4&quot;&gt;

&lt;p&gt;

Любой сервис, создающий объект (&lt;code&gt;tn_task_create()&lt;/code&gt;, &lt;code&gt;tn_sem_create()&lt;/code&gt;, &lt;code&gt;tn_queue_create()&lt;/code&gt;, &lt;code&gt;tn_event_create()&lt;/code&gt;, &lt;code&gt;tn_fmem_create()&lt;/code&gt; и &lt;code&gt;tn_mutex_create()&lt;/code&gt;), проверяет состояние объекта (уже создан или нет) и, либо продолжает работу, либо (если объект уже создан) возвращает код ошибки &lt;code&gt;TERR_EXS&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
Наличие проверки состояния объекта не зависит от типа вызываемого сервиса (с проверкой или без проверки параметров).
&lt;/p&gt;

&lt;/div&gt;

&lt;h4&gt;&lt;a name=&quot;получение_ревизии_tnkernel&quot; id=&quot;получение_ревизии_tnkernel&quot;&gt;9. Получение ревизии TNKernel&lt;/a&gt;&lt;/h4&gt;
&lt;div class=&quot;level4&quot;&gt;

&lt;p&gt;

Добавлен заголовочный файл &lt;code&gt;tnkernel_rev.h&lt;/code&gt;, в котором присутствуют следующие определения:

&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;code&gt;__TNKERNEL_VERSION&lt;/code&gt; - текущая версия (float)&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;code&gt;__TNKERNEL_REVISION&lt;/code&gt; - текущая ревизия (беззнаковое целое)&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;code&gt;__TNKERNEL_REVISION_TIME_STRING&lt;/code&gt; - время и дата создания ревизии (строка)&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;code&gt;__TNKERNEL_BUILD_TIME_STRING&lt;/code&gt; - время и дата сборки библиотеки (строка)&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;

Пример использования:
&lt;/p&gt;
&lt;pre class=&quot;cpp code cpp&quot; style=&quot;font-family:monospace;&quot;&gt;TN_UWORD  tn_revision &lt;span class=&quot;sy1&quot;&gt;=&lt;/span&gt; __TNKERNEL_REVISION;
&lt;span class=&quot;kw4&quot;&gt;char&lt;/span&gt;     &lt;span class=&quot;sy2&quot;&gt;*&lt;/span&gt;tn_data     &lt;span class=&quot;sy1&quot;&gt;=&lt;/span&gt; __TNKERNEL_REVISION_TIME_STRING;
&lt;span class=&quot;kw4&quot;&gt;char&lt;/span&gt;     &lt;span class=&quot;sy2&quot;&gt;*&lt;/span&gt;tn_build    &lt;span class=&quot;sy1&quot;&gt;=&lt;/span&gt; __TNKERNEL_BUILD_TIME_STRING;
&amp;nbsp;
&lt;span class=&quot;co2&quot;&gt;#if (__TNKERNEL_VERSION == 2.5)&lt;/span&gt;
    &lt;span class=&quot;co2&quot;&gt;#if (__TNKERNEL_REVISION == 977)&lt;/span&gt;
        &lt;span class=&quot;coMULTI&quot;&gt;/* ... */&lt;/span&gt;
    &lt;span class=&quot;co2&quot;&gt;#endif&lt;/span&gt;
&lt;span class=&quot;co2&quot;&gt;#else&lt;/span&gt;
    &lt;span class=&quot;coMULTI&quot;&gt;/*...*/&lt;/span&gt;
&lt;span class=&quot;co2&quot;&gt;#endif&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;kw3&quot;&gt;printf&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;tn_data&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/pre&gt;
&lt;/div&gt;

&lt;h4&gt;&lt;a name=&quot;системный_таймер&quot; id=&quot;системный_таймер&quot;&gt;10. Системный таймер&lt;/a&gt;&lt;/h4&gt;
&lt;div class=&quot;level4&quot;&gt;

&lt;p&gt;

Системным таймером назван счетчик, инкрементируемый каждый системный тик. Для установки и получения значения системного таймера используются следующие сервисы:

&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.pic24.ru/doku.php/tnkernel/ref/sys/tn_sys_time_set&quot; class=&quot;wikilink1&quot; title=&quot;tnkernel:ref:sys:tn_sys_time_set&quot;&gt;tn_sys_time_set()&lt;/a&gt; - установка системного таймера&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.pic24.ru/doku.php/tnkernel/ref/sys/tn_sys_time_get&quot; class=&quot;wikilink1&quot; title=&quot;tnkernel:ref:sys:tn_sys_time_get&quot;&gt;tn_sys_time_get()&lt;/a&gt; - получение значения системного таймера&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;

&lt;h4&gt;&lt;a name=&quot;файл_конфигурации&quot; id=&quot;файл_конфигурации&quot;&gt;11. Файл конфигурации&lt;/a&gt;&lt;/h4&gt;
&lt;div class=&quot;level4&quot;&gt;

&lt;p&gt;

Пользовательский проект должен включать в себя заголовочный файл конфигурации &lt;code&gt;tnkernel_conf.h&lt;/code&gt;, в котором определены (или не определены) дефайны &lt;code&gt;TN_DEBUG&lt;/code&gt; и &lt;code&gt;TN_NO_ERROR_CHECKING&lt;/code&gt;. Конечно, в свойствах проекта папка с этим файлом должна быть добавлена в пути поиска заголовочных файлов.
&lt;/p&gt;

&lt;p&gt;
&lt;a href=&quot;http://wiki.pic24.ru/lib/exe/detail.php/tnkernel/include_search.png?id=tnkernel%3Amchp_c30_16bit_port&quot; class=&quot;media&quot; title=&quot;tnkernel:include_search.png&quot;&gt;&lt;img src=&quot;http://wiki.pic24.ru/lib/exe/fetch.php/tnkernel/include_search.png&quot; class=&quot;media&quot; title=&quot;Добавление пути поиска заголовочных файлов&quot; alt=&quot;Добавление пути поиска заголовочных файлов&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;div class=&quot;plugin_uparrow&quot;&gt;
  &lt;a href=&quot;#&quot; title=&quot;Наверх&quot;&gt;
    &lt;img src=&quot;http://wiki.pic24.ru/lib/plugins/uparrow/images/blue_arrow.png&quot; alt=&quot;Наверх&quot;/&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Нововведения&quot; [46707-55941] --&gt;
&lt;h3&gt;&lt;a name=&quot;использование_прерываний&quot; id=&quot;использование_прерываний&quot;&gt;Использование прерываний&lt;/a&gt;&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;

Основное предупреждение: все прерывания должны быть запрещены до момента запуска системы. Для конфигурации источников прерываний и разрешения прерываний предназначена функция &lt;code&gt;cpu_int_en&lt;/code&gt;, указатель на которую передается в сервисе &lt;code&gt;tn_start_system()&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
Будем называть прерывания в которых вызываются сервисы системными, а все остальные прерывания - пользовательскими.
&lt;/p&gt;

&lt;p&gt;
&lt;p&gt;&lt;div class=&quot;notewarning&quot;&gt;
В TNKernel для PIC24/dsPIC системные прерывания должны иметь приоритет, равный &lt;code&gt;TN_INTERRUPT_LEVEL&lt;/code&gt; (приоритет 1). Вызов сервисов RTOS в обработчике прерывания с другим (более высоким) приоритетом (т.е. в ISR пользовательского прерывания) &lt;strong&gt;запрещен&lt;/strong&gt; - это приведет к краху системы. В текущей версии TNKernel защита от вызова системных сервисов в пользовательском прерывании не реализована.
&lt;/p&gt;

&lt;p&gt;
В TNKernel для PIC32 системные прерывания должны иметь &lt;strong&gt;одинаковый&lt;/strong&gt; приоритет, но не обязательно равный &lt;code&gt;TN_INTERRUPT_LEVEL&lt;/code&gt;. Однако для совместимости кода рекомендуется использовать приоритет 1, как и в версии TNKernel для PIC24/dsPIC.

&lt;/div&gt;&lt;/p&gt;
&lt;/p&gt;

&lt;p&gt;
В TNKernel для PIC24/dsPIC и PIC32 не реализована вложенность системных прерываний. С одной стороны это может привести к задержке обработки прерывания, с другой - экономит стек задачи, что на самом деле более важно, особенно для PIC32. Если задержка входа в прерывание недопустима, можно использовать пользовательское прерывание с приоритетом большим чем &lt;code&gt;TN_INTERRUPT_LEVEL&lt;/code&gt;. Однако, не нужно забывать, что вызов сервисов RTOS в пользовательском прерывании запрещен, поэтому задачи должны взаимодействовать с пользовательским прерыванием с помощью глобальных переменных. Это некрасиво и по большому счету неправильно, но другого выхода нет…
&lt;/p&gt;

&lt;p&gt;
Системные прерывания объявляются с помощью макроса &lt;code&gt;tn_sys_interrupt&lt;/code&gt;, аргументом которого является зарезервированый псевдоним вектора прерывания:
&lt;/p&gt;
&lt;pre class=&quot;cpp code cpp&quot; style=&quot;font-family:monospace;&quot;&gt;&lt;span class=&quot;coMULTI&quot;&gt;/* PIC24/dsPIC */&lt;/span&gt;
tn_sys_interrupt &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;_INT0Interrupt&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;   &lt;span class=&quot;coMULTI&quot;&gt;/* системное прерывание, источник INT0 */&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    IFS0bits.&lt;span class=&quot;me1&quot;&gt;INT0IF&lt;/span&gt; &lt;span class=&quot;sy1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nu19&quot;&gt;0&lt;/span&gt;;
    tn_queue_isend_polling&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy3&quot;&gt;&amp;amp;&lt;/span&gt;que_test, transceived_buff&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;coMULTI&quot;&gt;/* PIC32 */&lt;/span&gt;
tn_sys_interrupt&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;_CHANGE_NOTICE_VECTOR&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    INTClearFlag&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;INT_CN&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;
    &lt;span class=&quot;coMULTI&quot;&gt;/* обработка прерывания */&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
Пользовательские прерывания объявляются обычным для C30/C32 способом.
&lt;/p&gt;

&lt;p&gt;
Одно из системных прерываний всегда должно быть зарезервировано для системного таймера. Как правило это прерывание от аппаратного таймера с периодом 1-10 мс:
&lt;/p&gt;
&lt;pre class=&quot;cpp code cpp&quot; style=&quot;font-family:monospace;&quot;&gt;&lt;span class=&quot;coMULTI&quot;&gt;/* PIC24/dsPIC */&lt;/span&gt;
tn_sys_interrupt &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;_T2Interrupt&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;     &lt;span class=&quot;coMULTI&quot;&gt;/* системное прерывание, источник TMR2 */&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    IFS0bits.&lt;span class=&quot;me1&quot;&gt;T2IF&lt;/span&gt; &lt;span class=&quot;sy1&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nu19&quot;&gt;0&lt;/span&gt;;
    tn_tick_int_processing&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;coMULTI&quot;&gt;/* PIC32 */&lt;/span&gt;
tn_sys_interrupt&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;_CORE_TIMER_VECTOR&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;   &lt;span class=&quot;coMULTI&quot;&gt;/* системное прерывание, источник - системный таймер MIPS32 */&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    Sys_Tmr_Int_Handler&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;
    tn_tick_int_processing&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
&lt;p&gt;&lt;div class=&quot;notewarning&quot;&gt;
Сервис &lt;code&gt;tn_tick_int_processing()&lt;/code&gt; должен вызываться только из системного прерывания.

&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;&lt;div class=&quot;notewarning&quot;&gt;
&lt;strong&gt;Внимание!!!&lt;/strong&gt; Если в обработчике прерывания вызывается серсив &lt;code&gt;tn_tick_int_processing()&lt;/code&gt;, то вызов других сервисов RTOS в этом прерывании запрещен!

&lt;/div&gt;&lt;/p&gt;
&lt;/p&gt;

&lt;p&gt;
Следует заметить что сервисы &lt;code&gt;tn_sys_enter_critical()&lt;/code&gt; и &lt;code&gt;tn_sys_exit_critical()&lt;/code&gt; запрещают &lt;strong&gt;системные&lt;/strong&gt; прерывания, в то время как прерывания с приоритетом, большим &lt;code&gt;TN_INTERRUPT_LEVEL&lt;/code&gt; остаются активными - только для PIC24/dsPIC. Для PIC32 эти сервисы запрещают &lt;strong&gt;ВСЕ&lt;/strong&gt; прерывания.
&lt;/p&gt;
&lt;div class=&quot;plugin_uparrow&quot;&gt;
  &lt;a href=&quot;#&quot; title=&quot;Наверх&quot;&gt;
    &lt;img src=&quot;http://wiki.pic24.ru/lib/plugins/uparrow/images/blue_arrow.png&quot; alt=&quot;Наверх&quot;/&gt;
  &lt;/a&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Использование прерываний&quot; [55942-61220] --&gt;
&lt;h2&gt;&lt;a name=&quot;отличия_порта_для_pic32_от_порта_для_pic24dspic&quot; id=&quot;отличия_порта_для_pic32_от_порта_для_pic24dspic&quot;&gt;Отличия порта для PIC32 от порта для PIC24/dsPIC&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;
&lt;ol&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;code&gt;tn_sys_enter_critical()&lt;/code&gt; запрещает все прерывания, а не только с приоритетом &lt;code&gt;TN_INTERRUPT_LEVEL&lt;/code&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; данные и код не размещаются в именованные секции&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; системные прерывания могут иметь приоритет отличный от &lt;code&gt;TN_INTERRUPT_LEVEL&lt;/code&gt;, однако приоритет должен быть одинаковым для всех системных прерываний&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; приоритеты задач - от 1 до 30&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; переполнение стека не контролируется!&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Отличия порта для PIC32 от порта для PIC24/dsPIC&quot; [61221-] --&gt;</description>
    </item>
    <item rdf:about="http://wiki.pic24.ru/doku.php/tnkernel/ports?rev=1208439711">
        <dc:format>text/html</dc:format>
        <dc:date>2008-04-17T17:41:51+03:00</dc:date>
        <title>Порты TNKernel</title>
        <link>http://wiki.pic24.ru/doku.php/tnkernel/ports?rev=1208439711</link>
        <description>
&lt;p&gt;
&lt;br/&gt;
 
&lt;/p&gt;



&lt;h1&gt;&lt;a name=&quot;порты_tnkernel&quot; id=&quot;порты_tnkernel&quot;&gt;Порты TNKernel&lt;/a&gt;&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;

Благодаря тому, что большая часть кода реализована на Си (ассемблер используется только для платформозависимых функций типа переключения контекста, инициализации стека и т.п.) TNKernel может быть просто перенесена на различные архитектуры.
&lt;/p&gt;

&lt;p&gt;
&lt;a href=&quot;http://www.tnkernel.com&quot; class=&quot;urlextern&quot; title=&quot;http://www.tnkernel.com&quot;  rel=&quot;nofollow&quot;&gt; Оригинальная версия&lt;/a&gt; TNKernel разработана для микроконтроллеров с ядром ARM7 На сайте разработчика можно скачать порты для наиболее популярных контроллеров (NXP, Atmel, STM, Samsung), поддерживающие различные компиляторы (CW GCC, IAR, GCC, RealView, GreenHills). 
&lt;/p&gt;

&lt;p&gt;
Позже TNKernel была портирована для поддержки 16-битной архитектуры Microchip - микроконтроллеров PIC24F/H и  цифровых сигнальных контроллеров dsPIC30/33. Пока существует только порт для наиболее популярного компилятора Microchip C30.
&lt;/p&gt;

&lt;p&gt;
Планируется портирование TNKernel на 32-битные микроконтроллеры Microchip PIC32 с архитектурой MIPS32 M4K.

&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://wiki.pic24.ru/doku.php/tnkernel/mchp_c30_16bit_port&quot; class=&quot;wikilink1&quot; title=&quot;tnkernel:mchp_c30_16bit_port&quot;&gt;Порт для микроконтроллеров Microchip PIC24/dsPIC&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;!-- SECTION &quot;Порты TNKernel&quot; [7-] --&gt;</description>
    </item>
</rdf:RDF>
