[Tinyos-beta-commits] CVS: tinyos-1.x/beta/platform/imote2 binarymover.s, NONE, 1.1 TrickleC.nc, NONE, 1.1 TrickleM.nc, NONE, 1.1

Josh jsherbach at users.sourceforge.net
Tue Aug 30 17:41:27 PDT 2005


Update of /cvsroot/tinyos/tinyos-1.x/beta/platform/imote2
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2983

Added Files:
	binarymover.s TrickleC.nc TrickleM.nc 
Log Message:
iMote2 Boot loader components

--- NEW FILE: binarymover.s ---
@@@@@@@@@@@@@@@@@@@@@@@@@
@ to create an assembly function that confirms to AAPCS (or so I think o)
@ .func function name
@	STMFD R13!, {R4 - R12, LR}..alternatively STMFD R13!, {registers used, LR}
@	{function body}
@	LDMFD R13!, {R4 - R12, PC}...must match above with LR replaced by PC
@ .endfunc
@@@@@@@@@@@@@@@@@@@@@@@@@@
	

	.equ FLASH_READARRAY,(0x00FF)
	.equ FLASH_CFIQUERY,(0x0098)
	.equ FLASH_READSTATUS,(0x0070)
	.equ FLASH_CLEARSTATUS,(0x0050)
	.equ FLASH_PROGRAMWORD,(0x0040)
	.equ FLASH_PROGRAMBUFFER,(0x00E8)
	.equ FLASH_ERASEBLOCK,(0x0020)
	.equ FLASH_DLOCKBLOCK,(0x0060)
	.equ FLASH_PROGRAMBUFFERCONF,(0x00D0)
	.equ FLASH_LOCKCONF,(0x0001)
	.equ FLASH_UNLOCKCONF,(0x00D0)
	.equ FLASH_ERASECONF,(0x00D0)
	.equ FLASH_OP_NOT_SUPPORTED,(0x10)
	.equ ARM_CPSR_INT_MASK,(0xC0)

	.global __Binary_Mover
	.global __Binary_Mover_true_end

