본문 바로가기

CAN

8. HAL 드라이버 수정/추가 (3) 필터 설정 구조체와 필터 설정 함수 개선

필터 설정 파트에서 이미 필터 설정 구조체인 CAN_FilterConfTypeDef 구조체를 설명했습니다. 필터는 식별자 정보 뿐만 아니라 RTR과 IDE에 대한 정보도 들어가는데 CAN_FilterConfTypeDef 구조체의 맴버 변수를 보면 식별자와 RTR, IDE에 대한 모든 정보를 사용자가 알아서 배열한 다음 FilterIdHigh, FilterIdLow, FilterMaskIdHigh, FilterMaskIdLow 맴버 변수에 넣어주게 되어 있습니다. 좀 귀찮습니다. 하지만 CAN_FilterConfTypeDef 구조체와 HAL_CAN_ConfigFilter 함수를 새로 만들기는 더 귀찮습니다. 그래서 FilterIdHigh, FilterIdLow, FilterMaskIdHigh, FilterMaskIdLow 값을 만들어 주는 함수를 베니어(veneer) 방식으로 사용할 수 있도록 만들어 보았습니다.

uint32_t FilterID_Generator_16Bits(uint32_t ID, uint32_t RTR, uint32_t IDE)
{
    uint32_t ret;

    if (IDE == CAN_ID_STD)
    {
        ret = (ID & 0x7FF) << 5 | (RTR << 3) | (IDE << 1);
    }
    else // IDE == CAN_ID_EXT
    {
        ret = ((ID & 0x1FFC0000) >> 13) | (RTR << 3) | (IDE << 1) | ((ID & 0x38000) >> 15);
    }

    return ret;
}
void FilterId_Generator_32Bits( CAN_FilterConfTypeDef* sFilterConfig,
                                            uint32_t ID_1, uint32_t RTR_1,
                                            uint32_t ID_2, uint32_t RTR_2 )
{
    sFilterConfig->FilterIdHigh = (ID_1 & 0x1FFFE000) >> 13;
    sFilterConfig->FilterIdLow = (((ID_1 & 0x1FFF) << 3) | RTR_1 | CAN_ID_EXT) & ~(0x1U);
    sFilterConfig->FilterMaskIdHigh = (ID_2 & 0x1FFFE000) >> 13;
    sFilterConfig->FilterMaskIdLow = (((ID_2 & 0x1FFF) << 3) | RTR_2 | CAN_ID_EXT) & ~(0x1U);
}

FilterId_Generator_16Bits 함수는 FilterIdHigh, FilterIdLow, FilterMaskIdHigh, FilterMaskIdLow 맴버 변수마다 개별적으로 사용해야 되고, FilterId_Generator_32Bits 함수는 필터 설정 구조체 변수의 주소만 넣으면 FilterIdHigh, FilterIdLow, FilterMaskIdHigh, FilterMaskIdLow 맴버 변수를 알아서 채워줍니다. 위 함수 자체는 매우 간단합니다. 사실 개발자가 생각을 최대한 안할 수 있도록 만들려고 여러가지를 만들어 보다가 최종 선택된 것이 위에 있는 함수들입니다. 16비트 필터도 확장 식별자를 필터링 가능하고, 필터 길이마다 입력되는 필터의 개수가 달라서 새로운 구조체와 함수를 만들어도 사용 방법이 많이 제약되더라구요. 위에 있는 함수들이 그나마 나은 낫더라구요. 이 함수들을 사용했을 경우 필터 설정의 변화입니다. 필터와 이외 플래그들이 분리된 것을 확인할 수 있습니다.