EmbDev.net

Forum: ARM programming with GCC/GNU tools va_args, printf and DMA memory problems


von Kevin n. (Company: na) (fallentemplar)


Rate this post
useful
not useful
I've been scratching my head for the past few days as I try to 
understand why and what is going on... So here it goes:

Current config: stm32f407VG (same as stm32f4 discovery)

I set up a project using the default linker and startup files from 
www.onarm.com.



Init the ADC & DMA's
1
       ADC_CommonInitStructure.ADC_Mode = ADC_DualMode_RegSimult;
2
       ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
3
       ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1;
4
5
        DMA_InitTypeDef DMA_InitStructure;
6
        NVIC_InitTypeDef NVIC_InitStructure;
7
8
        DMA_InitStructure.DMA_Channel = DMA_Channel_0;
9
        DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) &RawADCData.adcRaw1;
10
        DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) ADC_CCR_ADDRESS;
11
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
12
        DMA_InitStructure.DMA_BufferSize = ADC_SAMPLE_NUM * ADC_NUM * ADC_BUFFER_MULTIPLIER;
13
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
14
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
15
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
16
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
17
        DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
18
        DMA_InitStructure.DMA_Priority = DMA_Priority_High;
19
        DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
20
        DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
21
        DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
22
        DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
23
        DMA_Init(DMA2_Stream0, &DMA_InitStructure);
24
25
        /*Interrupt when half of DMA is done, so we do not overwrite our values when processing*/
26
        DMA_ITConfig(DMA2_Stream0, DMA_IT_HT | DMA_IT_TC, ENABLE);
27
        DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TEIF0 | DMA_IT_DMEIF0 | DMA_IT_FEIF0 | DMA_IT_TCIF0 | DMA_IT_HTIF0);
28
29
        // Enable the DMA2_Stream0 global Interrupt
30
        NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
31
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
32
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
33
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
34
        NVIC_Init(&NVIC_InitStructure);
35
36
        /* DMA2_Stream0 enable */
37
        DMA_Cmd(DMA2_Stream0, ENABLE);


--Symptom A:
Compile on GCC with CooCox as IDE, the DMA values are all garbled, after 
looking at the memory, it seems like the DMA values were sometimes 
offset by 1 word.


--Symptom B: Floats do not print correctly, printf works, but they are 
not passed on VA_ARGS correctly, offset by x bytes, x is pretty random.


--Sympton C: I add a struct into my file somewhere, say
1
struct b 
2
{
3
 float z[40];
4
}

Everything begins to work, prints are correct, DMA is correct.

I add anther struct into anther file
1
struct b 
2
{
3
 float z[80];
4
 int z[3];
5
}

DMA is correct, but printf does not work again. If i twitter around with 
the structs, DMA can be broken, but printf works, or they all can be 
broken.

I have a feeling that it is a linker error or alignment error, but do 
not know where else to look.

The entire codebase is here 
(http://code.google.com/p/narwhalroboticsquad/source/browse/?r=25#svn%2Ftrunk%2FNarwhalQuad) 
if you are curious, built with Coocox IDE with the GNU ARM toolchain.

von Jim M. (turboj)


Rate this post
useful
not useful
Try to provide a simple test case. The code in your post is not enough 
to demonstrate the problem, the code you linked to is waaay too complex 
to expect an answer here.

von Kevin n. (Company: na) (fallentemplar)


Rate this post
useful
not useful
Hi,

I revisited test cases based on your comment.

Here is a really simple case:

1
int main()
2
{
3
  printf("%f", 0.3423f);
4
}

This prints correctly.
1
struct 
2
{
3
 float[255] test;
4
} test;
5
6
int main()
7
{
8
  printf("%f", 0.3423f);
9
}

This doesnt work, the va_args are shifted.

von co (Guest)


Rate this post
useful
not useful
please set the Code Optimization to Level "None -O0" and please reports 
what happend.

von coocox user (Guest)


Rate this post
useful
not useful
rich stack + heap

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.