posted by 샛별의꿈 2022. 4. 20. 13:42

VSCode 를 사용하면서 기본 폰트를 Ligature 폰트로 설정했었다.

 

최근 C와 Verilog 를 같이 보는데 Verilog 파일에서 <= 를 입력하니 

 

 

이렇게 보여버리는 문제가 생겨 버렸다.

C와 verilog 에서 의미가 다르니...

 

하지만 방법이 역시 있었다.

 

Ctrl + Shift + P를 눌러 설정을 고르는 메뉴를 열고, 

Configure Language Specific Settings...

를 찾아서 누르면 언어를 고르는 메뉴가 나오는데, 여기에서 설정을 변경하고자 하는 언어를 고른다.

그러면 나오는 화면의 좌측 탭에서 텍스트 편집기 -> 글꼴 을 선택하면 글꼴을 설정할 수 있는데,

일단은 기본 값이 설정되어 있을 것이다. 이상태에서 변경을 하면 언어별로 설정할 수 있다. 

아무것도 변경하지 않으면 기본값을 그대로 따라가고 settings.json 파일에 언어별 반영이 안되므로,

일단 Font Size 숫자를 한번 바꿔보자.

 

그리고 나서 "settings.json에서 편집" 을 눌러 열리는 settings.json 파일을 보면,

내가 선택한 언어 탭이 따로 추가되어 있을 것이다.

 

{
    "editor.fontFamily": "D2coding, Consolas, monospace, 'Courier New'",
    "editor.fontSize": 18,
    "editor.fontLigatures": false,
    "[verilog]": {
        "editor.fontFamily": "D2coding, monospace, Consolas, 'Courier New'",
        "editor.fontSize": 18,
        "editor.fontLigatures": false
    },
    "[c]": {
        "editor.fontFamily": "'D2coding ligature'",
        "editor.fontSize": 18,
        "editor.fontLigatures": true
    },
    "[c++]": {
        "editor.fontFamily": "'D2coding ligature'",
        "editor.fontSize": 18,
        "editor.fontLigatures": true
    },
    "[csharp]": {
        "editor.fontSize": 15
    },
}
 
대충 이런 식이다. 글 작성을 위해 c#을 선택하고 fontsize 만 15로 변경하고 "settings.json에서 편집" 을 눌렀다.
 
그러면 내가 바꾸고 싶은 font 탭에 fontFamily, fontLigatures, fontSize 설정 정도를 입력해 주고 저장하면 된다.
 
이후로는 언어별로 font가 설정된 대로 표시될 것이다.
 
긴 삽질은 아니었지만 아무튼 나중에 또 찾아볼 것 같으니 저장.

 

posted by 샛별의꿈 2022. 2. 28. 11:03

삽질을 안하면 하루도 편히 잠들 수 없는(아니 있는...)건지, 이번에도 또 삽질임.

 

STM32F1이나 F4, F7 계열로 쓸 때 겪어보지 못했던 문제였는데, 알고나서 생각해보니 F7에서도 충분히 발생할 만한 문제였던 것 같다.

 

UART RX를 DMA 로 사용하고, NDTR 레지스터 읽어가면서 버퍼가 채워지는 경우 처리를 했는데...

STM32H7로 했더니 갑자기 NDTR값은 바뀌는데 실제 버퍼가 채워지지 않거나 이상한 값이 나타난 것.

 

원인을 찾아보니 아래와 같은 내용 발견

https://community.st.com/s/article/FAQ-DMA-is-not-working-on-STM32H7-devices

 

Service Not Available

Your browser doesn’t support some features on this site. For the best experience, update your browser to the latest version, or switch to another browser.

community.st.com

내용에 따르면, D-Cache 를 켜는 순간 D-Cache가 SRAM에 내용을 쓰지 않고, Cache 에 데이터를 가지고 있는 문제로 인하여 SRAM에 할당된 UART 버퍼가 업데이트되지 않았던 것.

 

이를 해결하기 위해 몇 가지 방법이 있는데,

 

1. D-Cache를 사용하지 않고 모든 메모리 할당을 D1 도메인에 배치한다.

2. 캐싱이 필요한 변수 / 캐싱하지 않을 변수를 별도로 분리하고 분리배치한다. MPU에서 캐싱을 비활성화시킨다.

3. 캐시 유지관리 기능을 사용한다.

 

일단, 위와 같은 방법 중에서 1번은 손해볼 일이 많다.

실험을 위해 연산이 많으나 빨리 처리해야 하는 부분의 처리속도 측정 결과, 캐시를 사용하였을 때와 사용하지 않았을 때의 처리속도 차이가 5~6배 가량 발생하는 것을 확인하였다.

이런 속도차이를 포기하고 캐시를 비활성화시키는 건 그닥 올바른 방향은 아닌 것 같다.

 

그래서 2, 3번이 남는데 일단 3번은 메모리 할당 시 32바이트 단위로밖에 설정할 수가 없는 것 같고, 괜히 잘못 건드렸다가 Hardfault 에 빠질 수 있다는 내용이 있어 뒤로 미뤄두고(...)

 

2번을 테스트해 보기로 함.

 

이를 위해 위 문서에 자세히 설명이 되어 있지만 정리하면,

 

 1) 버퍼를 D2 Domain 에 할당한다. (DMA1/DMA2 채널이 모두 D2 Domain 에 가장 가까이 연결되어 있다)
   이를 위해, 링커스크립트 파일(*.ld) 에 아래 내용을 넣는다. 위치는 중요하지 않은 것 같지만 .bss 밑에 넣었다.
   STM32CubeIDE에서는 STM32xxxx_FLASH.ld 파일과 STM32xxxx_RAM.ld 파일 두개가 생성되는데, 처음엔 RAM쪽에만 넣어 보았으나 할당이 안되어서 FLASH 쪽에도 넣어보니 할당이 되었다. 왜 그런지는 아직 모르겠다.

   STM32CubeIDE에서 프로젝트를 기본 생성하면 링커 스크립트를 STM32xxxx_FLASH.ld 파일로 로드한다. (프로젝트 설정 -> Tool Settings -> MCU GCC Linker -> General 참고) 환경에 따라 바꿔주면 됨.

  .dma_buffer : /*Space before ':' is critical */
  {
  	*(.dma_buffer)
  } >RAM_D2

  다음으로, 버퍼로 사용할 변수를 .dma_buffer 영역에 할당하면 되는데 이 또한 위의 문서에 기록되어 있고 아래와 같이 하면 된다.

#if defined( __ICCARM__ )
  #define DMA_BUFFER \
      _Pragma("location=\".dma_buffer\"")
#else
  #define DMA_BUFFER \
      __attribute__((section(".dma_buffer")))
#endif

DMA_BUFFER uint8_t	U3_rxbuf[U3_DMA_RX_BUFSIZE];

 

 2) MPU를 설정하여 D2 Domain의 Cache 사용을 비활성화한다.

  MPU설정이 조금 헷갈리고, 아직 모르겠는 부분은 있지만 아래와 같이 하였다.

  MPU_InitStruct.Enable = MPU_REGION_ENABLE;
  MPU_InitStruct.BaseAddress = RAM_D2_ADDR;
  MPU_InitStruct.Size = MPU_REGION_SIZE_256KB;
  MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
  MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
  MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
  MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
  MPU_InitStruct.Number = MPU_REGION_NUMBER0;
  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
  MPU_InitStruct.SubRegionDisable = 0x00;
  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;

  HAL_MPU_ConfigRegion(&MPU_InitStruct);
  
  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);

  여기서 중요 포인트는 BaseAddress 속성을 D2주소값으로 설정, IsCacheable 속성을 MPU_ACCESS_NOT_CACHEABLE 로 설정, 그리고 Size를 정해줘야 하는 부분인데 D2가 288KB인데 설정가능한 크기가 32Byte 부터 배수 값으로밖에 안돼서 그냥 좀더 작은 256KB 로 선택함. Number 속성은 AN4838 문서에 구체적이진 않지만 나와있는걸 참고하면 내부메모리 영역이라서 Region 0 으로 설정하면 되는 것으로 보인다.

