Busan IT/Assembly2015. 10. 20. 17:34

==================================Outline====================================

memory_modify함수

----------------------------------------------------------------------------

메모리의 값을 수정해주는 함수를 만들자.

 

함수의 이름은 'memory_modify'이다. 이 함수는 원하는 메모리 주소에 찾아가서 1byte의 값을 바꾸는 역할을 한다.

 

void memory_modify()
{
  unsigned int uiAddr;
  unsigned int uiVal;  
  while(1)
  {
    printf("수정할 메모리 주소를 입력하세요 [%08X - %08X]  :  ", vpMem_start, vpMem_end);
    scanf("%x"&uiAddr);
    fflush(0);
    if(uiAddr < (unsigned int)vpMem_start || uiAddr > (unsigned int)vpMem_end)
    {
      printf("잘못입력하셨습니다. \n");
      continue;
    }
    break;    
  }
  hexaview((void *)uiAddr, 16);
  printf("수정할 값을 입력하세요 : ");
  scanf("%x"&uiVal);  
  
  fflush(0);  

  *((unsigned int *)uiAddr) = uiVal;
  hexaview((void *)uiAddr, 16);  
  return;
}

 

내일은 load함수를 하겠다.


 /*** 코드 ***/

#include <stdio.h>

/*  사용자 정의  */
#define CMD_SIZE   20
#define  MAX_PRG_SIZE  (64*1024)
#define  MEM_SIZE   (MAX_PRG_SIZE*2)
#define  MASK_CODE  0xFFFF0000
typedef struct
{
  unsigned int efl;
  unsigned int eip;
  unsigned int edi;
  unsigned int esi;
  unsigned int ebp;
  unsigned int esp;
  unsigned int ebx;
  unsigned int edx;
  unsigned int ecx;
  unsigned int eax;
  
}context;

typedef struct
{
  char * cpCmd;
  void (*fp)();  
}comm;

/*   전역 변수  */
static context stOld_state;
extern void stst(context *);
extern void ldst(context *);
void * vpMem_start;
void * vpMem_end;
void print_addr();
void * vpCode;
void * vpData;
void * vpStack;

/*  함수 원형  */
void print_r();
void print_help();
void memory_clear();
void quit();
void view_code();
void view_data();
void view_stack();
void load();
void memory_modify();


void hexaview(void *, unsigned int);

comm stCmd_Map[] ={  //메세지 맵 기법
         {
        "R", print_r
         },
      {
        "H", print_help
      },
      {  
        "MC", memory_clear      
      },
      {  
        "Q", quit
      },
      {
        "QUIT", quit 
      },
      {
        "P", print_addr
      },        
      {
        "CODE", view_code
      },
      {
        "DATA", view_data
      },
      {
        "STACK", view_stack
      },
      {
        "LOAD", load
      },
      {
        "MM", memory_modify
      },
         {
        00
         }        
      };
