My MCU hangs when i jump to an address in flash memory.. (SOLVED !)

Page 2 - Seeking answers? Join the AnandTech community: where nearly half-a-million members share solutions and discuss the latest tech.
May 11, 2008
20,136
1,149
126
damn it. My terminal crashed.

It did work but my terminal program was producing garbage..
Now i have still the same issue.

But now, when i do not upload an application, and i jump to address 0x00110000, at least my test application is executed. So the address 0x00110000 is reachable. Now i have to figure out why my application does not run.
 
May 11, 2008
20,136
1,149
126
Instead of doing that, try having the link script specify to output binary directly. Change the OUTPUT_FORMAT specifier to:

OUTPUT_FORMAT(binary);

It's probably not ld that was putting things where you didn't expect but objcopy. This method is what I've used for all of my MCU flash images.

Anyway, when you said this:

What did it mean exactly? Just that you give it an offset and it programs from there? It sounded to me like you were saying it knows where there are gaps in the file, something it wouldn't get from raw binary.

My programmer just takes a file and start programming the flash from address 0x00100000. 256 bytes (one flash page)at a time. And it will do so until the end of the binary file. So it really is just a binary file.

EDIT:

I am afraid i have to make use of a jumptable. But how do i know the linker will not modify that table ?

I am now trying objdump.

Another edit :

It does not work like that to create an output file. At least, that is what i read in the documentation.
I have to use : objcopy -o binary.
 
Last edited:

Exophase

Diamond Member
Apr 19, 2012
4,439
9
81
It does not work like that to create an output file. At least, that is what i read in the documentation.
I have to use : objcopy -o binary.

I've got a few link scripts that do just this, I don't use objcopy. What isn't working exactly?
 
May 11, 2008
20,136
1,149
126
My application does not run. I expect it to have a few bugs, but i made a small sequence of three assembly instructions in a loop to turn on a led. I tested this sequence separately to see if it works. And it works but after uploading my application and verifying that it is there, when i make the jump to 0x00110000 , nothing happens.

