ขณะที่ Debug [stm32f103] มีวิธีไหน ดูจำนวน clock ที่ใช้ไปบ้างครับ

  • 11 Replies
  • 1985 Views
*

Offline az

  • ***
  • 169
    • View Profile

หุๆ ลองมั่วดูแว้ววว
อย่างกะ สโคปเลย
 :o

อ่อ แล้วใช้ อาเรย์
เก็บค่า CNT แหล่มแมวเลยครับ

ขอบคุณมากมาย คร๊าบบบ
 8)
_/\_

ในกรณีที่ไม่ได้กำหนด interrupt priority สามารถนำวิธีนี้ไปประยุกต์เพื่อตรวจสอบลำดับการเกิดเหตุการณ์ก่อนและหลังได้ด้วย เพื่อป้องกันการเกิด interrupt ที่ผิดปกติ ซึ่งจะทำให้การงานเกิดความผิดพลาดได้
เพราะแสวงหา..  มิใช่เพราะรอคอย
เพราะเชี่ยวชาญ..  มิใช่เพราะโอกาส
เพราะสามารถ..  มิใช่เพราะโชคช่วย
ดังนี้แล้ว "ลิขิตฟ้า  หรือจะสู้มานะตน..."

*

Offline TaoTao

  • ***
  • 231
    • View Profile
ในกรณีที่ไม่ได้กำหนด interrupt priority สามารถนำวิธีนี้ไปประยุกต์เพื่อตรวจสอบลำดับการเกิดเหตุการณ์ก่อนและหลังได้ด้วย เพื่อป้องกันการเกิด interrupt ที่ผิดปกติ ซึ่งจะทำให้การงานเกิดความผิดพลาดได้

ขอบคุณมากมาย ครับ
 8)

*

Offline dec

  • **
  • 67
    • View Profile
ผมไปอ่านเจอว่า arm cortex-m มันมี Data Watchpoint and Trace (DWT) อยู่ สามารถใช้มันดูจำนวน Clock ที่ใช้ไปใน 1 instruction set ได้ครับ

ก่อนอื่นเราต้องเปิดใช้งาน Trace

Code: [Select]
  CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;       /* Trace Enable */
  DWT->CYCCNT = 0;                                      /* Clear cycle counter */
  DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;                  /* Enable cycle counter */
 

สำหรับ arm cortex-m7 ต้อง unlock DWT ก่อน
Code: [Select]
  CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;       /* Trace Enable */
  DWT->LAR = 0xC5ACCE55;                                /* Unlock access to DWT */
  DWT->CYCCNT = 0;                                      /* Clear cycle counter */
  DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;                  /* Enable cycle counter */
 

เมื่อเราเปิดใช้งาน DWT แล้ว มันก็จะเปิดตลอด จนกว่าจะเขียน Code Disable มัน หรือตัดไฟ MCU
การเคลียค่า CYCLECOUNTER ผมลองแล้วมันก็ไม่ค่อยได้ผล เคลียค่าแล้วมันก็ไม่เป็น 0 อันนี้ยังไม่รู้สาเหตุเหมือนกันครับ

ผมใช้ IAR Embedded Workbench ในการดูค่าใน Register นะครับ (Keil ก็น่าจะดูได้ เพราะเป็นของ arm เองเลย) ตอน Debug ให้เลือก View > Register มันจะมีหน้าต่างสำหรับดูค่า Register ขึ้นมา ให้ลือก filter เป็น CPU Register แล้วมันจะมี Register ให้ดู 3 ตัว คือ

CYCLECOUNTER
CCTIMER1
CCTIMER2

ส่วน CCSTEP จะเป็นค่า CYCLECOUNTER ที่เปลี่ยนไปจาก breakpoint ไป breakpoint


อย่างในภาพนี้ ผมเปิดใช้งานไปแล้ว มันก็จะโชว์ว่าก่อนจะเข้ามาถึง main มันมีการใช้ clock ไปแล้ว 4361 clock



เมื่อลองทำการ Step over ดูในหน้า Disassembly ก็จะเห็นว่าคำสั่ง PUSH {R7, LR} ค่า CYCLECOUNTER จะมีการเปลี่ยนแปลงไป 4361 ไป 4364 แล้ว CCSTEP ก็จะคำนวนค่าให้ว่าจากการ Step over เมื่อกี้มีการใช้งาน Clock ไป 3 tick เราก็เอามาคำนวนเวลาที่ใช้ไปได้โดยเอาค่า CCSTEP มาหารกับ SystemCoreClock


อันนี้ผมก็ได้ทดลองกับ function delay millisecond ทำการ delay ไป 1000ms (1 วินาทีนั่นแหละ)
ซึ่งผมใช้ บอร์ด nucleo f411 ทำงานที่ 100MHz ก็จะเห็นว่า Function Delay มีการใช้งาน Clock ไป 99,999,991 Tick เมื่อหาร System CoreClock แล้วก็จะได้ว่า Function delay นี้ใช้เวลาไป 0.99999991 วินาที ก็เกือบๆ 1 วิ มีความคลาดเคลื่อนเล็กน้อย

