How do I manually input a memory address into a pointer?

Kuba0040

Well-known member
Hello,
I have a simple question today. I want to maunally input some memory addresses into pointers, so then I can write and read data from these addresses easily. Here is an example:
Code:
int32_t *TCD_SADDR=0x1000; 
int32_t *TCD_DADDR=0x1010;

I want the pointer TCD_SADDR to point to address 0x1000. TCD_DADDR to address 0x1010. However, the compiler throws warnings at me about an invalid data conversion.

warning: invalid conversion from 'int' to 'int32_t* {aka long int*}' [-fpermissive]

For extra context, I need this to write/read the DMA’s TCD structure, where each channel has it’s parameters at the same address as all of the other channels, just with a channel specific offset applied to it. So, to for example set the Source adress of any channel using the pointers I would just have to do this:
Code:
*(TCD_SADDR+channel_number*0x20)=value I want to write here

So, I thought I’d just ask how to do this properly right away. Should I use something else than pointers? Please let me know.
Thank you for the help.
 
I normally use uint32_t (unsigned) for things like this.
likewise I would probably do something like:
Code:
uint32_t *TCD_SADDR=(uint32_t *)0x1000;
 
I want the pointer TCD_SADDR to point to address 0x1000. TCD_DADDR to address 0x1010. However, the compiler throws warnings at me about an invalid data conversion.

You can not directly assign a integer to a pointer. You need to cast it.

Code:
int32_t* TCD_SADDR  = (int32_t*) 0x1000;
int32_t* TCD_DADDR  = (int32_t*) 0x1010;
int32_t value_at_TCD_SADDR = *TCD_DADDR;

But I'm wondering if this is really what you want to do? At Address 0x1000 there probably is nothing you want to point at?
 
You can not directly assign a integer to a pointer. You need to cast it.

Code:
int32_t* TCD_SADDR  = (int32_t*) 0x1000;
int32_t* TCD_DADDR  = (int32_t*) 0x1010;
int32_t value_at_TCD_SADDR = *TCD_DADDR;

But I'm wondering if this is really what you want to do? At Address 0x1000 there probably is nothing you want to point at?

I wondered that as well.

I would personally use the dma structures already setup, like DMAChannel and likewise other structures defined...
Again not sure of which processor but assume T4.x...

Thinking this was taken from:
#define IMXRT_DMA_TCD ((IMXRT_DMA_TCD_t *)(IMXRT_DMA_ADDRESS+0x1000))

But notice it is an offset from IMXRT_DMA_ADDRESS
#define IMXRT_DMA_ADDRESS 0x400E8000

Or looking at the reference manual it shows: offsets 1000h-13e0h - as TCD...
But at the start of the section in the case of most recent pdf 6.5.5.1 shows DMA Base address 400e_8000h
 
Hello,
I’ve done some testing as well as applied the DMA base offset and all works fine now. I can write to the TCD just like I wanted to, however with slight problem.
When I want to write into SADDR (for example, but the same issue occurs with any other pointer) an address of a different pointer:
Code:
int32_t some_value_in_memory=0;
int32_t *myPointer=some_value_in_memory;

int32_t *TCD_SADDR=(int32_t*)0x400E9000; //0x400E8000+0x1000

*TCD_SADDR=myPointer;

The code compiles and works fine however, the compiler gives me this warning at the *TCD_SADDR=myPointer; line:

warning: invalid conversion from 'int32_t* {aka long int*}' to 'int32_t {aka long int}' [-fpermissive]

Is there any way to get rid of it? (I am using a Teensy 4.0)
Thank you for the help.
 
So, I thought I’d just ask how to do this properly right away.

By now I'm pretty sure you know DMAChannel is considered the proper way, so your DMA channel usage is coordinated with other libraries. Even if you continue to reject the idea of actually using DMAChannel, you could at least look at its source code as a reference for the C / C++ syntax.


Specifically about this:

Code:
int32_t *TCD_SADDR=0x1000; 
// ...
*(TCD_SADDR+channel_number*0x20)=value I want to write here

The DMA registers are in the peripheral address space, which starts at 0x40000000. Address 0x1000 is within ITCM used for code. If you use this pointer, you will modify the ITCM.

Pointer arithmetic in C / C++ is based on the size of the data type the pointer references. Because this pointer is to a 32 bit type, adding 32 (0x20) will be the location of 32 int32_t's farther in memory. So if channel_number=1, this would write a value to location 0x1080, not 0x1020.

But whether a write actually occurs may depend on the compiler's optimizations. Normally these sorts of pointers are declared with "volatile" so prevent the compiler from assuming normal memory which doesn't change on its own. For hardware registers like SADDR which do change, you almost certainly need volatile.

Even if you want to write everything from scratch, you really could gain some insight by at least looking at the existing code.
 
Hello,
I’ve done some testing as well as applied the DMA base offset and all works fine now. I can write to the TCD just like I wanted to, however with slight problem.
When I want to write into SADDR (for example, but the same issue occurs with any other pointer) an address of a different pointer:
Code:
int32_t some_value_in_memory=0;
int32_t *myPointer=some_value_in_memory;

int32_t *TCD_SADDR=(int32_t*)0x400E9000; //0x400E8000+0x1000

*TCD_SADDR=myPointer;

The code compiles and works fine however, the compiler gives me this warning at the *TCD_SADDR=myPointer; line:

warning: invalid conversion from 'int32_t* {aka long int*}' to 'int32_t {aka long int}' [-fpermissive]

Is there any way to get rid of it? (I am using a Teensy 4.0)
Thank you for the help.

Again seeing fragments of code and fragments of messages may not help as well, but again but again:
Code:
*TCD_SADDR=myPointer=myPointer

You are saying set the memory value at the location pointed to by the variable TCD_SADDR to the pointer variable myPointer.
So yes it is saying you are trying to assign a (uint32_t *) value to a uint32_t location.

You can do either do: TCD_SADDR=myPointer;
Which says set the value of one pointer to value of another pointer

or: *TCD_SADDR=*myPointer;
Which says to set the contents of where one pointer is pointing to the value that the other pointer was pointing to.
 
Hello,
I’ve done some testing as well as applied the DMA base offset and all works fine now. I can write to the TCD just like I wanted to, however with slight problem.
When I want to write into SADDR (for example, but the same issue occurs with any other pointer) an address of a different pointer:
Code:
int32_t some_value_in_memory=0;
int32_t *myPointer=some_value_in_memory;

int32_t *TCD_SADDR=(int32_t*)0x400E9000; //0x400E8000+0x1000

*TCD_SADDR=myPointer;

The code compiles and works fine however, the compiler gives me this warning at the *TCD_SADDR=myPointer; line:

warning: invalid conversion from 'int32_t* {aka long int*}' to 'int32_t {aka long int}' [-fpermissive]

Is there any way to get rid of it? (I am using a Teensy 4.0)
Thank you for the help.

You need to set the pointer to the address of the variable:
Code:
int32_t * myPointer = &some_value_in_memory;
 
Back
Top