Обновить
8K+
6

Пользователь

3
Рейтинг
2
Подписчики
Отправить сообщение

а еще можно начало пакета пометить как-то совсем уникально. например, перейти на 9бит. или протянуть еще один проводок между мастером и слейвом(ами). и заодно в этом уникальном байте кодировать тип пакета - код может определять направление передачи и длину блока данных.

заменю результаты в теле статьи

действительно не то, спасибо!
вот результат когда test1 более приоритетна
embos **_r.a

Perfomance info CPUclk=0900MHz
service_name   min[cyc/inst]   max[cyc/inst]    min[uS]  max[uS]  avg[uS] cpi
queue          000737/000382   000876/000382    00.818   00.973   00.867  02.044
               Cortex-A7 TRM result             00.833   01.000   00.876
PMU metrics    c1=000012       c2=000046
eventFlag      000580/000278   000673/000278    00.644   00.747   00.659  02.133
               Cortex-A7 TRM result             00.666   00.750   00.683
PMU metrics    c1=000009       c2=000035
semaphore      000533/000273   000591/000273    00.592   00.656   00.597  01.967
               Cortex-A7 TRM result             00.583   00.666   00.617
PMU metrics    c1=000002       c2=000034
mutex          000894/000474   001086/000474    00.993   01.206   01.039  01.972
               Cortex-A7 TRM result             01.000   01.250   01.061
PMU metrics    c1=000014       c2=000063

и threadx
tx_user.h пустой

Perfomance info CPUclk=0900MHz
service_name   min[cyc/inst]   max[cyc/inst]    min[uS]  max[uS]  avg[uS] cpi
queue          000309/000162   000347/000162    00.343   00.385   00.346  01.919
               Cortex-A7 TRM result             00.333   00.375   00.371
PMU metrics    c1=000006       c2=000022
eventFlag      000344/000174   000419/000174    00.382   00.465   00.396  02.045
               Cortex-A7 TRM result             00.416   00.500   00.418
PMU metrics    c1=000005       c2=000021
semaphore      000259/000139   000292/000139    00.287   00.324   00.298  01.928
               Cortex-A7 TRM result             00.291   00.375   00.329
PMU metrics    c1=000005       c2=000016
mutex          000339/000193   000371/000193    00.376   00.412   00.386  01.803
               Cortex-A7 TRM result             00.375   00.458   00.413
PMU metrics    c1=000006       c2=000028

tx_user.h содержит

#define TX_DISABLE_ERROR_CHECKING
#define TX_INLINE_THREAD_RESUME_SUSPEND
Perfomance info CPUclk=0900MHz
service_name   min[cyc/inst]   max[cyc/inst]    min[uS]  max[uS]  avg[uS] cpi
queue          000272/000142   000353/000142    00.302   00.392   00.322  02.035
               Cortex-A7 TRM result             00.291   00.375   00.345
PMU metrics    c1=000004       c2=000016
eventFlag      000303/000161   000343/000161    00.336   00.381   00.342  01.913
               Cortex-A7 TRM result             00.333   00.416   00.373
PMU metrics    c1=000003       c2=000017
semaphore      000240/000132   000262/000132    00.266   00.291   00.270  01.840
               Cortex-A7 TRM result             00.291   00.333   00.294
PMU metrics    c1=000002       c2=000014
mutex          000333/000182   000358/000182    00.370   00.397   00.374  01.846
               Cortex-A7 TRM result             00.375   00.416   00.391
PMU metrics    c1=000007       c2=000025

хммм...

#define TEST1_PRIORITY  (PRIO_LVL 16)   // отправитель
#define TEST2_PRIORITY  (PRIO_LVL 15)   // получатель — вытесняет сразу

то есть я не то меряю? а вероятно может быть
сейчас перемеряю

особенно тщательно не анализировал влияние отключения контроля ошибок. на первый взгляд отключение оного дает выигрыш незначительный, до 10% примерно
в данном тесте в обеих ос контроль ошибок не отключался.
вот прогон embos в варианте release (os7t_al_r.a)

Perfomance info threadX CPUclk=0900MHz
service_name   min[cyc/inst]   max[cyc/inst]    min[uS]  max[uS]  avg[uS] cpi     
queue          000998/000488   001976/000488    01.108   02.195   01.236  02.278  
               Cortex-A7 TRM result             01.125   01.916   01.240  
PMU metrics    c1=000015       c2=000060 
eventFlag      000796/000372   001030/000372    00.884   01.144   00.967  02.338  
               Cortex-A7 TRM result             00.875   01.166   00.983  
PMU metrics    c1=000007       c2=000044 
semaphore      000615/000332   001255/000332    00.683   01.394   00.696  01.888  
               Cortex-A7 TRM result             00.708   01.208   00.718  
PMU metrics    c1=000005       c2=000038 
mutex          000703/000328   001838/000328    00.781   02.042   00.817  02.240  
               Cortex-A7 TRM result             00.791   01.833   00.839  
PMU metrics    c1=000010       c2=000038 

чуть быстрее, но непринципиально

не знаю как "убрать под кат" слишком длинные блоки исх текста

