블로그 이미지
안녕1999

카테고리

전체 (3067)
자바스크립트 (20)
안드로이드 (14)
WebGL (4)
변비 (17)
정치,경제 (35)
C언어,ARM (162)
컴퓨터(PC, Note Book, 윈.. (41)
전자회로, PCB (27)
유머,안웃긴,GIF,동영상 (118)
국부론60 (71)
모듈(PCB) (3)
건강 (2)
FreeCAD (25)
PADS (43)
퇴직,퇴사,구직,취업 활동 (3)
C# (86)
엑셀 (8)
워드 (0)
LabView (6)
레고 (30)
FPGA (0)
Total
Today
Yesterday

달력

« » 2025.3
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31

공지사항

최근에 올라온 글

'C언어,ARM' 카테고리의 다른 글

AVR Studio - ATXMega 펌웨어 다운로드  (0) 2020.05.30
ATXMega-클럭 변경  (0) 2020.05.30
남에 소스코드 분석하기  (0) 2020.05.22
ARM cortex 업체별 코드 호환성  (0) 2020.05.09
STM32 - ST-LINK download  (0) 2020.05.09
Posted by 안녕1999
, |



남이 짜놓은 소스코드를 유지보수하는 일을 맏게되었습니다.
이전 담당자는 2년경력자이고, 전자과를 졸업하여, 소프트웨어, 펌웨어를 잘 작성하지는 못하지만, 자신만의 방식으로 그럭저럭 잘 사용해온것 같다.
물론, 이전에 다른사람이 작성해 놓은 코드를 가져다가 사용한 흔적도 있다.

자료구조를 잘 몰라, 좀 이상하게 작성해 놓았다.
소스코드를 보자 마자 머리가 아파온다.
초보자들은 보통 쉬운것을 빙빙 돌려서 어렵게 작성한다.
버그가 생길만한곳도 많다.
과연 제대로 돌아가는걸까?
여기저기서 버그 발생소지가 있는 코드들이 보인다.
아이고 머리야...
새로 작성하는건 어렵지 않으나, 기존 시스템과 호환성을 유지하는건 쉽지않다.

시스템을 완전히 이해하고 새로작성하든가, 시스템에 맞게 잘 고쳐써야한다.
둘다 어렵다.
시스템에서 변경 불가능한 부분이 있다면, 변경할 수 없다.
그냥 잘 고쳐쓰는것도 한계에 다다르면, 방법이 없다.

몇일 분석해보고, 어떻게할지 결정해야한다.

본론으로 들어가서, 남에 코드가 문제가 없는지 확인하는 방법은 사용하는 데이터를 모두 넣어보고, 문제점을 찾는것이다.
물론, 변수값이 많아지면, 이것도 불가능이 될 수 도 있다.

보통은 중간중간 디버깅코드를 넣어서, 해당 변수값의 범위를 알아낸다.
또한 특정 값이 입력될때 버그가 없는지 확인한다.

입력값은 데이터로 미리 넣어놓고, 실제로 입력을 받은것처럼 동작을 시켜보는 것이다.
완벽하게 분석하려면, 많은 부분에서 코드수정이 이루어져야하는 경우가 대부분이고,
일부 코드는 아예 처음부터 다시작성하는것이 쉬울 수도 있으나, 새로작성한 코드에 문제가 생기면 책임은 본인에게 돌아간다.

요약 : 거의 대부분의 코드를 검증해야하며, 쉽지않은 작업이다.

'C언어,ARM' 카테고리의 다른 글

ATXMega-클럭 변경  (0) 2020.05.30
J2Cal 계산기, RS232TestProgram3, ScreenBMPcopy  (0) 2020.05.25
ARM cortex 업체별 코드 호환성  (0) 2020.05.09
STM32 - ST-LINK download  (0) 2020.05.09
SMT32 - UART1 설정  (0) 2020.05.09
Posted by 안녕1999
, |

ARM cortex cpu 제조 업체별로 코드호환성 조사

제조사별로 주변장치(peripheral,module,interface)들이 달라서,
ARM 코어(core)는 거의 동일하나, 주변장치코드는 거의 다르다.
예) 업체1의 CPU는 USART가 있지만 업체2는 UART만 있다.
     (드라이버에 사용가능한 기능을 표시하는것이 있다)

