Thursday, January 7, 2016

ARM STM32F103x6 Notes



  • Clock Gating
    • After reset, all the peripherals clock are disabled.
    • To use any peripheral, you have to enable its clock
    • This is done via clock gating control registers
  • RISC:
    • Reduced Instruction Set Computer Architecture
    • You can load data from memory to register
    • You can store data from register to memory
    • All operations are done on register, no operations (except load and store) can be done on data in memory
  • CISC
    • Complicated Instruction Set Computer Architecture
    • Some operations can be done on data in memory

unsigned int t = 0;
while (t < 50){
t++;
}

    • This code may be optimized:
      • If t is used after the loop, then all this loop will be optimized to
        • MOVS    R0    50
      • If t is not used, then the loop will be entirely removed!
    • But what if you want to prevent this optimization for a reason? For example, you are not interested in t itself, but you need the loop to create some delay!
    • In this case, just define t as volatile
      • Volatile tells the compiler that the variable t, may be changed, even if this function is not changing it.
      • This implies that other programs, or HW component may change this value anytime
      • Hence, prevent any optimization that is assuming that your function is the only player with t.
      • unsigned volatile t = 0;
  • unsigned int x = 3;                 x = x>>2;                    x = x<<1;
    • Assembly: LSRS > Logic Shift Right Shift > No sign extension
    • Assembly: LSLS > Logic Shift Left Shift > No sign extension
    • In logic shift, right shift results in zeros on the left.
  • int x = -4;                 x = x>>2;              x = x<<1;
    • Assembly: ASRS Arithmetic Shift Right Shift > Sign extension
    • Assembly: ASLS Arithmetic Shift Left Shift > Sign extension
    • In Arithmetic shift, right shift results in zeros on the left for positive integers, ones for negative integers
  • The processor is connected to the peripherals via one of 2 buses
    • APB: Advanced Peripheral Bus
    • AHB: Advanced High Speed Bus
  • Some peripherals are connected to processor by both buses, normally APB is used, and you can switch to AHB via control registers.
  • For GPIO port, configured as output, there is a control register, in which each bit controls the state of a pin in this port.
    • To change the status of a pin, without changing neighbors pins status, use bit wise operations:
      • GPIOB_DATAO |= (1U < 1); // pin 1 => ON | Other pins => no change
      • This maps to 3 instructions in assembly
        • Load from peripheral register to processor register
        • Modify value
        • Store from processor register to peripheral register
      • This may be interrupted by interrupt
        • If the interrupt changes the GPIO states, then something unexpected may occur
      • Solution # 1: Use critical section
      • Solution # 2: Use GPIO bit registers
        Bit Registers are control registers provided by the GPIO peripheral.
        Each register is correspondent to one pin only
        The pin corresponding to this register is changed according to this register
        Other pins remains unchanged, regardless of this register value
      • Here, we have only one operation (Store to peripheral register - Atomic operation)
  • Function Calls
    • AAPCS (Arm Application Procedure(function) Call Standard)
      • A standard that describes agreements between caller function and called function in ARM
        • R0,R1,R2,R3,R12 are used for arguments passing
        • R0 is used for return value
        • R4 => R11 values, shall be preserved by the called function
          • i.e: push their values to the stack before using
          • and: pop their values from the stack after using
    • Leaf function is a function that does not call any functions
    • Inside any function:
      • Push LR and R4=>R11 values to stack
        • If leaf function, No need to push LR value
        • For R4=>R11, only need to push the registers that will be used in the function
        • Ex:
          • Not leaf, uses R4: PUSH [R4,LR]
          • Leaf, uses no registers: do nothing
      • Create local variables in the stack
        • Ex:
          • SUB  SP, #4               (Grow the stack by 4 bytes)
          • STR   R1, [SP]         (Store the local var to Stack top)
      • When calling a function
        • Pass Arguments
        • Save return address in LR
        • Branch to the function
        • Ex:
          • MOV  R0 , #1000
          • BL   func_1         (Save return address to LR, then branch
      • After returning from func_1, grep the return value from R0
        • Ex:
          • MOV R4, R0
      • At the end of the function
        • Restore all registers values, from Stack
          • If not leaf, and used R4:
            • POP [R4, PC], this will do the following:
              • Grep R4 value from stack to R4
              • Grep LR value from stack to PC, hence the next step will return from function
          • If leaf, uses no registers:
            • BX      LR
              • BX do the following:
                • Branch to the address provided (in this case LR)
                • Exchange the instruction set to
                  • if LSB of the provided register = 1 ==> Thumb Instruction set
                  • If LSB of the provided register = 0 ==> ARM instruction set
                  • Note that Cortex supports only Thumb Instruction Set

No comments:

Post a Comment