본문 바로가기

분류 전체보기876

리눅스 커널 모듈 (Linux Kernel Module) 1. Linux Kernel Module리눅스 커널 모듈은 리눅스 커널에 동적으로 로드하거나 언로드할 수 있는 코드 조각으로 커널의 기능을 확장하거나 특정 기능을 추가할 때 사용된다. 커널 모듈은 실행 중인 커널에 동적으로 추가될 수 있어 커널을 재부팅하지 않고도 기능을 추가하거나 제거할 수 있는 장점이 있다.   2. Linux Device Driver 디바이스 드라이버는 특정 하드웨어 장치를 제어하기 위해 커널에서 실행되는 소프트웨어이다. 하드웨어 장치와 커널 간의 인터페이스를 제공하여 응용 프로그램이 하드웨어를 제어할 수 있게 하는 용도로 사용되며, 대부분의 디바이스 드라이버는 커널 모듈로 구현된다. 이를 통해 사용자가 원하는 하드웨어를 커널에 동적으로 추가하거나 제거할 수 있다. 즉, 커널 모듈은.. 2024. 9. 28.
BBB ] 커널 업데이트 Host PC 정보 : Ubuntu 16.04 LTS, 64비트  1. 커널 소스 크로스 컴파일을 위한 툴체인 설치호스트는 x86이고 타겟은 ARM 아키텍처이므로 Linaro 사이트에서 크로스 컴파일을 위한 툴체인을 특정 경로에 다운받아 놓는다. https://releases.linaro.org/components/toolchain/binaries/$wget -c https://releases.linaro.org/components/toolchain/binaries/7.5-2019.12/arm-linux-gnueabihf/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz 압축 해제$tar xf gcc-linaro-7.5.0-2019.12-x86_64.. 2024. 9. 26.
BBB ] Internet over USB 설정 전원공급에 사용되는 USB 케이블을 통해 PC의 인터넷 연결을 공유해서 사용할 수 있는 Internet over USB 기능 활성화 방법   호스트(Linux PC) 설정/etc/sysctl.conf에 다음 문장 주석 해제하여 IP 패킷 포워딩 enable$sudo vim /etc/sysctl.confnet.ipv4.ip_forward=1  ifconfig 명령으로 인터넷과 연결된 인터페이스의 이름을 확인해 둔다.$ifconfig  그 다음은 매번 리부트 시마다 실행시켜야 하는 명령이라 다음과 같이 스크립트 파일로 만들어 두고 실행 권한을 부여한다.$vim usbnet.shsudo iptables --table nat --append POSTROUTING --out-interface [인터페이스명] -j.. 2024. 9. 24.
커널 소스 분석을 위한 ctags 사용법 1. ctags란? ctags는 소스 코드 파일을 분석하여 함수, 변수, 매크로 등과 같은 기호의 정의와 선언 위치를 저장한 태그 파일(tags)을 생성하는 명령어이다. 생성된 태그 파일을 Vim과 같은 에디터과 같이 사용하면 소스 코드 내에서 함수나 변수가 정의된 위치로 빠르게 이동할 수 있다.    2. ctags 설치 $sudo apt-get install exuberant-ctags     3. tags(태그 파일) 생성 리눅스 커널의 Makefile에는 tags를 생성하는 타겟 명령이 포함되어 있기 때문에 커널 소스가 위치한 디렉토리로 이동한 후 아래 명령어를 입력하면 tags를 생성할 수 있다. 커널 소스의 규모가 방대해서 이 과정은 몇시간 걸리니 할일 없을 때 실행시켜 놓으면 된다. $mak.. 2024. 9. 22.
Windows ] IP가 169.254.x.x로 설정되어 바뀌지 않을 때 해결 방법 169.254.x.x로 시작하는 IP는 PC에서 DHCP 서버에 IP 할당을 요청했지만 받지 못했을 때 윈도우에서 임의로 부여하는 IP이다. 만약 유동 IP를 사용하는 경우 DHCP 서버(가정집에서는 공유기)를 껐다 키거나 초기화하여 해결 시도해볼 수 있다. 아래에선 고정 IP를 사용하는 경우 윈도우의 IP 임의 부여 기능을 비활성화하는 방법이다.  1. ipconfig 명령을 통해 169.254.x.x로 설정된 인터페이스 명을 확인한다.ipconfig  2. 아래 명령으로 해당 인터페이스의 색인 번호를 확인한다.netsh interface ipv4 show inter     3. 확인한 색인번호를 사용해 아래 명령을 실행한다.netsh interface ipv4 set interface [색인번호] d.. 2024. 9. 20.
Ubuntu 16.04 ] 고정 IP 설정 + 디폴트 게이트웨이 우선순위 변경 1. ifconfig 명령어를 사용해 이더넷 인터페이스 명 확인$ifconfig   2. 네트워크 설정 파일 수정에디터를 사용해 설정 파일을 연다.$sudo vim /etc/network/interfaces 만약 lo 설정이 있다면 루프백 인터페이스니 그냥 두면된다. 그리고 설정하려는 인터페이스가 dhcp로 설정되어있으면 주석처리 해주고 아래와 같이 고정 IP 설정을 한다.auto eth0iface eth0 inet static address 192.168.1.100 netmask 255.255.255.0 gateway 192.168.1.1 :wq로 파일 저장 후 빠져나온다.  3. 네트워크를 재시작한다.$sudo systemctl restart networking.service   고정.. 2024. 9. 18.
Minicom 사용법 1. Minicom이란?미니컴은 리눅스 환경에서 사용되는 터미널 에뮬레이터이다.  2. Minicom 설치하기# Debian/Ubuntu 계열$sudo apt-get install minicom 3. 디바이스 인식 확인디바이스를 연결한 후 dmesg 명령어로 시스템로그를 확인해 디바이스가 올바르게 인식되었나 확인해보자. USB 시리얼 통신 장치의 경우 보통 /dev/ttyUSBx와 같은 이름으로 나타난다. 만약 올바르게 인식되지 않았다면 디바이스 드라이버를 설치해야 할 수도 있다.dmesg  4. Minicom 설정하기Minicom을 처음 실행하기 전에 통신 설정을 구성해야 한다. 이를 위해 -s 옵션을 사용해 설정 메뉴를 열고 설정한다.sudo minicom -sSerial port setup: 직렬 .. 2024. 9. 16.
Ubuntu ] 터미널 관련 단축키 Ctrl + Alt + T : 새로운 터미널 창 열기Ctrl + Shift + T : 현재 터미널 창에서 새로운 탭 열기Ctrl + Shift + N : 새로운 터미널 창 열기Ctrl + D : 현재 터미널 탭이나 창을 종료Ctrl + Page Up/Page Down : 터미널 탭 간 이동Alt + 숫자키 : 해당 번째 터미널 탭으로 이동 exit : 터미널 세션 종료clear : 터미널 화면 지우기reset : 터미널 리셋 Ctrl + C : 현재 명령어 중지Ctrl + Z : 현재 작업을 백그라운드로 일시 중지, fg 명령어로 다시 실행 가능 Ctrl + Shift + C : 터미널에서 텍스트 복사Ctrl + Shift + V : 터미널에 텍스트 붙여넣기 2024. 9. 14.
Ubuntu ] 화면 캡쳐(스크린샷) 단축키 전체 화면 캡쳐 : PrtScPrint Screen 키를 누르면 현재 화면 전체가 캡쳐 된다. 캡쳐된 이미지는 ~/Pictures 폴더에 저장된다.현재 활성창 캡쳐 : Alt + PrtSc현재 활성화된 창만 캡쳐된다.선택 영역 캡쳐 : Shift + PrtSc마우스로 캡쳐할 영역을 선택할 수 있다.선택 영역 캡쳐 + 캡쳐한 사진 클립보드에 복사 : Ctrl + Shift + PrtSc선택 영역 캡쳐 이후 Ctrl + V 로 붙여넣기 가능하다. 2024. 9. 12.
Ubuntu ] Num lock 키 자동 활성화 하기 Ubuntu에서 부팅 시 Num lock 키가 비활성화 되어 있어 매번 눌러줘야 하는 불편함이 있다. 이를 해결하기 위한 방법을 소개한다.    1. numlockx 설치$ sudo apt install numlockx  2. LightDM 디스플레이 매니저 구성 파일을 에디터로 열기sudo vim /usr/share/lightdm/lightdm.conf.d/50-unity-greeter.conf  3. 맨 아래 문구 추가하기greeter-setup-script = / usr / bin / numlockx on   이렇게 하면 로그인 화면에서 Num lock 키가 자동 활성화 된다. 2024. 9. 10.
ADC SNR ADC SNR (Signal to Noise Ratio) 신호와 잡음의 비율을 나타내는 SNR은 ADC 회로 상에서 발생하는 노이즈와 신호의 비율을 나타내기 위해서도 사용한다. 즉, 해당 값이 클수록 설계한 ADC 시스템이 신호에 비해 잡음이 얼마나 적고, 신호를 얼마나 정확하게 전달하는지 나타낸다. 이전 글(https://eteo.tistory.com/917)에서도 설명하였는데 SNR은 신호 수준 대 노이즈 수준의 비에 상용로그를 취한 뒤 20을 곱하여 dB 스케일로 표현한다. 단, ADC SNR을 말할 때의 '노이즈'는 양자화 오류만을 고려한 값이다. SNR은 내부 회로의 잡음이나 열 잡음, 전자기 간섭이로 인한 잡음 등 추가 잡음원을 고려하지 않고 양자화 오류만을 고려한 이상적인 값으로 ADC 시스.. 2024. 9. 8.
OP Amp 연산증폭기(OP-Amp, Operational Amplifier)는 회로 설계에 따라 다양한 용도로 사용될 수 있다. 몇가지 기본 회로에 대해서 한 번 알아보자.      1. 버퍼 (Buffer) - 구성 : 연산 증폭기의 비반전 입력(+)에 신호를 연결하고, 출력은 반전 입력(-)으로 피드백 된다 - 특징 전압 이득이 1이라서 입력 신호가 그대로 출력으로 전달되는데, 입력 전압과 출력 전압이 동일한 점 때문에 전압 팔로워(Voltage Follower)라고도 부른다.버퍼 회로는 입력 임피던스가 매우 높고 출력 임피던스가 낮아 입력 신호를 다른 회로에 전달할 때 소스 신호에 영향을 미치지 않고 전압 수준을 그대로 유지하면서 전달하는 용도로 사용된다.        2. 비교기 (Comparator)  -.. 2024. 9. 6.
Visual Studio ] 빌드 도구 추가 설치하기 시작 - Visual Stduio Installer 실행  수정 클릭     개별 구성 요소에서 키워드로 검색 후 수정 버튼을 눌러 설치 2024. 9. 4.
C++ ] 가변 인자 템플릿(Variadic Templates) 활용 C++ 11에서 도입된 가변 인자 템플릿이란 함수가 불특정 다수의 여러 인자를 받을 수 있게 해주는 기능이다. 가변 인자 템플릿은 C의 stdarg.h에 있는 가변 인자 매크로들과 비슷한 역할을 한다고 볼 수 있는데 그 사용법에 있어서는 큰 차이가 있다. 이에 대해 한번 알아보자.   1. 템플릿(Templates)이란?템플릿은 C++에서 함수나 클래스를 정의할 때 그 타입을 일반화하여 코드 재사용성을 높이는 기능이다. 템플릿을 사용하면 특정 데이터 타입에 종속되지 않고, 다양한 타입에 대해 동일한 코드 구조를 사용할 수 있다. 템플릿을 선언할 때는 다음과 같은 구문을 사용한다. 여기서 T는 타입 매개변수로 함수나 클래스가 다양한 데이터 타입에 대해 동작하도록 일반화할 수 있게 해준다. template .. 2024. 9. 2.
Python ] os.path 모듈 파이썬의 표준 라이브러리인 os 모듈의 서브모듈인 os.path 모듈은 경로, 파일, 디렉토리에 관련된 유용한 함수들을 제공해준다.   os 모듈 import os.path 서브모듈을 사용하기 위해 os 모듈을 import 한다.import os    경로를 다룰 때 자주 사용하는 함수   os.path.join 플랫폼에 따라 올바른 경로 구분자를 사용해 여러 경로 조각을 결합해 하나의 경로를 생성한다.path = os.path.join("folder", "subfolder", "file.txt")print(path)# 리눅스에서 결과: "folder/subfolder/file.txt"# Windows에서 결과: "folder\subfolder\file.txt"    os.path.exist 주어진 경로.. 2024. 8. 30.
경기도 가평 금다래 캠핑장 입실 13시 퇴실 11시 1박에 5만원, 연박시 1박당 만원 할인 A동과 B동이 있는데 사이트는 선착순으로 선택한다. 입실시간보다 일찍 오는사람들이 꽤 있었는데 남는 자리에 설치하는거면 사장님도 용인하시는 것 같았다.B동은 계곡과 붙어있는 사이트가 있는 대신 좁은편이고, A동은 계곡과는 떨어져있지만 바로 옆에 주차가 가능할만큼 사이트 더 넓은편이다.B동 옆에는 아이들이 놀 수 있는 얕은 계곡이 있고, 캠핑장 입구쪽에는 다이빙이 가능한 깊은 계곡이 있는데 넓진 않아서 수영까진 힘들다. 개인적으로는 화장실과 샤워실이 넉넉하지 않은 점이 아쉬웠다. 2024. 8. 28.
더 뉴 셀토스 에어로 와이퍼 리필 고무 교체 방법 셀토스 프론트 와이퍼는 에어로 타입으로 리필 고무만 교체하면 되는 형태이다.물론 통째로 교체해도 되긴 하지만 고무만 교체하는게 비용이 훨씬 저렴하다. 부품번호 : 98351-3M000, 98361-2V000구입가격 : 배송비 별도 5720원   와이퍼 탈거 방법 1. 와이퍼 암을 세운다.이 때 와이퍼를 빼고 나면 쇠로된 와이퍼암이 앞유리를 쳐서 손상이 갈 수 있으므로 수건같은 푹신한 물건을 대고 작업하는 것이 좋다.  2. 잠금쇠를 열고 와이퍼를 아래로 방향으로 당긴다.   3. 와이퍼를 유리방향으로 당겨 탈거한다.와이퍼암의 끝부분이 U자 고리형인 점을 고려하여 분리하면 쉽다.  분리한 와이퍼를 잘 들여다 보면 한쪽엔 아래와 같이 홈이 있고 다른 한쪽은 홈이 없다.     리필 고무교체 방법   와이퍼 .. 2024. 8. 26.
Visual Studio ] 기존 폴더 추가하기 솔루션 탐색기 상다의 모든 파일 표시 버튼 클릭  해당 폴더 우클릭 후 프로젝트에 포함   해당 폴더에 헤더파일이 포함되어 있는 경우 추가 포함 디렉터리에 추가해주자 프로젝트 우클릭 > C/C++ > 일반 > 추가 포함 디렉터리 > 편집   매크로 사용해서 상대경로로 디렉터리 추가해주고 세미콜론으로 구분한 뒤 적용 2024. 8. 24.
오버슈트와 언더슈트 오버슈트 (Overshoot)오버슈트는 신호의 출력이 목표 값에 도달하기 위해 반응할 때 일시적으로 목표 값을 초과하여 상승하는 것을 의미한다. 언더슈트 (Undershoot)언더슈트는 신호가 목표 값으로 수렴하는 과정에서 일시적으로 목표 값보다 낮은 값을 기록하는 현상을 의미한다. 2024. 8. 22.
멀티미터를 사용해 다이오드 테스트 하는법 디지털 멀티미터(DMM)를 사용해 다이오드의 극성을 구별하거나 고장여부를 테스트 하는 방법을 알아보겠다. 그 전에 먼저 다이오드에 대해 알아보자.   다이오드 (Diode)다이오드는 전류가 한 방향으로만 흐르게 하는 특성을 가진 전자 부품으로 애노드와 캐소드라는 두 단자로 구성된다. 순방향 바이어스에서는 약 0.7V 이상의 전위차가 발생할 때 전류가 흐르기 시작하며, 역방향 바이어스에서는 전류가 거의 흐르지 않는 특징을 가진다.   다이오드의 극성 애노드 (Anode) : 전류가 들어오는 쪽의 단자로 기호에서 화살표가 가리키는 곳의 반대 부분이다.캐소드 (Cathode) : 전류가 흘러나가는 쪽의 단자로 기호에서 세로 막대기 쪽이다.   다이오드의 주요 특징 순방향 바이어스 (Forward Bias) :.. 2024. 8. 20.
파워포인트 빨간줄 없애는 법 파워포인트의 빨간 밑줄은 맞춤범 검사 결과 오류가 있을 때 생기는 것으로 파일 > 옵션 > 언어 교정 > '입력할 때 자동으로 맞춤법 검사' 체크를 해제하면 없앨 수 있다. 2024. 8. 18.
TMS320F28388D ] 링커커맨드 파일과 컴파일러 섹션 링커커맨드 파일과 컴파일러 섹션에 대한 이해...  Compiler Sections C 코드는 컴파일러를 통해 어셈블리 코드로 변환되고 어셈블리 코드는 어셈블러를 거쳐 오브젝트 파일이 된다. 모든 C 코드는 섹션이라고 불리는 여러 부분으로 분리될 수 있는데 컴파일러는 컴파일 과정에서 C 코드를 분석하여 각 섹션에 들어갈 데이터를 구분한다. 그리고 오브젝트 파일의 구성을 보면 각 섹션별로 데이터가 저장되며 이외에도 변수, 함수 등의 심볼 정보를 가지고 있는 심볼 테이블이 포함된다. 이러한 섹션의 이름에는 .text, .stack, .bss 등 공통적으로 사용되는 것들도 있지만 툴체인마다 섹션의 이름이 약간씩 다르거나 추가적인 섹션이 있을 수 있다. C28x 컴파일러의 섹션은 다음과 같다. Section N.. 2024. 8. 16.
함수발생기 50옴, High-Z 설정에 관해 (함수 발생기 출력이 2배로 측정되는 이유) 함수발생기에서 출력 임피던스를 50옴으로 설정하면 계측장비에서 측정시 진폭이 2배로 측정되는 이유는? 보통 계측장비의 입력 임피던스가 높을수록 입력이 계측장비에 영향을 주지 않기 때문에 오실로스코프의 경우 특별한 경우가 아니면 디폴트가 1MΩ 설정이다. 여기서 특별한 경우란 수 MHz 이상 높은 대역의 신호를 측정하는 경우인데 이런 고주파 신호를 전송할 때는 송신단과 수신단의 임피던스 매칭이 되지 않으면 끝단에서 신호가 반사되어 왜곡될 수 있으므로 반드시 임피던스 매칭을 시켜 신호를 관찰해야한다. 이 경우 함수발생기와 계측장비 등에서 주로 사용하는 값이 50옴이며, 이것 때문인지 함수 발생기의 디폴트 출력 임피던스 설정은 보통 50옴이다. 다만 여기서 고려해야 할게 함수발생기와 계측장비를 둘 다 50옴으.. 2024. 8. 14.
PyInstaller ] 파이썬 스크립트(.py)를 실행파일(.exe)로 만들기 PyInstaller는 파이썬 스크립트를 파이썬 인터프리터가 설치되지 않은 환경에서도 실행이 가능하도록 실행 파일로 만들어 배포할 수 있게 해주는 패키지이다.      PyInstaller 설치 pip install pyinstaller    PyInstaller 기본 사용법 실행 파일로 만들려는 파이썬 스크립트를 지정하여 PyInstaller를 실행한다.pyinstaller example.py      PyInstaller로 생성되는 주요 폴더와 파일 project_root/├── example.py # PyInstaller로 패키징할 Python 스크립트├── build/ # 빌드 과정에서 생성된 임시 파일들│ └── ..... 2024. 8. 12.
VSCode ] 코드 접기, 펼치기 단축키 Windows 기준 전체 접기 : Ctrl + K + 0(숫자)전체 펼치기 : Ctrl + K + J현재영역 접기 : Ctrl + Shift + [현재영역 펼치기 : Ctrl + Shift + ] 2024. 8. 10.
의사난수 생성기 (PRNG, Pseudo Random Number Generator) 1. 의사난수(Pseudo Random Number)란?컴퓨터는 본질적으로 계산기이기 때문에 특정 연산의 결과는 항상 동일하며 스스로 난수를 만들어낼 수 없다. 따라서 우리는 일반적으로 알고리즘을 사용해 무작위성을 흉내내는데 이를 의사난수 생성기(PRNG)라고 한다. 의사 난수 생성기는 초기값(시드)에 의해 결정되는 수열을 생성하며 같은 시드값을 사용하면 항상 동일한 수열을 생성한다. 이러한 특성 때문에 사람이 보기에는 어느정도 난수로 보이지만 진짜 난수는 아니기에 가짜 난수라는 의미로 Pseudo Random Number라고 부른다.    2. 의사난수의 종류 2.1 중앙제곱법(Middle Square Method)중앙제곱법은 존 폰 노이만이 제안한 초창기 난수 생성 알고리즘이다. 이 방법은 숫자를 제.. 2024. 8. 8.
SNR SNR (Signal to Noise Ratio)이란? 신호 대 잡음비(SNR)는 배경 잡음 수준에 비해 원하는 신호의 수준을 정량화하기 위해 사용하는 척도이다. 신호의 레벨을 노이즈의 레벨로 나누어 계산하며, 일반적으로 데시벨(dB) 단위로 표시된다. SNR이 높으면 신호가 노이즈에 비해 더 뚜렷하고 식별 가능함을 나타내고, SNR이 낮으면 신호가 노이즈와 구별하기 더 어렵다는 것을 나타낸다.       SNR의 쓰임 SNR은 다양한 분야에서 다양한 역할로 쓰인다. 예를 들어, 통신 시스템에서는 높은 SNR이 데이터 전송의 정확성을 보장하며, 오디오 장비에서는 높은 SNR이 더 깨끗한 소리를 제공한다. 이미지 처리에서는 높은 SNR이 더 선명한 이미지를 의미하고, 아날로그 신호를 디지털로 변환하는 AD.. 2024. 8. 6.
TMS320F28388D ] DAC 겸용 ADC 핀 사용시 주의점 DAC 겸용 채널인 ADCINA0, ADCINA1, ADCINB1의 경우 내부의 50k옴 풀다운이 있다.      해당 채널을 ADC로 사용시 영향성은? 만약 ADC 입력 단에 높은 값의 저항이 있다면 전압분배기를 형성하여 게인 오류를 일으킬 수 있다고 한다.    https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/839807/tms320f28075-adcina1-internal-50kohm-pulldown-resistor-question     그리고 데이터시트를 찾아보면 ADC 입력 회로의 소스 임피던스에 대한 언급도 있다. 이건 모든 ADC 채널에 적용되.. 2024. 8. 4.
배치 파일 활용하여 윈도우 명령 프롬프트에서 사용할 커스텀 명령어 만들기 1. 커스텀 명령어로 사용할 배치파일들을 모아둘 폴더를 만든다.  2. 해당 폴더를 환경 변수 path에 등록한다.내 PC > 속성 > 고급 시스템 설정 > 환경 변수 > 사용자 변수 > path에 값 추가 3. 이제 해당 폴더에 .bat 파일을 만들어 두면 을 커스텀 명령어로 쓸 수 있다.해당 명령과 일치하는 프로그램이 있는지 path에 등록된 디렉터리를 탐색할거기 때문이다.     사용예시  배치파일을 사용해 정말 다양한 기능의 커스텀 명령어를 만들 수 있지만 여기선 한가지 예시를 들어보도록 하겠다. 다음 명령들은 특정 장비와 연동 테스트 목적으로 IP를 계속 바꿨다 돌렸다할 때 유용하게 쓸 수 있다.  1. 고정 IP로 설정하는 명령 ip-static.bat@echo offREM 코드페이지를 UTF.. 2024. 8. 2.
Wireshark ] UDP 중복 패킷 식별 Wireshark에서 중복으로 UDP 패킷이 캡쳐되는 경우 IP ID값을 보고 같은 패킷인지 확인할 수 있다. Wireshark의 IP Identification 필드는 16-bit HEX 값으로 IP 패킷의 고유한 식별자로 사용된다. 물론 IP Identification 값이 같다고 해서 반드시 중복 패킷인 것은 아니고 패킷이 조각화되었을 때 동일한 IP 패킷의 일부 조각들인 경우도 있다.하지만 페이로드 등 다른 필드가 동일하고 IP Identification까지 동일한 상황인 경우 포트 미러링 등 모종의 이유로 인해 동일 패킷이 여러번 캡쳐된 것으로 판단할 수도 있다.  해당 필드를 우클릭해 Apply as Column으로 추가하면 구분이 편하다.   참고 : https://wiki.wireshark.. 2024. 7. 30.