int main(void)
{
  char cInput[CMD_SIZE];
  comm * stpCmd;
  int iRet;  
  
  vpMem_start = (void *)malloc(MEM_SIZE);
  if(0==vpMem_start)
  {
    return -1;
  }
  vpCode = (void *)( ( ((int)vpMem_start) & (MASK_CODE) )+MAX_PRG_SIZE);
  vpData = (void *)((int)vpCode + 0x2000);   
  vpMem_end = (void *)( (int)vpMem_start + MEM_SIZE - 1 );    
  vpStack = (void *)( (int)vpMem_end - (16 * 16)+1);
  
  stst(&stOld_state);  
  printf("Moniter Program Start\n");
  while(1)
  {
    putchar('>');    
    iRet = read(0, cInput, CMD_SIZE);
    if(iRet < 2)
    {
      continue;  
    }    
    cInput[iRet-1= 0;    
    strupr(cInput);
    
    stpCmd = stCmd_Map;
    while(0 != (stpCmd->fp))
    {
      if(0 == strcmp(strupr(cInput), stpCmd->cpCmd))
      {
        break;
      }      
      ++stpCmd;
    }
    if(0!= (stpCmd->fp))
    {
      ((stpCmd->fp)());      
      
    }
    else
    {
      print_help();
    }    
  }
  return 0;
}
void print_r()
{
  printf("main    : %08X\n", main);
  printf("stOld_state  : %08X\n\n"&stOld_state);
  printf("EAX = %08X  EBX = %08X\nECX = %08X  EDX = %08X\nESI = %08X  EDI = %08X\nEBP = %08X  ESP = %08X\nEIP = %08X  EFL = %08X\n\n",stOld_state.eax, stOld_state.ebx, stOld_state.ecx, stOld_state.edx, stOld_state.esi, stOld_state.edi, stOld_state.ebp, stOld_state.esp, stOld_state.eip, stOld_state.efl);

}
void print_help()
{
  printf("Memory Debugging Prompt\n\n");
  printf("R: Print Register Info.\n");
  printf("H: Print Command List\n");    
  printf("H: Clear Momory\n");    
  printf("P: Print Memory\n");
}
void memory_clear()
{  
  memset(vpMem_start, 0, MEM_SIZE);  
}
void print_addr()
{
  printf("Code Start Address    : 0x%08X\n", vpCode);  
  printf("Dynamic Memory Area    : 0x%08X - 0x%08X [128Byte]\n", vpMem_start, vpMem_end);
}
void quit()
{
  free(vpMem_start);
  exit(0);
}
void view_code()
{
  hexaview(vpCode, 16*16);

  return;
}

void view_data()
{
  hexaview(vpData, 16*16);

  return;
}
void view_stack()
{
  hexaview(vpStack, 16*16);

  return;
}
void load()
{
  memset(vpCode, 0xFF, 16*16);
  memset(vpData, 0xEE, 16*16);
  memset(vpStack, 0xDD, 16*16);

  return;
}
void memory_modify()
{
  unsigned int uiAddr;
  unsigned int uiVal;  
  while(1)
  {
    printf("수정할 메모리 주소를 입력하세요 [%08X - %08X]  :  ", vpMem_start, vpMem_end);
    scanf("%x"&uiAddr);
    fflush(0);
    if(uiAddr < (unsigned int)vpMem_start || uiAddr > (unsigned int)vpMem_end)
    {
      printf("잘못입력하셨습니다. \n");
      continue;
    }
    break;    
  }
  hexaview((void *)uiAddr, 16);
  printf("수정할 값을 입력하세요 : ");
  scanf("%x"&uiVal);  
  
  fflush(0);  

  *((unsigned int *)uiAddr) = uiVal;
  hexaview((void *)uiAddr, 16);  
  return;
}


void hexaview(void * vP, unsigned int uiLen)
{
  unsigned int uiCnt;
  unsigned int uiLine;

  printf("===============================================================================\n");
  printf("  Address      Hexa           ASCII       \n"); 
  printf("-------------------------------------------------------------------------------\n");
  for (uiLine = 0; uiLine <  uiLen; uiLine += 16)
  {
    printf(" %08X  ", vP);
  
    for(uiCnt=0; uiCnt<16; ++uiCnt)
    {
      printf("%02X ", *((unsigned char *)vP));
      vP = (char *)vP + 1;
    }
    vP = (char *)vP - 16;
    putchar(' ');

    for(uiCnt=0; uiCnt<16; ++uiCnt)
    {
      if (32 > *((unsigned char *)vP))
      {
        putchar('.');
      }    
      else if(127 < *((unsigned char *)vP))
      {
        putchar('.');
      }
      else
      {        
        printf("%1c", *((unsigned char *)vP));
      }

      vP = (char *)vP + 1;
    }
    putchar('\n');
  }
  return;
}


 

반응형

'Busan IT > Assembly' 카테고리의 다른 글

LOAD함수 구현  (0) 2015.10.23
PE구조체  (0) 2015.10.22
코드/데이터/스택 영역 설정, load, clear  (0) 2015.10.20
메모리 출력 프로그램 #1  (0) 2015.10.15
stst(store state), ldst(load state)  (0) 2015.10.15
Posted by newind2000
Busan IT/로봇제어2015. 10. 20. 16:14

==================================Outline====================================

PWM을 사용한 LED dimming

스크래치

----------------------------------------------------------------------------

 

자바에서는 모든 함수는 클래스 내에 존재해야 한다. 반면에 C++는 함수가 main함수에서 수행된다.

 

java의 컴파일러는 javac이다. 'smart.java'라는 파일을 컴파일하면 'smart.class'라는 파일이 생성된다.

 

 

컴파일이 실행하는 도중에 진행되는 언어를 인터프리터 언어(Interpretor Language)라고 한다.

 

//‘wget‘ 웹에서 해당 파일을 직접 가져오는 명령어이다.

 

//직사각형 형태의 파형을 구형파라고 한다.


PWM을 사용한 LED dimming 

 

PWM을 사용한 LED dimming을 만들어 보자.

 

 

 

교재 p/114 [led_dimming.py]


 import RPi.GPIO as GPIO
 import time

 LED = 18
 GPIO.setmode(GPIO.BCM)

 GPIO.setup(LED, GPIO.OUT)

 LED = GPIO.PWM(LED, 100)

 LED.start(0)

 delay = 0.1

 try:
     while True:
         for i in range(0101):
             LED.ChangeDutyCycle(i)
             time.sleep(delay)
         for i in range(100, -1, -1):
             LED.ChangeDutyCycle(i)
             time.sleep(delay)

 except KeyboardInterrupt:
     LED.stop()
     GPIO.cleanup()

 

 

스크래치

 

p/116 스크래치

 

p/131까지 책을 보며 혼자 진행한다.

 

adobe AIR -

http://get.adobe.com/air/

 

스크래치 오프라인 에디터 - https://scratch.mit.edu/scratchr2/static/sa/Scratch-440.exe 

 

//윈도우용 스크래치를 다운 받아 수행한다.


반응형
Posted by newind2000
Busan IT/ARM Controller2015. 10. 20. 13:37

==================================Outline====================================

Timer를 활용한 LED제어

LCD 제어

----------------------------------------------------------------------------

 

Timer를 활용한 LED제어

 

 

Timer를 사용하여 1초에 한번 타이머 인터럽트가 발생하게 한 후에 딜레이 함수를 만들어 보자.

 

만드는 방법은 간단하다. 전역 변수를 선언해준 후 인터럽트 함수에서 1씩 더해준 다음 딜레이 함수를 만들어 딜레이 함수의 인자 값과 전역 변수의 값을 비교하는 'while'문을 사용하여 프로그램을 잡아주면 된다.

 

unsigned int uiDelay;

 

void TIM2_IRQHandler(void)

{

if(TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET)

{

// Timer Interrupt 가 처리하는 내용

//GPIOA->ODR ^= (uint32_t)0x01;

TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // Clear the interrupt flag

++uiDelay;

}

return;

}

 

 

void Delay_s(unsigned int uiNum)

{

uiDelay = 0;

while(uiNum > uiDelay) ;

}

 

이를 활용하여 PC12에 연결된 LED5초 간격으로 깜빡이게 하고, PA0에 연결된 LED1초 간격으로 깜빡이는 프로그램을 작성해보자.




/*** 코드 ***/

#include <stm32f10x.h>

#define ON 0x01
#define OFF 0x00

unsigned int uiDelay;

void  TIM2_IRQHandler(void)
{
    
  if(TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET)
    {
      // Timer Interrupt 가 처리하는 내용
      //GPIOA->ODR ^= (uint32_t)0x01;
                
      TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // Clear the interrupt flag
      ++uiDelay;  
    }
    
    return;
}

void PA0_out(void)
{
  /* Configure all the GPIOA in Input Floating mode */
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void TIM2_init(void)
{
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  
  /* TIM2 Initialize */   
    TIM_TimeBaseStructure.TIM_Period = (1200-1); 
    TIM_TimeBaseStructure.TIM_Prescaler = (60000-1); 
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);
}
void PC12_out(void)
{
    /* Configure all the GPIOA in Input Floating mode */
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
  
}

void NVIC_init(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
  /* Enable TIM2 global interrupt with Preemption Priority 0 and Sub Priority as 2 */
  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}
void Delay_s(unsigned int uiNum)
{
  uiDelay = 0;
  while(uiNum > uiDelay) ;
}
void init(void)
{
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC, ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  PA0_out();
  PC12_out();
  TIM2_init();
  NVIC_init();  
  TIM_Cmd(TIM2, ENABLE);    // Timer 활성화
  TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);  // Timer Interrupt 활성화
}

