특정한 비트열을 0으로 만들거나(0을 가지고 and연산) 특정한 비트열이 0인지 조사하고 싶을 때(1을 가지고 and연산), AND을 사용한다.
위의 어셈블리 코드에서는 ands 라고 해서 뒤에 s를 붙여서 and연산의 결과를 상태레지스터에 반영하겠다고 쓰여져있다.
그래서 바로 이어서 그 상태레지스터의 결과를 바탕으로 bne 명령을 시행하고 있다.
특정한 비트열을 1으로 만들거나 특정한 비트열이 1인지 조사하고 싶을 때, OR을 사용한다.
스크립트 링커영역에 커맨드 테이블을 관리하고 있다.
그래서 우리는 테이블 구조체 U_BOOT_CMD()에다가 우리가 구현한 내용을 추가해주는것만으로, u-boot의 다른 여러 함수들의 호출관계들을 몰라도 우리가 정의한 새로운 기능을 명령어로 추가할 수 있다는 것이 u-boot의 장점이었다.
U-Boot은 C언어를 통해서 만든 커스텀 명령어로 HW제어를 쉽게 해줄수 있도록 하는 편의성을 제공한다.
유인물 4-6페이지 까지의 코드를 "~/pi_bsp/u-boot/common/" 경로에 "cmd_kcci_led.c"라는 이름의 파일을 생성했다.
그리고 유인물에 있는 코드를 그대로 적어넣었다.
그리고 나서 "~/pi_bsp/u-boot/common/MakeFile"을 켜서 8번째 라인에 아래 코드를 추가하였다.
obj-y += cmd_kcci_led.o
U-Boot> help
...
우리가 생성한 led 관련 명령어 설명이 보인다.
...
U-Boot> led
사용법도 잘 출력된다.
U-Boot> led 0x55
U-Boot> led 0xff
등등의 명령을 통해 LED를 편리하게 껐다켰다 할 수 있다.
맨 마지막의 U_BOOT_CMD(); 매크로 함수의 내부를 타고 들어가서 보면 각 파라미터가 뭘 의미하는지 알 수 있다.
U-Boot는 동적라이브러리를 전부 사용할 수 없다. 아직 부팅이 되기 전이기 때문에 atoi()같은 형식의 기본 함수도 전부 U-Boot내부에 직접 구현되어있다. 그 예가 바로 "simple_strtoul(argv[1], NULL, 16);"인 것이다.
펌웨어 프로그래밍을 하면서 시스템 레지스터를 건드릴 때 위 코드처럼 우리가 관심있는 영역 빼고 나머지를 전부 0으로 설정해버리는것은 대단히 위험한 행위이다. 절대로 하면 안되는 행위이다. 다른 부분이 기존이 어떤 용도로 쓰이고 있었는지 알 방법이 없다. 그래서 함부로 0으로 바꾸면 안된다.
그래서 원래 위 코드처럼 코딩하는것은 잘못된 것이다. 반드시 Read -> Modify -> Write 3단계를 거치면서 내가 관심이 있어서 바꾸고 싶은 부분에 대해서만 수정을 하고 그 값을 다시 써줘야 한다. 그럴 때 쓰는방법이 비트마스킹이다.
내가 관심있는 비트영역에 대해서는 0으로 and 연산을 돌리고, 원래 쓰이고 있던 영역에 대해서는 1로 and 연산을 돌린다(그러면 그 영역은 원래 값으로 유지된다).
그러면
내가 관심있는 영역에 대해서 비트 형태를 적어주어 or 연산을 돌리고, 원리 쓰이고 있던 영역에 대해서는 0으로 or 연산을 돌린다(그러면 그 영역은 원래 값으로 유지된다).
이렇게 해서 만들어진 최종 비트 값을 시스템 레지스터에 입력해준다.
위와 같은 과정을 매 비트에 값을 쓸때마다 반복하면 그 자체로도 어셈블리어 레벨에서 보면 코드량이 꽤 많이 늘어난다. 그래서 STM같은 MCU들은 비트밴딩이라는 것을 통해서 그것을 해결한다.
핵심 컨셉은 모든 비트 하나하나에 남는 메모리 주소 값을 할당해놓는 것이다.
어떤 비트를 바꾸고 싶으면 위에서처럼 비트마스킹을 할 필요 없이 그냥 해당 주소값에 0이나 1을 써주는 것으로 그 비트 값이 바로 바뀌어버리는 것이다. 속도가 엄청 빨라진다.
(추가적인 내용은 STM32 교제 p.37을 참고하면 알 수 있다.)
위와 같은 Read - Modify - Write 과정을 담은 시스템 함수를 직접 만들어서 해봤는지, 아니면 그냥 STM32Cube API라이브러리 함수만 써봤는지 물어본다고 한다.
그러면 펌웨어에서 시스템 레지스터를 건드릴 때 위 3단계를 반드시 거쳐야 한다는 원리를 알고 있다는 점을 피력해야 한다는 것이다.
그래서 위와 같은 원리를 담아 수정된 코드는 아래와 같다.