|
Библиотека атомарных операций для STM32 |
|
|
|
 |
Ответов
|
Jun 24 2015, 04:19
|
Частый гость
 
Группа: Участник
Сообщений: 142
Регистрация: 10-11-12
Пользователь №: 74 318

|
Цитата(ViKo @ Jun 24 2015, 09:00)  Программы - в студию. К сожалению по мере тестирования программа менялась  Последний вариант - тестирование пустого прерывания. Устроит? А выводы - вроде как работает, но не настолько эффективно как хотелось. Скорее всего буду использовать.
Сообщение отредактировал ArtDenis - Jun 24 2015, 07:40
--------------------
|
|
|
|
|
Jun 24 2015, 08:00
|
Частый гость
 
Группа: Участник
Сообщений: 142
Регистрация: 10-11-12
Пользователь №: 74 318

|
Цитата(ViKo @ Jun 24 2015, 12:44)  Устроят любые программы, как образец. И тестировщиков прибавится. И выводы скорректируются. Ну держи. Правда, используется собственная либа для работы с периферией. Если светодиод загорелся, то монитор не отловил нарушений, если не загорелся, то отловил. К сожалению, светодиод на плате один. Поскупился я на них )) Код #include <stdint.h> #include "stm32_lib/stm32l1xx/hl_gpio.hpp" #include "stm32_lib/stm32l1xx/hl_adc.hpp" #include "stm32_lib/stm32l1xx/hl_rcc.hpp"
using namespace hl;
typedef PA8 LedPin;
static void init_led() { PA::clock_on(); PA::reset(); LedPin::conf_out_push_pull(); LedPin::off(); }
static void adc_init() { rcc_enable_hsi(); ADC_<1>::clock_on(); ADC_<1>::reset(); ADC_<1>::set_regular_len(1); ADC_<1>::set_regular_channel_pos(1, 0); ADC_<1>::enable_eoc_interrupt(); ADC_<1>::enable(); NVIC_EnableIRQ(ADC1_IRQn); }
static void led_on(bool value) { LedPin::set_out(value); }
// Нулевой тест. Между LDREXW и STREXW почти ничего нету // Монитор НЕ отлавливает нарушение static void test0() { volatile uint32_t var = 0; __LDREXW(&var); bool res = __STREXW(10, &var) == 0; led_on(res); }
// Изменение памяти при помощи STR // Монитор НЕ отлавливает нарушение static void test1() { volatile uint32_t var = 0; __LDREXW(&var); var = 20; bool res = __STREXW(10, &var) == 0; led_on(res); }
// Изменение одного участка памяти при помощи STREX // Монитор отлавливает нарушение static void test2() { volatile uint32_t var = 0; __LDREXW(&var); __STREXW(20, &var); bool res = __STREXW(10, &var) == 0; led_on(res); }
// Изменение разных участков памяти при помощи STREX // Монитор отлавливает нарушение static void test3() { volatile uint32_t var = 0; volatile uint32_t var2 = 0; __LDREXW(&var); __STREXW(20, &var2); bool res = __STREXW(10, &var) == 0; led_on(res); }
// Прерывание между LDREX и STREX // Монитор отлавливает нарушение // volatile bool interrupt_executed = false; static void test4() { volatile uint32_t var = 0; __LDREXW(&var);
// Вот таким вот нехитрым образом добиваемся прерывания )) ADC_<1>::start_regular_conversion(); ADC_<1>::start_regular_conversion(); ADC_<1>::start_regular_conversion(); ADC_<1>::start_regular_conversion(); ADC_<1>::start_regular_conversion(); ADC_<1>::start_regular_conversion(); ADC_<1>::start_regular_conversion(); ADC_<1>::start_regular_conversion(); ADC_<1>::start_regular_conversion(); ADC_<1>::start_regular_conversion(); ADC_<1>::start_regular_conversion(); ADC_<1>::start_regular_conversion(); ADC_<1>::start_regular_conversion(); ADC_<1>::start_regular_conversion(); ADC_<1>::start_regular_conversion(); ADC_<1>::start_regular_conversion(); ADC_<1>::start_regular_conversion(); ADC_<1>::start_regular_conversion(); ADC_<1>::start_regular_conversion(); ADC_<1>::start_regular_conversion(); ADC_<1>::start_regular_conversion(); ADC_<1>::start_regular_conversion(); // Тут прерывание точно произошло, т.к. мы работаем на частоте 2 МГц, а АЦП на 16 Мгц
// Это осталось от предыдущего теста: // while (!interrupt_executed) {}
bool res = __STREXW(10, &var) == 0; led_on(res); }
extern "C" void ADC1_IRQHandler() { // interrupt_executed = true; ADC_<1>::clear_eoc_flag(); }
int main() { init_led(); adc_init(); // test0(); // test1(); // test2(); // test3(); test4(); } Один из старых вариантов тестирования прерывания был таким: Код static void test4() { volatile uint32_t var = 0; __LDREXW(&var);
ADC_<1>::start_regular_conversion(); while (!interrupt_executed) {}
bool res = __STREXW(10, &var) == 0; led_on(res); }
extern "C" void ADC1_IRQHandler() { interrupt_executed = true; ADC_<1>::clear_eoc_flag(); } Он тоже показывал что монитор отловил нарушение эксклюзивного доступа. PS: критика крайне приветствуется ))
Сообщение отредактировал ArtDenis - Jun 24 2015, 08:01
--------------------
|
|
|
|
|
Jun 24 2015, 09:42
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(ArtDenis @ Jun 24 2015, 14:00)  PS: критика крайне приветствуется )) Все тесты, кроме test4() бессмысленны. Непонятно - что там тестируется? LDREX/STREX призваны для обнаружения нарушения эксклюзивного доступа (когда при работе одного процесса с переменной, происходит доступ к ней другого процесса). Везде кроме test4() имеется только работа одного процесса. Цитата(ArtDenis @ Jun 24 2015, 15:31)  Есть в STM32 такие прерывания для которых не надо сбрасывать флаг при выходе из обработчика? Все прерывания M-ядра квитируются (переходят в разряд обслуживаемых со снятием запроса). Путаете мух с котлетами. Сбрасывать возможно нужно флаги периферии, вызвавшие срабатывание этих прерываний. Ничего не мешает возбудить эти прерывания программно через NVIC. Читайте мануал на M-ядро.
|
|
|
|
|
Jun 24 2015, 09:49
|
Частый гость
 
