This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Tool/software: TI C/C++ Compiler
I'm trying to copy out the adc results into a structure in my application using memcpy and I'm noticing different compiler interpretations depending on how my pointers are declared. I have the code working, but I'd like to understand this better. Let me explain....
volatile uint16_t * vsource = (volatile uint16_t *)((uintptr_t)(ADCARESULT_BASE)); volatile uint16_t * vdest = &(adcData.adcAData); uint16_t * source = (volatile uint16_t *)((uintptr_t)(ADCARESULT_BASE)); uint16_t * dest = &(adcData.adcAData); memcpy(vdest, vsource, sizeof(adcAData_t)); memcpy(dest, vsource, sizeof(adcAData_t)); memcpy(dest, source, sizeof(adcAData_t));
Each call to memcpy above generates different ASM.
When both the destination and source are volatile pointers, a branch to the actual memcopy function is performed. This copy works.
243 memcpy(vdest, vsource, sizeof(adcAData_t)); 08659b: 8342 MOVL XAR5, *-SP[2] 08659c: 0210 MOVB ACC, #16 08659d: 76487611 LCR memcpy
When the source is volatile and the destination is not, the copy is implemented using a repeat and PWRITE instruction. This copy works.
244 memcpy(dest, vsource, sizeof(adcAData_t)); 08659f: 8A42 MOVL XAR4, *-SP[2] 0865a0: C548 MOVL XAR7, *-SP[8] 0865a1: F60F RPT #15 0865a2: 2684 || PWRITE *XAR7, *XAR4++ 0865a3: 7700 NOP 0865a4: 7700 NOP
When neither the source or destination is volatile, the copy is implemented using a repeat and PREAD instruction. This copy does not work.
245 memcpy(dest, source, sizeof(adcAData_t)); 0865a5: 8A48 MOVL XAR4, *-SP[8] 0865a6: C546 MOVL XAR7, *-SP[6] 0865a7: F60F RPT #15 0865a8: 2484 || PREAD *XAR4++, *XAR7
My C28x assembly is a little rusty but I looked at the instruction set guide and checked XAR4 and XAR7 and they have the correct values in them in all of the above cases. However in the third case the memory at the destination address is zero'ed out instead of data from the adc result registers being copied over. Can someone help me understand why the third case doesn't work? I'm guessing this has something to do with the compiler not knowing what addressing mode to use? Please enlighten me :)
Best,
Trey
What is the version of the compiler? Please show the build options exactly as the compiler sees them. Please copy-and-paste the text, and do not use a screen shot.
Thanks and regards,
-George
Invoking: C2000 Compiler "/Applications/ti/ccs1010/ccs/tools/compiler/ti-cgt-c2000_20.2.1.LTS/bin/cl2000" -v28 -ml -mt --cla_support=cla2 --float_support=fpu32 --tmu_support=tmu0 --vcu_support=vcu0 -Ooff --include_path="/Users/germanpm/ti/C2000Ware_3_03_00_00_Software/libraries/control/DCL/c28/include" --include_path="/Users/germanpm/ti/C2000Ware_3_03_00_00_Software/libraries/dsp/FixedPoint/c28/include" --include_path="/Users/germanpm/ti/C2000Ware_3_03_00_00_Software/libraries/dsp/VCU/c28/include/vcu0" --include_path="/Users/germanpm/ti/C2000Ware_3_03_00_00_Software/libraries/dsp/VCU/c28/include/common" --include_path="/Users/germanpm/Polymorphic_Labs_LLC/Sygnal/Firmware/MCM/Sygnal-MCM" --include_path="/Users/germanpm/ti/C2000Ware_3_03_00_00_Software/device_support/f28004x/common/include" --include_path="/Users/germanpm/ti/C2000Ware_3_03_00_00_Software/device_support/f28004x/headers/include" --include_path="/Users/germanpm/Polymorphic_Labs_LLC/Sygnal/Firmware/MCM/Sygnal-MCM/device" --include_path="/Users/germanpm/ti/C2000Ware_3_03_00_00_Software/driverlib/f28004x/driverlib" --include_path="/Applications/ti/ccs1010/ccs/tools/compiler/ti-cgt-c2000_20.2.1.LTS/include" --advice:performance=all --define=CPU1 --define=_FLASH --relaxed_ansi --printf_support=minimal --diag_suppress=10063 --diag_warning=225 --diag_wrap=off --display_error_number --gen_func_subsections=on --gen_data_subsections=on --abi=coffabi --preproc_with_compile --preproc_dependency="drivers/mcm-analog.d_raw" --obj_directory="drivers" "../drivers/mcm-analog.c"
Thanks for taking a look George.
This code is generated ...
Trey German8 said:0865a7: F60F RPT #15
0865a8: 2484 || PREAD *XAR4++, *XAR7
... because you build with the option -mt (short for --unified_memory). However, this instruction sequence must not be valid when this is attempted ...
Trey German8 said:data from the adc result registers being copied over
I lack the expertise needed to explain why that is the case. I will notify the C28x device experts about this thread. They will let you know the best way to copy data over from ADC registers.
Thanks and regards,
-George
The TMS320C28x Optimizing C/C++ Compiler v20.8.0.STS User’s Guide has the following description for the --unified_memory option:Trey German8 said:However in the third case the memory at the destination address is zero'ed out instead of data from the adc result registers being copied over.
Looking at the TMS320F280049 datasheet and TMS320F28004x Real-Time Microcontrollers Technical Reference Manual I can't seem to find a definition of which peripherals are only allocated in data memory.Use the --unified_memory (-mt) option if your memory map is configured as a single unified space; this allows the compiler to generate RPT PREAD instructions for most memcpy calls and structure assignments. This also allows MAC instructions to be generated. The -- unified_memory option also allows more efficient data memory instructions to be used to access switch tables.Even under unified memory, memory for some peripherals and some RAM associated with those peripherals is allocated only in data memory. If –unified_memory is enabled, you can prevent program memory address access to specific symbols by declaring those symbols as volatile.
However, the C2000Ware_3_03_00_00_Software/device_support/f28004x/headers/cmd/f28004x_headers_nonbios.cmd linker command file shows all peripherals in Data Memory
If the ADC data registers are only allocated in data memory, that would explain why the third case doesn't work, but the second case does.