Считаем синус быстро и точно: ч.3 - Практика

Наконец-то переходим к самой важной части — как это вот всё использовать. Здесь я расскажу, как выбрать подходящую комбинацию длины таблицы и степени полинома, как создать эти таблицы и приведу примеры, как посчитать быстро (ну или относительно быстро).
Картинки не будет, не нашёл подходящей…


Читать дальше
  • +6
  • 08 октября 2021, 14:49
  • vix

Считаем синус быстро и точно: ч.2 - Точность вычислений

В этой части наглядно будет показано, как на точность вычислений влияет длина таблицы и размер полинома, а так же будет небольшое сравнение аппроксимаций синуса Полиномами Чебышёва и рядами Маклорена.




Читать дальше
  • +8
  • 08 октября 2021, 14:43
  • vix

Считаем синус быстро и точно: ч.1 - Теория

Хочу поделиться своей статьёй с хабра здесь, думаю пригодится. На хабре всё было одним большим куском, здесь же разобью на несколько статеек.
Поехали!

Если нужно найти синус, или другую тригонометрическую функцию на ПК, это делается просто — в большинство современных процессоров встроен блок для работы с числами с плавающей точкой, который довольно шустро (что совсем не факт) это посчитает.
Если это надо сделать это на МК без плавающей точки — то возникают проблемы. Можно использовать функцию из поставляемой вместе с компилятором библиотеки, будет точно, но очень медленно. Если надо быстрее — то первое, что приходит в голову, заранее посчитать таблицу со значениями, но точность при этом сильно упадёт, и будет зависеть от шага аргумента между смежными значениями. Следующий интуитивно понятный шаг — использовать кусочно-линейную аппроксимацию. Это поможет поднять точность, но несильно. Иногда для достижения нужной точности размер таблицы всё равно превосходит разумные пределы.
Что же тогда делать? Увеличивать степень аппроксимации. Это позволит увеличить точность вычислений и (или) уменьшить размер таблиц. И сделать это совсем несложно.


Читать дальше
  • +2
  • 08 октября 2021, 14:39
  • vix

Программа для преобразования изображений и шрифтов в код топик-ссылка

Хорошая программа для подготовки изображений к выводу на разные экранчики. Гибкое преобразование последовательностей битов, добавление масок, можно свои шаблоны написать, то есть не только Си использовать, сжатие опять же.

SpriteMods.com топик-ссылка

Тут коллега Sprite выкладывает свои наработки. Некоторые весьма интересны и даже полезны. Ну и видео в конце каждой статейки.

Ещё один программный таймер

Решил тоже поучаствовать в конкурсе «у кого таймер проще» :)
Это даже не велосипед, а так, самокат :)

Времени расписывать особо нет, поэтому буду краток.
Да и пояснять особо нечего.
typedef enum eTimerStatus
{
	etsTimerIDLE = 0,
	etsTimerCount,
	etsTimerEvent
} eTimerStatus;

typedef struct stTimer
{
	volatile ShortTimer *Count;
	volatile eTimerStatus Status;
} stTimer;

Это базовые определения. Теперь функционал:

#include "Timers.h"

/**
*	\brief Пул таймеров
*/
static ShortTimer volatile TimersPool[eTimersNumber];
static eTimerStatus volatile TimersStatusPool[eTimersNumber];

void TickTimers()
{
	for(int i=0; i < eTimersNumber; i++)
	{
		if(TimersPool[i] > 0)
		{
			TimersPool[i] --;
			if(0 == TimersPool[i])
			{
				TimersStatusPool[i] = etsTimerEvent;
			}
		}
	}
}

void StartTimer(eTimerIndex timer, ShortTimer period_ms)
{
	TimersPool[timer] = period_ms;
	TimersStatusPool[timer] = etsTimerCount;
}