Группа: Участник
Сообщений: 142
Регистрация: 10-11-12
Пользователь №: 74 318

|
Цитата(jcxz @ Jun 24 2015, 14:42)  Все тесты, кроме test4() бессмысленны. Непонятно - что там тестируется? LDREX/STREX призваны для обнаружения нарушения эксклюзивного доступа (когда при работе одного процесса с переменной, происходит доступ к ней другого процесса). Везде кроме test4() имеется только работа одного процесса. Вообще тестируется работа монитора эксклюзивного доступа, которому все эти потоки и процессы по барабану. Он вообще не знает о таких вещах. Цитата(jcxz @ Jun 24 2015, 14:42)  Все прерывания M-ядра квитируются (переходят в разряд обслуживаемых со снятием запроса). Путаете мух с котлетами. Сбрасывать возможно нужно флаги периферии, вызвавшие срабатывание этих прерываний. Ничего не мешает возбудить эти прерывания программно через NVIC. Читайте мануал на M-ядро. Так что мне сделать, чтобы был пустой обработчик прерывания, в котором не надо сбрасывать флаг? И кстати, я не понял что именно я путаю и в каком месте ))
--------------------
|
|
|
|
|
Jun 24 2015, 10:34
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(ArtDenis @ Jun 24 2015, 15:49)  Вообще тестируется работа монитора эксклюзивного доступа, которому все эти потоки и процессы по барабану. Он вообще не знает о таких вещах. Вообще этот монитор как раз и создан для этих процессов и потоков. Если что. Цитата(ArtDenis @ Jun 24 2015, 15:49)  Так что мне сделать, чтобы был пустой обработчик прерывания, в котором не надо сбрасывать флаг? И кстати, я не понял что именно я путаю и в каком месте )) Программно активировать любое прерывание через NVIC. Открываете мануал на M-ядро и читаете про "Interrupt Set-Pending Register". Путаете NVIC с периферией посылающей запросы к NVIC.
|
|
|
|
|
Jun 24 2015, 10:44
|
Частый гость
 
Группа: Участник
Сообщений: 142
Регистрация: 10-11-12
Пользователь №: 74 318