마이컴용 간단한 cmsis UART드라이버는 없는듯.
리눅스타입의 드라이버는 존재.
예) Driver_USART.h (소스코드는 작성해야한다)
fsl_uart_cmsis.h
fsl_uart_cmsis.c <<-- 이 코드는 제조업체에서 작성
사용자는 ARM_DRIVER_USART를 사용하여 프로그램.(UART0_InitPins()등을 직접 호출하여 사용할 수 도 있다)
ARM_DRIVER_USART는 UART0_InitPins()등의 함수를 호출
void UART0_InitPins(void)함수는 RTE\Board_Support\MKV31F512VLL12\pin_mux.c 등에 있다.

typedef struct _ARM_DRIVER_USART {
  ARM_DRIVER_VERSION     (*GetVersion)      (void);                              ///< Pointer to \ref ARM_USART_GetVersion : Get driver version.
  ARM_USART_CAPABILITIES (*GetCapabilities) (void);                              ///< Pointer to \ref ARM_USART_GetCapabilities : Get driver capabilities.
  int32_t                (*Initialize)      (ARM_USART_SignalEvent_t cb_event);  ///< Pointer to \ref ARM_USART_Initialize : Initialize USART Interface.
  int32_t                (*Uninitialize)    (void);                              ///< Pointer to \ref ARM_USART_Uninitialize : De-initialize USART Interface.
  int32_t                (*PowerControl)    (ARM_POWER_STATE state);             ///< Pointer to \ref ARM_USART_PowerControl : Control USART Interface Power.
  int32_t                (*Send)            (const void *data, uint32_t num);    ///< Pointer to \ref ARM_USART_Send : Start sending data to USART transmitter.
  int32_t                (*Receive)         (      void *data, uint32_t num);    ///< Pointer to \ref ARM_USART_Receive : Start receiving data from USART receiver.
  int32_t                (*Transfer)        (const void *data_out,
                                                   void *data_in,
                                             uint32_t    num);                   ///< Pointer to \ref ARM_USART_Transfer : Start sending/receiving data to/from USART.
  uint32_t               (*GetTxCount)      (void);                              ///< Pointer to \ref ARM_USART_GetTxCount : Get transmitted data count.
  uint32_t               (*GetRxCount)      (void);                              ///< Pointer to \ref ARM_USART_GetRxCount : Get received data count.
  int32_t                (*Control)         (uint32_t control, uint32_t arg);    ///< Pointer to \ref ARM_USART_Control : Control USART Interface.
  ARM_USART_STATUS       (*GetStatus)       (void);                              ///< Pointer to \ref ARM_USART_GetStatus : Get USART status.
  int32_t                (*SetModemControl) (ARM_USART_MODEM_CONTROL control);   ///< Pointer to \ref ARM_USART_SetModemControl : Set USART Modem Control line state.
  ARM_USART_MODEM_STATUS (*GetModemStatus)  (void);                              ///< Pointer to \ref ARM_USART_GetModemStatus : Get USART Modem Status lines state.
} const ARM_DRIVER_USART;

 

cmsis 드라이버코드를 잘 사용하면, 쉽게 프로그램 작성이 가능하나,
코드 효율성은 매우 나빠보인다.
덩치가 크고, 메모리도 사용할것 처럼 보인다.

'C언어,ARM' 카테고리의 다른 글

J2Cal 계산기, RS232TestProgram3, ScreenBMPcopy  (0) 2020.05.25
남에 소스코드 분석하기  (0) 2020.05.22
STM32 - ST-LINK download  (0) 2020.05.09
SMT32 - UART1 설정  (0) 2020.05.09
error C2733: wmemchr  (0) 2020.05.01
Posted by 안녕1999
, |

'C언어,ARM' 카테고리의 다른 글

남에 소스코드 분석하기  (0) 2020.05.22
ARM cortex 업체별 코드 호환성  (0) 2020.05.09
SMT32 - UART1 설정  (0) 2020.05.09
error C2733: wmemchr  (0) 2020.05.01
디지털 오실로스코프 프로그램  (0) 2020.04.18
Posted by 안녕1999
, |

SMT32 - UART1 설정

C언어,ARM / 2020. 5. 9. 22:18

UART설정하려면,

/* Enable GPIO clock */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
/* Enable UART clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

 

2가지를 꼭 해주어야하는데,

USART1이 AHB1,APB2,... 어디 붙어있는지 알기위해서는, 데이터시트를 뒤지던가, 코드를 뒤지던가 해야한다.

이럴때, 헤더파일만 찾아보면, 쉽게 알 수 있다.

stm32f2xx_rcc.h
/** @defgroup RCC_APB2_Peripherals 

  * @{

  */ 

#define RCC_APB2Periph_TIM1              ((uint32_t)0x00000001)

#define RCC_APB2Periph_TIM8              ((uint32_t)0x00000002)

