메일: https://mail.worksmobile.com

주소록: https://contact.worksmobile.com

 

LINE WORKS를 이용하기 위한 접속 URL이 어떻게 되나요?

LINE WORKS 브랜드사이트 우측상단의 ‘My 서비스’를 클릭하면  로그인을 거쳐 Lite 상품 이용자는 홈 서비스로, Basic 또는 Premium 상품 이용자는 메일 서비스로 접속할 수 있습니다.

그 외 이용 중인 상품에 따라 아래의 각 서비스 페이지로 로그인해서 직접 접속할 수 있습니다.

Lite 상품

Basic 또는 Premium 상품

 

help.worksmobile.com/kr/topic/common/support-environment/urls-to-access-line-works/

 

LINE WORKS를 이용하기 위한 접속 URL이 어떻게 되나요? – 주제별 질문 – LINE WORKS 헬프센터

LINE WORKS 브랜드사이트 우측상단의 ‘My 서비스’를 클릭하면  로그인을 거쳐 Lite 상품 이용자는 홈 서비스로, Basic 또는 Premium 상품 이용자는 메일 서비스로 접속할 수 있습니다. 그 외 이용 중인

help.worksmobile.com

참... 오래 간다. 이 버그 ㅠㅠ 그냥 포스팅 해 두는게 낫겠다.

'블로그 항해 일지 > Tips' 카테고리의 다른 글

어제 오늘 방문자 수  (0) 2019.02.08
powergrep exclude  (0) 2019.01.22
포스트맨 정말 좋다.  (0) 2019.01.11
github에서 repo 미리 만들고 커맨드로 머지하기  (0) 2019.01.07
파이썬 관련 주요 인물  (0) 2019.01.06

26일 KBS 로 간다. 처음 가는 거라서 가는 방법을 기록해 두려고 일단 페이지를 만들었다. 추 후 수정 예정.




그 때는 안철수를 존경했었다.


블로그의 내 정치 성향도 바뀐다.

구글에 정리가 잘 되어있다.

'블로그 항해 일지' 카테고리의 다른 글

KBS 가는 방법  (0) 2019.03.19
운영했던 사이트  (0) 2019.03.18
내 블로그 내 사람들의 최대 관심사는 현실적 이야기  (0) 2019.03.18


다들 현실적 이야기에 관심이 많구나. 역시나.

'블로그 항해 일지' 카테고리의 다른 글

KBS 가는 방법  (0) 2019.03.19
운영했던 사이트  (0) 2019.03.18
블로그 방향 정할 떄 도움되는 카테고리 목록  (0) 2019.03.18

<!-- 방문자수 -->

<div class="section">

<div class="tx">

<p class="today">today : </p>

<p class="yesterday">yesterday : </p>

</div>

</div>

today :

yesterday :

SRSExample-webapp (1).doc


'블로그 항해 일지 > !F. Software Engineering' 카테고리의 다른 글

Performance requirements  (0) 2019.01.27
External Interface Requirements  (0) 2019.01.27
USE CASE의 중요성  (0) 2019.01.27

IoT 디바이스를 만든다고 하면 사실 S/W 부분보다 H/W 성능이 조건이 더 중요할 것이다. 또, RESTAPI도 많이 이용되므로 서버 성능도 함께 고려해야 한다.


얼마나 많은 트렉젝션(소켓통신, 패킷단위, DB CRUD, ...)을 감당할 수 있는지 해당 부분에 대한 포괄적인 사용 기준을 정해서 일반 사용자는 이러이러한 만큼 쓸 것이다. 그런 사용자를 얼마만큼 포용할 수 있는가 등... 


성능 조건은 스스로를 옥죄는 항목이 될 수도 있기 때문에 최대한 루즈하게 적어야 한다. 그러나 사람 목숨과 관련된 부분이라면 루즈한 성능 조건 정의가 되려 설득력을 잃을 수도 있기 때문에 성능 요구사항은 정말 각 실무자들이 최대한 협업해서 적어야 하는 항목일 수 밖에 없다. 기업간의 하청에도 늘 꼬투리를 잡거나 잡힐 수 있는 부분이니 이 부분 관련해서 우선 대화를 많이 해야 한다. 술자리도 좋다.




If there are performance requirements for the product under various circumstances, state them here and explain their rationale, to help the developers understand the intent and make suitable design choices.

Specify the timing relationships for real time systems.

Make such requirements as specific as possible. You may need to state performance requirements for individual functional requirements or features here or Functional Requirements section.

 

Specify both the static and the dynamic numerical requirements placed on the software or on human interaction with the software, as a whole. 

Static numerical requirements may include:

      (a)  The number of terminals to be supported

      (b)  The number of simultaneous users to be supported

      (c)  Amount and type of information to be handled

Static numerical requirements are sometimes identified under a separate section entitled capacity.

 

Dynamic numerical requirements may include, for example, the numbers of transactions and tasks and the amount of data to be processed within certain time periods for both normal and peak workload conditions.

All of these requirements should be stated in measurable terms.

For example,

95% of the transactions shall be processed in less than 1 second

rather than,

An operator shall not have to wait for the transaction to complete.

(Note: Numerical limits applied to one specific function are normally specified as part of the processing subparagraph description of that function.)



   Throughput (작업처리량) , Concurrent Session (동시 세션), Response Time (대응시간),  Performance Dependency (성능 종속 관계), Other Performance Requirements (기타 성능 요구사항)

'블로그 항해 일지 > !F. Software Engineering' 카테고리의 다른 글

[SRS Sample] Web Publishing System  (0) 2019.01.28
External Interface Requirements  (0) 2019.01.27
USE CASE의 중요성  (0) 2019.01.27

         External Interface Requirements (외부 인터페이스 요구사항)


여기에는 System Interface, User Interface, Hardware/Software Interface, Communication Interface, 기타 인터페이스가 포함되어야 하고 시스템 자체는 그룹화해서 표현해야 한다. 이것은 회사마다 양식이 다른데 꼭 SRS 포멧에 맞출 필요가 없다. 해당 문서를 첨부하고 첨부한 문서에 번호를 붙여(SRS-시스템이름-001) 따로 문서를 만들었다고 기입하면 된다. 그것이 power pointer 일 수도 있고 word 문서일 수도 있겠다. 모바일인 경우 User Interface는 simpli나 zeplin 일수도 있다. 기업간의 경우 주소로 대체해도 되겠으나 FDA 승인의 경우 printable 한 문서 형태여야 한다는 것이 주의점이다. 이것도 시대가 바뀌면 계속 바뀌겠지. User Case로 그린 후 첨부할 때는 동그라미(사용 사례, Use Case) 들이 사각형(시스템)안에 들어가도록 배치하고 <<시스템>> 혹은 <<하위시스템>>으로 명시한 후 아래 이름을 적어주면 된다.


졸라맨, 동그라미, 사각형, 화살표만 있는데 나름 규칙이 있으니 우선 따르고 본인이 고객을 상대하면서 변화되는 것을 반영하면 되겠다. 식약처든 FDA던 결국 요구사항에 대한 acceptance test에 대한 논의는 모두 이해 관계자들이 하게 되니까 너무 형식에 구애 받을 필요는 없다. 그러나 형식이 있는 이유는 혹시라도 생각하지 못했던 것에 대한 확인이니 되도록이면 따르는게 좋다.

 



 

If the product is independent and totally self-contained, it should be so stated here.  If the SRS defines a product that is a component of a larger system, as frequently occurs, then this subsection relates the requirements of the larger system to functionality of the software and identifies interfaces between that system and the software. 

 

A block diagram showing the major components of the larger system, interconnections, and external interfaces can be helpful.  This is not a design or architecture picture.  It is more to provide context, especially if your system will interact with external actors.  The system you are building should be shown as a black box.  Let the design document present the internals.

 

This contains a detailed description of all inputs into and outputs from the software system.

 

It contains both content and format as follows:

 

·          Name of item

·          Description of purpose

·          Source of input or destination of output

·          Valid range, accuracy and/or tolerance

·          Units of measure

·          Timing

·          Relationships to other inputs/outputs

·          Screen formats/organization

·          Window formats/organization

·          Data formats

·          Command formats

·          End messages

 

If the external interfaces are complicated , you may write a separate Interface Requirement Specification document for all or any of the following interfaces.




'블로그 항해 일지 > !F. Software Engineering' 카테고리의 다른 글

[SRS Sample] Web Publishing System  (0) 2019.01.28
Performance requirements  (0) 2019.01.27
USE CASE의 중요성  (0) 2019.01.27

난 UML을 그릴 때 visio 나 visual studio 2015 enterprise 버전을 이용한다. Xcode에는 없는 기능이다.


https://channel9.msdn.com/Series/Visual-Studio-2012-Premium-and-Ultimate-Overview-KOR/Visual-Studio-Ultimate-2012-Improving-architecture-through-modeling-KOR


이런 동영상이 있긴 하지만 사실 UML은 많이 보고 또 많이 그려보는 수 밖에 답이 없다. 그리고 USE CASE의 모든 규칙을 지킬 필요도 없다.


