[개발 일지] SNET ECAT Configurator 2

타키탸키·2023년 1월 16일
0

개발 일지

목록 보기
10/11

01.02

  • ScanRoutine method 로직 추가
    • Node Count만큼 Node를 가져와서 내부 struct 타입으로 변환
  • NodeInfo struct에 tag 추가
  • EtherCAT 관련 struct 필드의 타입 변환
    • int에서 uint32
    • 0에서 4294967295 사이의 값을 가진 부호 없는 정수
    • Runtime data의 type 따르기
    • 추후 실험 필요

01.04

  • getter 함수의 리턴을 두 개로 변경
    • call by reference로 값을 가져오는 대신 함수의 리턴으로 받도록 변경
      • Golang의 함수는 두 개의 리턴을 가질 수 있으므로 포인터 타입으로 받을 필요가 없다
      • 리턴으로 받는 것이 좀 더 직관적이며 출력값으로서의 의미를 더 잘 살릴 수 있다
  • 상수의 시작 수 변경
    • Golang에서는 열거형(enum)을 지원하지 않으므로 iota와 상수로 우회해서 구현해야 한다
    • 통상 첫번째 수는 nil을 의미하므로 실제로 사용할 상수는 1부터 시작해야 한다
  • byte order 변경
    • byte로 받아온 Node 정보를 Go 데이터 구조로 받기 위해 binary.Read() 메서드 사용
    • 파라미터로 byte order 방식을 받는다
    • Big Endian에서 Little Endian으로 변경
      • 인텔 CPU 계열이므로 Little Endian이 적합하다
  • ScanRoutine method 로직 추가

01.12

  • Runtime Update
    • Scan 기능 추가
      • scan을 위한 router 추가
  • scan 오류 해결
    • scan 요청이 Runtime에 전달되지 않는 문제
      • scan 명령어를 위한 메시지의 오타가 원인
    • Runtime 데이터를 저장할 struct의 타입 변경
      • call by reference 개념 다시 숙지 할 것
      • 함수의 파라미터가 포인터(*)일 때, 변수의 주소(&)를 넘긴다
      • 함수 밖에서는 포인터가 아닌 일반 변수를 선언하고 그 주소를 넘겨야 한다
// swap 함수 예시
func main() {
	x := 3
	y := 4
	
    swap(&x, &y)
    
	fmt.Println(x, y) // 4 3
}

func swap(a, b *int) {
	temp := *a
	*a = *b
	*b = temp
}
  • scan 요청 후 sleep 추가
    • sleep time 10ms로 설정
  • redis로부터 데이터를 가져오는 함수를 redis.Strings로 변경
    • 기존에는 응답 배열을 slice로 변환하는 redis.Values 사용
      • 타입이 다른 데이터를 가져올 수 있다
      • ScanStruct 함수를 사용하여 tag에 따라 struct에 자동으로 할당한다
    • 테스트 편의를 위해 string slice로 받아올 수 있는 redis.Strings 채택
      • 일단 type을 구분하지 않고 string으로 가져온 다음 형 변환
      • 동적 크기를 가진 Node 필드를 유연하게 가져오기 위한 방법

01.13

  • ReadNode method의 파라미터 타입 변경
    • 기존에는 NodeInfo struct를 파라미터로 설정
    • Runtime으로부터 전송된 데이터가 정해진 순서가 아닌 다른 순서로 값이 넘어오는 문제 발생
      • 내부적으로 탐색 속도를 높이기 위해 자동으로 순서를 변경하는 것으로 추측 됨
      • 순서에 영향을 받지 않는 map 타입 채택
      • map은 key로 value에 접근하므로 순서에 영향을 받지 않는다
    • 테스트를 위해 임시로 ReadNode method에만 적용
      • 검증이 완료되어 Read method에도 적용 예정

01.16

  • Read 함수 리팩토링
    • data를 call by reference가 아닌 리턴으로 넘김
      • 리턴으로 넘기는 것이 더 직관적
      • 인자는 적을수록 좋다
    • data 타입 변경
      • 특정 struct type에서 map으로 변경
      • key에 따라 접근하므로 순서에 구애받지 않을 수 있다
    • Read 함수의 역할을 하나로 재정의
      • Read 함수의 역할은 오직 DB로부터 data를 꺼내오는 것
      • 특정 key에 대한 처리는 상위 레이어에서 처리하도록 재설계
    • ReadNode 함수 제거 후 Read 함수로 대체
  • rtconn 패키지 이름 변경
    • 더 직관적이고 포괄적인 runtime으로 변경
  • device 패키지 생성
    • 제어기와 연결하는 device connection과 런타임과 연결하는 runtime connection 분리
  • RuntimeConnection struct에 SendRead 함수 추가
    • 기존에는 connect 함수가 제어기 및 런타임 연결을 모두 담당
    • 두 역할이 분리됨에 따라 각각의 wrapping 함수의 필요성 대두

01.17

객체 다이어그램

  • DeviceConnection struct 에 Initalize 함수 추가
    • 기존에는 DeviceConnection struct의 각 method마다 RuntimeConnection 객체를 생성하고 초기화하는 함수가 중복되어 들어가 있었다
    • 중복을 피하고자 공통 처리를 하는 Initialize 함수가 필요했다
    • 이 함수도 각 메서드마다 계속해서 반복되므로 중복을 줄일 다른 방안을 더 검토해야겠다
  • main에서 RuntimeConnection 관련 코드 제거
    • 위 객체 다이어그램에 따라 main이 의존하는 객체는 device에 한정 짓기 위해 관련 없는 runtime 객체 관련 코드를 제거했다
  • enum을 대체하는 const 필드 갱신
    • struct 네이밍과 구분하기 위해 const 이름에 Type을 붙임
    • 숫자로 하드코딩 되어 있던 부분을 const 필드명으로 대체
      • int로 정의했던 함수 파라미터로 const 이름으로 대체

01.19

  • EcatEsi struct 추가
    • 실제 esi 파일을 처리하기 위한 로직을 가진 struct
    • esi 파일의 요소들을 go sturct에 매핑한 EtherCATInfo들의 목록을 관리한다

01.20

  • scan 함수 로직 구현
    • EcatManager struct에 Initalize 메서드 추가
      • map은 선언 시, nil로 초기화되므로 make를 통해 필요한 공간을 할당 받아야 한다
      • map 관련 멤버(nodes, devices) 초기화
      • EcatEsi struct 사용을 위한 EcatEsi의 Initialize 메서드 호출
      • main 함수에서 Scan 시작 전 호출
    • 동적인 Node 멤버에 접근하기 위해 key 이름 파싱 작업
      • for문을 통해 count만큼 index를 차례대로 문자열로 변환 후, "Node" 문자열과 concat
      • 만들어진 key를 통해 nodes(map)의 Node들을 순서대로 접근 가능
    • 가져온 node data(bytes code)를 EcatNode(struct)로 치환
      • unsafe.Pointer() 문법 활용
      • 값이 제대로 복사되지 않으므로 재검토 필요
    • SetInfo() 메서드로 사용자 편집의 경우의 수를 모두 고려한 임시 데이터 저장
  • EcatAxisList struct 추가
    • 설계를 기반으로 임시 method 추가(구조 잡아두기)
    • 로직 구현은 설 연휴 이후 진행할 것
profile
There's Only One Thing To Do: Learn All We Can

0개의 댓글