__Binary_Mover:
.func __Binary_Mover	@r0 = addr
						@r1 = size
	
	ldr r5,=ARM_CPSR_INT_MASK	@Store int mask value
	mrs r4,CPSR					@Store Core Program Status Reg
	orr r4,r4,r5				@Add int mask
	msr CPSR,r4					@Replaces previous CPSR value
	
	ldr r5,=0x40000000
	add r5,r5,#0xe00000
	add r5,r5,#0x0100
	add r5,r5,#0x0c				@r5 contains 0x40e0 010c, address of GPDR3
	ldr r6,[r5]
	ldr r7,=0x7
	orr r6,r6,r7,LSL #7
	str r6,[r5]					@should set GPIO 103-105 to output
	
	ldr r6,=0x18				@offset between GPDR3 and GPCR3
	add r5,r5,r6				@r5 contains 0x40e0 0124
	ldr r6,=0x3
	mov r6,r6,LSL #7
	str r6,[r5]
	
	ldr r4,=0x0					@Counter
	cmp r4,r1
	beq __Binary_Mover_end		@If imagesize is 0 then skip a bunch of stuff
	
	ldr r5,=0x200000
	ldr r7,=0x2000000			@Final flash addr 0x0200 0000
	@preset all partitions to ReadArray
	__Binary_Mover_RA_setup:
	ldr r6,=FLASH_READARRAY
	strh r6,[r4]				@Readarray
	ldrh r6,[r4]				@Latch?
	add r4,r4,r5				@Increment
	cmp r4,r7
	blo __Binary_Mover_RA_setup	@Repeat
	
	ldr r4,=0x0					@Counter
	ldr r5,=0x8000				@Block size 0x0000 8000 initially...moves up to 0x0002 0000
	__Binary_Mover_Erase_loop:
	ldr r6,=FLASH_CLEARSTATUS	@Unlock block
	strh r6,[r4]				@Clear Status
	ldr r6,=FLASH_DLOCKBLOCK
	strh r6,[r4]				@Change lock
	ldr r6,=FLASH_UNLOCKCONF
	strh r6,[r4]				@Confirm Unlock
	ldr r6,=FLASH_READARRAY
	strh r6,[r4]				@Return to read array
	ldrh r6,[r4]				@latch?
		
	ldr r6,=FLASH_CLEARSTATUS
	strh r6,[r4]				@Clear Status register
	ldr r6,=FLASH_ERASEBLOCK
	strh r6,[r4]				@Send EraseBlock command
	ldr r6,=FLASH_ERASECONF
	strh r6,[r4]				@Confirm Erase Block
	EraseBlockSpin:
	ldrh r6,[r4]				@Read Block Status
	and r6,r6,#0x80
	cmp r6,#0x0					@Check if Erase is complete
	beq EraseBlockSpin			@Spin if not complete
	ldr r6,=FLASH_READARRAY
	strh r6,[r4]				@Set Block back to normal read mode
	ldrh r6,[r4]				@latch?
	
	add r4,r4,r5				@Increment to next block
	
	ldr r6,=0x20				@Check if Block size needs to increase
	mov r6,r6,LSL #0xc			@starting address for larger size
	cmp r4,r6
	bne __Binary_Mover_Erase_loop_end	@if r4!=r6 continue
	mov r5,r5,LSL #0x2			@Times 4 making 0x8000 become 0x2 0000
	
	__Binary_Mover_Erase_loop_end:
	cmp r4,r1
	blo __Binary_Mover_Erase_loop		@Repeat
	
	ldr r4,=0x0					@Reset counter for writing
	__Binary_Mover_Write_loop:
	ldrh r6,[r0, r4]			@Get data
	
	ldr r5,=FLASH_CLEARSTATUS	@Write word start
	strh r5,[r4]				@Clear Status register
	ldr r5,=FLASH_PROGRAMWORD
	strh r5,[r4]				@Send Program Word Command
	strh r6,[r4]				@Write Word
	WriteWordSpin:
	ldrh r5,[r4]				@Read Block Status
	and r5,r5,#0x80
	cmp r5,#0x0					@Check if Write is complete
	beq WriteWordSpin			@Spin if not complete
	ldr r5,=FLASH_READARRAY
	strh r5,[r4]				@Set Block back to normal read mode
	ldrh r5,[r4]				@Word written
	
	add r4,r4,#0x2				@Increment Counter
	cmp r4,r1
	blo __Binary_Mover_Write_loop	@Repeat
	
	__Binary_Mover_end:
	ldr r5,=0x40000000
	add r5,r5,#0xa00000
	add r5,r5,#0x18				@r5 contains 0x40a0 0018, OWER
	ldr r6,=0x1
	str r6,[r5]					@enables watchdog timer reset
	
	sub r5,r5,#0xC				@r5 contains 0x40a0 000c OSMR3
	add r4,r5,#0x4				@r4 contains 0x40a0 0010 OSCR0
	ldr r6,[r4]
	add r6,r6,#0x1000
	str r6,[r5]					@osmr3 = oscr0 + 0x1000
	__Binary_Mover_spin:
	b __Binary_Mover_spin		@spin until watchdog timer resets this
	
	ldr PC,=0x0					@Reset
	__Binary_Mover_true_end:
	nop
.endfunc

--- NEW FILE: TrickleC.nc ---
configuration TrickleC {
  provides interface StdControl as Control;
}
implementation {
  components 
    TrickleM,
    HPLUSBClientC,
    FlashC;
 
  Control = TrickleM;
  
  TrickleM.ReceiveBData -> HPLUSBClientC;
  TrickleM.SendJTPacket -> HPLUSBClientC;
  TrickleM.Flash -> FlashC;
}