USECASE는 requirements analysis 단계에서 작성하는 것이고 그것은 고객과의 의사 소통을 돕기 위해 만드는 것이지 내가 아는 지식을 자랑하려고 하는 것은 아니기 때문이다. 그리고 대부분의 고객은 돈이 많은 정도와 알고 있는 IT 지식이 반비례 하는 경우가 많다. 내가 하청을 받을 때는 몰랐는데 직접 고객을 만나 대응하는 경우 우 수백억의 자산가들은 IT에 대해서 전혀 모른다. 


보통은 use case를 그리지도 않고 구두로 설명하거나 해당 기술을 설명할 때 기껏 써봐야 sequence diagram, 개발자를 데리고 나온 경우 class diagram 정도였다. 그 중에서 나이 드신 분들도 좋아하는 것은 졸라맨(Actor)이 있는 use case 이다. 졸라맨과 벤다이어그램 하나면 시스템 전체를 설명할 수 있으니 정말 좋다.

그리고 같은 시스템이라도 다양한 관점에서 표현하고 구두로 설명하다보면 고객은 이해를 하고 IT 문외한인 자신도 이해하는 쉽고 자세한 설명을 할 수 있는 사람을 고수로 본다. 돈이 많은 데에는 이유가 있고, 대부분의 IT 기업 사장들이 그러하듯, 돈만 많고 IT는 전혀 몰라... 하는 식으로 접근하면 제대로 된 일을 따기란 불가능 하다고 생각하면 된다. 예전엔 먹혔지만 요즈음엔 다들 영악해서 일을 따더라도 헐값에 처리하거나 갑자기 다른 업체로 넘어가기도 한다.


쉽게 표현해 보자.



이런 경우 use case는 requirements 단계에서 작성하는 것이 아니게 된다.


어려운 용어는 SDS 단계에서 고려하는 것이 맞다. 그리고 졸라맨(Actor)이 "어라? 저게 뭐지 하면 안된다.


다시 그리면 다음과 같다. Visual Studio 2015 Enterprise 버전에서 그렸다.


액터에 이름을 따로 붙이지 않더라도 그냥 사람으로 생각이 될 것이고(그림부터가 사람)

사람 1과 2가 상호 작용을 할 수 있는데 사람 1, 2는 대부분 같은 기능을 공유한다.


사람1의 경우 메세지를 공유할 수 있지만 사람2는 메세지를 공유 할 수 없다는 것도 알 수 있다.


똑같은 기능이라도 여러번 그릴 수 있다. 목적은 내가 잘 그리느냐 못 그리느냐는 것이 아니라 사용자의 IT 지식 수준을 맞추고 이해시키는 것이 주된 목적이다.


그래서 요구사항 정의 단계에서 가장 먼저 선행되는 것은 용어의 정의, 용어의 명확화, 커뮤니케이션 할 때 빈번하게 나올 법한 


최소 개체에 대한 학습과 same page에 있기 위한 훈련이다.


사실 개발 전단계의 워크샵이 이런 것을 논의하기 위해 가는 것인데 뭐, ... 대부분 술먹고 놀자하고 끝나버린다.





'블로그 항해 일지 > !F. Software Engineering' 카테고리의 다른 글

[SRS Sample] Web Publishing System  (0) 2019.01.28
Performance requirements  (0) 2019.01.27
External Interface Requirements  (0) 2019.01.27

*.bin;*.bmp;*.buildinfo;*.bz2;*.cnf;*.conf;*.conv;*.csm;*.cs??s;*.csv;*.da;*.dat;*??.de;*.dic;*.dist;*.d??octree;*.dtd;*.en;*.??ent;*.eot;*.err;*.es??;*.euc-kr;*.exp;*.fi??le;*.fr;*.frm;*.gif;??*.gitignore;*.gz;*.h??;*.hhvm;*.htaccess;*??.html;*.icc;*.ico;*.??inc;*.ini;*.ini-deve??lopment;*.ini-produc??tion;*.inv;*.jpg;*.j??s;*.jshintrc;??*.koi8-;*.lang;*.lib??;*.log;*.map;*.md;*.??mediawiki;*.mo;*.myd??;*.myi;*.new;*.nocov??erage;*.ods;*.opt;*.??pdb;*.phar;*.php;*.p??html;*.pickle;*.pid;??*.pl;*.png;*.propert??ies;*.pt-br;*.py;*.r??st;*.sh;*.so;*.sql;*??.sty;*.svg;*.sys;*.t??pl;*.trg;*.trn;*.ttf??;*.txt;*.types;*.utf??8;*.var;*.woff;*.exe;*.obj;*.dll




json 은 제외했다.



