Jump to content

    
C2000

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

Recommended Posts

16 hours ago, haker_fox said:

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

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

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

Share this post


Link to post
Share on other sites
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:

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

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

Share this post


Link to post
Share on other sites
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:

Share this post


Link to post
Share on other sites
9 minutes ago, __inline__ said:

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

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

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

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

Share this post


Link to post
Share on other sites
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);
}

 

Edited by __inline__

Share this post


Link to post
Share on other sites
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*);

 

Share this post


Link to post
Share on other sites
14 minutes ago, __inline__ said:

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

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

Share this post


Link to post
Share on other sites
4 hours ago, __inline__ said:

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

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

10 hours ago, Chudik said:

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

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

Share this post


Link to post
Share on other sites
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-решение (с командной строки)

Edited by __inline__

Share this post


Link to post
Share on other sites
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:

Share this post


Link to post
Share on other sites
31.08.2020 в 09:30, haker_fox сказал:

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

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

Share this post


Link to post
Share on other sites
1 hour ago, dxp said:

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

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

1 hour ago, dxp said:

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

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

Share this post


Link to post
Share on other sites
31.08.2020 в 05:50, haker_fox сказал:

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


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

 

А лучше так:

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

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.