(아니 그렇다면 문서에 따르면 SDRAM이면 FMC 라서 Region 2여야 맞는데 예제 보면 Region 3으로 설정하던데...뭐가 맞는지 아직 모르겠다)

그외에는 우선 기본값인데 아직 문제가 발생하지는 않았다.

 

아무튼, 위와 같은 방법으로 설정하니 UART DMA RX 의 버퍼가 정상적으로 채워지는 것을 확인할 수 있었다.

 

시스템 인터럽트 부담 줄여서 마음이 편하다(이게 왜 편한지 모르겠지만)

 


2022-08-23 덧붙임.

 

위와 같이 Cache를 비활성화한 영역에 할당된 변수를 접근하려고 하니, 

Unaligned Access 에 의한 Hardfault 가 발생하였다.

처음엔 해당 변수를 사용하려는 코드의 문제라고 생각하였으나, 결론은 MPU 설정 문제.

 

MPU_RASR Register 설정 시, 각 속성들을 별도로 설정할 수 있으면 좋겠지만 원하는 기능에 따라 이미 정해진 Table 에서 설정값을 골라야 하는 것으로 보인다. 

AN4838 문서의 Table 4. Cache properties and shareability 를 참고하면,

Non-cacheable 로 설정하기 위해서는 TEX 001, Cacheable 0, Bufferable 0, Shareable(don't care) 

의 설정이 필요하다.

CubeMX 로 생성된 코드는 아래와 같다.

 

  MPU_InitStruct.Enable = MPU_REGION_ENABLE;
  MPU_InitStruct.Number = MPU_REGION_NUMBER0;
  MPU_InitStruct.BaseAddress = 0x30000000;
  MPU_InitStruct.Size = MPU_REGION_SIZE_256KB;
  MPU_InitStruct.SubRegionDisable = 0x0;
  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
  MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
  MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
  MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
  MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;

 

위와 같이 설정하니 Hardfault 에 빠지지 않고 정상적으로 Access 되는 것을 확인함.

언제나 그랬듯 나중에 또 같은 실수를 반복할테니 그때 빠른 수습을 위해 기록한다.

posted by 샛별의꿈 2020. 4. 6. 10:46

1. USB Host 기능이 이상동작한다

1) Stack / Heap 메모리 용량 늘려줘봐

 

2. HardFault Exception 으로 빠져들어간다

1) Stack / Heap 메모리 용량 늘려줘봐

2) Enable 되지 않은 Peripheral 에서 값을 읽어오는 경우 발생할 수 있다. 이러한 Logic 이 존재하는지 확인해본다.

3) Timer 여러개를 켰을때 발생할 수 있는데, 아마도 주기를 짧게 설정해놓고 콜백함수 안에서 많은 일을 수행해서 콜백함수가 끝나지 않았는데 중복호출되면서 발생하는 것으로 보임. 그리고 짧은 주기의 타이머의 인터럽트 Priority를 더 높게 잡아도 생길 수 있음. 경우가 다양하니 상황에 맞게 대처해야겠다.

4) HAL_Delay() 를 쓰니 갑자기 HardFault 로 빠지는 경우가 발생했는데, 어이없게도 해결은 다른 PC 에서 빌드하니까 그냥 됨. 환경도 CubeIDE 1.5.1 로 동일한 상황이었음. 아직 명확한 원인은 모르겠고 기회가 되면 더 찾아보겠음. 그냥 나중에 또 겪으면 고민하기전에 다른 PC에서 먼저 해보자.

 

3. SPI Comm 이 되지 않는다

1) IT 함수를 사용하면, NSS핀을 Software GPIO 로 제어하는 것이 매우 어려워진다. 실제로 NSS 핀은 1->0->1 로 원복되었는데, IT함수때문에 늦어져서 통신을 안하고 있다가 NSS가 원복된 후에서야 통신 시도를 하는 경우가 발생했다. 이건 DMA 함수라도 NSS를 Soft 로 제어할 경우는 마찬가지로 예상된다.
2) Polarity 같은 설정이 잘못되었거나, 통신속도가 Slave가 감당할 수 없을만큼 빠른 경우

3) Hardware NSS 로 설정하면, SPI를 Disable 할 때까지 NSS 가 1로 돌아오지 않는다. (원래 그런건지 버그인지 모르겠다)

관련자료는 https://community.st.com/thread/39153-spi-master-nss-always-low-in-stm32f4 참고

 

4. Timer 가 동작하지 않는다.

1) STM32CubeMX 자동생성 코드에서는 Timer Start 함수까지 다 실행시켜주진 않는다. 이건 사용자가 실행해야 할 부분.

 

5. SPI 통신시 NSS 지연시간 관련

1) SPI에서 NSS 를 컨트롤하는데 있어서 HAL 드라이버로 Software NSS 를 구현하면 NSS 제어 이후 SPI 통신을 수행하였을 때 많은 시간낭비를 초래함. (3Mbps 시 통신 전후로 약 1 datacycle(8bit) 수준의 시간낭비 발생)

  - 해결책으로, SPI HAL driver 의 통신단에서 통신시작 직전/직후에 NSS를 제어하면 상당량의 시간낭비 감축이 가능

  - GPIO HAL driver 는 거의 Lowlevel 과 다를 바 없어 그대로 써도 무방할 듯.

 

6. I2C가 안된다

1) 연결 잘 했냐?

2) 동작 순서는 잘 되었냐? 조금이라도 삐끗하면 무한루프로 가버렷!

3) Master Receiver 입장이 된다면, ACK를 무시하면 안된다. 간혹 이걸 빠뜨리면 SDA로 전송된 데이터의 마지막 비트와 같은 값이 ACK로 보내지는 경우가 생겨서, 그게 하필 NAK으로 가면 위의 말처럼 무한루프로 가버리는 지름길.(Slave Transmitter 입장에서는 보낼거 3바이트쯤 되는데 1바이트 받고선 Master가 NAK 보내고나서 Stop condition 도 안 주면 뭘 할수가 없어지게 되겠지?)

 

7. (TrueStudio 확인) 브레이크포인트 안잡았는데 엄한데에 자꾸 걸리고 진행이 안된다.

- 니가 이전에 브레이크포인트를 너무 많이 잡아서 그럼.

- 케이블 다 빼고 전원 다 빼고 다시 전원넣는다. TrueStudio 는 재시작할 필요는 없었음.

- 경험으로는 SystemClock_Config() 에서 걸리기도 했고, I2C의 Digital Filter 설정하는 함수에서도 걸린 적 있었다.

 

8. USB Mass Storage 로 hex 파일 복붙하여 F/W 다운로딩이 안된다.

- 원래 hex 지원 안함. hex2bin 으로 bin 으로 변경하여 넣자. IDE에는 bin생성 옵션 있으니 그걸로 생성해주면 더 편하다.

 

9. 코드를 작성했는데 전혀 해당 코드를 타지 않는다