상위 패널(상위 클래스)에서 골격을 만들고

  var dataLayer : CALayer = CALayer(layer: 0)


    func drawAdata(_ index : Int) {

    }


 override func drawAdata(_ index : Int) {


골격구현


    override func drawAdata(_ index : Int) {

        if GS.s.logLevel.contains(.graphPanel) { debugPrint("index \(index)") }

        

        dataLayer.removeFromSuperlayer()

        dataLayer = jhType1graphLayer<T>(self, 0, maxY, index)

        dataLayer.frame = CGRect(x: GS.s.jhLMarginX, y: GS.s.jhLMarginY, width: self.bounds.width - GS.s.jhLMarginX, height: self.bounds.height - GS.s.jhLMarginY)

        dataLayer.zPosition=1

        self.layer.addSublayer(dataLayer)

        dataLayer.setNeedsDisplay()

        jhDataCenter.attachObserver(observer: self)

    }


데이터 센터는 그래프 드로잉에 필요한 데이터를 저장하는 공간이다. 해당 공간에 옵저버 패턴으로 구현된 브로드 캐스팅 시스템이 있다. - redraw를 위해.


원리는 간단하다. 본래 그렸던 레이어를 지우면서 계속해서 새로 그리는 것이다. 포토샵 할 때 레이어를 여러장 얹는 것과 같다. hightlight 되는 그래프나 점 같은 것을 그 위에 덮는 것.



그런, 크롬 플러그인 때가 더 그립긴 하다.


구글에서 하나 만들어서 넣어줘도 좋을 듯.


'블로그 항해 일지 > Tips' 카테고리의 다른 글

어제 오늘 방문자 수  (0) 2019.02.08
powergrep exclude  (0) 2019.01.22
github에서 repo 미리 만들고 커맨드로 머지하기  (0) 2019.01.07
파이썬 관련 주요 인물  (0) 2019.01.06
Android 개발자 iOS전환 - 2  (0) 2019.01.03

최근 수업 과정에서 오드로이드와 라즈베리 파이의 GPIO로 소프트웨어 PWM, RS-232를 구현하고 있다. 물론, 하드웨어의 PWM을 이용하는 것보다는 깨끗한 파형을 내기 힘들다. 그러나 오실레이터나 크리스탈, 혹은 CPU Clock을 SW로 나누고 그것을 이용해 모터를 제어 하거나 관련 프로토콜을 SW로 구현하는 것은 꽤 괜찮은 수업 방식이라고 생각되어 진행하게 되었다.


결론은 잘 된다는 것. <- 이게 젤 중요하지


그러나 구현 과정에서 학생들이 보드를 많이 태웠는데 그 이유는 다음과 같았다.


1. 전원 연결이 중간에 끊겨 GPIO의 전류가 역방향으로 흐르게 하였다. 전원 껐다 켰다 하며...

2. 장치 연결 시 풀다운 저항이나 캐패시터를 이용하지 않았다.

3. 데스크톱과 직접 연결 시 전압 체크를 하지 않았다.

4. 주변 장치 연결 시 전원이 켜진 상태로 연결하였다.(GPIO, 화면 출력을 위한 HDMI 포트 等)


그리하여 작년 수업 과정과 합해서 총, 15대의 보드가 고장 났다. 물론, 1달 내내 수많은 과제를 하는데, 관련 과제가 많아 보드를 혹사시키는 것도 문제다. 실습 장비가 없으면 안되기에 미리, 어느 정도 귀띔은 해준다. 따라서 고의적으로 보드를 태우게 한 것은 아니다. 다만, 전자공학과 및 컴퓨터 공학 대학원까지 졸업하거나 전자공학과 4학년을 졸업한 친구들도 있기에 실무는 다르다는 것을 말해주고 싶은 마음이 있는 것은 사실이다. 간단히 말하면 보드를 태운 경험은 정말 소중하다는 것. 고의는 아니지만, 그에 따르는 수리나 추가 구입 비용에 대한 질타는 내 몫이다.


실무경험으로 한 가지 확실한 것은 GPIO를 이용한 프로젝트 진행 時 오드로이드에 반해 라즈베리 파이는 쇼트가 잘 나지 않는다는 것. 두 보드 모두 장/단점이 있고 이용 목적에 따라 다르다. 다만, 앞으로는 교육 비용 문제로 격이 더 저렴한 라즈베리파이를 이용하게 될 것 같다. 사실, 커뮤니티가 잘 안 되어 있는 보드를 찾아서 작년 1달 교육을 진행했는데,... 이제는 위키가 너무 잘 되어 있는 것도 하나의 이유.


소스는 github에 GPL 3.0으로 공개하고 모두 함께 작업하기로 하였다.


소스를 바로 보는 것은 실력 향상에 도움이 되지 않으니, 다음과 같은 과정을 거쳐 공부하길 바란다.


1. 오실로스코프로 UART 단자의 신호를 분석한다.

2. 하드웨어/소프트웨어 플로우 컨트롤 및 패리티 비트를 빼고 10비트가 나오는지 확인한다.

3. 시작 비트는 0 이 되는 순간이다.

4. 같은 신호를 GPIO와 delay 함수를 이용하여 구현한다.

5. usleep은 문제가 있어서 다른 함수(nanosleep)를 찾게 되고, 그것도 여의치 않아서 시간 계산을 따로 하는 함수를 찾게 된다.

6. 구현된 신호로 GPIO를 이용하여 UART Tx를 만든다.

7. 한 문자만 보내는 것을 여러 문자가 보내 지도록 함수를 만든다.

8. Rx도 같은 방법으로 구현한다. 다만, 같은 GPIO로 연결하면 둘 다 HIGH 상태이기 때문에 [처리]가 필요.

9. Tx, Rx 모두 구현하기 때문에 자신만의 신호를 만들 수 있다.

10. 완성형 한글 지원부터 유니코드 지원까지 customized UART protocol을 만들어 본다.

11. RS-232, 422, 485 까지 비교해 본다.


이런 과정을 거치면 같은 시리얼 통신인 CAN, I2C, SPI, I2S, CAN, USB 등을 한 번에 이해할 수 있게 된다. 일이관지(一以貫之, 하나의 이치로 모든 것을 꿰뚫는다). 인터넷을 돌아다니다 보면 UART, SPI, I2C 잘못 비교된 글이 많더라. UART 자체적으로 RS-232, 422, 423, 485 에 따라 속도나 전송거리, full/half duplex로 나뉘는데 그걸 마치 UART와 SPI, I2C의 차이로 적은 자료가 많았다. 주의! 주의!


'블로그 항해 일지 > Embedded' 카테고리의 다른 글

x86용 부트코드  (0) 2019.01.08
ODROID GPS 모듈 입양 完  (2) 2019.01.08
GPIO 제어 via 블루투스 on 삼성폰  (0) 2019.01.08
블루투스 연결  (0) 2019.01.08
GPIO 컨트롤  (0) 2019.01.08

부트코드를 이해하기 위해 USB에 부트코드를 만들고 USB로 부팅하는 방법을 소개한다. BIOS에서 부팅 순서는 변경 시킬 수 있고, 컴파일러의 역할을 알고 있는 사람이라면 쉽게 할 수 있겠다.


http://www.yes24.com/24/Goods/1469757?Acode=101

rawwrite를 찾을 수가 없어 dd 윈도우즈 버전으로 대체하여 실행하였다. 하드 지우긴 그래서 USB로 부팅하였다. USB 중 SANDISK는 안된다. 내부적으로 보안 영역이 따로 있어 이미지를 0번지부터 써도 0번지부터 기록되지 않는 듯하다. 윈도우용 부트로더를 먼저 이해하고 u-boot와 리눅스 커널을 보면 한결 쉽다.


[org 0]

[bits 16]

jmp 0x07C0:start    ;far jmp 를 한다.

start:

mov ax, cs    ;cs 에는 0x07C0 이 들어 있다.

mov ds, ax     ;ds 를 cs 와 같게 해준다.

        mov ax, 0xB800    ;비디오 메모리의 세그먼트를

mov es, ax    ;es 레지스터에 넣는다.

mov di, 0;제일 윗 줄의 처음에 쓸 것이다.

mov ax, word [msgBack] ;써야 할 데이터의 주소값을 지정한다. 

mov cx, 0x7FF       ;화면 전체에 쓰기 위해서는 

    ;0x7FF(10진수 2047)개의 WORD 가 필요하다.

paint:

mov word [es:di], ax;비디오 메모리에 쓴다.

add di,2;한 WORD를 썼으므로, 2를 더한다.

dec cx    ;한 WORD를 썼으므로, CX 의 값을 하나 줄인다.

jnz paint   ;CX 가 0이 아니면, paint로 점프하여

   ;나머지를 더 쓴다.

mov edi, 0;제일 윗 줄의 처음에 쓸 것이다.

mov byte [es:edi], 'A'  ;비디오 메모리에 쓴다.

inc edi;한 개의 BYTE를 썼으므로 1을 더한다.

mov byte [es:edi], 0x06 ;배경색을 쓴다.

inc edi;한 개의 BYTE를 썼으므로 1을 더한다.

mov byte [es:edi], 'B'

inc edi

mov byte [es:edi], 0x06

inc edi

mov byte [es:edi], 'C'

inc edi

mov byte [es:edi], 0x06

inc edi

mov byte [es:edi], '1'

inc edi

mov byte [es:edi], 0x06

inc edi

mov byte [es:edi], '2'

inc edi

mov byte [es:edi], 0x06

inc edi

mov byte [es:edi], '3'

inc edi

mov byte [es:edi], 0x06

jmp $;이 번지에서 무한루프를 돈다.

msgBack db '.', 0xE7;배경색으로 사용할 데이터

times 510-($-$$) db 0;여기서 부터, 509 번지까지 0 으로 채운다.

 dw 0xAA55;510 번지에 0xAA 를, 511 번지에 0x55 를 넣어 둔다.



updated at 20180722

다시 커널 책을 펴다 -> 현제 제목으로 변경 후 매거진 변경(Linux Master)

정상동작 확인(역시 Sandisk에서는 안되니 다른 USB 사용 요망)


nasm -Administrator 권한으로 설치 必

C:\NASM>nasm -f bin -o boot.bin boot.asm


USB 드라이브가 e라고 가정

C:\NASM>dd if=c:\nasm\boot.bin of=\\.\e: bs=512 count=1


NASM 2.13.01_64bit magnet

magnet:?xt=urn:btih:BDFF52A5C3CDD8604D4921CE75DD6D9D549D10BE&dn=nasm-2.13.01-installer-x64.exe&tr=udp%3a%2f%2ftracker.openbittorrent.com%3a80%2fannounce&tr=udp%3a%2f%2ftracker.opentrackr.org%3a1337%2fannounce


DD 0.4 beta magnet

magnet:?xt=urn:btih:2ACA21B101B83BBB83A663A90D7905A573A6EB81&dn=dd-0.4beta1.exe&tr=udp%3a%2f%2ftracker.openbittorrent.com%3a80%2fannounce&tr=udp%3a%2f%2ftracker.opentrackr.org%3a1337%2fannounce

'블로그 항해 일지 > Embedded' 카테고리의 다른 글

SW PWM, UART 구현  (0) 2019.01.11
ODROID GPS 모듈 입양 完  (2) 2019.01.08
GPIO 제어 via 블루투스 on 삼성폰  (0) 2019.01.08
블루투스 연결  (0) 2019.01.08
GPIO 컨트롤  (0) 2019.01.08

낙서 같은 거라서 ODROID 매거진이 아닌 ETC에 넣는다.


판다. 하드커널에서

설명서도 제공한다

https://wiki.odroid.com/accessory/connectivity/usb_gps

근데 설명서 업데이트를 해야할 것 같다. 제대로 안된다.


여하튼, 디바이스 드라이버가 잘 동작하고 관련 앱이 잘 도니

cgps는 


gpsmon은

근데 왜 값이 다를까 ㅡㅡ; 다른 플랫폼이라면 이해하겠는데 말이다 ㅠㅠ 

Latitude, Longitude는 정말 중요한데 말이다 ㅠㅠ


gps라 결국 모듈은 창문 밖으로 내어 놓아야 했다.


배움은 힘들다. 메뉴얼도 한번에 되는 것도 없다.

또 한, 계속 돈이 들어가고. 용어의 모호함도 많다. 


책도 그렇다.

서점을 가면, 프로그래밍 언어 관련 책은 외서 번역본이 많은 이유가 국내에서 뭔가를 제대로 정립해서 대가가 되어 이론을 만든 사람이 없다. 다 차용했다. 그래서 번역이 이상하게 된다.


프로그래밍 서적은 간단하다. 모든 것은 CPU와 메모리의 장난에서 출발하면 좋을 것 같다.

어려운 용어도 간단해진다.

선언 declaration : 변수의 저장 메모리 예약

정의 definition : 예약된 메모리에 데이터를 저장

초기화 initialization : 선언과 정의를 동시에


오늘도 기초 공부를 한다. 나이가 들고 경험이 쌓일수록 더더욱 기초만 공부하게 되는 것 같다.

integral - signed, unsigned, (struct, union, enum), (pointer, array, function) ...

'블로그 항해 일지 > Embedded' 카테고리의 다른 글

SW PWM, UART 구현  (0) 2019.01.11
x86용 부트코드  (0) 2019.01.08
GPIO 제어 via 블루투스 on 삼성폰  (0) 2019.01.08
블루투스 연결  (0) 2019.01.08
GPIO 컨트롤  (0) 2019.01.08

글자 수 ㅠㅠ 한글이 abbreviations 주말 엄마와 아이가 놀러 간 틈을 타, 


전등, 모터 등을 켜고 끌 때 블루투스를 이용하면 편리할 것 같고 이미 많은 사람들이 미리 만들어 놔서 오픈소스를 이용하여 금방 구현하였다. 3시간, 검색 및 오픈소스 검증 2시간, 수정 코딩 1시간. 


제목을 수정했는데 on 삼성폰이라고 ... Android 니 LG에서도 되겠지만 안해봤으니 그렇게 안 적으련다.


0 결과

https://www.youtube.com/watch?v=AuZUqi0V7qc


1 소스

http://webnautes.tistory.com/1137

https://github.com/OmarAflak/Bluetooth-Terminal

* 참조

http://ippuu.iptime.org/entry/Linux-Device-Driver-XU3XU4-GPIO-Timer-%EB%B0%8F-IOCTL-%EC%A0%81%EC%9A%A9-%EC%A0%9C%EC%96%B4

http://ippuu.iptime.org/entry/Device-DriverXU3XU4-GPIO-%EC%A0%9C%EC%96%B4-%EA%B4%80%EB%A0%A8


2 유의사항

- Android 터미널은 마이그레이션 해야 한다. 대부분 자동으로 되는데 중간에 퍼미션은 열어 줬던 듯. 

- 라즈베리나 오드로이드나 둘 다 리눅스 기반이지만 기본 탑재된 패키지가 다르니 몇몇 설치해줘야 패키지가 있을 것이다

- 컴파일 때, 라이브러리 지정 순서도 중요하다 -lwiringPi -lpthread -lcrypt -lwiritingPiDev -lm -lrt -lbluetooth 순으로 했다. 안 되는 조합이 딱 1개 있었는데 좀 신기했음. Makefile 만들기 전 테스트라 ^^;;


3 결론

블루투스 프로토콜 스택은 참 잘되어 있다. 오픈소스도 많다. 1.0~4.0까지의 하위 호환성도 참 좋다.

'블로그 항해 일지 > Embedded' 카테고리의 다른 글

x86용 부트코드  (0) 2019.01.08
ODROID GPS 모듈 입양 完  (2) 2019.01.08
블루투스 연결  (0) 2019.01.08
GPIO 컨트롤  (0) 2019.01.08
Ubuntu Image download  (0) 2019.01.08

ODROID에 BT 동글을 연결해 봅니다.


!! bT동글을 꽂았는데 안되는 경우

# dmesg -Hw

실행 해 보시면 간혹 USB 허브를 이용하는 경우 제대로 인식이 안되는 경우가 있다는 것을 알 수 있습니다. 

10번 중 1번 정도 발생


PARING

기본 내장이지만 customize 해서 쓰시는 분은 아래 패키지 설치 하셔야 합니다.

sudo apt-get install bluetooth bluez bluez-tools rfkill rfcomm

lsmod | grep bluetooth 로 검색되시면 블투모듈이 올라온겁니다.


# bluetoothctl

# list (이 명령어는 자동 실행됨)

[New] Controller 00:1A:7D:DA:71:13 odroid

로 ODROID MAC Address 확인

# info 00:1A:7D:DA:71:13 로 세부정보 확인 가능


# power on (보통 자동으로 on되어 있음)

# scan on

Android 휴대폰 MAC Address 확인


# scan off

# agent on

# default-agent

# pair XX:XX:XX:XX:XX:XX

# trust XX:XX:XX:XX:XX:XX 


볼거리

https://code.tutsplus.com/tutorials/create-a-bluetooth-scanner-with-androids-bluetooth-api--cms-24084

https://developer.android.com/guide/topics/connectivity/bluetooth?hl=ko

https://stackoverflow.com/questions/6141668/bluetooth-examples-for-android

https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/bluetooth/BluetoothSocket.java

https://arsviator.blogspot.com/2010/05/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-%EB%B8%94%EB%A3%A8%ED%88%AC%EC%8A%A4-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-bluewatch-project-2.html

https://github.com/bablokb/pi-btnap

'블로그 항해 일지 > Embedded' 카테고리의 다른 글

x86용 부트코드  (0) 2019.01.08
ODROID GPS 모듈 입양 完  (2) 2019.01.08
GPIO 제어 via 블루투스 on 삼성폰  (0) 2019.01.08
GPIO 컨트롤  (0) 2019.01.08
Ubuntu Image download  (0) 2019.01.08


GPIO 제어를 위해 WiringPI library를 이용합니다. WiringPI는 Broadcom의 BCM2835, BCM2836, BCM2837 칩을 위한 라이브러리입니다.

http://wiringpi.com/




브로드컴의 BCM 시리즈 칩은 다음과 같은 페리(Peripheral, 주변장치)를 붙여 설계할 수 있습니다.


• Timers

• Interrupt controller

• GPIO

• USB

• PCM / I2S

• DMA controller

• I2C master

• I2C / SPI slave

• SPI0, SPI1, SPI2

• PWM

• UART0, UART1 

* 2835 datasheet 참조 https://www.raspberrypi.org/app/uploads/2012/02/BCM2835-ARM-Peripherals.pdf




Raspberry Pi Model B+ 은 Broadcom BCM2835을 쓰고, Raspberry Pi 2 Model B는 Broadcom BCM2836 칩을 씁니다. 둘 다 GPIO 개수가 40개로 ODROID-XU4 보다 10개가 많습니다. 라즈베리 파이는 PWM도 달려있어 장치 제어에 많이 쓰고 그만큼 유저도 많습니다. 현재로서는 직접 설계 없이 콘텐츠를 붙이는 장치 제어 필드(업계)에서는 사실 오드로이드 보다는 라즈베리 파이를 이용한 프로젝트가 많습니다. 다른 것 보다 가격이...

https://www.board-db.org/compare/84,4,28/




ODROID에는 듀얼코어(Samsung Exynos5422 Cortex-A15 2 Ghz and Cortex-A7 Octa core CPU) 칩이 들어 있습니다. 브로드컴 제품이던 삼성 제품이던 둘 다 ARM Architecture를 기반으로 하기 때문에 S/W도 비슷하게 갑니다. ODROID를 제작한 HardKernel에서도 wiringPI를 이용합니다. 이전에는 잘 정리된 위키 페이지가 없어서 많은 삽질(실습)을 했어야 했습니다. 지금은 아래 사이트 보고 그대로 따라 하면 만들기 쉽도록 되어 있습니다.

https://wiki.odroid.com/odroid-xu4/application_note/gpio/wiringpi




1편에서 리눅스를 설치했으니 대부분의 장치는 리눅스에서 제어하도록 매핑되어 있습니다. 펌웨어 단에서 장치에서는 MMIO(Memory Mapped I/O), IMIO(IO Mapped I/O)가 주류지만 리눅스 시스템에서는 파일/디렉토리로 모든 것을 가능하게 해 놓았죠. 이미 디바이스 드라이버란 이름이 있지만 MMIO, IMIO, PMIO(Port mapped I/O) 처럼 FMIO(File Mapped I/O)라고 하고 싶습니다.




PIN 번호 참조

https://wiki.odroid.com/odroid-xu4/hardware/expansion_connectors
odroid-xu4:hardware:expansion_connectors [ODROID Wiki]



wiki.odroid.com

0. 결과

https://youtu.be/Ifztgr99bRs


ODROID CON10 header의 핀번호는 인터넷에서 구할 수 있는 표번호와 다르다. 전에 한 학생이 다시 그려서 줬는데 구글 드라이브를 쓰기 전이라 잃어버렸다. 진작에 포스팅 할껄 하는 아쉬움이 남는다 그런데 넌(그 학생) 지식공유를 위해 블로그 하래두 안하니... 마음 편하게 확장 보드를 구매하자.



1. FMIO in shell

odroid@odroid-server:~$ echo 29 > /sys/class/gpio/export

odroid@odroid-server:~$ echo out > /sys/class/gpio/gpio29/direction

odroid@odroid-server:~$ echo 1 > /sys/class/gpio/gpio29/value



2. FMIO with source

#include <string.h>

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h> 




int main(int argc, char** argv)

{

FILE *fp;

char setValue[4];

int toggle = 0; 

if((fp = fopen(“/sys/class/gpio/export”, “ab”)) == NULL) {

printf(“Cannot open export file.\n”);

return -1;

}

rewind(fp);

strcpy(setValue, “1”);

fwrite(&setValue, sizeof(char), 1, fp);

fclose(fp);

sleep(1);

if((fp == fopen(“/sys/class/gpio/gpio25/value”, “rb+”)) == NULL) {

printf(“Cannot open value file. \n”);

return -1;



rewind(fp);

strcpy(setValue, “0”);

fwrite(&setValue, sizeof(char), 1, fp);

fclose(fp);

return 0;

}



3. FMIO using WiringPI

#include <stdio.h>

#include <wiringPi.h>

#include <sys/time.h>

int main(int argc, char **argv) {

unsigned int delay_cnt=0;

wiringPiSetup();

pinMode(06,OUTPUT);

digitalWrite(06,HIGH);

return 0;

}

https://wiki.odroid.com/odroid-xu4/application_note/gpio/wiringpi
odroid-xu4:application_note:gpio:wiringpi [ODROID Wiki]



wiki.odroid.com





ODROID에는 PWM이 없습니다. 각도 제어 서보모터의 경우 delay를 이용하여 S/W 파형을 만들어도 떨림없이 제어가 잘 되네요. 물론, 100%(모든 서보모터)는 아니고맥심칩처럼 컨버터를 넣은 보조 회로가 필요합니다.


뭐든 추상화하면 상위단 코드는 간결해집니다. 또, 알고리즘이나 다지인 패턴같이 좀 더 낫다고 생각되는 과제를 고민할 수 있게 됩니다. 임베디드 월드와 비교해 볼 때, 데스크톱에서 하는 응용 프로그램이야 정말 생각한 대로 작동한다고 할 수 있습니다. 응용프로그래머는 그렇게 추상화시킨 API를 사용할 때 정말 수많은 엔지니어가 많은 고생을 했었다는 사실을 잊지 말았으면 합니다.

'블로그 항해 일지 > Embedded' 카테고리의 다른 글

x86용 부트코드  (0) 2019.01.08
ODROID GPS 모듈 입양 完  (2) 2019.01.08
GPIO 제어 via 블루투스 on 삼성폰  (0) 2019.01.08
블루투스 연결  (0) 2019.01.08
Ubuntu Image download  (0) 2019.01.08


라즈베리 파이와 경쟁할 국내 기술의 뛰어난 제품, 오드로이드!

기본적으로 밑에 단 작업이 다 되어 있는 운영체제, 우분투 16.04를 받아보자.

1. 이미지 받기 전 eMMC 카드 포멧

다음 명령어를 이용하여 포멧해야 한다. on Windows®

C:\> Diskpart
DISKPART> list disk
DISKPART> select disk (id)
DISKPART> online disk (if the disk is not online)
DISKPART> attributes disk clear readonly
DISKPART> clean
DISKPART> convert mbr (or gpt)
DISKPART> create partition primary
DISKPART> select part 1
DISKPART> active (if this is the boot partition)
DISKPART> format fs=ntfs label=(name) quick
DISKPART> assign letter (letter)
DISKPART> list volume


2. Win32 Disk Imager for ODROID 이용, 다운로드

마그넷 링크 원본은 이 글 가장 아래에...

마그넷 다운로드를 위한 비트 토렌트 다운로드

Disk Image 마그넷

Ubuntu 16.04 Image 마그넷


3. 부팅 확인

* 주의 *

1. USB 허브 비추

2. 앞쪽 USB 포트 비추(메인보드에 직접 꽂으세요-전력문제 배제-)


Disk Image


magnet:?xt=urn:btih:22394D44F7E369D838CC63470387F1415C95A031&dn=win32diskimager2-binary.zip&tr=udp%3a%2f%2ftracker.openbittorrent.com%3a80%2fannounce&tr=udp%3a%2f%2ftracker.opentrackr.org%3a1337%2fannounce


Ubuntu mate 16.04 


magnet:?xt=urn:btih:2F97C2B4265EB528A72FCE8BD5FF11886FF63BAD&dn=ubuntu-16.04-mate-odroid-xu4-20170731.img&tr=udp%3a%2f%2ftracker.openbittorrent.com%3a80%2fannounce&tr=udp%3a%2f%2ftracker.opentrackr.org%3a1337%2fannounce




'블로그 항해 일지 > Embedded' 카테고리의 다른 글

x86용 부트코드  (0) 2019.01.08
ODROID GPS 모듈 입양 完  (2) 2019.01.08
GPIO 제어 via 블루투스 on 삼성폰  (0) 2019.01.08
블루투스 연결  (0) 2019.01.08
GPIO 컨트롤  (0) 2019.01.08

git init

git add .

killall gpg-agent //제껀 좀 꼬여서...

git remote add original git@github.com:hajunho/iOS_project_pad.git

git fetch

git remote -v //original 이름 확인

git remote set-branches original

git pull original master --allow-unrelated-histories

git push --set-upstream original master



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


echo "# Myproject" >> README.md

git init

git add README.md

git commit -m "first commit"

git remote add origin git@github.com:hajunho/myProject.git

git push -u origin master

'블로그 항해 일지 > Tips' 카테고리의 다른 글

powergrep exclude  (0) 2019.01.22
포스트맨 정말 좋다.  (0) 2019.01.11
파이썬 관련 주요 인물  (0) 2019.01.06
Android 개발자 iOS전환 - 2  (0) 2019.01.03
Android 개발자 iOS전환 - 1  (0) 2019.01.03

https://github.com/hajunho/iOS_startUpCodes


깃헙 latest에는 그래프가 없지만, 히스토리를 보면 만들다가 회사로 넘겨진 그래프 프로토타입이 하나 있다.


프로토 타입인데 framwork 화까지는 되어 Xcode 에서 framwork 타입으로 불러 올 수 있다. 


내가 혼자 만드는 거라 이 후 품질을 향상하려면 오픈 소스화 해야 한다고 했는데 회사에서 오픈소스화 한다는 메세지를 줬었기에


블로그에 내 고민을 남겨 두면 아마 나중에 새로운 그래프를 만들거나 더 나은 그래프를 만들려고 할 때 도움이 될 것 같아서


이 카테고리를 만들었다. 그리고 첫 글을 쓰는 시점 즈음에는 이제 오픈소스 그래프를 좀 봐야지 했다.


본디 처음부터 그것을 보면 절대 그 안에서 벗어날 수 없는 법이라...


깃헙에 올려졌었던 그래프와 오픈 소스 그래프와 다른 점은 한 패널에 여러개의 그래프를 붙일 수 있다는 점이다.


처음부터 다른 철학으로 쌓아올려지는 것이라 참고를 하지 않았었다. 코어 그래픽이라 딱히 복잡하진 않은데


싱글톤, 빌더, 옵저버 패턴 정도는 들어갔다.


나도 개발하느라 바빠서 잘 정리하지는 짧막한 글이라도 분명 후진에는 도움이 될거라 생각한다.

  1. 귀도 반 로섬 (Guido van Rossum): 파이썬의 창시자로, 그의 기여와 이 언어에 대한 지속적인 관심으로 커뮤니티에서 가장 높은 존경을 받습니다.
  2. 레이몬드 헤팅거 (Raymond Hettinger): 파이썬 코어 개발자이자, 파이썬의 내장 기능과 라이브러리 개발에 중요한 기여를 한 인물입니다. 그는 또한 탁월한 강연자로도 유명합니다.
  3. 데이비드 비즐리 (David Beazley): 파이썬 교육자이자 저자로, 'Python Essential Reference'와 같은 중요한 파이썬 책들을 저술했습니다. 그는 또한 파이썬의 고급 기능과 내부 작동 원리에 대한 심층적인 이해를 공유합니다.
  4. 트레비스 올리판트 (Travis Oliphant): 과학 계산을 위한 파이썬의 주요 라이브러리인 NumPy의 주요 개발자 중 한 명이며, SciPy와 Anaconda의 공동 창시자입니다.
  5. 캐롤 윌링 (Carol Willing): 파이썬 소프트웨어 재단 이사회 멤버이자, 교육과 다양성 증진을 위한 활동으로 존경받습니다.

 

 

링크는


https://github.com/danielgindi/Charts



ChartsDemo-iOS Swift 그룹 아래 다음 개의 파일을 복사한다.

LineChart1ViewController

BalloonMarker

DemoBaseViewController


xib 복사하지 않고, interface builder 에서 view 추가하고 Custom Class

LineChartView 맞춘다. -> Module Charts 자동으로 들어간다.


LineChart1ViewController 열고 기존 리소스를 지우고, 다시 연결해 준다.

다음 세개를 연결한다.


    @IBOutlet var chartView: LineChartView!

    @IBOutlet var sliderX: UISlider!

    @IBOutlet var sliderY: UISlider!

    

    override func viewDidLoad() {

        super.viewDidLoad()


2개를 올렸으니 주석 처리해야할 것이 생긴다.


        chartView.rightAxis.enabled = false

        

//        [_chartView.viewPortHandler setMaximumScaleY: 2.f];

//        [_chartView.viewPortHandler setMaximumScaleX: 2.f];



    @IBAction func slidersValueChanged(_ sender: Any?) {

//        sliderTextX.text = "\(Int(sliderX.value))"

//        sliderTextY.text = "\(Int(sliderY.value))"


그래프 나옴.

Fin.


2편이다.


각 언어의 특징으로만 보라는 이상한 말


내가 좋아하는 책이라 여러 권을 산 책이 있다. Objective-C라는 책인데 난 2권 다 있다. 물론, 내가 책을 쓸 때도 이 책의 영향을 많이 받았다.(2.0버전) 마크 달림플(Mark Dalrymple), 스콧 내스 터(Scott Knaster), 와카르 말릭(Waqar Malik). 실무 개발자 3인방의 내공을 책으로도 크게 느낄 수가 있다. 사실, 실무를 오래 한 프로그래머가 깊게 파보면 다른 프로그래밍 언어 책과 큰 내용 차이는 없다. 작은 두 가지의 의견을 새롭게 낼 뿐이었다. 그러나 그 작은 의견은 아는 사람이 보면, 프로그래밍의 정수를 담은 것이라 하겠다. indirection layer와 이 세상의 문제를 완벽하게 해결해 줄 수 있는 단일 프로그래밍 언어는 존재하지 않는다는 것이다. 그래서 각 언어의 특징은 그 언어로 이해하라는 식의 글귀가 있었다.(책 뽑아서 보면 되지만 너무 아래 깔려 있다 ㅠ)


그중 후자는 시중의 책에서 가장 많이 인용되어 잘못 생각하는 사람이 많이 생겨나는 것 같아서 몇 글자 적어 본다. 다른 책이 원조일 수도 있겠지만, 그들의 프로그래밍 역사로 봤을 때 벤치마킹이 분명하다. 후자는 프로그래밍 언어는 바로 그 언어의 특징으로만 봐야 한다는 말이다. 어느 책이나 이 말을 돌려서 하던지, 직접적으로 적던지... 비슷하게 쓴다.


미국에서 사는 사람들의 문화, 한국 사람의 문화. 다르고 언어도 그 문화의 다름과 같이 1:1로 완벽하게 대치될 수 없는 부분이 있다. 그러나 뿌리가 판이하게 다르고 역사도 너무도 깊다. 그에 반해 컴퓨터의 역사를 깊지도 않고 그 뿌리는 결국 인텔 프로세서다. 혹은, ARM Instruction Set이다.


3인방이 말한 것도 한 가지 언어를 배울 때 집중해서 깊게 이해라 하는 뜻이지. 이기종의 언어에서 말하는 똑같은 개념까지도 다르게 표현하라는 뜻은 아니다. 한국말에 있는 부모님 마음속의 한, 인연 등 문화적 관점에서 이해해야 할 부분도 있거니와. 영어 사전에서 쉽게 찾을 수 있는 한국말은 같다고 봐도 무방하듯이 각 프로그래밍 언어의 비슷한 부분은 비슷하게 이해하면 된다.


상속, 다형성, 캡슐화, interface, delegate, abstract, protocol


요즘 코딩 교육을 일반 교사가 직접 배워서 하기 때문에 가끔 지인을 만나 비 전공자 교사의 고충을 듣는다. 사실 나도 코딩 교사가 따로 있을 줄 알았는데 말이다. 어차피 모든 지식은 학교로 다시 돌려보내야 하는 것이 맞으니 몇 가지 적어 본다. 교사는 워낙 똑똑한 사람들이라 이미 지식은 꽉 차 있다. 두리뭉실한 개념을 이 분야의 묵은지가 연결만 시켜주면 되겠다. 비공개로 출판한 책에서 밝힌 적이 있는데, 글로 쓰는건 제대로 전달되지 않지만 끄적여 본다.(장자 윤편으로 검색해서 관련 글을 보시길)


어려운 개념들은 쉽게 말해도 관계없고, 또 그게 많다.


상속은

복사/붙여 넣기.


내가 프로그래밍 수업에서 상속을 가르칠 때도 이렇게 간단히 말한다.


썰을 더 풀면,

다형성은 배열 돌려서 동시 다발적으로 실행하게 만들기 위함이라고 했는데, 사실 실무에서는 그게 다다. 

void pointer가 java에서 object type이다. 그래서 모든 객체를 가리킬 수 있고 그것을 다형성이라 부른다. 


간단한 이론이지만 이것으로 메시지 큐를 구현하고, 또 애플이나 안드로이드 앱 프레임워크를 만든다. 어떤 알림이 오면 각 앱을 list 에 등록하고 for문을 돌면서 브로드 캐스팅 메시지를 날리게 되는 것이다. 


Xcode에서 싱글뷰 어플 test 하나 만들고 Viewcontroller에 넣으면 된다.


우선 해당 글에 있던 델이게이터 예제.

//

//  ViewController.swift

//  test

//

//  Created by Junho HA on 2018. 10. 5..

//  Copyright © 2018년 hajunho.com. All rights reserved.

//


import UIKit


class ViewController: UIViewController {


    override func viewDidLoad() {

        super.viewDidLoad()

        // Do any additional setup after loading the view, typically from a nib.

        let a : implementMe = 지나가던사람()

        a.날사랑하니()

    }

}


protocol implementMe {

    func 날사랑하니() -> Void

}


class 남자 : implementMe {

    func 날사랑하니() {

        print("...")

    }

}


class 관심있던남자 {

    func 날사랑하니() {

        print("어")

    }

}


에서 implementMe 를 상속받는 친구는 implementMe type으로 생성가능하다. 추상화된 포인터로 보면 되겠다.


행인을 하나 추가하고 배열로 선언하면 다음과 같다.


//

//  ViewController.swift

//  test

//

//  Created by Junho HA on 2018. 10. 5..

//  Copyright © 2018년 hajunho.com. All rights reserved.

//


import UIKit


class ViewController: UIViewController {


    override func viewDidLoad() {

        super.viewDidLoad()

        // Do any additional setup after loading the view, typically from a nib.

        let a : [implementMe] = [ 지나가던사람() , 행인1() ]


        a[0].날사랑하니()

        a[1].날사랑하니()

    }

}


protocol implementMe {

    func 날사랑하니() -> Void

}


class 남자 : implementMe {

    func 날사랑하니() {

        print("...")

    }

}


class 관심있던남자 {

    func 날사랑하니() {

        print("어")

    }

}


class 지나가던사람 : 관심있던남자, implementMe {

}


class 행인1 : implementMe {

    func 날사랑하니() {

        print("누구슈")

    }

}


a[0], a[1] 은


   for x in a {

            x.날사랑하니()

        }


로 치환 가능하다.


결국, 인터페이스 하나 던져주고 아래에서 다 구현하라고 하고 어떻게 구현했던 상위 포인터(Object  던 Void Pointer던 상위 포인터든)로 하위 구현부의 메소드를 for 문 돌려서 실행시켜 주면,


모든 앱의 이름도 반환 받을 수 있고,

모든 앱을 실행시킬수도,

모두 지울 수도,

모든 앱의 메시지 수신부에 메세지를 보낼 수도 있다.


다형성은 간단한 개념이지만 매우 강력한 아키텍쳐 패턴의 주요 개념이다. 참고로 우리가 패턴이라고 하는 것들은 대부분 모듈 패턴이다.


캡슐화는

변수 마음대로 못 바꾸게 하기.

가령 속도라는 변수가 있어서 자동차를 제어한다면 그 속도가 0보다 크고 200보다 크게 세팅되어야 한다는 조건을 걸어 주는 게 좋다. 그래서 변수를 직접 제어하지 안혹, getter/setter를 쓴다.


인터페이스는 상속자(상속받은 무언가)가 구현해야 할 껍데기다.

앱스트랙트는 껍데기에 살을 좀 붙인 것이다.


껍데기는 다중 상속이 가능하다.

살이 붙은 것(내용이 있는 것)은 다중 상속이 불가능하다.


다중 상속(복사/붙여 넣기) 해봤자. 껍데기는 껍데기일 뿐이다. 구현해야 할 것만 많아진다.

제약 사항이 많다는 것은 누가 편하게 쓰라고 만들어 놓으면서 제약을 걸어 놓은 것이다.


가령 허허벌판 일 때는 규칙이 없지만, 놀이터를 만들어 줄 테니 아이들만 뛰어놀게 하라는 제약처럼.


프로토콜은 인터페이스와 같다. 다만, 다른 애들이 대신 구현해 줄 수 있다.


protocol implementMe {

    func 날사랑하니() -> Void

}


라는 프로토콜이 있다. 프로토콜은 껍데기다.

Protocol methods must not have bodies


그럼 이 프로토콜(인터페이스, abstract class)를 상속하는 클래스는 무조건 구현을 해 줘야 한다.

class 남자 : implementMe {

    func 날사랑하니() {

        print("...")

    }

}

안하면,

Type '남자' does not conform to protocol 'implementMe'

맞지 않는다고 한다.


만약 구현하고 싶지 않은 누군가가 있다고 하자

class 지나가던사람 : implementMe {

}

이 경우엔 다른 클래스가 구현해도 된다.


class 관심있던남자 {

    func 날사랑하니() {

        print("어")

    }

}


class 지나가던사람 : 관심있던남자, implementMe {

}


관심있던 남자가 날사랑하니()를 구현해 놓았었으니 복/붙하면 implementMe의 요구사항을 충족시켜준다는 뜻. UITableViewDelegate, UIScrollViewDelegate 같이 복잡한 녀석들로 이런 개념으로 쉽게 분석이 가능하다. 다른 복/붙(상속)없이 해당 델리게이트만 상속하면 구현해야할 수많은 stub이 있다.



위에서 말한 모든 개념은 사실 아래의 요구사항으로 생겼다.


1. 잘 만들어 놓으니(framework, library, api,...)

2. 네가 맘대로 복/붙해서 가져다 써(상속)

3. 그런데 몇 가지는 네가 알아서 넣어야 하니까 구현을 해야 할 거야 내가 정해놓은 규칙대로 (인터페이스, 프로토콜, 앱스 트렉트 클래스/매소드)

4. 모두 구현하기 싫으면 다른 애들이 구현한 거 그대로 상속(복사)해서 써(델리게이트)

5. 내가 만든 것의 값은 마음대로 못 바꿔(접근 제한자, 캡슐화) 수치가 0이 되면 사람이 죽을 수도 있으니 0이 들어오면 에러를 발생시켜버릴 때(setter, assert)


그래서 사실 따지고 보면 다 같은 개념은 아니다.


그러나 실무에서는 비슷하다.


모듈을 보는 단계에서는 완전히 다르고,

아키텍처를 보는 단계 해서는 부분 부분 다르고,

시스템을 보는 관점에서는 완전히 같다.


프로그래밍은 어차피 메모리와 CPU의 장난.


lambda, 함수형 프로그래밍, 클로저

 

셋 다 같은 말이다.


모든 함수는 y=f(x) 에서 나왔다.


세상 간단.


함수형 프로그래밍은 람다 대수에서 나왔다.


람다 대수의 핵심은 무언가를 추상화하는 방법과 구체화 하는 방법에 대한 철학이고.

특징은 익명 함수라는 것.


클로저는 기본적으로 함수 포인터다.


    func 주문받기() -> [String] {

        let 주문목록 : [String] = ["짜장면", "짬뽕"]

        return 주문목록

    }


swift 에 이런 함수를 만들었다면 C의 함수포인터로


String (*v)();

v = 주문받기


이렇게 만들 수 있을 것이다.


그러나 swift 는 문법이 쉽다.


let v = 주문받기

var v = 주문받기


쉽게 만들 수 있다. 배가 고프니 중국집을 하나 만들어 본다. 배가 고파 자장면이 아닌 입에 촥 감기는 짜장면을 불러 본다.


class 중국집 {

    func 주문받기() -> [String] {

        let 주문목록 : [String] = ["짜장면", "짬뽕"]

        return 주문목록

    }

}


프로그래밍은 많은 사람들이 작업을 하기 때문에 수많은 클래스에 수많은 함수가 있다. 클래스는 메모리에 없으니 생성해서 만들어 줘야 함수를 쓸 수 있다.


let a : 중국집 =  중국집()

let b = a.주문받기()


자바였다면,

중국집  a = new 중국집();

이었겠지.


클래스 생성없이 메모리에 바로 생성시키는 방법도 있다. primitive type, new, malloc, static

static 은 swift에도 있으니


  static func 주문받기() -> [String] {

        let 주문목록 : [String] = ["짜장면", "짬뽕"]

        return 주문목록

    }

로 선언하면


print(중국집.주문받기())

가 가능하다.


내가 주문하려면, 파라미터를 넣고

  func 주문받기(s : [String]) -> [String] {

        let 주문목록 : [String] = s

        return 주문목록

    }


 let c : [String] = ["짜장면", "짬뽕"]

 print(a.주문받기(s: c))


혹은


  print(a.주문받기(s: ["짜장면2", "짬뽕2"]))

로 하면 된다.


위의 위키피디아 링크 "람다대수"를 보면 함수가 반드시 이름을 가질 필요는 없다. 는 구절이 있다.

b가 그렇다. print(b) 도 되지만, a.주문받기() 혹은 print(a.주문받기(s: ["짜장면2", "짬뽕2"])) 처럼 b를 안 써도 된다. b가 생긴다는 것은 상태 변수 혹은 속성 혹은 멤버변수 혹은 프로퍼티(다 같은 말이다)가 생긴다는 말인데 b 를 안쓰니 함수형 프로그래밍의 특징이 하나는 상태값을 저장하지 않는 것으로 귀결된다. C/C++, Objective-C, C#, JAVA, SWIFT 모두 함수형 프로그래밍 언어의 특징을 구현할 수 있다. 그러나 하나의 프로그래밍 패러다임만 구현하지 않는다.


이 상황에서 주문하는 쪽은 상태를 가질 필요가 없다(중국집 전화번호만 있으면 된다) 그러나 중국집은 주문 목록은 있어야 한다.



한타임 쉬고. <밥먹음 ㅋㅋ> 배부르니 중국집이 하기 싫어진다.


자, 여기까지 하고 문법 짚고 가보자.

보면, 클로저는

(parameters) -> return type in

statements

}

이렇게 선언한다고 한다.


swift 에서 함수 선언은


func #name(parameters) -> return type {

        function body

}


이랬다. func와 이름이 사라지고 {} 가 바깥으로 나와버려서 function body 시작점을 몰라 in 이 들어갔다.

별거 없다.


이제 중국집을 다시 만들고, 고객의 소리를 받아보자.


class 중국집 {

    private var 주문목록 : [String] = []

    static func 고객소리(x : ()->Void) {

        x() //고객의 소리는 x, 실행 명령어는 ()

    }

}


고객의 소리는 이렇게 만드는데,

    func name() -> Void {

            print("짜장면 더 맛있게 해주삼")

        }

        중국집.고객소리(x: name)


앞 서 말했 듯이 내가 func를 가질 필요는 없겠다.


중국집.고객소리(x: {})

중국집.고객소리(x: { () -> Void })

중국집.고객소리(x: { () -> Void in print("짜장면 더 맛있게 해주삼")})


그런데 () -> Void 이거 왠지 결국엔 C의 함수포인터랑 같다. 안돼! 난 최신 언어라구.


중국집.고객소리(x: { print("짜장면 더 맛있게 해주삼")})


이렇게도 가능하겠다.


        중국집.고객소리(x: { print("짜장면 더 맛있게 해주삼")

            print("짬뽕은 더 맵게")

        })


결국 실행은 사장이 하는 거고 구현을 클라이언트(함수를 호출하는 사람)이 하게 되었다. 그리하여 파라미터도 사장이 넣을 수 있다. 사장의 성깔이 좋은지 아닌지 중국집 사장이 직접 넣어보자.


class 중국집 {

    private var 주문목록 : [String] = []

    static func 고객소리(x : (Bool)->Void) {

        x(true)

    }

}


성격이 좋다고 넣었다. 그러면 고객은 한마디 더 할 수 있다.


        중국집.고객소리(x: { (사장성깔좋아) in

            print("짜장면 더 맛있게 해주삼")

            print("짬뽕은 더 맵게")

            if(사장성깔좋아) { print("진짜 맛없어요")}

        })


이렇게 클로저가 탄생하게 되었다. UI 기초 2편을 써야 하는데 스냅킷 내용이 반 이상이라. 클로저를 먼저 짚고 넘어가야할 것 같아서. 물론, 축약 안하고 써도 된다.


        중국집.고객소리(x: { (사장성깔좋아) -> Void in

            print("짜장면 더 맛있게 해주삼")

            print("짬뽕은 더 맵게")

            if(사장성깔좋아) { print("진짜 맛없어요")}

        })


그리고 사실 프로그래밍 할 때 이런 프로그래밍 언어적 특성이나 모듈 패턴을 몰라도 아키텍처만 잘 짜면 굳이 축약 코드로 도배 안해도 충분히 재 사용성이나 메모리 사용량은 감소한다.


결국 임베디드, C/C++을 해야 언어를 제대로 이해할 수 있다. 기초 서적은 외서를 보지만 가끔 국내 서적도 여러권 가서 내가 이해한 것이랑 비교해 보는데 생략된 부분이 너무도 많다. 물론, 나 역시도 써봐서 싣고자 했는데 까먹고 못 실었던 내용이 많으니... 비슷한 경우일 수도 있겠다.


그러나 람다 대수의 위키 페이지를 참고하는 게 함수형 프로그래밍을 더 확실히 이해할 수 있는 지름길이라 하겠다. fxJAVA 도 함수형 프로그래밍인데,...


사실 수학을 떠나, 프로그래밍 언어에서 완전히 함수형으로 된다는 것은 메모리 관리가 완전히 순차적으로 되어야 한다는 말이다. 메모리 청크 찾는 거야 운영체제 단에서 어쩔 수 없다고 해도 그 상위에서는 정말 순차적으로 들어가야 한다. 그래야 데이터 무결성도 지켜지고 액세스 속도도 빠르다.


뭐, 응용 프로그래머야 함수형 프로그래밍 흉내만 잘 내어도 쓸데없는 상태 변수를 만들지는 않겠지만, 결국 언어를 만든 사람이 적절한 타이밍에 메모리 관리를 효율적으로 하는 게 중요하다고 생각한다.



최근 코틀린이 아닌 자바를 사용하는 안드로이드 개발자가 iOS 개발을 하고 싶다고 하여 이야기 한 내용을 적어 둔다. 글은 2개로 쪼갠다.



1. MAC을 안 사도 된다.


이전에 포스팅 올렸다가 지워서 캡처 화면은 없지만 인터넷 뒤지니 자료가 많았다. 삼성 시리즈 9 노트북, VMWARE 위에 시에라 버전 올리고 XCode로 해 보았다. 전혀 문제없다. 맥의 커맨드 키는 컨트롤키 기능의 일부를 가져갔다고 생각하면 되고(cmd+C, cmd+V처럼) 맥의 옵션 키는 알트키(Alt, @)로 생각하면 금방 적응될 것이다. 맥이 있었지만 3개월가량 삼성 노트북으로 iOS 앱 개발했다.


2. 적응


맥의 프로그램 실행은 대부분 cmd+space bar를 눌러서 실행한다. 윈도에서 윈도키를 누르고 앱 이름을 실행하는 것과 같다. 윈도에서 Ctrl+Shift+ESC를 눌러 실행하는 프로세스 모니터는 Activity monitor란 이름이니 커맨드+스패이스 바를 통하여 실행하면 된다. 나머지는 우분투 리눅스 배포판과 창 모양, 창 닫기 위치, bash shell(맥에서는 terminal)이므로 사용하기 쉬울 것이다. 바꾸자. 맥으로. 오버워치 때문에 윈도우는 무조건 써야하니 하나 더 사자는 말


윈도우의 익스플로러는 finder 이며, 윈도우처럼 쉬프트 우클릭으로 쉘을 바로 열 수 있는게 아니라 몇가지 작업을 좀 해줘야 한다. 그리고 윈도에서 cmd 말고 powershell을 쓰듯이 맥은 기본 터미널 말고 iterm2를 쓴다. 거기에 zsh를 더해주면 더 좋다. 화면이 좁으니 모니터를 더 구입하는 것보다 bettersnap tool 같은 앱을 연결해서 창을 다룬다. 윈도 유저는 많은 모니터를, 맥 유저는 그냥 맥북 프로에 창 관리를 잘 하는 차이라고 보면 되겠다.



3. SWIFT


우선, ARM Firmware를 하는 내 입장에서는 JAVA나 C/C++, SWIFT가 모두 똑같은 언어로 보인다. PYTHON 은 perl이나 bash shell script 정도로 보이고 ^^;; 인터넷 서핑 공부법으로 편하게 공부하면 되지만 몇 가지 팁을 적어 본다.


(1) module, framework


module은 application 이나 framwork 을 말한다. Andoird에서 Project 와 같은(비슷하다는 말을 "같은"으로 표현하여 더욱 접근 장벽을 더 낮추겠다.) 개념이다. Eclipse에서 여러 Project를 하나의 workspace에 띄우는 것과 같다. Visual Studio 의 Project 개념. 더 큰 개념은 Solution이고 XCode에서는 그것을 workspace라고 부르니 결국 Eclipse의 workspace랑 같다. Android studio 에서는 gradle로 다양한 라이브러리를 import 한다. gradle의 그 한줄이 module, 또는 framework 이라고 보면 되겠다. 즉, framwork은 라이브러리다.



(2) cocoa Pods


cocoa는 STL이나 GLIBC처럼 표준 라이브러리 집합이다. swift 하는 분은 서버 개발자나 iOS 개발자, 특히 모바일 개발자가 많다고 생각된다. iOS는 UIKit을 쓴다. UI 프레임웍은 다음을 참고!


https://developer.apple.com/videos/frameworks/ui-frameworks

Frameworks - UI Frameworks - Videos - Apple Developer


developer.apple.com 



그리고 node.js에 npm이 있고, react에 yarn이 있고, fedora의 yum, ubuntu의 apt 가 있듯이 맥에는 brew 라는 패키지 관리자가 있다. brew를 이용해서 cocoapods를 설치할 수 있는데 pod은 라이브러리 관리 프로그램이다. pod 설치 후 pod init 하면 Podfile이 생성되고 해당 파일에 pod 'SwiftyJSON', '~> 4.0' 와 같이 패키지명을 적어주고 pod install 하면 라이브러리를 설치해 준다. 지우는 명령어는 따로 없고, Podfile에서 삭제하고 pod install 로 지운다. 현재 설치된 버전은 Podfile.lock에 저장된다. 설정파일 2개로만 관리하니 많이 편리하다. workspace 파일(각 project를 관리하는)이 없는 경우 자동 생성해 준다.




(3) 접근 제한자


2 때는 public, private, internal 만 있어서 비슷했는데 3버전 부터 open, fileprivate이 늘어났다. 자바에서의 public 은 swift의 open과 같다. 


https://docs.swift.org/swift-book/LanguageGuide/AccessControl.html

Access Control — The Swift Programming Language (Swift 4.2)


docs.swift.org 




(4) 함수 선언



void 리턴값은 아예 적지 않는다.

func stringMetohd(source : [String]){

for a in source {

print(a)

}

}


var weekdays : [String] = ["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"]


stringMetohd(source: weekdays)






모든 프로그래밍 언어에 y=f(x) 개념이 있듯이 스위프트도 함수가 기본이다.


func square(n:Int) -> Int {…}


로 함수 선언을 한다.


자바에서 public int square(int n) {...} 겠다.


C에서 함수포인터가 JAVA에서 인스턴스 변수로 편하게 객체를 대입하듯이


swift에서는 더 쉽게 할 수 있다.


let a=square


변수 선언은 var나 let을 쓸 수 있는데, let은 C에서 const, java에서 final과 같다.


물론, 자동 자료형 casting이 되지만 중급 이상 프로그래머는 알 것이다. 결국 자료형을 컨트롤해줘야 한다는 것을(뭐 frontUI만 짜면 별 상관 없겠지만 통신 기능만 들어가도 객체 직렬화 때문에 고려할 수 밖에)






믓튼, 이걸 더 쉽게 쓸 수 있다.


var b={(n:Int) -> Int in return n*n}


b(3) 하면 9가 나온다.






더 쉽게 쓸 수도 있다.


var c:(Int) -> Int


c={$0 * $0}


c(3)






bash shell programming을 많이 했던 사람에게는 별 이상할 게 없다.






Activity = ViewController


List View = Table View


Function Pointer, Instance = closer + new programming rules라고 보면 된다.


등 용어가 바뀌는 게 있지만 사실 안드로이드에게 바뀐 건 API 네임뿐.


애플이 삼성 베끼고, 삼성이 애플 베끼듯이 정책이 결국 requirement인데 requirements가 같아지다 보니 그걸 구성하는 system, architecture, module도 같아질 수밖에 없다. 즉, 메커니즘도 별반 차이 없다는 이야기. 애플이 파워칩을 계속 생산했으면 모르겠으나 어차피 Intel base고 각 회사 엔지니어들이 서로 이직을 하는 이상 바뀌는 것은 이름뿐일 거라는.






(5) Array


선언 방법은 다양하다.


var a = [Bool]()


var b : [Int] = []


a = [true, false, (3==3)]


var c = Array(repeating : true, count : 5)


var d : [Int ] = [1, 2, 3, 4]






이와 같이 선언을 먼저하고, 값을 넣는 방법도 있다.


개인적으로 변수가 nil을 포함한다는 개념인 Optional(?)이 있으니


C/C++과 비슷하게


var e : [Character]? = nil 을 선호한다.






배열을 JAVA의 ArrayList 처럼


var chart : [Character] = ["A", "�"]


chart.append("d")


chart += ["4", "5"]


chart.insert("h", at: 1)


chart.remove(at: 2)


편하게 넣었다 뺐다 할 수 있으니 자주 쓴다.






(6) for loop


()가 없는 점이 다르다. 


var weekdays : [String] = ["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"]






for index in 0...6 { //for index in 0..< 7 { 요렇게 해도 된다.


print(weekdays[index])


}






for index in 0...(weekdays.count-1) { //이렇게도


print(weekdays[index])


}






for day in weekdays {


print(day)


}






이런 식으로 쓴다. JAVA에도 for(String a : Iteratores), C++에서 for each(String a in ...) 하고 쓰는 것과 같기 때문에 편하게 볼 수 있다. 다만 ... , ..< 문법이 좀 생소할테지만 쓰다보면 더 직관적라는 것을 알게 된다.






(7) enum


enum integers : Int {


case one


case two


case three


}






print(integers.one.rawValue)


0


보통 enum 은 rawValue를 뽑아내기 위해 쓰는 개념이 아니긴하지만 이렇게 값을 뽑아낼 수 있는 방법이 있다는 뜻.






(8) casting


자바에서는 (String)을 했지만 as를 쓴다.


value as! Int


같이.






4. 조금 더...


struct 는 메소드 없이 멤버변수만 있는 자료형, 


struct myStruct {


var a : String?


var b : Int?


}






var c = myStruct()


c.a = "hello"


print(c.a!)






class의 경우 메소드 포함. Swift 용어로는 프로퍼티, 펑션이 둘 다 있는 class, 프로퍼티만 있으면 struct . 이 정도 개념이면, 맥으로 개발하는데 별 무리 없이 금방 적응하리라 생각된다. JAVA 던, 코틀 린이던, Swift 던 base 코드는 어셈블리랑 C일 수밖에 없어서... 다만 그들이 쌓아 올린 개념이 거대한 프로그램(프레임웍)인 경우 안 무너지기를 바라지만. 내 경험상 칩 단까지 디버깅을 해야 하는 상황도 오기 때문에 결국 안 무너지지는 않는다.






그냥 프런트 UI에 집중하고, 아키텍처나 모듈 단위를 벗어나지 않는 범위에서 디자인 패턴으로 개발자들끼리 싸우게끔 해서 시스템을 못 보게 하는 게 공룡 기업이 하는 방식이다. 






끝으로 대부분의 상황에서 폴링 방식보다 인터럽트 방식이 좋듯. 함수 포인터로 콜백을 구현하듯이 인터페이스를 잘 뽑으면 된다. 그 콜백이 옵서버가 되고 그런 옵서버를 편하게 만들어 주는 API 라이브러리를 사용하면 그게 곧 반응형 프로그래밍이다.






내 책에서도 밝혔지만 사실 더 편한 건 그런 개발을 알아서 다 해주는 개발자 API를 쓰는 기업 사장이 최고의 프로그래머!





sudo /usr/libexec/locate.updatedb


updatedb는 linux랑 이름이 같다.


sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.locate.plist


이렇게 로딩 후 

locate 가 동작한다.


#if DEBUG

        txtID.text = "itsme"

        txtPASSWD.text = "goodToSeeU#123"

#endif


//  Copyright © 2018 hajunho.com All rights reserved.



import UIKit


//Where am I, exactly  ex) "".pwd(self)

//I recommend the codes below to a base view controller


extension String {

    func pwd(_ x: Any)  {

        debugPrint("🍭pwd_"String(describing: x.self))

    }

}


+ Recent posts