спасибо за замечания по оформлению. буду учиться писать статьи

Форматтер хабра плохо умеет обрабатывать .png, снова загрузил картинки в .jpg

клоны J-Link сейчас не сказать что дороги

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

итак, «Народная отладка» многоядерных приложений ARM Cortex

преамбула:
..попала мне в руки плата с 2х ядерным Cortex-A7

амбула:
Как оказалось, нельзя просто так подключиться ко всем (2м в моем случае) ядрам Cortex-A7 при помощи JLink.

И нельзя останавливать по software breakpoint ядро0 (к которому легко и просто цепляется отладчик IARa), ибо в этом случае ядро1 может налететь на измененный код (breakpoint) и, если не повезет, что случается, как оказалось чаще, в итоге debug-сессия зависает наглухо вместе с процессором (почему не разобрался пока).

Однако нас это не остановит! Как известно, технология Segger RTT умеет несколько каналов как upStream, так downStream.

Нас в данном случае интересуют up (от нашего процессора к компутеру). По умолчанию их даже и сконфигурировано 2!. В памяти они расположены независимо, каждый имеет свой буфер и свои указатели голова-хвост.

Эврика! Пишем простейший враппер на SEGGER_RTT_WriteString:

unsigned int RTT_WriteStringEx(unsigned char str) { unsigned int rc=0,bufN=getCPUID(); if(bufN<SEGGER_RTT_MAX_NUM_UP_BUFFERS) { rc=SEGGER_RTT_WriteString(bufN,(const char )str); } return(rc); }


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

Со стороны компьютера поток rtt0 смотрим, как обычно, RTTViewer'ом, поток rtt1 он не умеет к сожалению, поэтому используем JlinkRTTLogger.exe (его путем нехитрых танцев с бубном можно направить в консоль)

И вот такую красоту получаем на экране:

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

Со стороны компьютера поток rtt0 смотрим, как обычно, RTTViewer'ом, поток rtt1 он не умеет к сожалению, поэтому используем JlinkRTTLogger.exe (его путем нехитрых танцев с бубном можно направить в консоль)

И вот такую красоту получаем на экране:

PS. Останавливать ядро0 (к которому, как мы помним, подключен наш отладчик IARa) можно!
там где код гарантированно выполняется на ядре0, что можно обеспечить в случае режима SMP заданием affinity_mask при создании задачи rtos.

PPS Данный прием может пригодиться и для отладочной печати, например, из прерывания.

PPPS Вопрос, сколько потоков upStream умеет RTT, мне пока хватило 2, но видимо скоро понадобится 4 или 5.

PPPPS "Антинародная" отладка выглядит сильно круче, может потом сделаю еще подход к пробитию входного фильтра хабра

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

да полно ) ЖД, Росатом, связь, медицина - это знакомые и коллеги, бывшие и настоящие

карта вроде говорит какую частоту она умеет. через csd если правильно помню

автор сильно заблуждается. есть проекты и посложнее задвижек на водопроводных трубах

возможно стоит для начала найти где ошибка? в низкоуровневых процедурах чтения записи карты (стм куб ведь поди, да? с дма?) или в фатфс (в которой, например, некоторые действия в фат32 вызывают рекурсию, посему от фат32 я напрочь отказался при использовании фатфс)

проверить корректность записи чтения можно, не используя никакую файл систему, работать с секторами, что кстати, несколько быстрее )

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

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

речь о рекурсии не обработки прерывания а пользовательских функций,
добавлю, что если используется ртос, то вложенные (то, что вы, видимо, называете рекурсивными, что не совсем корректно, мне кажется) прерывания совершенно не являются необходимостью, ибо _хорошая практика - НЕ ДЕЛАТЬ ничего в обработчике прерывания, в нем только отправляется сигнал задаче, которая, собственно, уже и производит обработку события

а мне НЕ нужно прописывать уникальные пути и добавлять/убирать .c файлы (ибо условная трансляция как я выше написал). видимо мы о разном говорим, подразумевая разные варианты конфигурации проекта

в этом случае я делаю так - переменные, задающие конфигурацию сборки/прошивки выносятся в отдельный .h, в исходниках проекта эти переменные анализируются директивами #if define...
На каждый вариант прошивки создается такой файл. При необходимости собрать нужн вариант - в определенное место копируется соотв конфиг файл. Дальше либо из ИДЕ, либо из ком строки это все собирается. В особо извратном случае пишется разлапистый командный файл, который на RAM-диске запускает параллельно несколько потоков сборки. Реальный случай - число конфигураций сборки 101. Собирается в 8 потоков ибо компилятор GHS древней версии однопоточный

PS В другом проекте эти "опции" можно задать в процессе работы прошивки. Изменения применяются после рестарта. Методы решения зависят от задачи

Ну это давно известный прием, практически все ртос его имеют, как и контроль стека задач "на лету" с выпадением в ловушку. Но это все борьба с УЖЕ случившейся проблемой. А мы выше обсуждали способ недопущения этой проблемы

1

Информация

В рейтинге
1 539-й
Зарегистрирован
Активность