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

Помогите перевести с одного диалекта C на другой.

Нашел в сети простой понятный и без наворотов алгоритм для прошивания QSPI под STM32H743. Не знаю, под что он был писан, непонятно, но я работаю в KEIL. 

Процедура "вживления" этого кода в проект под keil прошла более или менее гладко, но в в оконцовке я наткнулся вот на что:

На вот этот код

volatile uint32_t *GPIOx_base    = (base + (bank - 'A') * 0x400);
	volatile uint32_t *GPIOx_MODER   = (void *)GPIOx_base + 0x00;
	volatile uint32_t *GPIOx_OTYPER  = (void *)GPIOx_base + 0x04;
	volatile uint32_t *GPIOx_OSPEEDR = (void *)GPIOx_base + 0x08;
	volatile uint32_t *GPIOx_PUPDR   = (void *)GPIOx_base + 0x0C;

Вот такая ругань

hal\gpio.c(8): error:  #852: expression must be a pointer to a complete object type
  	volatile uint32_t *GPIOx_base    = (base + (bank - 'A') * 0x400);
hal\gpio.c(9): error:  #852: expression must be a pointer to a complete object type
  	volatile uint32_t *GPIOx_MODER   = (void *)GPIOx_base + 0x00;
hal\gpio.c(10): error:  #852: expression must be a pointer to a complete object type
  	volatile uint32_t *GPIOx_OTYPER  = (void *)GPIOx_base + 0x04;
hal\gpio.c(11): error:  #852: expression must be a pointer to a complete object type
  	volatile uint32_t *GPIOx_OSPEEDR = (void *)GPIOx_base + 0x08;
hal\gpio.c(12): error:  #852: expression must be a pointer to a complete object type
  	volatile uint32_t *GPIOx_PUPDR   = (void *)GPIOx_base + 0x0C;

Мне, калокуберу, малопонятная.

Можно в двух словах объяснить, как это исправить?

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


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

2 minutes ago, Arlleex said:

Как описаны 'base' и 'bank'?

вот так

 

void gpio_set(void *base, char bank, uint8_t port,
	uint8_t otype, uint8_t mode, uint8_t ospeed, uint8_t pupd)
{

 

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


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

volatile uint32_t *GPIOx_base    = (volatile uint32_t *)((uintptr_t)base + (bank - 'A') * 0x400);
volatile uint32_t *GPIOx_MODER   = (volatile uint32_t *)((uintptr_t)GPIOx_base + 0x00);
volatile uint32_t *GPIOx_OTYPER  = (volatile uint32_t *)((uintptr_t)GPIOx_base + 0x04);
volatile uint32_t *GPIOx_OSPEEDR = (volatile uint32_t *)((uintptr_t)GPIOx_base + 0x08);
volatile uint32_t *GPIOx_PUPDR   = (volatile uint32_t *)((uintptr_t)GPIOx_base + 0x0C);

или

volatile uint32_t *GPIOx_base    = (volatile uint32_t *)((uintptr_t)base + (bank - 'A') * 0x400);
volatile uint32_t *GPIOx_MODER   = &GPIOx_base[0];
volatile uint32_t *GPIOx_OTYPER  = &GPIOx_base[1];
volatile uint32_t *GPIOx_OSPEEDR = &GPIOx_base[2];
volatile uint32_t *GPIOx_PUPDR   = &GPIOx_base[3];

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


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

16 minutes ago, Arlleex said:

Как описаны 'base' и 'bank'?

Но если вы, обратили внимание - эта ошибка во вех строках, в том числе и последующих, где нет base и bank

 

volatile uint32_t *GPIOx_base    = (volatile uint32_t *)((uintptr_t)base + (bank - 'A') * 0x400);
volatile uint32_t *GPIOx_MODER   = (volatile uint32_t *)((uintptr_t)GPIOx_base + 0x00);
volatile uint32_t *GPIOx_OTYPER  = (volatile uint32_t *)((uintptr_t)GPIOx_base + 0x04);
volatile uint32_t *GPIOx_OSPEEDR = (volatile uint32_t *)((uintptr_t)GPIOx_base + 0x08);
volatile uint32_t *GPIOx_PUPDR   = (volatile uint32_t *)((uintptr_t)GPIOx_base + 0x0C);

ПРокатило! Спасбио.

Осталось проверить, работает ли)

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

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


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

Какой, интересно, компилятор позволяет:

- присваивать указателям целочисленные значения без явного приведения типа;

- работать с арифметикой указателей над нетипизированными указателями (типа void* );

- присваивать типизированному указателю значение нетипизированного без явного приведения типа к итоговому

Как этот код вообще компилировался у автора?

Это какая-то странная попытка самостоятельного описания структуры порта, типа, как в CMSIS, только без указателей на структуру. Вручную прописываются смещения регистров, относительно базового адреса порта. Настоятельно рекомендуется переписать по-человечески, как это делается в CMSIS или SPL.

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


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

10 часов назад, Darth Vader сказал:

Какой, интересно, компилятор позволяет:
- присваивать указателям целочисленные значения без явного приведения типа;
- работать с арифметикой указателей над нетипизированными указателями (типа void *)...

Думаю, как-нибудь ключиками компиляции регулируется (хотя, ИМХО, не должно).

Цитата

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

В Си это позволительно. В C++ - уже нет. И я считаю, что первый вариант несколько удобнее.

Цитата

Настоятельно рекомендуется переписать по-человечески...

ТС явно указал, что он калокубер, поэтому ему необходимо и достаточно того, что я написал выше:wink:

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


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

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

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

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

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

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

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

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

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

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