|
Цитата(jcxz @ Jun 24 2015, 15:34)  Вообще этот монитор как раз и создан для этих процессов и потоков. Если что. Если он создан для процессов и потоков, это ещё не означает, что для тестирования и проверки как он работает, нам надо обязательно использовать процессы и потоки. Цитата(jcxz @ Jun 24 2015, 15:34)  Программно активировать любое прерывание через NVIC. Путаете NVIC с периферией посылающей запросы к NVIC. А в каком конкретно месте путаю? Цитата(AHTOXA @ Jun 24 2015, 15:27)  Ну, для полноты охвата тестами  Например, SysTick. Или, вот, PendSV. Взводится вот так: Код SCB->ICSR = SCB_ICSR_PENDSVSET_Msk; О. Отлично. Код static void test4() { NVIC_EnableIRQ(PendSV_IRQn);
volatile uint32_t var = 0; __LDREXW(&var);
SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
bool res = __STREXW(10, &var) == 0; led_on(res); }
extern "C" void PendSV_Handler() { } Монитор отловил нарушение доступа
--------------------
|
|
|
|
Сообщений в этой теме
ArtDenis Библиотека атомарных операций для STM32 Jun 18 2015, 16:31 Gleb80 Атомарная, тоесть выполняющаяся за один машинный ц... Jun 18 2015, 18:47 ArtDenis Цитата(Gleb80 @ Jun 18 2015, 23:47) Атома... Jun 19 2015, 12:40  AlexandrY Цитата(ArtDenis @ Jun 19 2015, 15:40) Их ... Jun 19 2015, 19:14 AlexandrY Цитата(ArtDenis @ Jun 18 2015, 19:31) Кто... Jun 18 2015, 19:27 Aner QUOTE (AlexandrY @ Jun 18 2015, 23:27) ST... Jun 18 2015, 19:41 AHTOXA Цитата(ArtDenis @ Jun 18 2015, 21:31) Кто... Jun 18 2015, 20:40 AlexandrY Цитата(AHTOXA @ Jun 18 2015, 23:40) Не то... Jun 19 2015, 04:40  jcxz Вот моя реализация инкремента/декремента, обмена и... Jun 19 2015, 07:48   AlexandrY Цитата(jcxz @ Jun 19 2015, 10:48) Вот моя... Jun 19 2015, 08:24    jcxz Цитата(AlexandrY @ Jun 19 2015, 14:24) А ... Jun 19 2015, 08:27     AlexandrY Цитата(jcxz @ Jun 19 2015, 11:27) Работае... Jun 19 2015, 08:34      jcxz Цитата(AlexandrY @ Jun 19 2015, 14:34) Но... Jun 19 2015, 08:42 ViKo Объясните, на какой диапазон памяти распространяет... Jun 19 2015, 08:19 ArtDenis Может особо не париться с атомарными операциями, и... Jun 20 2015, 05:07 jcxz Цитата(ArtDenis @ Jun 20 2015, 11:07) Как... Jun 20 2015, 11:12 ArtDenis Ковыряю std::atomic. Оказывается они работают для ... Jun 22 2015, 04:01 AHTOXA Цитата(ArtDenis @ Jun 22 2015, 09:01) В а... Jun 22 2015, 06:08 ArtDenis Так непонятно, нужны ли там барьеры. У STM32 вроде... Jun 22 2015, 08:16 AHTOXA Насколько я понимаю, эти барьеры (DMB) нужны для м... Jun 22 2015, 08:56 jcxz Цитата(ArtDenis @ Jun 22 2015, 14:16) Так... Jun 22 2015, 08:59 AlexandrY Цитата(ArtDenis @ Jun 22 2015, 11:16) Так... Jun 22 2015, 10:03  AlexandrY Цитата(AlexandrY @ Jun 22 2015, 13:03) Из... Jun 22 2015, 13:26   ArtDenis Цитата(AlexandrY @ Jun 22 2015, 18:26) Те... Jun 22 2015, 13:53    AHTOXA Цитата(ArtDenis @ Jun 22 2015, 18:53) А м... Jun 22 2015, 18:40   jcxz Цитата(AlexandrY @ Jun 22 2015, 19:26) Зн... Jun 23 2015, 02:44    AHTOXA Цитата(jcxz @ Jun 23 2015, 07:44) Даташит... Jun 23 2015, 05:01 ArtDenis Ну вообще это очень легко проверить. Завтра поэксп... Jun 22 2015, 19:34 ViKo Если бы эксклюзивные операции отслеживали только с... Jun 23 2015, 05:55 AlexandrY Цитата(ViKo @ Jun 23 2015, 08:55) Если бы... Jun 23 2015, 06:45 jcxz Цитата(ViKo @ Jun 23 2015, 11:55) Если бы... Jun 23 2015, 07:21  AlexandrY Цитата(jcxz @ Jun 23 2015, 10:21) Вполне ... Jun 23 2015, 17:24   AHTOXA Цитата(AlexandrY @ Jun 23 2015, 22:24) Вы... Jun 23 2015, 17:29    AlexandrY Цитата(AHTOXA @ Jun 23 2015, 20:29) А как... Jun 23 2015, 17:32   jcxz Цитата(AlexandrY @ Jun 23 2015, 23:24) Т.... Jun 23 2015, 18:14 ArtDenis На моём STM32L151 получились такие результаты:
Мо... Jun 23 2015, 17:45 AlexandrY Цитата(ArtDenis @ Jun 23 2015, 20:45) Мон... Jun 23 2015, 18:25  ArtDenis Цитата(AlexandrY @ Jun 23 2015, 23:25) Ст... Jun 23 2015, 18:42   ArtDenis Цитата(ArtDenis @ Jun 23 2015, 23:42) Воо... Jun 24 2015, 02:48 ArtDenis Недокопипастил. Там в конце main() ещё
Кодfor ... Jun 24 2015, 09:02 AHTOXA Ну, вроде всё вполне согласуется с моими опытами.
... Jun 24 2015, 09:19  ArtDenis Цитата(AHTOXA @ Jun 24 2015, 14:19) Ну, в... Jun 24 2015, 09:31   AHTOXA Цитата(ArtDenis @ Jun 24 2015, 14:31) Так... Jun 24 2015, 10:27
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|