int main(void)
{
  unsigned int uiCnt;
  
  // 사용할 기능 : GPIOA0, TIM2
  init();
  
  while(1)
  {
    //PC12에 연결된 LED를 5초 간격으로 깜빡이게 하고,
    //PA0에 연결된  LED를 1초 간격으로 깜빡이는 프로그램을 작성
    for(uiCnt = 0; uiCnt < 5; ++uiCnt)
    {
      Delay_s(1);
      GPIOA->ODR ^= (uint32_t)0x01;      
    }
    GPIOC->ODR ^= (uint32_t)0x1000;
      //GPIO_SetBits(GPIOC, GPIO_Pin_12);
  }
}

 

 

 

LCD 제어

 

우선 회로도의 핀 설명을 보고 회로 연결을 한다.

 



PORTGPORTF를 사용해서 코딩을 한다. 일반출력은 F, INSTRUCTIONG포트를 사용한다.

 

 

 

 

 

 

 

반응형

'Busan IT > ARM Controller' 카테고리의 다른 글

PWM를 사용한 LED 불 밝기 조절  (0) 2015.11.02
USART를 활용한 LED ON/OFF  (0) 2015.10.30
Timer  (0) 2015.10.19
Advanced-control timers(TIM1&8)  (0) 2015.10.16
인터럽트 코드 분석  (0) 2015.10.13
Posted by newind2000
Busan IT/Assembly2015. 10. 20. 09:35