- 컴파일 옵션을 내려보고, 그렇게 되면 최적화에 의한 결과이므로 해당 사용변수를 volatile 로 선언한다. 예전에 겪었던 경험이 있는데 게시판에서 같은 경험 한 사람을 보며 나도 나중에 똑같은 실수 또 할까봐 적음..

 

10. Timer 를 잘 수행중인데, HAL_Delay() 가 들어간 구문을 쓰니 갑자기 Systick 에서 무한루프 돌고 있다.

- Timer Interrupt 의 Priority 가 너무 높아서 그렇다. Systick 이 0이니까 TImer는 그보다 아랫단계로 낮추자.

(이건 System Timer 을 일반 TIM으로 바꿔주면 Priority 에 관계없이 될지도 모르겠다?)

 

11. Float 타입 변수값을 printf 했더니 값이 하나도 안 나온다.

- 링커 기본설정값에 floating point 는 사용안함으로 되어 있어 그렇다. 

프로젝트 옵션 -> C/C++ Build -> Settings -> Tool Settings -> C Linker 의 Command 에 -u _printf_float  을 넣어주면 해결...

타겟보드 FLASH가 너무 작으면 이거 하나 켰다고 플래시 오버플로우 될 수 있다. 최적화 옵션을 조금씩 올려가면서 오버플로우 안되게 맞춰봐.

 

12. EXTI 가 어쩌다 한번 발생하고 더 안된다.

- 32L476Disco 보드에서 발생한 문제였는데, 스위치 GPIO를 EXTI로 변경하고, Rising Edge Triggering 을 했다. 그랬더니 EXTI가 한번쯤 발생은 하는데 더이상 발생이 안되는 것이다. 확인해보니 하드웨어 회로적으로는 각 입력핀마다 직렬저항 하나 물려있고 병렬로 C가 하나 붙어 있고, COMMON 핀에 풀업이 걸려있어서 누르면 H가 뜨도록 되어있다. 그런데 죄다 핀이 Floating 되게 생겨먹었으니, 핀 내부에서 풀다운 걸어줘야 한다. 안그러면 이상현상 발생함. 이 글 쓰고나서 CubeMX 에서 설정된 기본값 보니 풀다운 걸려있네. 어휴 바보.

 

13. STM32CubeIDE (Eclipse 환경) 에서 한글을 적었더니 다음 실행시 작성된 한글 다 깨짐

- 기본 Encoding 값이 뭔지는 모르겠지만(비어있다), 
Window - Preferences - General - Content Types - Text 까지 클릭 후에 아래쪽 Default encoding 란에 EUC-KR 로 변경하고 저장. 기존 소스코드에 작성된 한글(이미 깨지거나 한)이 있다면 문서에 EUC-KR로 표시할수 없는 문자셋이 있다고 오류 뱉는데 깨진건 어쩔 수 없고 새로 작성해야지 뭐. CubeMX 의 자동 소스코드 생성기 녀석이 자동으로 돌리면서 깨지는 거 같다.

 

14. STM32F1 에서 UART 로(외부는 RS-422) 전송시 반응이 이상하다

- 일단, STM32의 문제라기보다는 RS-422를 연결하면서 GND 를 안 붙였을 때 문제가 되는데, USB-RS422 컨버터와 개발 보드간에 연결 선이 짧을 경우 별 문제가 없다. 그래서 괜찮은 줄 알고 막 코딩 다 하고 잘 되네 했는데...

장비에 붙이니까 안되기 시작. 오잉? 원래 붙어있던 기존보드는 통신이 잘 된다. 그럼 내 보드가 문제인건 맞으니까, 열심히 디버깅을 한다.

그런데 답이 안나와. 분명 PC->Board 로 특정 헤더가 전송되면 이에 따라 프레임 1개를 응답하도록 코드를 짰는데, 특정 헤더가 1번 왔는데 두세번씩 막 응답을 한다.

대체 펌웨어를 그렇게 안짰는데 왜 왜 왜 하다가 나온 결론은 USB-RS422 컨버터와 타겟장비 간에 GND를 연결을 안해서 노이즈때문에 발생하는 문제였다.

이상한 것은, 노이즈더라도 특정 헤더(내 경우는 3byte) 가 동일하지 않은데 왜 응답을 하느냐는 것인데, 이건 좀더 생각해봐야 할 것 같고, 이 디버깅을 하면서 발견한 이상한점은,

UART를 HAL 드라이버로 작성했는데 UART_ErrorHandler 함수가 발생해서 Error 내용을 확인해보면 값이 0(No Error) 이라는 점이다. 로직애널라이저로 보면 전송 전후로 노이즈가 많이 끼는 것을 확인하였고, 이 노이즈에 의해서 ErrorHandler가 호출되는 것으로 보인다. 아래 추가 내용과 같이 컨버터를 변경하고 나니 ErrorHandler 가 한번도 호출되지 않았다.

추가 - Coms USB to 485/422 컨버터가 노이즈에 매우 취약하다. 아니 노이즈를 만들어내는거같은?그정도의 상황. 동일한 칩셋을 쓴 Realsys CNV485 로 바꿨더니 문제 다 사라짐. 다시는 Coms 컨버터 안 쓰리라..

보드 쪽 칩은 SN65C1168E 였는데, 이게 노이즈에 좀 더 취약한 것은 아닐까도 확인해봐야겠다. 저 Coms 제품으로도 DS34C86 / DS34C87 과 인터페이스 하는데는 그닥 문제가 없었으니까.

 

15. STM32L1xx 에서 USB CDC를 포함 USB기능이 작동을 안함

분명 회로 구성할때 찾아보니 D+ D- 신호를 추가 회로 없이 USB커넥터로 바로 연결해도 된다고 했다(아마 ST정식 문서였을 것이다). 그리고 나중에 찾다 보니 STM32 내부에 D+ 라인에 풀업을 걸어주는 기능을 넣어 외부에 아무것도 연결하지 않아도 되도록 만든 것으로 보인다.

그런데, CubeMX(던 CubeIDE 내에 들어가 있는 것이든)에서 자동생성해주는 코드에 이 풀업 기능을 활성화하도록 하는 코드 생성이 빠져 있는 것이 문제였다.

CubeMX 에서 뭘 잘못 설정했으면 오류라도 떴어야 하는데 그런것도 없었고, USB 설정에서 GPIO 에 풀업 설정조차 n/a 로 나타나고 있기에 이 부분은 전혀 예상을 못 하고 있다가 

https://community.st.com/s/question/0D50X0000B5IXCVSQ4/usb-cdc-not-working-with-stm32cubemx521-and-stm32l151

위 링크에서 답을 찾았다. 

결론은 설정이 잘 되었다면, main 함수 시작되는 부분에 어디든

__HAL_SYSCFG_USBPULLUP_ENABLE();

이 매크로함수 하나만 넣어주면 끝.

LL드라이버에도 같은 기능 하는 함수가 있으니 골라쓰면 되겠다.

 

16. STLINK GDB Server 실행시 에러가 발생하고 디버깅모드로 진입되지 않는다. Error MI Command 등의 에러가 발생한다.

일단 이 상황을 설명하자면, 32L476DISCO 에 포함된 STLINK를 외부 모드로 써서 다른 타겟 보드 디버깅을 하고 있다가, 새로 산 STLINK-V3가 있어 이걸 타겟보드에 연결한 다음 디버깅을 수행했더니 타겟 보드와 연결할 수 없다며 와이어링을 점검해보라는 에러가 떴다.