:(

EDIT:
How do you get LD to produce a binary file ?

I do not know how to edit my makefile in a way that it produces a binary with LD.
 
Last edited:
May 11, 2008
20,136
1,149
126
Well, i found out something interesting.
To see if it is a compiler issue, i changed some setting which did nothing. But when i changed the optimization settings, the xmodem code stops working.
The xmodem code i use is proven code. It has been used on a variety of compilers and mcu architectures and just works.
But for some reason with the gcc comiler 4.4.2 that i use it stops functioning with optimization level 0. Level 0 means not optimization at all.

So i decided that is time for a more recent compiler. I installed atmel studio 6 but unfortunately, sam7s series are not supported by atmel studio. :mad:

So i wanted to upgrade to a newer version of gcc compiler alone and use the same IDE. I got the new GCC compiler 4.7.2. But it is incompatible with my make file script.

I editted my make file script to use the new arm-none-eabi-gcc-4.7.2
instead of the arm-elf-gcc-4.4.2, but unfortunately i get errors.
The file does not exist.


Do you know guys know what i have to change to get it to work ?

This works :
Code:
# Automatically generated by W-ARM !
# Do not edit this file with an editor that replaces tabs with spaces !
################################################################################

CC = arm-elf-gcc
AS = arm-elf-gcc -x assembler-with-cpp
CREATE_OUTPUT_FILE = arm-elf-objcopy -O binary

SRC = ./src/fastexec.c ./src/inithardware.c ./src/isr.c ./src/isr_ctrl.c ./src/low_level_init.c ./src/main.c ./src/menu.c ./src/os_functions.c ./src/sci.c ./src/semi_stdio.c ./src/string.c ./src/timer.c ./src/xmodem.c
ASRC = ./src/isr_asm.s ./src/startup.s

USR_INC_DIR = ./inc
USR_LIB_DIR = 
################################################################################

INC_DIR  = $(patsubst %,-I%, $(USR_INC_DIR))
LIB_DIR  = $(patsubst %,-L%, $(USR_LIB_DIR))

OBJS = $(ASRC:.s=.o) $(SRC:.c=.o)

MCU_FLAGS = -mcpu=arm7tdmi

# optimisation level
OPT = -O2 

#Assemble assembly source files to object code   *.s to *.o  .
AS_FLAGS = $(MCU_FLAGS) -g -gdwarf-2 -Wa,-amhls=$(<:.s=.lst)

#compile and assemble C source files to object code   *.c to *.o  .
CP_FLAGS = $(MCU_FLAGS) $(OPT) -gdwarf-2 -fomit-frame-pointer -Wall -Wstrict-prototypes -fverbose-asm -Wa,-ahlms=$(<:.c=.lst)

# link all objects to elf file   *.o to *.elf .
LD_FLAGS = $(MCU_FLAGS) -nostartfiles -T./prj/warm_ld.ld -Wl,-Map=./output/bootloader_xmodem.map,--cref,--no-warn-mismatch $(LIB_DIR)

# Generate dependency information
CPFLAGS += -MD -MP -MF .dep/$(@F).d

# Eye candy.
begin:
	@echo
	@echo ---------------- begin ----------------
	@echo

finished:
	@echo
	@echo Errors none. 
	@echo
	@echo Output format = binary
	@echo
	@echo Project name = bootloader_xmodem
	@echo

end:
	@echo
	@echo ---------------- end ----------------
	@echo

clean_message:
	@echo
	@echo Cleaning directories of current project : bootloader_xmodem
	@echo

# Display compiler version information.
gccversion:
	@$(CC) --version

#Excute from here.
all: begin gccversion ROM finished move_files end

#copy files to new destination.
move_files:
	@cp ./src/*.lst ./list/
	@cp ./src/*.o  ./object/
	@-rm -f ./src/*.lst
	@-rm -f ./src/*.o

# create output files.
ROM: $(OBJS) ./output/bootloader_xmodem.elf ./output/bootloader_xmodem.bin

%o : %c
	$(CC) -c $(CP_FLAGS) -I . $(INC_DIR) $< -o $@
	
%o : %s
	$(AS) -c $(AS_FLAGS) $< -o $@

%elf: $(OBJS)
	$(CC) $(OBJS) $(LD_FLAGS) $(LIBS) -o $@

%bin: %elf
	$(CREATE_OUTPUT_FILE) $< $@



clean: begin gccversion deletefiles clean_message end

deletefiles:
	@-rm -f $(OBJS)
	@-rm -f $(SRC:.c=.c.bak)
	@-rm -f $(SRC:.c=.lst)
	@-rm -f $(ASRC:.s=.s.bak)
	@-rm -f $(ASRC:.s=.lst)
	@-rm -fR .dep
	@-rm -f ./output/bootloader_xmodem.elf 
	@-rm -f ./output/bootloader_xmodem.map 
	@-rm -f ./output/bootloader_xmodem.bin 
	@-rm -f ./list/*.lst
	@-rm -f ./object/*.o

#
# Include the dependency files, should be the last of the makefile
#
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)

# Listing of phony targets.
.PHONY : all begin finish end sizebefore sizeafter gccversion build elf hex lss sym clean clean_list program

# *** EOF ***


Here i changed the names of the compiler and objcopy.
But i get an error.
Code:
# Automatically generated by W-ARM !
# Do not edit this file with an editor that replaces tabs with spaces !
################################################################################

CC = arm-none-eabi-gcc
AS = arm-none-eabi-gcc -x assembler-with-cpp
CREATE_OUTPUT_FILE = arm-none-eabi-objcopy -O binary

SRC = ./src/fastexec.c ./src/inithardware.c ./src/isr.c ./src/isr_ctrl.c ./src/low_level_init.c ./src/main.c ./src/menu.c ./src/os_functions.c ./src/sci.c ./src/semi_stdio.c ./src/string.c ./src/timer.c ./src/xmodem.c
ASRC = ./src/isr_asm.s ./src/startup.s

USR_INC_DIR = ./inc
USR_LIB_DIR = 
################################################################################

INC_DIR  = $(patsubst %,-I%, $(USR_INC_DIR))
LIB_DIR  = $(patsubst %,-L%, $(USR_LIB_DIR))

OBJS = $(ASRC:.s=.o) $(SRC:.c=.o)

MCU_FLAGS = -mcpu=arm7tdmi

# optimisation level
OPT = -O2 

#Assemble assembly source files to object code   *.s to *.o  .
AS_FLAGS = $(MCU_FLAGS) -g -gdwarf-2 -Wa,-amhls=$(<:.s=.lst)

#compile and assemble C source files to object code   *.c to *.o  .
CP_FLAGS = $(MCU_FLAGS) $(OPT) -gdwarf-2 -fomit-frame-pointer -Wall -Wstrict-prototypes -fverbose-asm -Wa,-ahlms=$(<:.c=.lst)

# link all objects to elf file   *.o to *.elf .
LD_FLAGS = $(MCU_FLAGS) -nostartfiles -T./prj/warm_ld.ld -Wl,-Map=./output/bootloader_xmodem.map,--cref,--no-warn-mismatch $(LIB_DIR)

# Generate dependency information
CPFLAGS += -MD -MP -MF .dep/$(@F).d

# Eye candy.
begin:
	@echo
	@echo ---------------- begin ----------------
	@echo

finished:
	@echo
	@echo Errors none. 
	@echo
	@echo Output format = binary
	@echo
	@echo Project name = bootloader_xmodem
	@echo

end:
	@echo
	@echo ---------------- end ----------------
	@echo

clean_message:
	@echo
	@echo Cleaning directories of current project : bootloader_xmodem
	@echo

# Display compiler version information.
gccversion:
	@$(CC) --version

#Excute from here.
all: begin gccversion ROM finished move_files end

#copy files to new destination.
move_files:
	@cp ./src/*.lst ./list/
	@cp ./src/*.o  ./object/
	@-rm -f ./src/*.lst
	@-rm -f ./src/*.o

# create output files.
ROM: $(OBJS) ./output/bootloader_xmodem.elf ./output/bootloader_xmodem.bin

%o : %c
	$(CC) -c $(CP_FLAGS) -I . $(INC_DIR) $< -o $@
	
%o : %s
	$(AS) -c $(AS_FLAGS) $< -o $@

%elf: $(OBJS)
	$(CC) $(OBJS) $(LD_FLAGS) $(LIBS) -o $@

%bin: %elf
	$(CREATE_OUTPUT_FILE) $< $@



clean: begin gccversion deletefiles clean_message end

deletefiles:
	@-rm -f $(OBJS)
	@-rm -f $(SRC:.c=.c.bak)
	@-rm -f $(SRC:.c=.lst)
	@-rm -f $(ASRC:.s=.s.bak)
	@-rm -f $(ASRC:.s=.lst)
	@-rm -fR .dep
	@-rm -f ./output/bootloader_xmodem.elf 
	@-rm -f ./output/bootloader_xmodem.map 
	@-rm -f ./output/bootloader_xmodem.bin 
	@-rm -f ./list/*.lst
	@-rm -f ./object/*.o

#
# Include the dependency files, should be the last of the makefile
#
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)

# Listing of phony targets.
.PHONY : all begin finish end sizebefore sizeafter gccversion build elf hex lss sym clean clean_list program

# *** EOF ***

This is the error i get :
make: Entering directory `f:/arm/projecten/bootloader_xmodem'

---------------- begin ----------------

arm-none-eabi-gcc (GCC) 4.7.2
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

arm-none-eabi-gcc -x assembler-with-cpp -c -mcpu=arm7tdmi -g -gdwarf-2 -Wa,-amhls=src/isr_asm.lst src/isr_asm.s -o src/isr_asm.o
arm-none-eabi-gcc: error: CreateProcess: No such file or directory
make: *** [src/isr_asm.o] Error 1
make: Leaving directory `f:/arm/projecten/bootloader_xmodem'

> Process Exit Code: 2
> Time Taken: 00:01

What do i need to change to get it to work ?

EDIT:

Well, i got this issue solved, after systematic trying, i found out that i forgot to copy a directory.
Now i am compiling with arm-none-eabi-gcc4.7.2. But i still have the same problems as i had when i first posted. And when compiling with optimization option -O0, the xmodem code does not function.
:(
I have just no luck at all.
 
Last edited:

SOFTengCOMPelec

Platinum Member
May 9, 2013
2,417
75
91
I had similar problems (crashes when calling functions and/or interrupts), using GCC Arm7.

Your problem(s) could be completely different, so I am describing what I did to fix my problem(s), for information ONLY.

It turns out that the GCC arm optimization was very buggy, and it was incorrectly putting in (or not) thumb code (instructions and/or mode), badly enough to cause it to crash.

I solved the problem by turning the optimization from speed (which was activating the bug), to SIZE optimization. i.e. speed optimization=off, size (program size) optimization = on. (i.e. GCC -O2 (or whatever), changed to GCC -Os etc)

In my case the GCC options were complicated by the fact that I was using an IDE (with GCC and other stuff pre built into it), which potentially limited my choices. The IDE (and the GCC etc) was supplied to me by the supplier (of the arm stuff).

I find it best to start with a (probably very small program), such as an included example program, which e.g. flashes a couple of leds on and off. Then gradually (incrementally) change it over to the program that you are trying to write.
Then if it suddenly stops working and/or produces error messages, you know the last few lines that you changed, making it much easier to find out what the problem is.

I've NOT dealt with Atmel Arm cpus, so I can't help you directly here.
 
Last edited:
May 11, 2008
20,136
1,149
126
Thanks for the reply. I had THUMB interworking disabled in advance from the beginning. So, gcc should not insert thumb instructions. It should be ARM instructions only.
On the other hand, i removed the optimization option : -O and i had the same problem as when selecting -O0, removing optimization breaks the xmodem code.
So i tried -Os (size) and the xmodem code works again but i still have the same problem as described in my first post. Jumping to an address by use of a function call just does not work.
 
May 11, 2008
20,136
1,149
126
I have the watchdog timer disabled in the bootloader i am trying to make. I do that very early on in my low level init function.

I also found out something strange.
The trick i found out to increase the memory map to 64K while only using 25K no longer works with this version GCC 4.7.2.

When i try to add padding to force my test application to start at 0x00110000, the filling is removed and the application is placed at the end of the ROM region where my other functions reside. I though it was because of the -Os so i changed it back to -O1 but to no prevail. It looks like the documentation here :

http://www.math.utah.edu/docs/info/ld_3.html#SEC18

no longer applies to the location counter.

edit:

I got it working by subtracting the 0x00110000 - the used amount of bytes. This will give me an offset that i can add to the location counter [.].

snip from linker file :
Code:
	.application :
		{
		. = . + 0xCE88;
		. = ALIGN (4);
		*application.o (.text)
		} >ROM

mapfile :
Code:
.application    0x00103178     0xcea8
                0x00110000                . = (. + 0xce88)
 *fill*         0x00103178     0xce88 
                0x00110000                . = ALIGN (0x4)
 *application.o(.text)
 .text          0x00110000       0x20 ./src/application.o
                0x00110000                Application

I have to modify this value every time i make a change to the program but at least it works.
It is only this time for the bootloader, so i can live with that.
Now when i do a jump to 0x00110000, my test function called Application is executed. So if i overwrite the contents from the flash memory starting from 0x00110000, that code should be executed. At least, that seems logical to me.

So i can safely assume that my Application has an error that i do not understand yet.
 
Last edited:

SOFTengCOMPelec

Platinum Member
May 9, 2013
2,417
75
91
That's good that it is somewhat working now!

Hopefully you can use the fact that you can turn leds on and off (and/or use an oscilloscope or something to look at the ports), to pinpoint the exact line(s), where your application is crashing (or whatever the ERROR is that you have just referred to).
 
Last edited:
May 11, 2008
20,136
1,149
126
Well, i am now trying to understand how it works by using objdump.
With this i can turn the elf file back into assembly code by using the disassembly option -d. For example :
Code:
 objdump -d application.elf > application.txt.

When checking i see what you mean SOFTengCOMPelec. I also find thumb instructions like push and pop in the disassembly list although i specified to the compiler that no thumb instructions should be used. Strange, i thought. Then i found out that the arm assembler understands pseudo instructions. And push and pop are pseudo instructions for the ARM instruction set. These instructions are converted to proper arm instructions by the assembler. This i found out after reading.

Everything seems to be in order and be set at the right address. So the search why the led is not turning on in my application continues.

edit:
Looking at the disassembly code from my bootloader, i am now sure that the jump address is correct. So my previous assumption about the jump address being changed was wrong. :oops:
I no longer need to do any padding in my linker file.
 
Last edited:
May 11, 2008
20,136
1,149
126
Yahooo. I finally found the error i made.

The SAM7S series mcu works in little endian mode.
The bin file is in little endian mode.
The memory controller can only be written to in 32bit words.
When i programmed my application, i took the bytes as they came and put 4 bytes and grouped them into 32bit words. But i did not take the little endian format into account.
I found this out after adding another dump function to compare how the bootloader code was stored in memory.
Time for the next hurdle. :)
 
Last edited:

SOFTengCOMPelec

Platinum Member
May 9, 2013
2,417
75
91
I'm glad that you're making progress, and have apparently solved that problem, or at least found the problem. It's much easier to deal with bug(s)/issues when it basically works, whereas if it crashes, it is a real pain in the neck to sort out, especially without debugging aids.
I usually find that compilers that have been written or modified to work with smallish microcontrollers, are more often than not more buggy, fussy and problematic than the mainstream (PC x86) compilers.
This is probably because compilers such as GCC (x86) are probably used by hundreds of thousands, or even millions of people, and so are usually well polished, and relatively bug free.
 
May 11, 2008
20,136
1,149
126
Everything is up and running now. I decreased the size of my bootloader code from 25KB down to about 9kB. So i decided that my bootloader code should never be bigger than 16kB even after adding extra functionality.

The memory map is that at address 0x00100000 the bootloader code is stored and starts. And at address 0x00104000 the application is stored and will start executing from that address. And it works. Already got the assembly startup code done and i can now program the application in c.

Now i can finally use the ease of the bootloader to test and run new written application code on the sam7s. :)

The optimization bug happening in the xmodem code in side the bootloader, i let that be for now.
I will just use the -Os switch for the bootloader code.
I have first other things to try out and solve.
 
May 11, 2008
20,136
1,149
126
I just discovered the stranged thing.
I no longer need the xmodem code in my application so i removed the xmodem.c and h files from my application project. Started my W-ARM manager to correctly set the makefile and linker file. And after compilation and uploading, my application did not start. That is so weird, that removing 2 files from where no functions are used breaks the code somehow.

So, i changed the optimization setting from 1 to s (size) again, compiled it and uploaded it and now my application runs. Strange...

Anyway , i am having fun times.

I found some old example code to use Chan's fatfs on my controller. So, i copied the files and wrote the code following the examples on Chan's page and from the example code i got... And now i can read a text file from an SD card. ^_^.
Next step is to implement the latest version of fatfs and get the sdcard io functions to work with the latest fatfs version. That is going to be some serious work.
 
Last edited:
May 11, 2008
20,136
1,149
126
Well SOFTengCOMPelec, I finally found the error why the code would randomly crash while changing the optimization flags of GCC.
This happened when i recompiled my application, uploaded my application by use of my bootloader and then it would not run. It would hang. Only by adding some random code it would work.
This code had nothing to do with the real problem, it just solved the memory alignment and sometimes it would break it.

I compiled with optimization switch Os and i dissasembled the code.
I compiled again with optimization switch O1 and i dissasembled the code.
I used winmerge to compare the files and i knew from this that the startup.s code is not modified. So it had to be something else. Of course, the c code was heavily modified, so i was not sure about this either but at least , i could check and verify that the assembly code in startup.s is running.

I have made a small routine in my bootloader and my application that when a Program abort, data abort, undefined instruction abort or an SWI/SVC abort happens, that it traps the instruction, the memory location and dump the status from the memory controller. But unfortunately, this only works while all the code is running properly so i could never find out what happenend this way.
However, when it works :
But it is fun to see a 32 bit pointer loaded with an address where bit0 and bit1 are not 0, get trapped with a "guru meditation" error. I took that from the good ol Amiga. :awe:

What is going on
I will explain :
When the mcu starts, it runs a small assembly file called startup.s.
The mcu starts, it copies interrupt vectors and some interrupt routines to ram. Ram has no waitstates while flash has 1 waitstate, so execution is faster when run from ram. After the interrupt vectors and interrupt routines are copied to ram, the data section, the bss section, all the different stacks are copied from flash to ram and are initialized to 0 or another fill value. What i had done, to speed up execution, i do it 32 bits at once. I take full advantage of the 32bit wide architecture of the ARM. I use the LDR instructions and STR instruction that do 4 bytes (32 bits) at once.

But in my linker file there are flaws. When i change the optimization level, sometimes the load addresses for the data or the bss are not always aligned to a 4 byte boundary. Meaning bit0 and bit 1 are not both 0. Or when loading up the stack with a fill value, bit 0 and bit 1 of the start address or end address are not 0. What then will happen is that the Dabort exception will happen.
and i will have a hard crash.

I figured it out by constantly moving a bit of assembly code to turn on a led through my startup.s and see when the led is no longer turned on.
I then compared it with the map file and found out these addresses to align to 32bit boundaries.
 
Last edited:
May 11, 2008
20,136
1,149
126
See my previous post : Well, it works. I can now use any kind of optimization.

I modified my W-ARM program manager to produce a proper linker file where the alignment on a 32bit boundary is enforced. So all addresses end with 0, 4, 8 or C. I loose a bit of bytes because of the padding but it works. Finally i got that solved.
 

SOFTengCOMPelec

Platinum Member
May 9, 2013
2,417
75
91
Well SOFTengCOMPelec, I finally found the error why the code would randomly crash while changing the optimization flags of GCC.
This happened when i recompiled my application, uploaded my application by use of my bootloader and then it would not run. It would hang. Only by adding some random code it would work.
This code had nothing to do with the real problem, it just solved the memory alignment and sometimes it would break it.

I compiled with optimization switch Os and i dissasembled the code.
I compiled again with optimization switch O1 and i dissasembled the code.
I used winmerge to compare the files and i knew from this that the startup.s code is not modified. So it had to be something else. Of course, the c code was heavily modified, so i was not sure about this either but at least , i could check and verify that the assembly code in startup.s is running.

I have made a small routine in my bootloader and my application that when a Program abort, data abort, undefined instruction abort or an SWI/SVC abort happens, that it traps the instruction, the memory location and dump the status from the memory controller. But unfortunately, this only works while all the code is running properly so i could never find out what happenend this way.
However, when it works :
But it is fun to see a 32 bit pointer loaded with an address where bit0 and bit1 are not 0, get trapped with a "guru meditation" error. I took that from the good ol Amiga. :awe:

What is going on
I will explain :
When the mcu starts, it runs a small assembly file called startup.s.
The mcu starts, it copies interrupt vectors and some interrupt routines to ram. Ram has no waitstates while flash has 1 waitstate, so execution is faster when run from ram. After the interrupt vectors and interrupt routines are copied to ram, the data section, the bss section, all the different stacks are copied from flash to ram and are initialized to 0 or another fill value. What i had done, to speed up execution, i do it 32 bits at once. I take full advantage of the 32bit wide architecture of the ARM. I use the LDR instructions and STR instruction that do 4 bytes (32 bits) at once.

But in my linker file there are flaws. When i change the optimization level, sometimes the load addresses for the data or the bss are not always aligned to a 4 byte boundary. Meaning bit0 and bit 1 are not both 0. Or when loading up the stack with a fill value, bit 0 and bit 1 of the start address or end address are not 0. What then will happen is that the Dabort exception will happen.
and i will have a hard crash.

I figured it out by constantly moving a bit of assembly code to turn on a led through my startup.s and see when the led is no longer turned on.
I then compared it with the map file and found out these addresses to align to 32bit boundaries.

As well as the Led method of debugging, I also like (on Arms), sending information serially to a terminal window or small Lcd display.

The Led method is good to see if it gets to a particular place in the code (without crashing). The Terminal or Lcd method is better, when the program basically works, but is NOT quite right. So you can look at individual variable(s), to see what is going on.

You might need BOTH methods, if it is a real time embedded system. The Led signal (probably watched for on a scope), to see that the timings are correct, and the terminal/Lcd to check that the value is correct.


See my previous post : Well, it works. I can now use any kind of optimization.

I modified my W-ARM program manager to produce a proper linker file where the alignment on a 32bit boundary is enforced. So all addresses end with 0, 4, 8 or C. I loose a bit of bytes because of the padding but it works. Finally i got that solved.

I'm glad that you managed to properly solve this problem. Making it so that the 4 byte (32 bit) alignment is guaranteed, sounds like exactly what you should be doing.

On the (x86, I know you are using Arm), usually if the optimization setting (with GCC) changes the program, from working to NOT working. E.g. -O3 causes bugs. I initially think that it might be a bug in the GCC compiler.

But usually after an extensive investigation, find out that I had made a mistake in the C (or C++) code, which happened to NOT matter too much, at lower levels of optimization.
E.g. Forgetting to initialize a variable. Highest levels of optimization may make this LESS forgiving, as it is more likely to share memory with something else (and then be a funny value, which messes up your program).

On the Arm (and other microcontrollers, for that matter). I often find that setting up the built in peripherals, to be the most problematic/fiddly/annoying part of the programming.
There can be so many fiddly little control bits, all over the place, and it is so easy to miss one or two, which will then usually completely mess up its correct operation.

E.g. Some peripheral devices (on chip), insist that you read a particular flag, in order for it to process the next byte. If you forget to do this (even though you don't really care about that flag). It may "jam up", and refuse to process any more bytes.
 
May 11, 2008
20,136
1,149
126
I too use a terminal window, always. And since the sam7s has 3 uarts, there is always a way to send some data.

Fun to make a small menu and test some stuff out.
Here is a screendump of a terminal connected to the controller when i deliberately loaded a32bit pointer with an address that is not word(32bit) aligned and then tried to access that adress location after pressing a button.

screendump.png
 

SOFTengCOMPelec

Platinum Member
May 9, 2013
2,417
75
91
I too use a terminal window, always. And since the sam7s has 3 uarts, there is always a way to send some data.

Fun to make a small menu and test some stuff out.
Here is a screendump of a terminal connected to the controller when i deliberately loaded a32bit pointer with an address that is not word(32bit) aligned and then tried to access that adress location after pressing a button.

That looks really good.

It makes the development process much smoother, easier, and more robust/reliable.

Reading/writing to SD cards is very useful, especially if you can do this on your own projects.

One of the things I did with my Arm stuff, was read/write to some old PC Dram memory (for fun). It was interesting to see how quickly the data faded, when I (on purpose) delayed the refresh time period, by ever larger amounts.

It was difficult to find out how to interface to the Dram (with the Arms PIO pins), because the Dram manufactures tend to keep such details secret. I had to find a (relatively secret) code sequence, which initialized the Dram, and allowed me to use it.
Apparently they keep it secret, to help fight competition between the Dram manufacturers. But I still can't properly understand why they can't put that information, into the published datasheets, which has the appropriate pinout, voltages and timings.
 
May 11, 2008
20,136
1,149
126
I also do not understand why some semiconductor manufacturers are so secretive when it comes to datasheet information.

I just finished adding a function to my program manager to load in a file by use of a open file dialog and then calculate the crc value of that file and displaying it in a messagebox.
I need that to use it as a verification of proper data handling when i am going to test my still to write sd card/spi drivers. The drivers i have now are from Andreas Schwarz but they only work with Chan fatfs version 0.03a. And fatfs is currently at version 0.11. I found some examples from Martin Thomas but unfortunately it does not work out of the box for me. So i have to do some writing of my own to get it all to work. To verify data integrity, i have some testfiles that i calculated the CRC value from. I will let my mcu load in the files, one 57 bytes large and one 32kB large. And then calculate the crc value. After that i will do a read and write test and then compare the files with WinMerge. If all those tests are succesful, i will have fatfs r0.11 up and running. Then i can start with the next project, getting the adc to sample and use dma to load in a buffer of 1000 samples and then perform a Goertzel algorithm on it to look for certain frequencies. I can then finally test how fast the good ol' ARM7TDMI core is.
 
Last edited:
May 11, 2008
20,136
1,149
126
Yahooo. I got fatfs v0.07 working and the sdcard io drivers seem to work as wel.
I made a pointer to pointer error and the guru meditation text popped up again. :)

It is really handy, i can immediately see that something went wrong without crashing the program.
But for some reason, with fatfs 0.03 i got the correct size of the sdcard. Now it is rubbish. I hope to solve that error when moving on to fatfs R0.11.
 
May 11, 2008
20,136
1,149
126
Yahooo. i got fatfs r0.11 up and running. Now to do some serious testing and get those weird values for free disk space solved...
 
May 11, 2008
20,136
1,149
126
I had some free time and i solved the free space error. Now i get the correct size of the memory card in bytes and i get the correct size of the amount of free bytes. I made a calculation error. While looking through the header file of fatfs called ff.h and reading through the FATFS struct i found out what i did wrong. :) CRC functions work, now i have to write a few read write tests for the sd card and perform the tests and compare the results.