==================================Outline====================================

코드/데이터/스택 영역 설정

load, clear

----------------------------------------------------------------------------

 

코드/데이터/스택 영역 설정

 

동적 할당을 받은 영역에 코드영역, 데이터영역, 스택영역을 설정 해주자.

 

코드 영역은 헥사 값으로 뒤의 4자리가 ‘0’으로 채워져 있어야 한다. 이를 위한 마스크 설정을 해주자.

 

#define MASK_CODE 0xFFFF0000

#define MAX_PRG_SIZE (64*1024)

#define MEM_SIZE (MAX_PRG_SIZE*2)

 

vpCode = (void *)( ( ((int)vpMem_start) & (MASK_CODE) )+MAX_PRG_SIZE);

 

프로그램 사이즈를 더해준 이유는 마스크 코드를 적용할 시 뒤에 4자리가 삭제되기 때문이다.

뒤에 네 자리는 0xFFFF - 0x0000까지 가능한데 이 값을 복구시켜주기 위해 프로그램 사이즈를 더해준다. 처음에 동적할당을 받을 때 'MEM_SIZE' , 프로그램 사이즈의 2배임으로 동적할당을 받은 영역 내에서 프로그램이 존재하게 된다.

 

데이터영역은 코드영역에서 헥사 값으로 2000떨어진 곳에 존재한다.

 

vpData = (void *)((int)vpCode + 0x2000);

 

스택 값은 끝에서부터 시작된다. 이것을 헥사뷰로 16줄을 출력시키기 위해 다음과 같은 코딩을 한다.

 

vpStack = (void *)( (int)vpMem_end - (16 * 16)+1);

 

load, clear

 

각 영역이 올바른 주소 값으로 설정되어 있는지 출력해본다. 올바르게 나온다면 각 영역에 값을 저장할 'load'명령어와 해당 영역을 ‘0’으로 채워주는 'mc'(memory clear) 함수를 만들어준다.

 

void load()

{

memset(vpCode, 0xFF, 16*16);

memset(vpData, 0xEE, 16*16);

memset(vpStack, 0xDD, 16*16);

 

return;

}

 

void memory_clear()

{

memset(vpMem_start, 0, MEM_SIZE);

}




/*** Code ***/

#include <stdio.h>

/*  사용자 정의  */
#define CMD_SIZE   20
#define  MAX_PRG_SIZE  (64*1024)
#define  MEM_SIZE   (MAX_PRG_SIZE*2)
#define  MASK_CODE  0xFFFF0000
typedef struct
{
  unsigned int efl;
  unsigned int eip;
  unsigned int edi;
  unsigned int esi;
  unsigned int ebp;
  unsigned int esp;
  unsigned int ebx;
  unsigned int edx;
  unsigned int ecx;
  unsigned int eax;
  
}context;

typedef struct
{
  char * cpCmd;
  void (*fp)();  
}comm;

/*   전역 변수  */
static context stOld_state;
extern void stst(context *);
extern void ldst(context *);
void * vpMem_start;
void * vpMem_end;
void print_addr();
void * vpCode;
void * vpData;
void * vpStack;

/*  함수 원형  */
void print_r();
void print_help();
void memory_clear();
void quit();
void view_code();
void view_data();
void view_stack();
void load();


void hexaview(void *, unsigned int);

comm stCmd_Map[] ={  //메세지 맵 기법
         {
        "R", print_r
         },
      {
        "H", print_help
      },
      {  
        "MC", memory_clear      
      },
      {  
        "Q", quit
      },
      {
        "QUIT", quit 
      },
      {
        "P", print_addr
      },        
      {
        "CODE", view_code
      },
      {
        "DATA", view_data
      },
      {
        "STACK", view_stack
      },
      {
        "LOAD", load
      },
         {
        00
         }        
      };
