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.

Newbie question

I just got started on the MSP430. I have used PIC uC before. I am  planning to code in assembly. Couple of things I don't understand are -

Why should the watchdog timer be stopped at the beginning of each program?

I don't understand the difference between Absolute and Symbolic addressing.

While Initializing the Stack pointer, why can't it be initialized to the last memory location like FFFFh in a 16K memory.

 

 

  • Most demo programs stop the WDT as they don't trigger it anywhere in the code. (well, it's a demo). Also, it migh tbe necessary to stop it in the reset vector init code if you're programming in C and there is a lot of initialized data in your program. Copying the initialisation data from flash top ram or clearing RAM for the zeroed variabels might take longer than the WDT-timeout. The MSPGCC compiler silently disables the WDT right at the start for this reason. (I had to write my own startup code that triggers the watchdog instead constantly while copying/clearing)

     

    The difference between symbolic and absolute addressing is that in one case an absolute address is used, in the other the address is calculated relative to the current program counter.

    For the source code it makes no difference, but if the destination is relative to the program counter, code is moveable. So e.g. constants which are stored right behind your function, can be move with the code and do not need linking. In some rare cases it also leads to slightly faster program execution. Even subroutine calls can be relative to the PC and do not need any absolute address. For C programming, this is useless, but it might be handy for some assembly programming - especially if you don't use a linking stage or implement modular reloadable code.

     

    About the stack pointer, of yourse it must eb initialized at the top of the physical ram and not at the end of the addressing range. The MSP is a von-neumann-machine. This means that code and data memory  are in teh same physical address range and the processor does not separate the two. On MSP, the flash is located fown from the 0xffff (or on soem newer devices, even exceeds 0xfff), as all teh hardware vectors are located there (e.g. the reset vector is at 0xfffe). At the beginning of the memory range are the special funciton registers and the hardware I/O registers. Then there is an area with the boot strap loader, teh info memory (als flash) and of course the ram.

    The excat addresses vary from device to device. There is a memory map in your device datasheet showing what is where. The stack poitner usually is initialized to the highest RAM address and uses the RAM from there down. variables are usually placed at the lowest ram address and above them is the heap, using the ram up, until top of the heap and bottom of the stack meet (which shouldn't happen in any program). This is the 'usual way' for most processors, even on the PC. PICs are different, as they have a separate hardware stack that is not located in the normal addressing range. But PICs are different in almost every respect :)

     

  • Thank you very much for the answers. I have 3 more questions -

    1. Initializing Stack Pointer in Relocatable Assembly code :

                       Rseg CSTACK

                       Mov.w #SFE(CSTACK), SP

    So CSTACK creates a bunch of memory locations in RAM for storing stack pointers. SFE is last location in CSTACK+1.

    Can you explain with an example.

    2. When the uC resets, where does the execution of code start? at 0000h?

    I find the reset vector a bit confusing.

                       Rseg Reset

                       DW Reset

                       End

    can't you just say goto/jump to main at 0000h. why do you have to declare a Rseg for reset.

     

     

     

  • Both questions have (almost) the same answer.

    The 'segments' in the source code define a place where to put things in. The resulting absolute position is determined in the linking stage. The linker has a device-specific data file where the possible or absolute positions of segments are defined.

    In your case, the segment CSTACK is (usually, but maybe not in every case) defined as being at the end of the physical ram area. Since this is at different locations for different CPUs, you use CSEG in your code instead of a dedicated address. The linker will insert what fits for your CPU.

    Same for the RESET segment. This is a 2 byte sized segment located (for all MSPs) at the address 0xfffe. It neds to contain the address of where your reset vector function is placed. This is determined at linking stage too (the reset function can be anywhere in the lower 64k address range). This instruction tell the linker to place a data word with the address of your reset function at the address 0xffe. When programming in C, the compiler usualyl automatically generates this kind of information, not only for the reset vector but for any interrupt function too.

    On MSP, code execution does not just 'start' at an address. And of course not at 0x0000, as this is the location of the special function registers and no flash area. Processors mit harvardt architecture have code and data space separate (and cannot execute code in ram). There often the code execution is automatically started at 0x0000, as this is always the start of the code flash memory. But on von-Neumann-processors it isn't. So executing a RESET condition is done the same way any kind of interrupt is done, by fetching a vector address from the end of the address area and takign this as start address for the required interrupt function. the RESET vector is at 0xfffe, the NMI vector at 0xfffc and all others are below. But since the linker does not implicitely know about MSP or whatever processor, but just takes the assembly output and links it according to its script with segment information, you need to supply a command to put the vector addresses at the vector memory location. This is what the segment directive does: telling the linker to put the info where it belongs. So the processor finds there the info where to jump to when it executes a reset.

    Just to make sure you understand: with the Rseg directive you do not declare a (new) segment, you declare into which (predefined!) segment the following data/code shall be put. All available segments are known to the linker by its script file. And using 'Rseg foo' will most certainly make the linker issue an error, as 'foo' is no known segment to him.

**Attention** This is a public forum