그래서 다시 32L476DISCO의 STLINK로 연결했더니 제목과 같은 에러가 발생했는데..

결론적으로는 여러 STLINK를 쓰면서 Debug Configuration 이 꼬였던 것으로 보인다.

Configuration 을 제거해버리고 다시 만들어서 했더니 잘 된다.

 

17. STLINK-V3로 STM32L151 타겟보드 디버깅 연결 시 연결 에러 발생 문제

GDB Server Frequency 가 Auto로 되어 있을건데, Auto 로 하면 24MHz 로 연결시도 하는 것 같다. STM32L151이 이걸 못 받아주는거 같다. 21MHz 로 하면 된다. Configuration 가서 강제로 수치를 바꿔주자

 

18. UART LL 드라이버로 개발 시, 전원넣고 첫 부팅때는 잘 동작하다가 시스템 리셋(전원은 계속 공급 중)되는 경우(nRESET 또는 IWDG 등) 시스템이 멈추는(실제로는 수신 인터럽트 처리함수만 무한대로 실행하고 있는) 문제가 발생

조건은, 외부에서 계속 해당 UART 채널로 데이터를 송신하여 이 Peripheral 이 데이터를 수신하고 있는 경우이다. 이 때 리셋이 걸리면, 이후 시스템이 재 초기화되면서 UART채널의 인터럽트를 처리하기 위해 LL_USART_EnableIT_xxxx(); 를 수행하는 순간 USARTx_IRQHandler(); 함수가 미친듯이 호출되고 이를 처리하기 위해 다른것을 아무것도 못하는 경우가 발생한다. [왜 처음부팅엔 괜찮은거야?]

타이머보다 UART채널이 NVIC Priority 가 높게 설정해놔서 그런가 타이머도 안돌고...

 

이를 해결하기 위해서는, LL_USART_EnableIT_xxxx(); 를 수행하기 직전에 인터럽트 플래그를 초기화해줘야하는데, 어떤 특정 플래그인지 몰라서 플래그란 플래그는 다 초기화해줬다.(하나하나씩 빼보면 되겠지만 귀찮...)

아래와 같이...

-----------------------------------------------------------------------------------------

LL_USART_RequestTxDataFlush(USART6);

LL_USART_RequestRxDataFlush(USART6);

LL_USART_ClearFlag_PE(USART6);

LL_USART_ClearFlag_FE(USART6);

LL_USART_ClearFlag_NE(USART6);

LL_USART_ClearFlag_ORE(USART6);

LL_USART_ClearFlag_IDLE(USART6);

LL_USART_ClearFlag_TC(USART6);

LL_USART_ClearFlag_LBD(USART6);

LL_USART_ClearFlag_nCTS(USART6);

LL_USART_ClearFlag_RTO(USART6);

LL_USART_ClearFlag_EOB(USART6);

LL_USART_ClearFlag_CM(USART6);

LL_USART_ClearFlag_WKUP(USART6);

 

LL_USART_EnableIT_RXNE(USART6);

-----------------------------------------------------------------------------------------

이러고 나니 리셋걸려도 다시 잘 처리한다. 

이 분의 내용과 같은 문제 아닐까도 생각된다. 방법은 조금 다른 것 같지만.

https://kjt9109.tistory.com/entry/stm32-uart-interrupt-%EB%A9%88%EC%B6%94%EB%8A%94-%ED%98%84%EC%83%81-RXNEIE-disable-overrun

 

동일한 문제가 HAL Driver 기반에서도 발견되었다. 컴파일러 버그인가?

[이 글을 쓰는 시점은 20/09/11, stm32CubeIDE V1.4.2에 Toolchain 은 GNU 7-2018-q2-update 버전이다. 참고]

아무튼 HAL 에서는 이렇게 하니까 된다.

-----------------------------------------------------------------------------------------

  __HAL_UART_FLUSH_DRREGISTER(&huart1);

  __HAL_UART_CLEAR_FLAG(&huart1, UART_CLEAR_PEF);

  __HAL_UART_CLEAR_FLAG(&huart1, UART_CLEAR_FEF);

  __HAL_UART_CLEAR_FLAG(&huart1, UART_CLEAR_NEF);

  __HAL_UART_CLEAR_FLAG(&huart1, UART_CLEAR_OREF);

  __HAL_UART_CLEAR_FLAG(&huart1, UART_CLEAR_IDLEF);

  __HAL_UART_CLEAR_FLAG(&huart1, UART_CLEAR_TCF);

  __HAL_UART_CLEAR_FLAG(&huart1, UART_CLEAR_LBDF);

  __HAL_UART_CLEAR_FLAG(&huart1, UART_CLEAR_CTSF);

  __HAL_UART_CLEAR_FLAG(&huart1, UART_CLEAR_CMF);

  __HAL_UART_CLEAR_FLAG(&huart1, UART_CLEAR_RTOF);

  // EOB 플래그와 WKUP 플래그는 없다. 스마트카드 모드가 아닌 상태에선 지원안하는듯

if (HAL_UART_Receive_IT(&huart1,&u1rx,1) != HAL_OK){

  Error_Handler();

}

 

19. 특정 위치에 브레이크 포인터를 걸었는데 콘솔에 "handle_vCont_t, Thread already stopped" 출력되는 경우

   FreeRTOS 올리고 디버깅하다가 발생한 문제인데, 아직 정확히 원인은 모르겠으나 버그같음.

   STM32CubeIDE 환경에서 발생하였고, 이 문제와 잘못짠 코드 문제가 맞물려서 뭐가 문제인지 모르겠는 상황에서, CubeIDE 를 전체 종료하고 컴퓨터도 한번 껐다켰고, 다시 실행 후 프로젝트도 모두 Clean 시키고 재빌드하였음.

이후 문제가 해결됨.

  오래 삽질하지 말고 발생했을 땐 한번 모두 정리작업을 해보자. 원인을 찾으면 추후기재하자.

 

20. running 중 갑자기 hardfault_Handler() 로 빠짐

   여러가지 경우가 있겠지만 이번에 겪었던 일을 기재하자면, 

코딩 스타일이 모듈화를 시키고자 드라이버 코드에 UART Handler 포인터를 선언하고 Init 과정에서 UART 핸들을 넘겨받아서 처리하는 식으로 코딩을 하고 있다. 그래서 여느 때와 다름없이 포인터를 선언해두고 Init 과정에서 핸들을 넘겨받아 처리하고 있었는데, 갑자기 UART TX 채널에서 Hardfault 로 빠져버린 것이다.

   이상해서 추적을 해보니 핸들 포인터에 저장된 핸들이 운용 도중 갑자기 다른 값으로 오염되는 현상이 발생했다.

이전에 동작 확인을 해두고 다른 UART채널을 사용하는 코드를 추가했는데, 다른 채널이 460800bps 의 고속채널이라서 Queue 에 쌓이는 속도가 빨라서 그랬는지 모르겠으나 중간에 갑자기 핸들이 오염되고 오염된 주소값을 가지고 UART 전송을 시키려 하니 Hardfault 로 빠지는 현상이 발생한 것.

   핸들 포인터의 오염 원인은 정확하지는 않으나, 메모리 맵을 보니 바로 앞에 할당되었던 고속의 UART 채널 수신버퍼 처리 관련 변수들을 처리하는 과정에서 바로 뒤쪽 어드레스의 데이터들을 잘못 접근해서 오염시킨 것으로 보인다.

