Jump to content

    
Salamander

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

Recommended Posts

Нашел в сети простой понятный и без наворотов алгоритм для прошивания 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;

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

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

Share this post


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

Share this post


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

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

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

Edited by Salamander

Share this post


Link to post
Share on other sites

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

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

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

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

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

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

Share this post


Link to post
Share on other sites
10 часов назад, Darth Vader сказал:

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

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

Цитата

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

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

Цитата

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

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

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.