eTimerStatus GetTimerStatus(eTimerIndex timer)
{
	if(etsTimerEvent == TimersStatusPool[timer])
	{
		TimersStatusPool[timer] = etsTimerIDLE;
		return(etsTimerEvent);		
	}
	else
	{
		return(TimersStatusPool[timer]);
	}
}

ShortTimer GetTimerCount(eTimerIndex timer){
	return(TimersPool[timer]);
}


Ну и пример использования.
typedef unsigned int ShortTimer;

typedef enum eTimerIndex
{
	eADC1Timer = 0,
	eADC2Timer,
	eADC3Timer,
	eADCProcessTimer,
	eChanDiapSwitchDelayTimer,
	eModbusTimer,
	eTimersNumber
} eTimerIndex;

void SysTick_Handler(void){

	TickTimers();
}

void main(){
    ...
    StartTimer(eADCProcessTimer, 5);

    while (1){
	...
	if(etsTimerEvent == GetTimerStatus(eADCProcessTimer)){
	    ProcessADC();
	    StartTimer(eADCProcessTimer, 5);
	}
        ...
    }
}


Если что непонятно (что вряд ли), спрашивайте, добавлю.
Главное удобство в простоте использования. Нужен ещё один таймер — добавили имя в enum eTimerIndex и можно пользоваться.

PS: Сейчас глянул ещё раз — а зачем мне вообще stTimer? Наверно, изначально что-то другое задумывал. Ну да ладно.

Мысли о STM32 HAL или стоит ли стремиться в метапрограммирование на C++

Навеяно сообщением коллеги evsi
Что же до либ, то есть куда более перспективный путь, хотя он и не лежит в плоскости очередного HAL от конкретного производителя. Я имею в виду вот эту либу: github.com/andysworkshop/stm32plus
Кстати, сам Andy Brown (автор либы) ведет весьма интересный сайт andybrown.me.uk/
в недавнем обсуждении STM32 Peripheral Libs: FWLib -> SPL -> Middleware+HAL+CubeMX -> Middleware+Snippets -> CMSIS-Driver API? Куда это все ведет и есть ли истинный путь?

Шаблонное метапрограммирование.
По мере изучения С++, я вижу, что все пути ведут туда. Но пока я не способен (легко) понимать такой код, а уж тем более написать.
У меня к такой библиотеке вопросы:

1. Полностью ли абстрагирует эта конкретная библиотека железо, во всей его сложности? Вопрос шире. Пусть не эта конкретная, а в принципе, можно ли с помощью шаблонного метапрограммирования написать библиотеку, с помощью которой можно включить железо в любом описанном в datasheet режиме?
Не будем брать GPIO, возьмем АЦП. Какой-нибудь сложный режим совместного использования отдельных модулей АЦП, с пересылкой по DMA, запуском по таймеру. Повторюсь, простая периферия не интересует, интересует сложная в извращенных режимах.
Если кто-то из гуру положительно ответит на этот вопрос, буду расти в ту сторону.

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

Хорошо, допустим можно написать на шаблонах вообще все, что угодно, во всей полноте. Что мы видим? С помощью достаточно сложного в применении языка шаблонов мы заставляем компилятор сгенерировать нужный нам код.

Почему бы не взять для генерации исходников более мощный язык, предназначенный для манипулирования текстом? Perl, Python, Javascript и так далее.
Описать в декларативном стиле (a-la QML) в JSON формате, что нам нужно от периферии. Парсим этот файл, генерируем C++ исходник, в котором классы периферии имеют простое АPI, минимально необходимое в конкретной задаче.

class AdcSigmaDelta
{
public:
    enum Gain
    {
        Gain05,
        Gain1,
        Gain2,
        Gain4,
        Gain8,
        Gain16,
        Gain32,
    };

    AdcSigmaDelta(const std::vector<Pin> & pins);

    bool start();
    int16_t code(size_t idx) const;
    float voltage(size_t idx) const;
    bool setGain(Gain gain);
...
}