volatile, static, L1 캐시 사용 등 뭔 짓을 다 해봐도 증상은 여전했고, 거의 180Byte 의 완충용 더미변수를 중간에 두어 오염을 막았다. 

컴파일러 차이인가 싶어 MDK 쪽에서 돌려봐도 별 차이가 없고, MDK 에서는 추적도 잘 안되었던 고로 일단 CubeIDE GCC 로 사용하고, 당장은 전역 외부변수로 설정된 핸들을 직접 가져다 하드코딩 하기로 했다.

  이 내용을 쓴 지 2년 쯤 지난 거 같은데, 우연히 디버깅을 하다가 원인을 파악하였다. 

STM32F7 을 사용중이었는데, 여기에서 Data cache 를 활성화 할 경우 나타나는 현상으로 이를 disable 하면 사라지는 것을 확인하였다.

단, 내 경우엔 쓸데없이 D-Cache 를 사용하였기에 제거하여 해결하였지만 LWIP 같이 D-Cache 를 요구하는 middleware 를 사용해야 할 경우 어떻게 해야할지에 대해서는 아직 확인해보진 못하였으니 반쪽짜리 해결책인 셈이다.

 

21. CAN1 / CAN2 동시 사용 시 CAN2 수신 인터럽트 미 발생 문제

  STM32F7 사용 중 발생했고, 문제라기 보다는 잘못 했던 것임.

 각 Peripheral 별 필터뱅크를 따로 잡아야 하는데, 똑같은걸로 해서 문제가 되었었던 것.

 여튼, 아래와 같이 설정하자.

if(id==0){
  sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;
  sFilterConfig.FilterBank = 0;
  sFilterConfig.SlaveStartFilterBank = 0;//
}
else{
  sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO1;
  sFilterConfig.FilterBank = 1;
  sFilterConfig.SlaveStartFilterBank = 1;//
}

 

if(id==0)
  HAL_CAN_ActivateNotification(p_mtr_hCAN[id], CAN_IT_RX_FIFO0_MSG_PENDING);
else if(id==1)
  HAL_CAN_ActivateNotification(p_mtr_hCAN[id], CAN_IT_RX_FIFO1_MSG_PENDING);

 

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
  if(hcan->Instance == CAN1){
    HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &can1rxhdr, buffer_can1rx);
    //copy to destination
  }
}

void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
  if(hcan->Instance == CAN2){
    HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO1, &can2rxhdr, buffer_can2rx);
    //copy to destination
  }
}

 

22. 사용자 Application에서 STM32 기본 Bootloader 로 Jump하기

장비를 만들다보면 Debug 포트에 접근하기 어려울때가 참 많은데, 

이럴때 쓰라고 ST에서 기본적으로 Bootloader 탑재를 해 놓는다.

물론 Bootloader에 접근하는 방법이 처음에 켤 때 BOOT0 핀을 제어해야 한다는 것이 문제였는데,

 

문득 그냥 Application에서 Bootloader로 점프시키면 되는 거 아닌가? 하고 찾아보니 역시나..

수많은 선구자분들이 계셨던 것이었다.

 

아무튼, 많은 선구자분들의 글을 탐독하며 갖다 쓰는데,

이상하게 1200bps로밖에 접근이 안되는 거다.

 

왜죠? 왜때문이죠? 하면서 스코프 찍어보니 1200bps 말고는 전부다 Frame Error 가 발생하는 상황..

USB-RS232 컨버터 문제인가 싶어서 PC에서 온갖 설정도 바꿔보았는데 그것도 아니고...

하여 찾다가 아래 글을 발견하였다.

https://www.os4all.com/103

 

STM32F103 DFU BOOTLOADER로 펌웨어 업데이트하기 내용 업데이트

이전에 올린 글 STM32F103 DFU BOOTLOADER로 펌웨어 업데이트하기의 내용을 수정했습니다. STM32CubeMx의 버전이 바뀌면서 STM32CubeMx가 만들어 주는 코드가 달라져서, 이전의 방법대로 만든 프로젝트는 제

www.os4all.com

그리고 위 블로그분의 글에서 타고간 링크

https://stm32f4-discovery.net/2017/04/tutorial-jump-system-memory-software-stm32/

 

Tutorial - Jump to system memory from software on STM32 - STM32F4 Discovery

One of you are already familiar with STM32 feature of embedded bootloader for software download to flash. This memory is called system memory and is normally accessible with BOOT configuration (either pin hardware or option bytes (later OB) in flash soft

stm32f4-discovery.net

 

아...초기화를 잘못하였구나.

클럭이 잘못되어 통신속도를 못 맞추는 모양이었다.

 

아무튼 그래서 아래와 같이 하여 정상적으로 Bootloader로 점프된다.

프로세서 바꾸면 addr 값 정도만 바꿔주면 될 것 같다.

void resetTosystemBoot(void)

{

    void (*SysMemBootJump)(void);

    volatile uint32_t   addr;

 

    addr = 0x1FF00000//For F7 Series

//  addr = 0x1FF09800; //for H7 Series

 

    //HAL De-Initialization

    HAL_DeInit();

 

    //RCC De-Initialization

    HAL_RCC_DeInit();

 

    //Interrupt Clear

    for(int i = 0i<8i++){

        NVIC->ICER[i] = 0xFFFFFFFF;

        NVIC->ICPR[i] = 0xFFFFFFFF;

        __DSB();

        __ISB();

    }

 

    //Systick initialization

    SysTick->CTRL = 0;

    SysTick->LOAD = 0;

    SysTick->VAL = 0;

 

    //Stack Pointer set to Bootloader

    SysMemBootJump = (void (*)(void)) (*((uint32_t *)(addr+4)));

    __set_MSP(*(uint32_t *)addr);

 

    //Jump

    SysMemBootJump();

 

}

 

23. CAN에서 수신인터럽트 안 되는 상황(2)

  에..뭐 항상 내가 잘못이지만, 나중에 또 같은짓을 반복할거같아서 적자면

  CAN쪽 IRQ핸들러 보면 수신시에

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)

위 콜백을 호출하도록 되어 있는데, 

  그냥 별 생각없이 우선 필터나 필터마스크 설정 대충 해도 인터럽트는 뜨고 나서 되든 안되든 할줄 알았건만,

  아예 뜨지 않더라는 게 문제였다. 

  설정에 문제가 없는데 인터럽트가 되지 않고 있다면 마스크나 필터ID 값을 잘 확인해보자.

  

 

24. 변수 오염 문제

 20번의 연장선상인데, 그때는 안되더니 이번엔 되어서 이상하지만 아무튼 기록.

 

UART 쪽에서 빠른 속도로 데이터가 들어오고 있고, 이를 처리하기 위해 RX를 DMA 로 설정하고 버퍼에 쌓아놓으면서 버퍼 처리를 하도록 구현하였는데,

이상하게 버퍼 주변 주소값을 갖는 다른 변수가 종종 비주기적인 형태로 오염이 발생하는 문제였다.

 

나같은 경우엔 UART 핸들을 포인터로 받아서 모듈쪽에서 처리하도록 구현해놨더니 UART 핸들 포인터변수가 오염되면서 엉뚱한 곳을 Access, 그리고 HardFault 로 빠지게 된 것이었다.

 

레지스터를 봐도 CFSR 레지스터를 보면 PRECISERR 플래그가 떴으니 잘못된 Access인건 맞는데,

어디서 오염을 시켰는지 원인은 아직 찾지는 못했다.

 

