본문 바로가기

프로그래밍/Keil RTX7

[C/Keil RTX] I2C 통신 임베디드 소프트웨어 개발을 하다보면 알기 싫지만 알아야 하는 많은 것들이 있다. 하기 싫지만 해야 하는 것이므로 오늘도 난 열심히 한다. 😂 I2C란? I2C (Inter-Intergrated Circuit)는 2개의 선을 이용하는 직렬 통신 방식으로, 하나의 마스터와 여러 개의 슬레이브 장치가 통신하기 위한 프로토콜이다. 데이터 통신을 위한 선(SDA) 하나와 타이밍 동기화를 위한 선(SCL) 하나로 이루어져 있다. 이러한 특징 때문에 TWI (Two Wire Interface)라고도 불린다. 우선, I2C를 이해하기 위해서는 UART 통신과 SPI 통신을 알 필요가 있다. ※ UART 통신이란? (Universal Asyncronous Receiver/Transmitter) 비동기식 시리얼 통신으로 .. 2023. 1. 5.
[C/Keil RTX] CAN 통신 요즘 하고 있는 프로젝트에서 제일 많이 사용하는 통신이 CAN 통신이다. CAN 통신은 이 프로젝트를 통해 처음 접해 보기도 했고, 그렇게 세세하게 알아보지 못한 채 개발을 해서 오늘에서야 세부적으로 파헤쳐보려고 한다. CAN 통신 배경 Controller Arean Network의 약자로 차량 내에서 호스트 컴퓨터 없이 마이크로 컨트롤러나 장치들이 서로 통신하기 위해 설계된 표준 통신 규격이다. 메시지 기반 프로토콜이며 최근에는 차량 뿐만 아니라 산업용 자동화기기나 의료용 장비, 엘리베이터 등에서도 종종 사용되고 있다. 각 제어기들 간의 통신을 위해 주로 사용되는 non-host 버스 방식의 메시지 기반 네트워크 프로토콜이다. CAN 통신이 개발되기 전까진 과거에는 모듈들이 통신하기 위해 UART 통신.. 2023. 1. 3.
[C/RL-ARM KEIL] event 처리 구현 CAN0_IRQHandler 로 들어온 응답을 __task 함수에서 처리하고 싶은데 마땅히 좋은 방법이 없어 찾다가 ARM Library에서 os_evt_set 이라는 함수를 발견했다. 냅다 갖다 써보기~! 예제에서 다뤄볼 RL-ARM 함수는 아래와 같다. isr_evt_set os_evt_set os_evt_clr os_evt_wait_and os_evt_wait_or os_evt_get 우선, 각 함수에 대해 알아보자 os_evt_set #include void os_evt_set ( U16 event_flags, /* Bit pattern of event flags to set */ OS_TID task ); /* The task that the events apply to */ U16 event_.. 2022. 12. 28.
WDT이란? Watchdog이란? 임베디드를 다루다보면 시스템 적인 문제로 또는 프로그램의 오류로 중단 상태에 빠지거나 무한 루프에 빠질 때가 있다. 이런 경우 스스로 살아날 수가 없고 계속 멈춰있기 때문에 다시 살릴 수 있는 방법을 찾아보다가 WDT (Watchdog) 라는 것을 알게 됐다. 와치독(워치독) / WDT / Watchdog 이란? 컴퓨터의 오작동을 탐지하고 복구하기 위해 쓰이는 전자 타이머라고 한다. 정상 작동 중의 컴퓨터는 시간이 경과하거나 타임아웃이 되는 것을 막기 위해 정기적으로 와치독 타이머를 재가동 시킨다. 즉, 일정 시간 동안 시스템을 감시하다가 시스템을 리셋하는 기능을 뜻한다. Watchdog 와치독은 집을 지킨다는 뜻을 내포하고 있는 단어의 조합이다. 개에게 밥을 주지 않는다면 그 밥을 주는 프로그램을 맡고.. 2022. 12. 28.
[C/RL-ARM KEIL] thread 대신 os_tsk_create 사용하기 커널에 올리는 코드라 그런지 thread를 사용할 수 없다. 대신, thread처럼 사용할 수 있는 os_tsk_create를 사용하자! int main(void) { ... os_sys_init(os_init); ... } os_sys_init 함수는 RTX(Real-Time eXecutive) 커널을 초기화하고 시작할 수 있는 함수이다. 그 안에 인자로 커널이 초기화된 후 시작할 태스크 함수를 넣어주자. __task void os_init(void) { // 1 os_tsk_create(Test1, 3); // 2 os_tsk_create_ex(Test2, 1, (void *)0); os_tsk_delete_self(); } os_tsk_create(테스크 함수, 우선순위); os_tsk_create.. 2022. 12. 1.
[C/RL-ARM KEIL] 포인터 사용하기 (malloc 대체) keil에서 malloc을 사용하면 계속 hard fault error가 난다.... 삽푸다가 결국 알아낸 방법. rtx 함수를 이용하는 것이다! // 1 #include // 2 typedef struct { PILOT_STATE m_state; PILOT_STATE (*GetState)(void); void (*SetState)(PILOT_STATE pstate); } Pilot; // 3 _declare_box(g_poolPilot, sizeof(Pilot), 1); 1 : RTL.h 함수 선언 2 : 사용하려는 포인터 구조체 선언 3 : _declare_box(pool 변수 이름, 포인터 구조체 사이즈, 포인터 개수) 위와 같이 전역으로 선언을 해줬으면, 초기화를 해주자. // 1 Pilot* g.. 2022. 12. 1.
[C/Keil RTX] GPIO INPUT 이벤트 처리 (IRQHandler) 나는 PA.6을 EINT0으로 설정하려고 한다. // 1 SYS->GPA_MFPL = SYS_GPA_MFPL_PA6MFP_INT0; // 2 SYS->GPA_MFPL = (SYS->GPA_MFPL & (~SYS_GPA_MFPL_PA6MFP_Msk) ) | SYS_GPA_MFPL_PA6MFP_INT0 ; 1 또는 2 방법으로 설정해주면 된다. 그 다음 아래와 같이 설정해주기. // a GPIO_SetMode(PA, BIT6, GPIO_MODE_INPUT); // b GPIO_EnableInt(PA, 6, GPIO_INT_BOTH_EDGE); // c NVIC_EnableIRQ(EINT0_IRQn); // d GPIO_ENABLE_DEBOUNCE(PA, BIT6); a : PA.6 핀을 input 모드로 설.. 2022. 12. 1.