Перейти к содержанию
    

Кооперативная RTOS для STM32

16 hours ago, haker_fox said:

А какое отношение ОС имеет к регистрам?

Никакого. А написание своего драйвера под эту ОС с учётом её особенностей - имеет

А вообще, смотрю, народ в запале давно отошёл от исходной темы. :rofl:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5 hours ago, dimka76 said:

uint32_t* gpio_ptr = (uint32_t*)0x40000000;

Тут пропустили volatile) Должно быть так

volatile uint32_t* gpio_ptr = (uint32_t*)0x40000000;

 

5 hours ago, dimka76 said:

volatile Gpio* port = reinterpret_cast<volatile Gpio*>(0x40000000);

А здесь можно и так

volatile auto * port = reinterpret_cast<Gpio*>(0x40000000);

Вполне себе равны по длине) Зато тип выводится автоматически)

Но вы взяли один пример в лоб. И он ни о чём не говорит. Приводить контрпример не буду. Считаю, что это асурдно. Кому нужно, сам разберётся. На эту тему и так слишком много было разговоров.

5 hours ago, AlexandrY said:

С плюсами есть конкретные суровые обломы в embedded и их как бы стоит знать

О каких обломах вы говорите?

4 hours ago, Chudik said:

А написание своего драйвера под эту ОС с учётом её особенностей - имеет

Так это применимо к любой ОСРВ)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

7 hours ago, dimka76 said:
8 hours ago, __inline__ said:

Ну и как бонус С++ - можно сделать шифрование строк во время компиляции, чтобы усложнить задачу нескромным любителям смотреть HEX-код бинарников. :biggrin:

Это как ?

 

Например, вот так: https://habr.com/ru/post/245719/

Но это самый простейший способ, демонстрирующий лишь возможность.

Есть способ намного сильнее, но здесь писать о нём не буду.

 

 

1 hour ago, haker_fox said:

А здесь можно и так


volatile auto * port = reinterpret_cast<Gpio*>(0x40000000);

 

Простите, но это уже - есть само зло, самое настоящее! :russian_ru:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

9 minutes ago, __inline__ said:

Простите, но это уже - есть само зло, самое настоящее!

Согласен) const пропустил, надо так (это и для Си-пример справедливо)

volatile auto * const port = reinterpret_cast<Gpio*>(0x40000000);

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

7 hours ago, mantech said:

Наверно, а бонусом еще лишний раз замедлить работу программы, пока это все расшифровывается.

 

В моих задачах временные затраты на раскодирование строк, не особо влияют на итоговую производительность.  Текстовых символов намного меньше, чем точек на дисплее :biggrin:

 

7 hours ago, mantech said:

И почему-то меня терзают смутные сомнения, что так они и делают, когда я вижу, что с каждым годом все работает медленнее после каждого обновления, хотя комп тот же самый...

 

Это - основной принцип гнилого капитализма. Железо должно устаревать как можно быстрее, чтобы  хомячки покупали постоянно новое. Поэтому и пишутся тонны говнософта, чтобы убить всю производительность на корню.  С++ тут не причём.   Мне тоже Altium 17 не нравится, потому что идёт очень медленно. Использую 6-й.

 

 

15 minutes ago, haker_fox said:

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

 

:acute:Предпочитаю регистры объявлять классически (через volatile).  Типы тоже свои сокращённые использую (помогает при переносе кода с STM32 <=> C6745 <=> V3s <=> ПК )

 

#define IO volatile

#define u8 unsigned char
#define u16 unsigned short int
#define u32 unsigned int
#define u64 unsigned long long

#define s8 signed char
#define s16 signed short int
#define s32 signed int
#define s64 signed long long

///////////////////////////////////////

#define DMA_BASE_ADDR 0x01C02000

#define NDMA_CHANNEL 0 /* 0..7 */

#define DMA_IRQ_EN_REG        (*(IO u32*)(DMA_BASE_ADDR+0x0000                       )) /* DMA IRQ Enable                 */
#define DMA_IRQ_PEND_STAS_REG (*(IO u32*)(DMA_BASE_ADDR+0x0004                       )) /* DMA IRQ Pending Status         */
#define NDMA_CTRL_REG         (*(IO u32*)(DMA_BASE_ADDR+0x100+(NDMA_CHANNEL*0x20)    )) /* Normal DMA Configuration       */
#define NDMA_SRC_ADDR_REG     (*(IO u32*)(DMA_BASE_ADDR+0x100+(NDMA_CHANNEL*0x20)+0x4)) /* Normal DMA Source Address      */
#define NDMA_DEST_ADDR_REG    (*(IO u32*)(DMA_BASE_ADDR+0x100+(NDMA_CHANNEL*0x20)+0x8)) /* Normal DMA Destination Address */
#define NDMA_BC_REG           (*(IO u32*)(DMA_BASE_ADDR+0x100+(NDMA_CHANNEL*0x20)+0xC)) /* Normal DMA Byte Counter        */

 

Обращения к регистрам:

 

#include "ndma.h"

void NDMA_Init(u32 src,u32 dst,u32 bc,u32 cont)
{
 DMA_IRQ_EN_REG=(1<<1)|1;          //NDMA0 FT(100%), HT(50%) INT enable
 DMA_IRQ_PEND_STAS_REG=0xFFFFFFFF; //Reset all INT

 NDMA_SRC_ADDR_REG=src;
 NDMA_DEST_ADDR_REG=dst;
 NDMA_BC_REG=bc;        //max. 128K

 //continuous, DST 16 bit, DST no increment, DST DRQ Audio, SRC 16 bit, SRC DRQ SRAM //DDR
 NDMA_CTRL_REG=(cont<<30)|(1<<25)|(1<<21)|(0x13<<16)|(1<<9)|0x15; //0x16;
}