그러던 와중, MDK-ARM 으로 생성해서 코드를 돌려보니 CubeIDE에서 발생하지 않던 warning 들이 몇군데 발생하였고, (변수타입 캐스팅 등에서 주로 발생했던 것 같음) 

이 warning 들을 해결하고 MDK-ARM에서 빌드해서 돌려보니 문제가 발생하지 않았다.

 

그리고, 이렇게 수정된 코드를 다시 CubeIDE에서 빌드해서 돌려보니 이제 문제가 발생하지 않는다(!?!)

어딘가에서 포인터를 잘못 썼나 싶기도 한데, 수정 전 코드를 홀라당 날렸다(...)

앞으로는 빌드를 양쪽 다 해보고 warning도 격파해야겠다(;;;)

20번 Issue 원인이 파악되어 엄한 땜빵책을 제거함.

 

25. Multiple Definition Error 관련 문제

어느 버전에서부터 발생했는지 모르겠는데 (계속 사용하던 중에 최근부터 겪은 현상이라...),

CubeIDE에서 프로젝트 생성하고 처음엔 빌드가 아무런 문제 없이 되는데 ioc 파일 수정해서 다시 프로젝트 재생성시키고 빌드하면 어느 순간에서부턴가 multiple definition of 'SystemCoreClock' .... 하면서 링커에서 에러가 발생한다.

에러에 써있는 함수가 SystemCoreClock 이 아닐 수도 있지만, 일단 문제는


"system_stm32abxx.c (ab는 사용하는 MCU따라 달라진다) 파일이 프로젝트 안에 두개가 생성되고 빌드된다."

 

그래서 같은 함수가 두개라 그런건데, 

CubeMX로 프로젝트 생성시키면 Project/Core/Src/system_stm32abxx.c 파일이 함께 생성되는데,

엉뚱하게 Project/Drivers/CMSIS/Device/ST/STM32abxx/Source/Templates/ 경로에도 같은 파일이 또 있다.

예전에 생성된 다른 프로젝트 보니 해당 경로에 아무것도 없었음...

따라서, 이 파일을 지워주던가, 해당 폴더를 exclude from build 시키면 되는데

파일을 지워주면 CubeMX로 프로젝트 재생성 시 친절하게 또 살려놓는다.

그러므로 그냥 Templates 폴더 선택하고 alt+Enter 눌러서 Exclude resource from build 를 체크인 하자.

 

 

26. UART RX DMA 설정시 계속 버퍼의 첫 바이트에만 수신되는 문제

우선, 모든 경우에 발생하는 문제인지는 모르겠으나 발생했던 환경은 다음과 같다.

모든 환경에서 발생할 수 있는 문제로 보임. 자세한 내용은 아래에...

 Target :STM32H750 (STM32H750B-DK board)

 개발환경 : STM32CubeIDE 1.10.1

 

CubeIDE 내 Code generation Tool 을 통해 USART 설정을 하고, DMA RX 도 circular 모드로 설정하였다.

이후 코드에서

HAL_UART_Receive_DMA(handle, pbuffer, buflen);

의 코드를 실행하여 buffer 에 데이터가 차는 것을 기대하였으나,

buffer 의 첫번째 바이트에만 계속 데이터가 중복으로 써지는 문제가 있었다.

 

이번에도 역시 뭘 잘못했나 찾다가, 기존에 만들었던 코드에서는 잘 돌아가는데 왜 안되나 하고 차이점을 찾아보니

 

cubeMX 에서 자동으로 생성시켜 준 MX_USART3_UART_Init() 함수 안에서 HAL_UART_Init() 을 해주기에 별 문제 없겠지 하고 믿고 있었으나, 그게 문제였던 것 같다.

 

아주 단순히, 

  HAL_UART_DeInit(&huart3);
  HAL_UART_Init(&huart3);

이 두줄만을 다시 실행했더니, 이후부터는 DMA buffer 에 순차적으로 데이터가 잘 쌓임을 확인하였다.

 

HAL Driver 의 전체적인 버그인지, H7 에서만 나타나는 버그인지는 확인하긴 귀찮아 안해보지만, 혹시 같은 문제가 발생하는 누군가에게 도움이 될까 적어둠

ST에 문의결과 Peripheral 이 DMA 사용하여 수신하기 위해서는 DMA가 먼저 활성화/초기화 된 이후 Peripheral 을 활성화 해야 이후 수신시도 시 peripheral data register에 값이 들어왔을 때 DMA request 를 하고 설정된 destination 주소로 데이터 전송이 가능하다고 함.

 

확인해보니 CubeMX 가 자동생성해준 코드에서  MX_USARTx_UART_Init() 을 먼저 수행하고 MX_DMA_Init()을 나중에  하는 순서로 생성되어 있었고, 이를 코드상에서 바꾸어 주었더니 정상동작 함.

위에서 해결했던 해결책은 이미 MX 에서 생성된 모든 함수가 다 수행되고 나서 다시 UART 를 init 하였기 때문에 순서가 지켜져서 정상 작동한 거였음.

 

CubeMX 에서 코드 자동 생성 시 이 순서를 변경할 수 있게 되어있는데, 문제는 몇몇 경우에 MX_DMA_Init() 과 MX_USARTx_UART_Init() 함수의 순서를 변경하는 버튼이 비활성화 되어 있어 순서를 뒤집을 수 없는 경우가 발생하고 있다는 것.

이 부분 또한 ST에 확인해보니 CubeMX 의 버그로 보여 해당 부서에 수정 요청하겠다는 회신을 받았음.

 

 

발생할때마다 계속 적어나가자.

posted by 샛별의꿈 2019. 11. 20. 16:06
  1. asc 파일을 PADS import 시, " *pads Not valid pin name for part type xxxx " 에러
    찾아보면 OrCAD 에서 네트 이름을 숫자가 아닌 문자로 했다던지, 두번을 import 시켜서 그렇다던지 하는 얘기가 있는데,
    결론은 PADS 에서 쓰려던 부품의 Library 에서 Parts 의 Pins 탭에 보면, 핀 넘버가 숫자가 아닌 영문으로 되어 있는 경우였다.
    OrCAD 가 아니라 PADS 쪽에서 그렇게 되어 있어서, 아예 새로운 Parts 를 생성해버리고 연결하니 에러가 사라졌다.

  2. asc 파일을 PADS import 시, " *Bad *CONNECTION* ascii data format, nets must contain more than one pin. Signal ..." 에러
    에러 그대로 해석하면 엉뚱한 삽질을 하기 십상인데, 내 경우에는 BUS를 BUS[0:13] 까지 설정해놓고, 각 네트 네임을 BUS00 ~ BUS13 으로 설정한 문제였다. 그래놓고 다른 쪽에는 BUS0 ~ BUS13 으로 잘 설정했으니, 해당 네트가 떠버린 형태가 되었다. 정신차리자!
    아! 실제로 의도적으로 네트 이름을 지정해놓고 아무데도 연결하지 않아도 뜬다. 이 경우에는 무시해도 된다.

  3. PADS 에서 Decal 을 Library 에 Import 해놓고 Part Type 은 생성하지 않은 채, 해당 Decal Name 으로 OrCAD에서 footprint 를 지정하면 없는 Part 로 뜬다.
    아니 뭐 이건 당연히 그런데 깜빡 잊고 그랬으니, 놓치지 말고 Decal 은 Parts 와 연결되든 새로 생성하든 해야한다.

  4. PADS 에서 처음으로 4층기판으로 설계를 하다보니, 하는건 Copper Pour 깔듯이 내층을 plane 으로 설정하고 VCC와 GND로 깔아주면 되고 VIA를 partial 타입으로 층간 지정해놓고 Router 돌리니 지가 알아서 해당하는 VIA 로 선택해서 쓰고 뭐 그러는데...
    에...문제는 이렇게 해서 모든 net 를 다 router 로 돌렸는데 영 100% 로 라우팅이 끝나질 않았다. 아니 근데 눈에 보이는 unrouted net 이 없는게 문제다. 복잡하지도 않은 pcb를 한 이틀동안 붙잡고 어디가 unrouted 인가 찾아봤는데 눈만 버렸다. 여튼 layout 으로 돌아와서 unrouted net 필터걸고 선택해보니 GND와 VCC가 전부 다 선택되었는데, pin pair 를 카운트하는게 아니라 net로 카운트해서 몇개 안되는것처럼 보였던 것 같다.
    아무튼, 이 문제가 정확히 뭐때문인지는 아직 모르겠다. plane층을 pour 상태로 만들지 않아서 그런가? (아니 그러면 router 놈아 니가 알아서 pour 하든가 하지...)
    이건 나중에 4층기판 다시 설계할 일 생기면 확인해볼 생각이다. 결국은 2층으로 일단 만들고 말았다. (다 그리고 보니 2층 네트도 딱히 복잡하지 않았던 게 함정)

 