int main(void)
{
  char cInput[CMD_SIZE];
  comm * stpCmd;
  int iRet;  
  
  vpMem_start = (void *)malloc(MEM_SIZE);
  if(0==vpMem_start)
  {
    return -1;
  }
  vpCode = (void *)( ( ((int)vpMem_start) & (MASK_CODE) )+MAX_PRG_SIZE);
  vpData = (void *)((int)vpCode + 0x2000);   
  vpMem_end = (void *)( (int)vpMem_start + MEM_SIZE - 1 );    
  vpStack = (void *)( (int)vpMem_end - (16 * 16)+1);
  
  stst(&stOld_state);  
  printf("Moniter Program Start\n");
  while(1)
  {
    putchar('>');    
    iRet = read(0, cInput, CMD_SIZE);
    if(iRet < 2)
    {
      continue;  
    }    
    cInput[iRet-1= 0;    
    strupr(cInput);
    
    stpCmd = stCmd_Map;
    while(0 != (stpCmd->fp))
    {
      if(0 == strcmp(strupr(cInput), stpCmd->cpCmd))
      {
        break;
      }      
      ++stpCmd;
    }
    if(0!= (stpCmd->fp))
    {
      ((stpCmd->fp)());      
      
    }
    else
    {
      print_help();
    }    
  }
  return 0;
}
void print_r()
{
  printf("main    : %08X\n", main);
  printf("stOld_state  : %08X\n\n"&stOld_state);
  printf("EAX = %08X  EBX = %08X\nECX = %08X  EDX = %08X\nESI = %08X  EDI = %08X\nEBP = %08X  ESP = %08X\nEIP = %08X  EFL = %08X\n\n",stOld_state.eax, stOld_state.ebx, stOld_state.ecx, stOld_state.edx, stOld_state.esi, stOld_state.edi, stOld_state.ebp, stOld_state.esp, stOld_state.eip, stOld_state.efl);

}
void print_help()
{
  printf("Memory Debugging Prompt\n\n");
  printf("R: Print Register Info.\n");
  printf("H: Print Command List\n");    
  printf("H: Clear Momory\n");    
  printf("P: Print Memory\n");
}
void memory_clear()
{  
  memset(vpMem_start, 0, MEM_SIZE);  
}
void print_addr()
{
  printf("Code Start Address    : 0x%08X\n", vpCode);  
  printf("Dynamic Memory Area    : 0x%08X - 0x%08X [128Byte]\n", vpMem_end, vpMem_start);
}
void quit()
{
  free(vpMem_start);
  exit(0);
}
void view_code()
{
  hexaview(vpCode, 16*16);

  return;
}

void view_data()
{
  hexaview(vpData, 16*16);

  return;
}
void view_stack()
{
  hexaview(vpStack, 16*16);

  return;
}
void load()
{
  memset(vpCode, 0xFF, 16*16);
  memset(vpData, 0xEE, 16*16);
  memset(vpStack, 0xDD, 16*16);

  return;
}


void hexaview(void * vP, unsigned int uiLen)
{
  unsigned int uiCnt;
  unsigned int uiLine;

  printf("===============================================================================\n");
  printf("  Address      Hexa           ASCII       \n"); 
  printf("-------------------------------------------------------------------------------\n");
  for (uiLine = 0; uiLine <  uiLen; uiLine += 16)
  {
    printf(" %08X  ", vP);
  
    for(uiCnt=0; uiCnt<16; ++uiCnt)
    {
      printf("%02X ", *((unsigned char *)vP));
      vP = (char *)vP + 1;
    }
    vP = (char *)vP - 16;
    putchar(' ');

    for(uiCnt=0; uiCnt<16; ++uiCnt)
    {
      if (32 > *((unsigned char *)vP))
      {
        putchar('.');
      }    
      else if(127 < *((unsigned char *)vP))
      {
        putchar('.');
      }
      else
      {        
        printf("%1c", *((unsigned char *)vP));
      }

      vP = (char *)vP + 1;
    }
    putchar('\n');
  }
  return;
}


 

 

 

 

반응형
Posted by newind2000
Busan IT/로봇제어2015. 10. 20. 09:13

==================================Outline====================================

교재 훑어보기

라즈베리파이2와 파이선을 활용한 코딩

----------------------------------------------------------------------------

 

교재 훑어보기

 

라즈베리 파이로 구현하는 사물 인터넷 프로젝트

 

Chapter 1 ~ 4

 

 

USART를 지원한다는 것은 비동기 데이터 전송 시 사용되는 헤더(header)와 테일(tail)을 만들어 준다는 뜻이다.

 

GPIO로 모든 신호를 만들어 낼 수 있다.


라즈베리파이2와 파이선을 활용한 코딩

 

라즈베리파이와 파이썬을 활용하여 코딩을 해보자.

 

1. 라즈베리파이2GPIO도면 습득

 

2. 파이선 라이브러리 설치

apt-get install python-dev

 

3. GPIO핀에 대해서 H/L pin 테스트

 

우선 파이선 패키지가 설치 되어 있는지 확인해 보자.

 

설치가 되어 있다면 파이썬 패키지를 설치해야 한다.

 

apt-get install python-dev

 

설치가 완료되면 'python'을 입력하여 프롬프트를 실행시키고 구구단을 프로그램을 만들어본다.

 

이제 LED를 활용하여 불을 켜고 끄는 프로그램을 만들어보자.



 

코드를 'led_onoff.py'로 저장한 후 ‘python led_onoff.py'로 실행시켜본다.

깜빡거리는 것을 볼 수 있다.

 


 

반응형
Posted by newind2000
Busan IT/ARM Controller2015. 10. 19. 13:48

==================================Outline====================================

Timer

----------------------------------------------------------------------------

 

reference manual p/372

 

타이머는 클럭의 설정의 따라 사용이 달라지게 된다.

 

//시간과 관련된 기능들은 모두 클럭의 영향을 받는다.

 

 


 

캡쳐/비교 채널은 쉐도우 레지스터를 가지고 있는다. 이것은 필요한 정보를 잠시 저장하는 레지스터이다.

 

 

타이머를 사용한 딜레이 함수를 만들어 보자.

 

함수 이름 : Delay_ms(uint8_t time)

 

ex) 8ms 지연 -> Delay_ms(8); 

 

