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

 
 
4 страниц V  < 1 2 3 4 >  
Reply to this topicStart new topic
> Библиотека атомарных операций для STM32
jcxz
сообщение Jun 23 2015, 07:21
Сообщение #31


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(ViKo @ Jun 23 2015, 11:55) *
Если бы эксклюзивные операции отслеживали только сами себя, толку от них было бы никакого. Так можно и обычным флагом обойтись, когда захотел - установил, когда надо - проверил... Смысл именно в том, что мониторится любое обращение к памяти

А зачем Вам мониторить все обращения? Ведь нужны только те обращения, которые могут использоваться для доступа к переменным синхронизации.
Если Вам нужна чтение-модификация-запись переменной синхронизации, или неатомарное чтение (несколькиим командами) этой переменной, или запись (любая) в эту переменную,
то извольте все эти операции выполнять только инструкциями LDREX/STREX. Тогда всё будет нормально и ставить этот бит по каждому обращению к памяти совсем излишне
(но конечно возможно для упрощения реализации ядра CPU).
А просто чтение этой-же переменной синхронизации можно делать и вообще одной командой LDR (которая априори атомарна) пусть даже она и попадёт между LDREX и STREX
выполняющимися в другом потоке - это никак не повлияет на результат.


Цитата(AlexandrY @ Jun 23 2015, 12:45) *
В Cortex-M4 операция STREX даст отбой даже если в прерывании запись была сделана командой STR и совсем в другую ячейку памяти.

Вполне возможно для упрощения реализации механизма в ядре сделали срабатывание не только на эксклюзивный доступ.
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Jun 23 2015, 17:24
Сообщение #32


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(jcxz @ Jun 23 2015, 10:21) *
Вполне возможно для упрощения реализации механизма в ядре сделали срабатывание не только на эксклюзивный доступ.


С LDREX/STREX все еще более запутанней.

Решил тут протестировать как там насчет работы из разных областей памяти.
Выяснилось, что LDREX/STREX правильно работает когда переменные находятся в RAM вблизи 0x1000_0000-0x3000_0000
То, что кэширование разное сверху и снизу границы 0x2000_0000 никак не влияет, барьеры памяти можно не ставить.
А вот если использовать память которая находится после границы 0x4000_0000 , то пара LDREX/STREX там никакого эффекта не дает, хотя и исключений не вызывает.
Т.е. можно спокойно испортить переменную, а STREX ничего не покажет.

Ну и как положительный момент можно отметить, что выполнение кода из RAM на работу LDREX/STREX тоже не влияет.

А с DMA вопрос еще темный.
Мутный момент также с областями внешней памяти.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jun 23 2015, 17:29
Сообщение #33


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(AlexandrY @ Jun 23 2015, 22:24) *
Выяснилось, что LDREX/STREX правильно работает когда переменные находятся в RAM вблизи 0x1000_0000-0x3000_0000

А какой контроллер вы тестировали?


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Jun 23 2015, 17:32
Сообщение #34


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(AHTOXA @ Jun 23 2015, 20:29) *
А какой контроллер вы тестировали?


MK60FN1M0VLQ12
Go to the top of the page
 
+Quote Post
ArtDenis
сообщение Jun 23 2015, 17:45
Сообщение #35


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

Группа: Участник
Сообщений: 142
Регистрация: 10-11-12
Пользователь №: 74 318



На моём STM32L151 получились такие результаты:

Монитор НЕ отлавливает нарушение эксклюзивного доступа при простом изменение области памяти для которой был вызван LDREX или любой другой области памяти

Монитор отлавливает нарушение эксклюзивного доступа если
1. Был вызван STREX на любую область ОЗУ (не обязательно на ту, для которой был вызван LDREX)
2. Произошло любое прерывание

Сообщение отредактировал ArtDenis - Jun 23 2015, 17:47


--------------------
http://ufa-darts.ru/ - собираем дартс-лигу в Уфе
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 23 2015, 18:14
Сообщение #36


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(AlexandrY @ Jun 23 2015, 23:24) *
Т.е. можно спокойно испортить переменную, а STREX ничего не покажет.