#define RCC_APB2Periph_USART1            ((uint32_t)0x00000010)

#define RCC_APB2Periph_USART6            ((uint32_t)0x00000020)

#define RCC_APB2Periph_ADC               ((uint32_t)0x00000100)

#define RCC_APB2Periph_ADC1              ((uint32_t)0x00000100)

#define RCC_APB2Periph_ADC2              ((uint32_t)0x00000200)

#define RCC_APB2Periph_ADC3              ((uint32_t)0x00000400)

#define RCC_APB2Periph_SDIO              ((uint32_t)0x00000800)

#define RCC_APB2Periph_SPI1              ((uint32_t)0x00001000)

#define RCC_APB2Periph_SYSCFG            ((uint32_t)0x00004000)

#define RCC_APB2Periph_TIM9              ((uint32_t)0x00010000)

#define RCC_APB2Periph_TIM10             ((uint32_t)0x00020000)

#define RCC_APB2Periph_TIM11             ((uint32_t)0x00040000)

#define IS_RCC_APB2_PERIPH(PERIPH) ((((PERIPH) & 0xFFF8A0CC) == 0x00) && ((PERIPH) != 0x00))

#define IS_RCC_APB2_RESET_PERIPH(PERIPH) ((((PERIPH) & 0xFFF8A6CC) == 0x00) && ((PERIPH) != 0x00))

 

//TX=PA9,RX=PA10
#define UART1_GPIOx    GPIOA
//#define UART1_BaudRate	115200
//#define UART1_BaudRate	57600
//#define UART1_BaudRate	38400
#define UART1_BaudRate    9600
void UART1_Init()
{
    USART_InitTypeDef ui;GPIO_InitTypeDef g;NVIC_InitTypeDef n;

    /* Enable GPIO clock */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
    /* Enable UART clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

    /* Connect PXx to USARTx_Tx*/
    GPIO_PinAFConfig(UART1_GPIOx,GPIO_PinSource9,GPIO_AF_USART1);
    /* Connect PXx to USARTx_Rx*/
    GPIO_PinAFConfig(UART1_GPIOx,GPIO_PinSource10,GPIO_AF_USART1);

    /* Configure USART Tx as alternate function  */
    g.GPIO_OType=GPIO_OType_PP;
    g.GPIO_PuPd=GPIO_PuPd_UP;
    g.GPIO_Mode=GPIO_Mode_AF;
    g.GPIO_Pin=GPIO_Pin_9;
    g.GPIO_Speed=GPIO_Speed_2MHz;//GPIO_Speed_50MHz;
    GPIO_Init(UART1_GPIOx,&g);

    /* Configure USART Rx as alternate function  */
    g.GPIO_Mode=GPIO_Mode_AF;
    g.GPIO_Pin=GPIO_Pin_10;
    GPIO_Init(UART1_GPIOx,&g);

    /* Enable USART Interrupt */
    n.NVIC_IRQChannel=USART1_IRQn;
    n.NVIC_IRQChannelPreemptionPriority=15;//0~15 lower priority value indicates a higher priority
    n.NVIC_IRQChannelSubPriority=15;
    n.NVIC_IRQChannelCmd=ENABLE;
    NVIC_Init(&n);

    /* USART configuration */
    ui.USART_BaudRate=UART1_BaudRate;
    ui.USART_WordLength=USART_WordLength_8b;
    ui.USART_StopBits=USART_StopBits_1;
    ui.USART_Parity=USART_Parity_No;
    ui.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
    ui.USART_Mode=USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART1,&ui);

    /* Enable Receive interrupts */
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//Receive Data register not empty interrupt
    //USART_ITConfig(UART1_GPIOx, USART_IT_TXE, ENABLE);//Transmit Data Register empty interrupt
    //USART_ITConfig(UART1_GPIOx, USART_IT_TC, ENABLE);//Transmission complete interrupt

    /* Enable USART */
    USART_Cmd(USART1,ENABLE);
}
void UART1_write(void *pdata,int len)
{
    byte *p=(byte*)pdata;
    while(len)
    {
        UART1_WRITE_BYTE(*p);
        p++;
        len--;
        while(UART1_IS_TX_END()==0)
        {
            CPU_sleep();
        }
    }
}
void UART1_putch(char a)
{
    UART1_write(&a,1);
}
void UART1_puts(char *s)
{
    UART1_write(s,strlen(s));
}
Posted by 안녕1999
, |

error C2733: wmemchr

C언어,ARM / 2020. 5. 1. 13:25

error C2733: wmemchr

PC를 바꾸었더니, 에러발생