1ms 간격의 Timer Interrupt 함수를 우선 만들어야 한다.

 

1ms Timer Interrupt 서비스 루틴 안에서 별도의 카운트가 필요하다.


코딩 순서는 다음과 같다.

- 클럭을 공급한다.

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);


- 타이머 설정을 해준다.(TIM2, NVIC)


void  TIM2_IRQHandler(void)

{

if(TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET)

    {

// Timer Interrupt 가 처리하는 내용

//GPIOA->ODR ^= (uint32_t)0x01;

     

TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // Clear the interrupt flag

++uiDelay;

    }

return;

}

void TIM2_init(void)

{

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

/* TIM2 Initialize */   

    TIM_TimeBaseStructure.TIM_Period = (1200-1); 

    TIM_TimeBaseStructure.TIM_Prescaler = (60-1); 

    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

    TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);

}


void NVIC_init(void)

{

NVIC_InitTypeDef NVIC_InitStructure;

/* Enable TIM2 global interrupt with Preemption Priority 0 and Sub Priority as 2 */

NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

- 타이머 작동 확인을 위한 내부 LED설정을 해준다.

void PA0_out(void)

{

/* Configure all the GPIOA in Input Floating mode */

GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_Init(GPIOA, &GPIO_InitStructure);

}




/*** 소스 ***/

#include <stm32f10x.h>

#define ON 0x01
#define OFF 0x00

unsigned int uiDelay;

void  TIM2_IRQHandler(void)
{
    
  if(TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET)
    {
      // Timer Interrupt 가 처리하는 내용
      //GPIOA->ODR ^= (uint32_t)0x01;
                
      TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // Clear the interrupt flag
      ++uiDelay;  
    }
    
    return;
}

void PA0_out(void)
{
  /* Configure all the GPIOA in Input Floating mode */
  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void TIM2_init(void)
{
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  
  /* TIM2 Initialize */   
    TIM_TimeBaseStructure.TIM_Period = (1200-1); 
    TIM_TimeBaseStructure.TIM_Prescaler = (60-1); 
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);
}

void NVIC_init(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
  /* Enable TIM2 global interrupt with Preemption Priority 0 and Sub Priority as 2 */
  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}
void Delay_ms(unsigned int uiNum)
{
  uiDelay = 0;
  while(uiNum > uiDelay) ;
}

int main(void)
{
  // 사용할 기능 : GPIOA0, TIM2
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  PA0_out();
  TIM2_init();
  NVIC_init();
  
  TIM_Cmd(TIM2, ENABLE);    // Timer 활성화
  TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);  // Timer Interrupt 활성화
  
  while(1)
  {
    Delay_ms(1000);
    GPIOA->ODR ^= (uint32_t)0x01;
  }
}

 

반응형

'Busan IT > ARM Controller' 카테고리의 다른 글

USART를 활용한 LED ON/OFF  (0) 2015.10.30
Timer를 활용한 LED제어, LCD 제어  (0) 2015.10.20
Advanced-control timers(TIM1&8)  (0) 2015.10.16
인터럽트 코드 분석  (0) 2015.10.13
Interrupt  (0) 2015.10.12
Posted by newind2000
Busan IT/로봇제어2015. 10. 16. 16:07

==================================Outline==================================== 

모듈 파라미터

장치 드라이버의 형식

----------------------------------------------------------------------------

//모듈을 위한 프로그래밍 시 코딩 파일의 이름을 'main'으로하면 에러가 난다.

 

 

모듈 파라미터

 

make up, down도 마저 작성한 후 모듈을 올리고 내려 본다.

 

//모듈 상태를 보는 명령어 ‘lsmod'

 

 

 

모듈 사용 시 인자를 선언하여 그 값을 바꿔줄 수 있다.

 

이를 사용하기 위해서는 아래의 매크로를 등록해야 한다.

 

module_param(name, type, perm);