또 꺼리가 생기면 계속 적어나갈 예정.

 

posted by 샛별의꿈 2019. 2. 21. 10:25

일이 일이다보니 이 오래된 걸 쓰게 될 줄이야...

그나마도 좀 덜 오래된 CUPL 로 컨버전하다가 겪은 일들.

이게 다 Ti 와 ROM Writer 떄문이다

이것도 ABEL로 컴파일 하다가 IC 구하기 힘들어서 그나마 구하기쉬운 ATF22V10C 쓰려고 컨버전 하고있는 건 안비밀


어쨌든 잊을거같아서 정리 해두자.


  • ABEL 의 := 는 CUPL에 없다.

그래서 컨버전 문서를 찾아봤더니 = 를 쓰랜다. 알아서 지가 판단한다고?!

뭔 말도 안되는 소리야 하고 ABEL에서 := 를 왜 쓰나 찾아봤더니, Sequential Logic 표현할 때 쓴다.

Combinational Logic은 그냥 = 만 쓴다.

  * 참고로 PAL/GAL22V10  은 1번핀 입력을 CLK 로 쓰게 되어 있다 *

 

자 그럼, := 로 작성된 코드는 다 어떻게 바꾸지?


22V10 은 D Flip-Flop 을 가지고 있으니 그걸 쓰면 된다. 그리고 그것의 표현법(업계에선 Extensions)은 .D

22V10 이 지원하는 Extensions 는 총 4개, D, AR, SP, OE


아무튼 OUTPIN.d = Logic expression;

 

하면 되는 줄 알았더니 컴파일러가 에러를 막 뱉는다.

.AR 과 .SP 를 안넣었으니 넣으란다.


  • 위 에러를 보며 검색하니 보통 Preset 이나 Reset 을 외부입력받아 DFF 입력들에 넣도록 설계하는 게 일반적.

아놔 하필 내가 만드려는 원래놈이 이런 입력 1도 안 받는다.

....그럼 강제로 1을 넣든 0을 넣든 해야 하는데, 여기서 갑자기 막혔다. 0이 enable 인가 1이 Enable 인가?


나중에 와서야 이게 네번만 해보면 되는 조합이라는걸 알았지만 고정관념에 사로잡혀서 Reset에는 1을 집어넣어야 할거야 라고 생각하며 AR에 1 SP도 1로 초기화되게 해야겠다 하고 넣었더니 시뮬 돌려보니 아무것도 안해?!

(그와중에 0아니면 1나오면 되니 대충 반은 정상인걸로 나오는 개그)

막 AR은 1넣고 SP는 0 넣고 해봐도 안돼? 그럼 0 1 은 되냐?


하다가 모르겠다 다 0으로 넣어보자 하니까 된다. 아놔 시발


  • .OE는 써도 그만 안 써도 그만.

이거 안써서 그런가싶어 위에서 삽질할때 다 넣어봤지만(그래서 경우의 수 상승) 아니었다. 기본적으로 출력을 쓰는게 일반적이니 기본값이 ENABLE 상태인것같다.


  • 보통 .D를 먼저 쓰고 .AR과 .SP 를 나중에 쓰는데 관계없다.

순서가 있을까 싶어 이것도 해봤지만(경우의 수 또 상승) 아니었다. 삽질하지 말자. 난 AR SP 먼저 다 썼다.


  • 큰 문제는, 하나의 DFF AR이나 SP에 강제로 0이든 1이든 넣었으면 다른 DFF에도 똑같이 넣어야 한다는 점.

이건 아직 답을 모르겠다. 다르게 쓰는순간 컴파일러가 에러 뱉는다. (내부적으로 다 묶여있냐?-_-)


  • ABEL에서 node 로 핀을 선언하고 실제 없는 번호의 핀을 할당하는데 CUPL에선 필요없고 컴파일도 안된다.

그 node 가 무슨 역할을 하는지는 코드를 봐야 안다. 무턱대고 삭제할수는 없다. CUPL에서도 PINNODE는 있지만 이것도 실제 없는 핀번호를 할당할 수는 없다. 이 이상은 아직 모르겠다.


  • 만일 컴파일 했는데 JED 파일이 없다면 이유는 PLD 파일내용 상단에 기재된 Device 가 정확히 적혀있지 않기 때문이다.

뭘 적냐면 WinCUPL의 Options - Devices 에서 내가 쓰는 IC 찾으면 Device mnemonic 이 나오니 그거 적으면 됨.



이정도만 알아도 ABEL 을 CUPL로 바꾸는데 큰 문제 없을 거 같다.

생각보단 쓰기 간편해서 좋다.


걍 기록만 하려다가 누가 혹시 와서 보면 도움될까 싶어 발행해놓음.

posted by 샛별의꿈 2016. 10. 27. 18:22

기계식을 쓰고 싶은데, 회사에다 매우 비싼것을 사 달라고 하기도 그렇고..


해서 적당히 고른놈이 아이락스 KR-6251 모델이었다.


생각지 않았던 매우 큰 장점은 텐키 위에 USB허브가 달려서 주변장치 연결하기 정말 편리하다는 것?


개발하며 테스트하느라 잠깐잠깐 끼우고 빼야 하는 장비들 꽂기에 아주 제격이다.



그리고 키스킨을 기본으로 주는데, 누군가는 뭔 기계식을 키스킨씌우고 쓰냐고 하겠지만


회사에서 쓰다보니 은근 눈치보이는 수준이다. 그래서 여태껏 키스킨 씌우고 써왔는데..



키스킨이 찢어졌다. 그 자체는 상관이 없다만, 손에 걸리적거리는 부분이 생겨서 느낌이 구려졌다는 거.


아이락스 쇼핑몰 가보니 이 키보드의 키스킨은 팔지도 않는다. 덕분에 눈치보며 키스킨 벗김.



그리고 오늘 키스킨을 검색하다 엄청난(그런데 쓸데없는) 사실을 하나 발견하였으니....


메뉴얼에 있는지 없는지 몰랐지만 안봐서 전혀 몰랐던 기능이 하나 숨어있었다.


그거슨!!!!


게임모드.


어쩐지 박스가 게이밍 키보드더라.