원인 : *.c 파일에서 wmemchr관련 헤더파일 include(찾기가 쉽지 않음)

해결책 : ??

임시 해결책 : WCHAR.H에서 아래코드 주석처리

/*inline wchar_t *wmemchr(wchar_t *_S, wchar_t _C, size_t _N)
        {return ((wchar_t *)wmemchr((const wchar_t *)_S, _C, _N)); }
inline wchar_t *wcschr(wchar_t *_S, wchar_t _C)
        {return ((wchar_t *)wcschr((const wchar_t *)_S, _C)); }
inline wchar_t *wcspbrk(wchar_t *_S, const wchar_t *_P)
        {return ((wchar_t *)wcspbrk((const wchar_t *)_S, _P)); }
inline wchar_t *wcsrchr(wchar_t *_S, wchar_t _C)
        {return ((wchar_t *)wcsrchr((const wchar_t *)_S, _C)); }
inline wchar_t *wcsstr(wchar_t *_S, const wchar_t *_P)
        {return ((wchar_t *)wcsstr((const wchar_t *)_S, _P)); }*/
Posted by 안녕1999
, |

오실로스코프가 없어서, CPU 남는 핀으로 7개입력 받을 수 있도록 만들어 봤다.
입력핀은 외부인터럽트를 사용.
통신은 UART
SPI통신
PC-----(RS232)-------CPU

CPU-------+--(SPI)---------IC
              |
GPIO<----+

정확하게는 안됨(딜레이가 어느정도 있어야함)
하드웨어 SPI통신은 고속이라, 안됨.(128분주해도 안됨. 진짜 오실로 스코프가 있어야함.)
소프트웨어 방식으로 SPI통신.(딜레이를 소프트웨어에서 조정)

검증 후, 고속으로 동작 예정.






 

Posted by 안녕1999
, |

5>xDialog.obj : error LNK2001: "public: virtual struct CRuntimeClass * __thiscall CxDialog::GetRuntimeClass(void)const " (?GetRuntimeClass@CxDialog@@UBEPAUCRuntimeClass@@XZ) 외부 기호를 확인할 수 없습니다.
5>E:\xProject\Debug\xmain.exe : fatal error LNK1120: 1개의 확인할 수 없는 외부 참조입니다.

 

 

원인: 아래 코드 없음

IMPLEMENT_DYNAMIC(CxDialog, CDialogEx)

Posted by 안녕1999
, |

버튼 DrawItem

C언어,ARM / 2020. 4. 11. 23:26

버튼 DrawItem

void xButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	...
	TCHAR sCaption[1024];
	RECT r=lpDrawItemStruct->rcItem;

	GetWindowText(sCaption,_countof(sCaption));
	pDC->SetBkMode(TRANSPARENT);
	if(lpDrawItemStruct->itemState & ODS_DISABLED)
	{
		pDC->SetTextColor(GetSysColor(COLOR_3DHILIGHT));
		pDC->DrawText(sCaption,&tr,DT_SINGLELINE|DT_VCENTER|DT_CENTER);
		
		OffsetRect(&tr,-1,-1);
		pDC->SetTextColor(GetSysColor(COLOR_GRAYTEXT));//pDC->SetTextColor(m_TextColor);
		pDC->DrawText(sCaption,&tr,DT_SINGLELINE|DT_VCENTER|DT_CENTER);
	}
	else
	{
		//Nomal
		if((lpDrawItemStruct->itemState & ODS_SELECTED))//Pushed
		{
			...
			OffsetRect(&tr,1,1);//shift text
		}
		pDC->SetTextColor(m_TextColor);
		pDC->DrawText(sCaption,&tr,DT_SINGLELINE|DT_VCENTER|DT_CENTER);
	}
	...
}
Posted by 안녕1999
, |

Visaul Studio 2012에서 특정 코드에 break point 적용이 안되는 문제

Visaul Studio 2012에서 특정 코드에 break point 적용이 안되는 문제
"중단점이 현재 적용되지 않습니다. 이 줄과 관련된 디버거의 대상 코드 형식의 실행코드가 없습니다."
ctrl+shift+F9 모든 브레이크 포인트 삭제해도 안됨.
원인:Relase모드에서는 최적화된 코드에 대해서 break point가 적용되어, 실제로 해당 코드가 존재하지 않을 수 도 있다.

pin 식별자 "pin"이(가) 정의되어 있지 않습니다.
원인:Relase모드에서는 최적화된 코드에 대해서 break point가 적용되어, 실제로 해당 코드가 존재하지 않을 수 도 있다.

Posted by 안녕1999
, |

최근에 달린 댓글

글 보관함