*ข้อควรระวัง: การวาง Breakpoint ค่า CCSTEP จะมากกว่าการใช้ Step over อันนี้ผมคิดเองว่ากระบวนการในการวาง Breakpoint อาจมีการแทรก instruction set พิเศษทำให้มีการใช้ Clock มากกว่าปกติ และช่วงเวลาระหว่าง Breakpoint ถึง Breakpoint มันมีโอกาสที่จะเกิด Interrupt มาแทรกได้ ซึ่งก็จะทำให้มีจำนวน Clock ที่ใน interrupt เพิ่มเข้ามาด้วย

*

Offline TaoTao

  • ***
  • 231
    • View Profile
ผมไปอ่านเจอว่า arm cortex-m มันมี Data Watchpoint and Trace (DWT) อยู่ สามารถใช้มันดูจำนวน Clock ที่ใช้ไปใน 1 instruction set ได้ครับ

ก่อนอื่นเราต้องเปิดใช้งาน Trace

Code: [Select]
  CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;       /* Trace Enable */
  DWT->CYCCNT = 0;                                      /* Clear cycle counter */
  DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;                  /* Enable cycle counter */
 

สำหรับ arm cortex-m7 ต้อง unlock DWT ก่อน
Code: [Select]
  CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;       /* Trace Enable */
  DWT->LAR = 0xC5ACCE55;                                /* Unlock access to DWT */
  DWT->CYCCNT = 0;                                      /* Clear cycle counter */
  DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;                  /* Enable cycle counter */
 

เมื่อเราเปิดใช้งาน DWT แล้ว มันก็จะเปิดตลอด จนกว่าจะเขียน Code Disable มัน หรือตัดไฟ MCU
การเคลียค่า CYCLECOUNTER ผมลองแล้วมันก็ไม่ค่อยได้ผล เคลียค่าแล้วมันก็ไม่เป็น 0 อันนี้ยังไม่รู้สาเหตุเหมือนกันครับ

ผมใช้ IAR Embedded Workbench ในการดูค่าใน Register นะครับ (Keil ก็น่าจะดูได้ เพราะเป็นของ arm เองเลย) ตอน Debug ให้เลือก View > Register มันจะมีหน้าต่างสำหรับดูค่า Register ขึ้นมา ให้ลือก filter เป็น CPU Register แล้วมันจะมี Register ให้ดู 3 ตัว คือ

CYCLECOUNTER
CCTIMER1
CCTIMER2

ส่วน CCSTEP จะเป็นค่า CYCLECOUNTER ที่เปลี่ยนไปจาก breakpoint ไป breakpoint


อย่างในภาพนี้ ผมเปิดใช้งานไปแล้ว มันก็จะโชว์ว่าก่อนจะเข้ามาถึง main มันมีการใช้ clock ไปแล้ว 4361 clock



เมื่อลองทำการ Step over ดูในหน้า Disassembly ก็จะเห็นว่าคำสั่ง PUSH {R7, LR} ค่า CYCLECOUNTER จะมีการเปลี่ยนแปลงไป 4361 ไป 4364 แล้ว CCSTEP ก็จะคำนวนค่าให้ว่าจากการ Step over เมื่อกี้มีการใช้งาน Clock ไป 3 tick เราก็เอามาคำนวนเวลาที่ใช้ไปได้โดยเอาค่า CCSTEP มาหารกับ SystemCoreClock


อันนี้ผมก็ได้ทดลองกับ function delay millisecond ทำการ delay ไป 1000ms (1 วินาทีนั่นแหละ)
ซึ่งผมใช้ บอร์ด nucleo f411 ทำงานที่ 100MHz ก็จะเห็นว่า Function Delay มีการใช้งาน Clock ไป 99,999,991 Tick เมื่อหาร System CoreClock แล้วก็จะได้ว่า Function delay นี้ใช้เวลาไป 0.99999991 วินาที ก็เกือบๆ 1 วิ มีความคลาดเคลื่อนเล็กน้อย

*ข้อควรระวัง: การวาง Breakpoint ค่า CCSTEP จะมากกว่าการใช้ Step over อันนี้ผมคิดเองว่ากระบวนการในการวาง Breakpoint อาจมีการแทรก instruction set พิเศษทำให้มีการใช้ Clock มากกว่าปกติ และช่วงเวลาระหว่าง Breakpoint ถึง Breakpoint มันมีโอกาสที่จะเกิด Interrupt มาแทรกได้ ซึ่งก็จะทำให้มีจำนวน Clock ที่ใน interrupt เพิ่มเข้ามาด้วย
โอ้.. ขอบคุณมากมายครับ
เดี๋ยวได้ลอง ๆ กับ KEIL
 :D