void NDMA_Start(void)
{
 NDMA_CTRL_REG|=(1UL<<31);
}

void NDMA_Stop(void)
{
 NDMA_CTRL_REG&=~(1<<31);
}

 

Изменено пользователем repstosw

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 minutes ago, __inline__ said:

#define u8 unsigned char

Для объявления типа данных даже в Си есть ключевое слово typedef)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 hours ago, haker_fox said:

Для объявления типа данных даже в Си есть ключевое слово typedef)

 

Я в курсе про typedef

То что выше, это не определение типа, а макрос, сокращающий написание стандартных типов.

 

Typedef целесообразно использовать при объявлении сложных типов, наподобие как тут:


typedef void (SYNCPROC)(HSYNC handle,DWORD channel,DWORD data,void *user);

typedef BOOL     (_stdcall *BASS_INIT)(int,DWORD,DWORD,HWND,const GUID*);

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

14 minutes ago, __inline__ said:

Typedef целесообразно использовать при объявлении сложных типов

Почему? typedef позволяет вести контроль типов на этапе компиляции, чем не стоит пренебрегать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 hours ago, __inline__ said:

В моих задачах временные затраты на раскодирование строк, не особо влияют на итоговую производительность.  Текстовых символов намного меньше, чем точек на дисплее :biggrin:

Если нужно закодировать строки, то можно было бы написать утилиту для извлечения и кодирования строк перед компиляцией.
И уродовать сорсы не пришлось бы. 
Так давно уже делается в RAD Studio.

10 hours ago, Chudik said:

А вообще, смотрю, народ в запале давно отошёл от исходной темы. :rofl:

Ответ был с самого начало очевиден.
Юзайте Stateflow и он вам выдаст идеальный кооперативный движок.  Писать даже ничего не придется. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

46 minutes ago, AlexandrY said:

Если нужно закодировать строки, то можно было бы написать утилиту для извлечения и кодирования строк перед компиляцией.

 

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

 

46 minutes ago, AlexandrY said:

И уродовать сорсы не пришлось бы. 

 

Макрос-обёртка над строкой.  Много ли науродует?

Захотел - обратил в директ, если шифрование надо отключить:

 

#if ( __cplusplus >= 201402L ) && ( CR_EN ) /* Если компилятор от C++14 и старше И разрешён дефайн шифрования строки */

#define _OutString(b) OutString(CRYPTEDSTR(b)) /* CRYPTEDSTR - макрос для расшифровки строки */

#else /* Если шифрование не нужно */

#define _OutString(b) OutString(b) /* прямой вызов функции */

#endif

 

55 minutes ago, haker_fox said:

Почему? typedef позволяет вести контроль типов на этапе компиляции, чем не стоит пренебрегать

 

Ну так в моём случае он и будет вести контроль над:

 

Quote

unsigned char
unsigned short int
unsigned int
unsigned long long

signed char
signed short int
signed int
signed long long

 

 

46 minutes ago, AlexandrY said:

Так давно уже делается в RAD Studio.

 

Не всегда есть возможность и желание использовать студии с весом несколько тонн.  Нужно простое CLI-решение (с командной строки)

Изменено пользователем repstosw

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

10 minutes ago, __inline__ said:

Ну так в моём случае он и будет вести контроль над:

Не совсем так.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 minutes ago, haker_fox said:

Не совсем так.

 

Идея убрать звезду указателя (*) мне не приходила.  Использую так:

 

(u8*)
(s8*)
(u16*)
(s16*)
(u32*)
(s32*)
(u64*)
(s64*)

 

Пример:

u8 *p=NULL;

 

Следует помнить, что "звезда" относится к переменным, а не к типу.

 

Вот так будет корректно:

 

u8 *a, *b, *c;

 

А вот так - нет! :

 

u8* a, b, c;

 

:acute:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

31.08.2020 в 09:30, haker_fox сказал:

Соглашусь, что reinterpret_cast пишется длинновато, и мне конкретно оно самому не нравится.

Такой безобразный синтаксис кастов введён специально, чтобы это выделялось на общем фоне, и программисту было напоминание лишний раз подумать, надо ли делать ручное преобразование типа или эта необходимость возникла из-за ошибки проектирования. И это видные места, где может быть проблема.. Прежний (сишный) синтаксис в этом плане плох - он не выделяется из кода. К тому же он усугубляет и без того злоупотребление скобками, чем и так грешат C/C++. Ну, и в С++ static_cast и reinterpret_cast - это разные уровни кастования - например, static_cast не позволит целое преобразовать к указателю, т.е. как бы разные уровни severity, а сишный вариант не различает их - объединяет оба.  

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, dxp said:

надо ли делать ручное преобразование типа или эта необходимость возникла из-за ошибки проектирования.

Теперь понятно. Это воплощает в жизнь известное высказывание: "если вы делаете преобразование типов, то ваша программа, скорее всего, написана неправльно".

1 hour ago, dxp said:

а сишный вариант не различает их - объединяет оба.

Я, не смотря на длинну операторов, не использую сишное кастование)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

31.08.2020 в 05:50, haker_fox сказал:

А здесь можно и так


volatile auto * port = reinterpret_cast<Gpio*>(0x40000000);

 

А лучше так:

auto port = reinterpret_cast<volatile Gpio*>(0x40000000);

Так у вас весь тип переменной определяется в одном месте.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...