Вы портили при помощи другой STREX или просто STR? Если второе - эксперимент некорректный.
И надо посмотреть как классифицируется память находящаяся по этим адресам. Возможна это область памяти периферии, возможно с этим связано, лень заглядывать в карту памяти в описании М-ядра. :-)
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Jun 23 2015, 18:25
Сообщение #37


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(ArtDenis @ Jun 23 2015, 20:45) *
Монитор отлавливает нарушение эксклюзивного доступа если
2. Произошло любое прерывание


Странно, у меня не на любое, а только такое где был STREX или STR во внутреннюю RAM , а вот на PUSH в ту же RAM не реагирует.


Цитата(jcxz @ Jun 23 2015, 21:14) *
Вы портили при помощи другой STREX или просто STR? Если второе - эксперимент некорректный.
И надо посмотреть как классифицируется память находящаяся по этим адресам. Возможна это область памяти периферии, возможно с этим связано, лень заглядывать в карту памяти в описании М-ядра. :-)


Конечно использовал STREX.
Go to the top of the page
 
+Quote Post
ArtDenis
сообщение Jun 23 2015, 18:42
Сообщение #38


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

Группа: Участник
Сообщений: 142
Регистрация: 10-11-12
Пользователь №: 74 318



Цитата(AlexandrY @ Jun 23 2015, 23:25) *
Странно, у меня не на любое, а только такое где был STREX или STR во внутреннюю RAM , а вот на PUSH в ту же RAM не реагирует

Вообще, в прерывании был STR. Не подумал когда тестировал, что это имеет значение


--------------------
http://ufa-darts.ru/ - собираем дартс-лигу в Уфе
Go to the top of the page
 
+Quote Post
ArtDenis
сообщение Jun 24 2015, 02:48
Сообщение #39


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

Группа: Участник
Сообщений: 142
Регистрация: 10-11-12
Пользователь №: 74 318



Цитата(ArtDenis @ Jun 23 2015, 23:42) *
Вообще, в прерывании был STR. Не подумал когда тестировал, что это имеет значение

Проверил ещё раз. Достаточно любого прерывания.


--------------------
http://ufa-darts.ru/ - собираем дартс-лигу в Уфе
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jun 24 2015, 04:00
Сообщение #40


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Программы - в студию.
И выводы, желательно, не противоречивые. rolleyes.gif
Go to the top of the page
 
+Quote Post
ArtDenis
сообщение Jun 24 2015, 04:19
Сообщение #41


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

Группа: Участник
Сообщений: 142
Регистрация: 10-11-12
Пользователь №: 74 318



Цитата(ViKo @ Jun 24 2015, 09:00) *
Программы - в студию.

К сожалению по мере тестирования программа менялась sad.gif Последний вариант - тестирование пустого прерывания. Устроит?

А выводы - вроде как работает, но не настолько эффективно как хотелось. Скорее всего буду использовать.

Сообщение отредактировал ArtDenis - Jun 24 2015, 07:40


--------------------
http://ufa-darts.ru/ - собираем дартс-лигу в Уфе
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jun 24 2015, 07:44
Сообщение #42


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(ArtDenis @ Jun 24 2015, 07:19) *
К сожалению по мере тестирования программа менялась sad.gif Последний вариант - тестирование пустого прерывания. Устроит?

А выводы - вроде как работает, но не настолько эффективно как хотелось. Скорее всего буду использовать.

Устроят любые программы, как образец. И тестировщиков прибавится. И выводы скорректируются.
Go to the top of the page
 
+Quote Post
ArtDenis
сообщение Jun 24 2015, 08:00
Сообщение #43


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

Группа: Участник
Сообщений: 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


--------------------
http://ufa-darts.ru/ - собираем дартс-лигу в Уфе
Go to the top of the page
 
+Quote Post
ArtDenis
сообщение Jun 24 2015, 09:02
Сообщение #44


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

Группа: Участник
Сообщений: 142
Регистрация: 10-11-12
Пользователь №: 74 318



Недокопипастил. Там в конце main() ещё
Код
for (;;) {}

стоит


--------------------
http://ufa-darts.ru/ - собираем дартс-лигу в Уфе
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jun 24 2015, 09:19
Сообщение #45


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Ну, вроде всё вполне согласуется с моими опытами.
Единственный момент, ADC_<1>::clear_eoc_flag() - наверняка делает STR в область периферии. Для чистоты эксперимента хорошо бы сделать совсем пустой обработчик прерывания.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 13:43
Рейтинг@Mail.ru


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