ctrl + alt + shift + g 를 누르면 게이밍 모드로 변신한다. 스크롤 락에 달린 LED 가 dimming 되면서.


뭐가 좋냐고?


동시 입력이 일반모드에선 최대 6키인데, 무제한이 된다.


끌때는 g대신 n



회사에서 게임할 일이 없어서 정말 쓸데없긴 한데,


쓸수록 은근 맘에 드는 키보드이다. 아쉬운건 조금 오래 돼서 그런가 축에서 끽끽 거리는 소리가 들린다.


기름이라도 발라줘야 하나. 


에이. 키 뽑는 도구도 없는데 뭔 기름인가 싶다.



이 글은, 안 써서 언젠가 까먹을 저 기능을 언젠가 다시 쓸 그날을 위해 적어두는 것.


그리고 같은 키보드를 쓰는 누군가가 이 글을 검색해서 유용하게 써먹는다면 좋겠다. 



은근 막 쓰기 괜찮은데 요샌 팔지도 않네. 수지타산이 안 맞는 모양.


전에 부모님 쓰시는 컴퓨터에 쓰시라고 사드렸는데 잘 한 거 같다.


에...그리고 회사에서 같은거 쓰던 분이 고장났다며 뽑아놨는데 갖다 테스트 해보니 잘된다. 꾸...꿀꺽?

posted by 샛별의꿈 2016. 1. 11. 17:38

MLX90614 붙이다보니 겪은 일들.


1. Slave Address 가 0x5A 가 기본값이다. 라고 데이터 시트에 나와 있다. MCU의 코드에 따라 어떻게 될지 모르겠지만, 
    결과적으로 전송되어야 하는 바이트 값은

0b1011010x (x는 0:Write, 1:Read)이다. 

STM32 keil 컴파일러용 Periphiral Driver 에서 제공하는 

I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction)

이 녀석은 Address 에 8bit 데이터를 줘야 하므로, 0x5A가 아니라 0xB4를 줘야 된다. Direction 가지고 마지막 비트를 0이든 1로 바꿔주는 녀석이라..


2. 어드레스도 맞고 해서 전송하는 데 오류는 하나도 안 나는데, 수신된 값이 죄다 0xFF 가 뜨는 경우가 있다.

이건, I2C 버스 프로토콜을 보면 Repeated Start 를 어떻게 실제로 구동하느냐의 문제인데, 

어떤 소자는 이 Repeated Start 를 Stop+Start 로 요구하는 경우가 있기도 한데, MLX90614 의 경우에는 그냥 다시 Start 만 해주면 된다. Stop 하고나서 Start 하면 죄다 0xFF 뜬다. 아오 이거 찾느라 삽질한거 생각하면 ㅡ.ㅡ;

(막상 데이터시트 프로토콜 그림 보면 딱 1비트로 표현되어있으니 사실 Start만 다시 해주는게 맞다는 것은 나의 불찰로 하고...)


3. 데이터가 들어오는 데 표현되는 값이 막 섭씨 수백도 이상 왔다갔다 한다.

보....통은 MSB First 인데, 이건 LSB First(.........). 데이터시트에 있으니 할말은 없다만 아 쫌..ㅠㅠ


4. crc 값이 안맞는다.

이것도 보....통은 전송되는 데이터만 가지고 CRC 계산해서 붙여보내는데,
MLX90614는 무려 

SlaveAddress[tx] byte + Command byte + SlaveAddress[rx] byte + Data(LSB) byte + Data(MSB) byte

이만큼 갖고 만들어서 붙여보내고 있다. 뭐, 고....고맙다ㅠㅠ귀찮게 해 주셔서....


1,2번 항목이 동시에 불확실한 상태로 삽질하니까 뭐가 맞는 줄 몰라서 온갖 삽질을...



뭐 여튼 그래서 잘 동작은 하는데, 문제는 이놈의 것이 거리가 어느정도 떨어진 것까지 잘 재는건지 대충 봐서 모르겠다;;

얼음 갖다 찍어봤더니 -10도 뜨는데, 이것도 맞는건지 당최...접촉식 센서하고 같이 놓고 평가해야 하나;

posted by 샛별의꿈 2013. 7. 3. 13:22

이놈의 우분투 설치하면서 기본 데스크탑으로 설치하는데 너~~~무 오래걸려!!

문제는, 다운로드 서버를 해외를 기본설정으로 놓는 데 있는 거 같다. (혹은 말많은 카이스트 서버?)

게다가 sk망 쓰니 외국이 드럽게 느리다-_-

(특히, 한글 언어팩 받아서 설치하는데 몇시간이 걸린다. 그게 뭐라고;;)


그래서 국내에 빠른 미러가 있는 다음 서버를 선택해서 설치하기 위해 지인의 조언과 삽질을 하여!

위 경험을 대략적으로 정리해보자면,


1. http://www.ubuntu.com/download/alternative-downloads  에서 최소화된 Network Installer 를 받는다.

2. VM이 됐든 뭐가 됐든 넣는다.

3. 기본설치로 가서 언어선택 하고, 설치하는 국가의 Location 을 선택할 때 최상위에 가보면 경로 수동 입력이 있다.

4. 수동으로 ftp.daum.net 을 입력하고

5. 아카이브 폴더는 /ubuntu/ 가 기본으로 입력되어있는데 다음 서버에 저게 잘 있으니 그냥 둔다.

6. 5번에서 엔터치면 그냥 보라색 화면에 밑에 라인 하나만 생기고 가만히 있는데, 진행중이다 선잠 2분쯤 자면 된다;

7. 설치 뚝딱뚝딱 하고선 추가설치로 뭘 더 할건지 물어본다. 선택은 자유에. (ubuntu-desktop 을 보통 설치하는 듯?)


아무튼 이걸로 끝났다. 

아마 업데이트 관리자 가보면 기본 서버도 미러로 바뀌어 있을 것으로 본다.


apt서버도 바꿔주면 되는데, 검색해둔 창을 닫아버렸네; 근데 그 이전부터 파일내에 daum 쪽이 기록되어 있는거보면

그냥 될 것 같기도 하니, 다음 설치할 때는 기억해뒀다가 테스트해보자.


posted by 샛별의꿈 2013. 1. 7. 11:41

 갤노트2

 아이폰4

posted by 샛별의꿈 2009. 2. 15. 21:51
사용자 삽입 이미지

HiHat(HH)은 오선지 위 첫째 칸에 "X"표 형태로 표기하고,

Open은 하이햇 표기 위에 동그라미("ㅇ")를 , Close는 십자표("+")를 합니다.
Cymbal은 HiHat과 마찬가지 위치에 마름모(심벌)형태로 표기하며 종류에 따라 SC(Splash Cymbal), RC(Ride Cymbal), CC(Crash Cymbal)등으로 영문표기할 수도 있습니다.
Tom Tom과 Snare는 위 그림처럼 차례로 표기하고 탐탐은 갯수에 따라 여러 가지로 표기(나머지 줄과 칸에 차례대로)하며 T1(Tom 1), T2(Tom 2), FT(Floor Tom), LT(Large Tom)등으로 영문표기합니다.
Bass Drum(BD)와 HiHat Foot Pedal은 오선지 아랫 방향으로 그림과 같이 표기합니다.
리듬 앞에 작은 리듬은 꾸밈음으로 Flam은 꾸밈음이 하나이고 Ruff는 꾸임음이 2개입니다.

꾸밈음은 실제 리듬과 거의 동시에 이루어져야 박자가 흔들리지 않습니다.