Методы класса наш генератор реализует напрямую регистрами максимально эффективно.
Генератор должен не давать использовать одну периферию в разных местах, GPIO, задействованные в АЦП не задействовать для ШИМ.
Отсюда плавно приходит в голову использовать GUI для генерации JSON файла описателя.

Та-дам! Вот и он — STM32CubeMx.

Для меня, пока, круг замкнулся. Тот Cube, который сейчас есть, пускать в свой код нельзя, только для быстрого старта — сгенерил, посмотрел, взял в свой код, навел порядок.

Тот Cube, который я хотел бы видеть:
открытый исходный код — чтобы тысячи эмбеддеров совместно развивали проект (тысячи бесплатных тестировщиков!),
гибкий, настраиваемый — чтобы код генерился в моем стиле, раскиданный по мной описанному заголовочному файлу.

Эмуляция носителя FAT32 на stm32f4


Некоторое время назад возникла данная задача — эмуляция носителя FAT32 на stm32f4.
Её необычность заключается в том, что среди обвязки микроконтроллера вовсе может не быть накопителя, вроде FLASH-контроллера или SD-карты.
В моём случае накопитель был, но правила работы с ним не позволяли разместить файловую систему. В ТЗ, тем не менее, присутствовало требование организовать Mass Storage интерфейс для доступа к данным.
Результатом работы явился модуль, который я озаглавил «emfat», состоящий из одноимённого .h и .c файла.
Модуль независим от платформы. В прилагаемом примере он работает на плате stm32f4discovery.
Функция модуля — отдавать куски файловой системы, которые запросит usb-host, подставляя пользовательские данные, если тот пытается считать некоторый файл.
Итак, кому это может быть полезно и как это работает — читайте далее.


Читать дальше

Программный многозадачный таймер на STM32.

После начало освоения STM32 с применением библиотеки HAL и STM32Cube и наигравшись с LEDBlink пришло время прокачатся до уровня 1, благо экспириенса получил прилично, спасибо за это СООБЩЕСТВУ. Глаз положил решил написать модуль для программных таймеров на базе SysTick, но без особых проблем под эту задачу можно использовать любой другой аппаратный таймер.
И тут многие скажут, зачем изобретать велосипед? Почему не использовать уже обкатанные варианты?
Все эти варианты хороши, выбирай на вкус, но все таки я попробую изобрести свой велосипед в этой области, к тому же это:
  1. бесценный опыт
  2. попробовать реализовать другой подход к решению задачи
  3. удовлетворить свое самолюбие
  4. ну и т.д.

Итак, мы приступаем…

Читать дальше
  • +4
  • 09 декабря 2015, 13:19
  • Helix
  • 1

Жизненный цикл программиста

Михаил Донской,
опубликовано в 2008 году

Полный текст статьи известного российского системного программиста, зав. лабораторией Института системного анализа РАН, члена Российской академии интернета, автора шахматной программы «КАИССА» (первого чемпиона мира среди шахматных программ), президента компьютерной фирмы ДИСКо, лауреата всех профессиональных опросов «Top-100 Российского компьютерного бизнеса», Михаила Донского.



Так получилось, что время моей жизни практически совпало с жизненным циклом моей профессии. Я – программист. Сами компьютеры появились в 40-х годах (и не надо здесь вспоминать ерунду про дочку Байрона), то есть в то же десятилетие, когда я родился.



В начале 1970-х появились машины серии «Ряд». Так получилось, что во время моего распределения после МГУ мне пришлось быть свидетелем, как А.С. Кронрод боролся за продолжение проектирования и производства оригинальных советских машин (он даже предлагал назвать серию «АС» — автоматическая советская — по своим инициалам) против В.М. Глушкова и Л.Т. Кузина, которые ратовали за копирование IBM. Одним из аргументов у последних было то, что можно будет воспользоваться всем математическим обеспечением, созданным для IBM и ликвидировать то небольшое отставание в вычислительной технике, которое имелось в конце 1960-х.


Читать дальше