01.02
ScanRoutine
method 로직 추가
- Node Count만큼 Node를 가져와서 내부 struct 타입으로 변환
- 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이 적합하다
01.12
- scan 오류 해결
- scan 요청이 Runtime에 전달되지 않는 문제
- Runtime 데이터를 저장할 struct의 타입 변경
- call by reference 개념 다시 숙지 할 것
- 함수의 파라미터가 포인터(
*
)일 때, 변수의 주소(&
)를 넘긴다
- 함수 밖에서는 포인터가 아닌 일반 변수를 선언하고 그 주소를 넘겨야 한다
func main() {
x := 3
y := 4
swap(&x, &y)
fmt.Println(x, y)
}
func swap(a, b *int) {
temp := *a
*a = *b
*b = temp
}
- 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에 Send
와 Read
함수 추가
- 기존에는 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 추가(구조 잡아두기)
- 로직 구현은 설 연휴 이후 진행할 것