--- NEW FILE: TrickleM.nc ---
module TrickleM {
  provides interface StdControl as Control;
  uses{
    interface Flash;
    interface ReceiveBData;
    interface SendJTPacket;
  }
}
implementation {
  int sprintf(char *, const char *, ...) __attribute__ ((C, spontaneous));  

  extern void __Binary_Mover() __attribute__ ((C,spontaneous));
  extern uint32_t __Binary_Mover_true_end __attribute__ ((C));

#include "Flash.h"
#include "PXA27XUSBClient.h"

  void verifyData(uint32_t addr, uint32_t numBytes);
  void reboot(uint32_t imageAddr, uint32_t imageSize);

  uint32_t startWriteAddr, lastWriteAddr, busy = 0;

  command result_t Control.init() {
    return SUCCESS;
  }
  
  command result_t Control.start() {    
    return SUCCESS;
  }
  
  command result_t Control.stop() {
    return SUCCESS;
  }

  void verifyData(uint32_t addr, uint32_t numBytes){
    atomic busy = 1;
    call SendJTPacket.send((uint8_t *)addr, numBytes,
			   IMOTE_HID_TYPE_CL_BINARY);
  }

  event result_t SendJTPacket.sendDone(uint8_t* packet, uint8_t type, result_t success){
    uint8_t impType = IMOTE_HID_TYPE_CL_BINARY | 
		       (IMOTE_HID_TYPE_MSC_BLOADER << IMOTE_HID_TYPE_MSC);
    if((type & impType) == impType)
      free(packet);
    return SUCCESS;
  }

  event result_t ReceiveBData.receive(uint8_t* buffer, uint8_t numBytesRead,
				      uint32_t i, uint32_t n, uint8_t type){
    uint32_t j;
    if((type >> IMOTE_HID_TYPE_MSC) == IMOTE_HID_TYPE_MSC_BLOADER){
      switch(buffer[0]){
      case 0:
	startWriteAddr = (buffer[1] << 24) | (buffer[2] << 16) |
	  (buffer[3] << 8) | buffer[4];
	break;
      case 1:
	atomic busy = 0;
	break;
      case 2:
	reboot((buffer[1] << 24) | (buffer[2] << 16) | (buffer[3] << 8) |
	       buffer[4],
	       (buffer[5] << 24) | (buffer[6] << 16) | (buffer[7] << 8) |
	       buffer[8]);
	break;
      }
      return SUCCESS;
    }
    if(busy == 1)
      return SUCCESS;
    
    if(i == 0){
      for(j = 0; j < numBytesRead * (n + 1); j += FLASH_BLOCK_SIZE)
	call Flash.erase(startWriteAddr + j);
      lastWriteAddr = startWriteAddr;
    }

    call Flash.write(lastWriteAddr, buffer, numBytesRead, FLASH_NORMAL);
    
    lastWriteAddr += numBytesRead;
    if(i % 5 == 0 || i - n < 5){
      if(n==i){
	uint8_t *temp = (uint8_t *)malloc(4);
	*(uint32_t *)temp = i;
	call SendJTPacket.send(temp, 4, IMOTE_HID_TYPE_CL_BINARY |
			       (IMOTE_HID_TYPE_MSC_BLOADER << 
				IMOTE_HID_TYPE_MSC));
	verifyData(startWriteAddr, lastWriteAddr - startWriteAddr);
      }
      else{
	uint8_t *temp = (uint8_t *)malloc(4);
	*(uint32_t *)temp = i;
	call SendJTPacket.send(temp, 4, IMOTE_HID_TYPE_CL_BINARY |
			       (IMOTE_HID_TYPE_MSC_BLOADER << 
				IMOTE_HID_TYPE_MSC));
      }
    }
    return SUCCESS;
  }

  void reboot(uint32_t imageAddr, uint32_t imageSize){
    uint32_t binSize = (uint32_t)&__Binary_Mover_true_end;
    uint8_t *rebootBinary;
    binSize -= (uint32_t)__Binary_Mover;
    rebootBinary = (uint8_t *)malloc(binSize);
    memcpy(rebootBinary, __Binary_Mover, binSize);

    asm volatile(
		 "mov r0,%0;  \
		 mov r1,%1;   \
		 mov PC,%2"
		 :/*no output*/
		 :"r"(imageAddr), "r"(imageSize), "r"(rebootBinary));
    /*everything is clobbered*/
  }
}



More information about the Tinyos-beta-commits mailing list