คือ ผมลองตั้ง TIM1 ดูบิต TIM1->CNT
และ Interrrupt TIM1
มันก็เหมือนว่า จะเชื่อไม่ได้
เพราะ ตำแหน่งเดียวกันที่ ISR ถัดไป
ค่ามันไม่เท่ากัน เฉยเลย
ARM มันมีวิธีอื่นอีกเปล่าอ่ะครับ
ขอบคุณล่วงหน้าครับ
8)
ใน debug โหมด มันจะ break cpu ครับ การ break cpu ไม่ได้ทำให้ peripheral หยุดทำงานด้วยครับ พวก clock มันก็ยังทำงานอยู่
ทางที่ดีถ้าจะจับเวลาอย่าหยุด cpu ครับ เขียน code เก็บค่าเวลาตามจุดต่างๆ ในโปรแกรมที่จะวัดลงตัวแปรไว้ แล้วปล่อยให้ cpu รันจนจบโปรแกรมที่ต้องการ แล้วค่อยมา break ดูทีหลังทีเดียวครับ ค่ามันคงไม่เท่ากันเป๊ะๆ ทุกรอบ แต่ก็น่าจะใกล้เคียงกัน
หา j-link ไว้สักอัน แล้วโลกของ ARM มันจะง่ายขึ้น
Quote from: dec on February 16, 2017, 11:01:53 AM
ใน debug โหมด มันจะ break cpu ครับ การ break cpu ไม่ได้ทำให้ peripheral หยุดทำงานด้วยครับ พวก clock มันก็ยังทำงานอยู่
ทางที่ดีถ้าจะจับเวลาอย่าหยุด cpu ครับ เขียน code เก็บค่าเวลาตามจุดต่างๆ ในโปรแกรมที่จะวัดลงตัวแปรไว้ แล้วปล่อยให้ cpu รันจนจบโปรแกรมที่ต้องการ แล้วค่อยมา break ดูทีหลังทีเดียวครับ ค่ามันคงไม่เท่ากันเป๊ะๆ ทุกรอบ แต่ก็น่าจะใกล้เคียงกัน
อ่อ ได้ ไอเดียละ
เดี๋ยวจัด arr สัก 100 สมาชิกเลย อิอิ
ขอบคุณมากมายครับ
^_^!
_/\_
Quote from: az on February 16, 2017, 12:55:13 PM
หา j-link ไว้สักอัน แล้วโลกของ ARM มันจะง่ายขึ้น
ง่ะ ปัจจุบันก็ใช้อยู่ครับ v9.4
แต่ก็ ใช้อย่างฉาบฉวย ดีบักอย่างเดียว
มันมีอะไรหว่า เดี๋ยวลองดูเพิ่มสักหน่อย
หายไปนานครับ ลืมไปหมด เพิ่งมาจับอีกรอบ อิอิ
8)
ดูได้จาก program counter อย่างเดียว .. แล้วเอาไปคูณกับคำสั่งแต่ล่ะคำสั่ง .. คงต้อง asembly มั้ง
Quote from: TaoTao on February 17, 2017, 02:24:09 AM
Quote from: az on February 16, 2017, 12:55:13 PM
หา j-link ไว้สักอัน แล้วโลกของ ARM มันจะง่ายขึ้น
ง่ะ ปัจจุบันก็ใช้อยู่ครับ v9.4
แต่ก็ ใช้อย่างฉาบฉวย ดีบักอย่างเดียว
มันมีอะไรหว่า เดี๋ยวลองดูเพิ่มสักหน่อย
หายไปนานครับ ลืมไปหมด เพิ่งมาจับอีกรอบ อิอิ
8)
https://www.segger.com/j-link-j-scope.html
ลองศึกษาดูนะครับ
ผมว่าหลายๆคน ไม่คุ้นการใช้งาน j-scope เพราะส่วนใหญ่จะใช้ j-link เพื่อprogram และ debug แบบ break point (อ้างอิงตามความคิดเห็นที่ 1 )
unsigned cnt1;
unsigned cnt2;
ISR1 tim1_ovf {
cnt1 = timer_counter1_reg;
..
...
....
}
ISR2 tim2_ovf {
cnt2 = timer_counter2_reg;
..
...
....
}
หลังจากนั้นก็ลองใช้ J-Scope อ่านค่า cnt1,cnt2
Quote
https://www.segger.com/j-link-j-scope.html
ลองศึกษาดูนะครับ
ผมว่าหลายๆคน ไม่คุ้นการใช้งาน j-scope เพราะส่วนใหญ่จะใช้ j-link เพื่อprogram และ debug แบบ break point (อ้างอิงตามความคิดเห็นที่ 1 )
unsigned cnt1;
unsigned cnt2;
ISR1 tim1_ovf {
cnt1 = timer_counter1_reg;
..
...
....
}
ISR2 tim2_ovf {
cnt2 = timer_counter2_reg;
..
...
....
}
หลังจากนั้นก็ลองใช้ J-Scope อ่านค่า cnt1,cnt2
หุๆ ลองมั่วดูแว้ววว
อย่างกะ สโคปเลย
:o
อ่อ แล้วใช้ อาเรย์
เก็บค่า CNT แหล่มแมวเลยครับ
ขอบคุณมากมาย คร๊าบบบ
8)
_/\_
Quote from: TaoTao on February 19, 2017, 01:18:05 AM
หุๆ ลองมั่วดูแว้ววว
อย่างกะ สโคปเลย
:o
อ่อ แล้วใช้ อาเรย์
เก็บค่า CNT แหล่มแมวเลยครับ
ขอบคุณมากมาย คร๊าบบบ
8)
_/\_
ในกรณีที่ไม่ได้กำหนด interrupt priority สามารถนำวิธีนี้ไปประยุกต์เพื่อตรวจสอบลำดับการเกิดเหตุการณ์ก่อนและหลังได้ด้วย เพื่อป้องกันการเกิด interrupt ที่ผิดปกติ ซึ่งจะทำให้การงานเกิดความผิดพลาดได้
Quote from: az on February 19, 2017, 08:52:20 PM
ในกรณีที่ไม่ได้กำหนด interrupt priority สามารถนำวิธีนี้ไปประยุกต์เพื่อตรวจสอบลำดับการเกิดเหตุการณ์ก่อนและหลังได้ด้วย เพื่อป้องกันการเกิด interrupt ที่ผิดปกติ ซึ่งจะทำให้การงานเกิดความผิดพลาดได้
ขอบคุณมากมาย ครับ
8)
ผมไปอ่านเจอว่า arm cortex-m มันมี Data Watchpoint and Trace (DWT) อยู่ สามารถใช้มันดูจำนวน Clock ที่ใช้ไปใน 1 instruction set ได้ครับ
ก่อนอื่นเราต้องเปิดใช้งาน Trace
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 ก่อน
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
(https://s2.postimg.org/589n9sasp/001.png)
อย่างในภาพนี้ ผมเปิดใช้งานไปแล้ว มันก็จะโชว์ว่าก่อนจะเข้ามาถึง main มันมีการใช้ clock ไปแล้ว 4361 clock
(https://s17.postimg.org/fgz5lpojz/002.png)
(https://s2.postimg.org/oqibgfnuh/003.png)
เมื่อลองทำการ Step over ดูในหน้า Disassembly ก็จะเห็นว่าคำสั่ง PUSH {R7, LR} ค่า CYCLECOUNTER จะมีการเปลี่ยนแปลงไป 4361 ไป 4364 แล้ว CCSTEP ก็จะคำนวนค่าให้ว่าจากการ Step over เมื่อกี้มีการใช้งาน Clock ไป 3 tick เราก็เอามาคำนวนเวลาที่ใช้ไปได้โดยเอาค่า CCSTEP มาหารกับ SystemCoreClock
(https://s12.postimg.org/ji4ufjuel/004.png)
อันนี้ผมก็ได้ทดลองกับ 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 เพิ่มเข้ามาด้วย
Quote from: dec on March 12, 2017, 04:20:04 PM
ผมไปอ่านเจอว่า arm cortex-m มันมี Data Watchpoint and Trace (DWT) อยู่ สามารถใช้มันดูจำนวน Clock ที่ใช้ไปใน 1 instruction set ได้ครับ
ก่อนอื่นเราต้องเปิดใช้งาน Trace
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 ก่อน
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
(https://s2.postimg.org/589n9sasp/001.png)
อย่างในภาพนี้ ผมเปิดใช้งานไปแล้ว มันก็จะโชว์ว่าก่อนจะเข้ามาถึง main มันมีการใช้ clock ไปแล้ว 4361 clock
(https://s17.postimg.org/fgz5lpojz/002.png)
(https://s2.postimg.org/oqibgfnuh/003.png)
เมื่อลองทำการ Step over ดูในหน้า Disassembly ก็จะเห็นว่าคำสั่ง PUSH {R7, LR} ค่า CYCLECOUNTER จะมีการเปลี่ยนแปลงไป 4361 ไป 4364 แล้ว CCSTEP ก็จะคำนวนค่าให้ว่าจากการ Step over เมื่อกี้มีการใช้งาน Clock ไป 3 tick เราก็เอามาคำนวนเวลาที่ใช้ไปได้โดยเอาค่า CCSTEP มาหารกับ SystemCoreClock
(https://s12.postimg.org/ji4ufjuel/004.png)
อันนี้ผมก็ได้ทดลองกับ 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