name => 변수 이름type   => 변수 타입perm  => 퍼미션

 

int iNum과 문자열 “Hello"를 선언해주고 모듈 인자에 넣어 값을 변동한 뒤 출력해본다.

 

insmod smart.ko iNum=999

insmod smart.ko cpT="Hello"

 

//‘dmesg’로 출력할 수 있다..

 



[smart.c]

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>

MODULE_LICENSE("GPL");

static int rp_init(void);
static void rp_exit(void);
module_init(rp_init);
module_exit(rp_exit);
int iNum = 100;
char * cpT = "Test Message";
module_param(iNum, int0);//charp = char *

static int rp_init(void)
{
  printk("Welcome to Smart World!\n");
  printk("[%d]\n", iNum);
  printk("[%s]\n", cpT);
  return 0;
}

static void rp_exit(void)
{
  printk("Farewell Dear\n");

  return;
}  

[makefile]

obj-m = smart.o

#KDIR = /lib/modules/$(shell uname -r)/build
KDIR = /usr/src/linux

PWD = $(shell pwd)

all:
  @clear
  $(MAKE) -C $(KDIR) M=$(PWD) modules
  @ls -al smart.ko

up:
  @clear
  @insmod smart.ko
  @echo ================== dmesg =================
  @dmesg | tail
  @echo ================== dmesg =================

down:
  @clear
  @rmmod smart
  @echo ================== dmesg =================
  @dmesg | tail
  @echo ================== dmesg =================

clean:
  @clear
  @rm -rf *.ko
  @rm -rf *.mod.*
  @rm -rf .*.cmd
  @rm -rf *.o
  @rm -rf modules.order
  @rm -rf Module.symvers
  @rm -rf .tmp_versions
  @ls -al
  @echo Clean :Done.

 

장치 드라이버의 형식

 

Unix방식을 물려받은 linux는 모든 장치들을 파일로 관리한다.

노란색 폴더가 장치를 의미한다.

 

장치 드라이버의 형식

 

장치 드라이버는 3개로 나눈다. 

 

c: c for character : 데이터 전송 단위 1byte(크기가 고정되어 있지 않다)

ex) 마우스, 키보드

 

b: b for block: 블록은 데이터 크기가 고정되어 있다. 데이터를 보낼 때 고정된 크기만큼 보낸다.

ex) 하드드라이브

 

n: n for network: ???

 

Q: 하드드라이브가 일정한 크기(블록으)로 조각나 있는 이유?

반응형
Posted by newind2000
Busan IT/ARM Controller2015. 10. 16. 12:48

==================================Outline====================================

Advanced-control timers(TIM1&8)

----------------------------------------------------------------------------

 

Advanced-control timers(TIM1&8)

 

RM0008 p/292

 

//PWM은 인터럽트가 아니라 단순 비교 출력이다.

 

타이머/카운터와 인터럽트는 분리하여 설명할 수 없다.

 

타이머/카운터와 PWM의 공통점

- 타이머/카운터를 사용한다

- 클럭의 속도에 따라 결과 값이 바뀐다.



Timer의 모드는 아래와 같다. 

1. Base Mode

2. Counter Mode

- up count

- down count

- center-aligned

...











 

 

반응형

'Busan IT > ARM Controller' 카테고리의 다른 글

Timer를 활용한 LED제어, LCD 제어  (0) 2015.10.20
Timer  (0) 2015.10.19
인터럽트 코드 분석  (0) 2015.10.13
Interrupt  (0) 2015.10.12
ARM Clock 설정  (0) 2015.10.12
Posted by newind2000
Busan IT/로봇제어2015. 10. 15. 17:36

커널이 있는 폴더가 linux이다.

 

MODULE_LICENSE("GPL")

 

커널 사용을 위해 GPL 규약을 승인한다는 뜻이다.

 

라즈베리파이로 프로그래밍을 하는 방법은 2가지이다.

 

1. 라이브러리를 사용

2. 디바이스 커널을 사용






 

Line. 6 : $(shell uname -r)

쉘 창에서 'uname -r' 값을 가져오는 것이다.

Line. 11: *.ko

커널 오브젝트라는 뜻이다.

 

//makefile 생성시 m은 대문자이다.

 

반응형
Posted by newind2000
Busan IT/Assembly2015. 10. 15. 16:46

[smart.c]
#include <stdio.h>

#define CMD_SIZE 20

typedef struct
{
  unsigned int efl;
  unsigned int eip;
  unsigned int edi;
  unsigned int esi;
  unsigned int ebp;
  unsigned int esp;
  unsigned int ebx;
  unsigned int edx;  
  unsigned int ecx;  
  unsigned int eax;
  
}context;

typedef struct
{
  char * cpCmd;
  void (*fp)();  
}comm;

static context stOld_state;
extern void stst(context *);
extern void ldst(context *);
void print_r();
void print_help();
comm stCmd_Map[] ={  //메세지 맵 기법
         {
        "R", print_r
         },
      {
        "H", print_help
      },      
         {
        00
         }        
      };

int main(void)
{
  char cInput[CMD_SIZE];
  comm * stpCmd;
  int iRet;  

  stst(&stOld_state);  
  printf("Moniter Program Start\n");
  while(1)
  {
    putchar('>');    
    iRet = read(0, cInput, CMD_SIZE);
    if(iRet < 2)
    {
      continue;  
    }  
      
    cInput[iRet-1= 0;
    
    stpCmd = stCmd_Map;
    while(0 != (stpCmd->fp))
    {
      if(0 == strcmp(strupr(cInput), stpCmd->cpCmd))
      {
        break;
      }      
      ++stpCmd;
    }
    if(0!= (stpCmd->fp))
    {
      ((stpCmd->fp)());      
      
    }
    else
    {
      print_help();
    }    
  }
  return 0;
}

void print_r()
{
  printf("main    : %08X\n", main);
  printf("stOld_state: %08X\n"&stOld_state);
  printf("EAX = %08X  EBX = %08X\nECX = %08X  EDX = %08X\nESI = %08X  EDI = %08X\nEBP = %08X  ESP = %08X\nEIP = %08X  EFL = %08X\n\n",stOld_state.eax, stOld_state.ebx, stOld_state.ecx, stOld_state.edx, stOld_state.esi, stOld_state.edi, stOld_state.ebp, stOld_state.esp, stOld_state.eip, stOld_state.efl);

}

void print_help()
{
  printf("Memory Debugging Prompt\n\n");
  printf("R: Print Register Info.\n");
  printf("H: Print Command List.\n");

    
}

[main.asm]

.386

.MODEL FLAT

PUBLIC _stst
PUBLIC _ldst    ; '_stst''_ldst'함수 외부 접근 허용 코드

.code

_start:  

_stst   PROC   NEAR32  ;store status

    ; - entry code -
    push  ebp    
    mov   ebp, esp

    pushfd
    mov esp, [ebp+8]  ;esp obj로 이동
    add esp, 40    ;esp obj 가장 아래로 이동

    pushad      ;eip와 efl을 제외한 모든 레지스터 구조체에 삽입
    push [ebp+4] ; eip삽입
    push [ebp-4] ; eflags삽입
    add esp, 20  ; 구조체의 esp자리로 내려온다.

    mov eax, ebp ; main의 esp를 구조체의 넣기 위해 레지스터 eax를 사용한다.
    add eax, 8   ; eax를 main의 esp가 있는 자리로 옮겨준다.
     ;12가 아닌 8인 이유는 esp는 마지막 변수를 가리키고 있기 때문이다.
    mov [esp], eax ; 구조체 esp에 main의 esp를 넣어준다.
    push [ebp]     ; 구조체 ebp자리에 main의 ebp를 넣어준다.

    
    ;mov eax, [esp+20] eax에는 return값이 들어감으로 복구시킬 필요가 없다.


    ; - exit code -
    mov  esp, ebp
    pop  ebp
    ret ;pop eip
    
    ;메인 함수에서의 복구
    ;add esp, 4 ;함수의 인자 자리를(&obj) 복구 시키기 위해 esp 사용한 인자의 크기만큼 옮긴다.

  
  _stst ENDP

  _ldst   PROC   NEAR32  ;
      
    ;mov esp, [esp+4]  ;esp를 구조체로 이동
    ;popfd    ;구조체 efl값을 레지스터 efl로 이동
    ;pop eax    ;eax값에 구조체 eip값을 이동
    ;mov ebx, esp  ;현재 esp값(구조체에 edi를 가리킨다)을 백업
    ;mov esp, [esp+12]  ;구조체 esp값을 esp에 저장한다.
    ;push eax    ;구조체eip값을 구조체 esp에 저장
    ;mov esp, ebx  ;esp를 구조체에 edi를 가리키는 값으로 이동시킨다.
    ;popad    ;스택에 있는 내용을 레지스터에 채운다.
    ;mov esp, [esp-20]  ;esp를 구조체 esp가 가리키는 곳으로 이동시킨다.
    ;sub esp, 4    ;esp - 4

    mov esp, [esp+4]
    popfd
    pop eax
    mov ebx, [esp+12]
    mov [ebx-4], eax
    popad
    mov esp, [esp-20]
    sub esp, 4


    ret ;pop eip

  _ldst ENDP


반응형
Posted by newind2000