ฉันจะทำ TDD บนอุปกรณ์ฝังตัวได้อย่างไร


17

ฉันไม่ได้ใหม่กับการเขียนโปรแกรมและฉันได้ทำงานกับระดับต่ำ C และ ASM ใน AVR แต่ฉันไม่สามารถไปรอบ ๆ โครงการ C ขนาดใหญ่ที่ฝังตัวได้

ด้วยความเสื่อมของปรัชญารูดี้ของ TDD / BDD ฉันไม่สามารถเข้าใจได้ว่าผู้คนเขียนและทดสอบโค้ดเช่นนี้อย่างไร ฉันไม่ได้บอกว่ามันเป็นรหัสที่ไม่ดีฉันไม่เข้าใจว่ามันจะทำงานได้อย่างไร

ฉันอยากจะเขียนโปรแกรมระดับล่างให้มากขึ้น แต่ฉันไม่รู้ว่าจะทำอย่างไรกับสิ่งนี้เพราะมันดูเหมือนความคิดที่แตกต่างไปจากเดิมอย่างสิ้นเชิงที่ฉันคุ้นเคย ฉันไม่มีปัญหาในการทำความเข้าใจตัวบ่งชี้ทางคณิตศาสตร์หรือการจัดสรรหน่วยความจำทำงานอย่างไร แต่เมื่อฉันเห็นว่าโค้ด C / C ++ ที่ซับซ้อนมีลักษณะอย่างไรเมื่อเทียบกับ Ruby ดูเหมือนว่ายากมาก

ตั้งแต่ฉันสั่งบอร์ด Arduino มาเองฉันชอบที่จะเพิ่มระดับ C ที่ต่ำลงและเข้าใจวิธีการทำสิ่งต่าง ๆ ได้อย่างถูกต้อง แต่ดูเหมือนว่าไม่มีกฎของภาษาระดับสูงมาใช้

เป็นไปได้ไหมที่จะทำ TDD บนอุปกรณ์ฝังตัวหรือเมื่อพัฒนาไดรเวอร์หรือสิ่งต่าง ๆ เช่น bootloader แบบกำหนดเองเป็นต้น


3
สวัสดี Darth เราไม่สามารถช่วยคุณให้เอาชนะความกลัว C ได้ แต่คำถามเกี่ยวกับ TDD บนอุปกรณ์ฝังตัวอยู่ในหัวข้อที่นี่: ฉันได้แก้ไขคำถามของคุณเพื่อนำเสนอสิ่งนั้นแทน

คำตอบ:


18

ก่อนอื่นคุณควรรู้ว่าการพยายามเข้าใจโค้ดที่คุณไม่ได้เขียนนั้นหนักกว่าการเขียนด้วยตัวคุณเอง 5 เท่า คุณสามารถเรียนรู้ C โดยการอ่านรหัสการผลิต แต่มันจะใช้เวลานานกว่าการเรียนรู้ด้วยการทำ

ด้วยความเสื่อมของปรัชญารูดี้ของ TDD / BDD ฉันไม่สามารถเข้าใจได้ว่าผู้คนเขียนและทดสอบโค้ดเช่นนี้อย่างไร ฉันไม่ได้บอกว่ามันเป็นรหัสที่ไม่ดีฉันไม่เข้าใจว่ามันจะทำงานได้อย่างไร

มันเป็นทักษะ คุณทำได้ดีขึ้น โปรแกรมเมอร์ C ส่วนใหญ่ไม่เข้าใจว่าคนใช้ Ruby อย่างไร แต่นั่นไม่ได้หมายความว่าพวกเขาไม่สามารถทำได้

เป็นไปได้ไหมที่จะทำ TDD บนอุปกรณ์ฝังตัวหรือเมื่อพัฒนาไดรเวอร์หรือสิ่งต่าง ๆ เช่น bootloader แบบกำหนดเองเป็นต้น

มีหนังสือเกี่ยวกับเรื่องนี้อยู่:

ป้อนคำอธิบายรูปภาพที่นี่ หากภมรสามารถทำเช่นนั้นคุณก็สามารถทำได้!

โปรดทราบว่าการใช้วิธีปฏิบัติจากภาษาอื่นมักจะไม่ทำงาน แม้ว่า TDD นั้นค่อนข้างเป็นสากล


2
TDD ทุกตัวที่ฉันเห็นสำหรับระบบฝังตัวของฉันพบเฉพาะข้อผิดพลาดในระบบที่ง่ายต่อการแก้ไขข้อผิดพลาดที่ฉันจะพบได้ง่ายด้วยตัวเอง พวกเขาจะไม่พบสิ่งที่ฉันต้องการความช่วยเหลือเวลาขึ้นอยู่กับการโต้ตอบกับชิปอื่น ๆ และการโต้ตอบขัดจังหวะ
Kortuk

3
ขึ้นอยู่กับระบบที่คุณใช้อยู่ ฉันพบว่าการใช้ TDD เพื่อทดสอบซอฟต์แวร์ควบคู่ไปกับการใช้ฮาร์ดแวร์ที่เป็นนามธรรมทำให้ฉันสามารถเลียนแบบการโต้ตอบตามเวลาได้ง่ายขึ้น ประโยชน์อื่น ๆ ที่ผู้คนมักจะมองข้ามคือการทดสอบแบบอัตโนมัติสามารถทำงานได้ตลอดเวลาและไม่ต้องการให้ใครนั่งบนอุปกรณ์ด้วยเครื่องวิเคราะห์ตรรกะเพื่อให้แน่ใจว่าซอฟต์แวร์ทำงานได้ดี TDD ช่วยฉันในการดีบักหลายสัปดาห์ในโครงการปัจจุบันของฉันคนเดียว บ่อยครั้งเป็นข้อผิดพลาดที่เราคิดว่าง่ายต่อการตรวจพบซึ่งทำให้เกิดข้อผิดพลาดที่เราไม่คาดคิด
Nick Pascucci

นอกจากนี้ยังช่วยในการพัฒนาและทดสอบเป้าหมาย
cp.engr

ฉันสามารถติดตามหนังสือเล่มนี้เพื่อทำความเข้าใจ TDD สำหรับผู้ที่ไม่ได้ฝังตัว C หรือไม่? สำหรับการเขียนโปรแกรม C พื้นที่ของผู้ใช้?
แลกเปลี่ยนที่มากเกินไป

15

คำตอบมากมายที่นี่ ... ส่วนใหญ่แก้ไขปัญหาได้หลายวิธี

ฉันเขียนซอฟต์แวร์และเฟิร์มแวร์ระดับล่างที่ฝังมานานกว่า 25 ปีในหลากหลายภาษา - ส่วนใหญ่เป็น C (แต่ด้วยความหลากหลายใน Ada, Occam2, PL / M และแอสเซมเบลอร์ที่หลากหลาย)

หลังจากความคิดและการลองผิดลองถูกมาเป็นเวลานานฉันได้ตัดสินวิธีการที่ได้ผลลัพธ์ค่อนข้างเร็วและค่อนข้างง่ายในการสร้างชุดทดสอบและชุดสายรัด (ที่พวกเขาเพิ่มค่า!)

วิธีการบางอย่างเช่นนี้:

  1. เขียนหน่วยรหัสนามธรรมของไดรเวอร์หรือฮาร์ดแวร์สำหรับอุปกรณ์ต่อพ่วงที่สำคัญแต่ละรายการที่คุณต้องการใช้ เขียนหนึ่งเพื่อเริ่มต้นตัวประมวลผลและตั้งค่าทุกอย่าง (ทำให้สภาพแวดล้อมเป็นมิตร) โดยทั่วไปแล้วในโปรเซสเซอร์แบบฝังตัวขนาดเล็ก - AVR ของคุณเป็นตัวอย่าง - อาจมี 10 - 20 ยูนิตเช่นขนาดเล็กทั้งหมด เหล่านี้อาจเป็นหน่วยสำหรับการเริ่มต้นการแปลง A / D เป็นบัฟเฟอร์หน่วยความจำที่ไม่ได้ปรับขนาดเอาต์พุตบิตพุทอินพุตปุ่มกด (ไม่มีตัวอย่างเพียงแค่ debounce) ไดรเวอร์การปรับความกว้างพัลส์พัลส์ UART / ไดรเวอร์อนุกรมธรรมดา อาจมีอีกสองสาม - เช่นไดรเวอร์ I2C หรือ SPI สำหรับ EEPROM, EPROM หรืออุปกรณ์ I2C / SPI อื่น ๆ

  2. สำหรับแต่ละฮาร์ดแวร์นามธรรม (HAL) / ไดรเวอร์ยูนิตฉันจะเขียนโปรแกรมทดสอบ สิ่งนี้อาศัยพอร์ตอนุกรม (UART) และตัวประมวลผล init - ดังนั้นโปรแกรมทดสอบแรกใช้ 2 หน่วยเหล่านั้นเท่านั้นและทำอินพุตและเอาต์พุตพื้นฐานบางส่วนเท่านั้น สิ่งนี้ให้ฉันทดสอบว่าฉันสามารถเริ่มโปรเซสเซอร์และฉันมีการดีบักการสนับสนุนพื้นฐาน I / O อนุกรมทำงาน เมื่อใช้งานได้ (และหลังจากนั้น) ฉันจะพัฒนาโปรแกรมทดสอบ HAL อื่น ๆ แล้วสร้างสิ่งเหล่านี้ขึ้นบนหน่วย UART และ INIT ที่รู้จักกันดี ดังนั้นฉันอาจมีโปรแกรมทดสอบสำหรับอ่านอินพุต bitwise และแสดงสิ่งเหล่านี้ในรูปแบบที่ดี (hex, ทศนิยม, อะไรก็ตาม) ใน terminal debug ของฉัน จากนั้นฉันสามารถเลื่อนไปยังสิ่งที่ใหญ่กว่าและซับซ้อนกว่าเช่นโปรแกรมทดสอบ EEPROM หรือ EPROM ฉันใช้ประโยชน์จากเมนูเหล่านี้เป็นส่วนใหญ่ดังนั้นฉันจึงสามารถเลือกการทดสอบเพื่อเรียกใช้รันและดูผลลัพธ์ ฉันไม่สามารถคัดลอกมันได้ แต่โดยปกติฉันจะไม่ '

  3. เมื่อฉันได้ HAL ของฉันทำงานทั้งหมดแล้วฉันจะหาวิธีที่จะได้รับเห็บตัวจับเวลาปกติ โดยทั่วไปจะมีอัตราอยู่ระหว่าง 4 ถึง 20 มิลลิวินาที สิ่งนี้จะต้องเป็นปกติสร้างขึ้นในการขัดจังหวะ ปกติการโรลโอเวอร์ / โอเวอร์โฟลว์ของเคาน์เตอร์สามารถทำได้ ตัวจัดการขัดจังหวะแล้ว INCREMENTS ขนาดไบต์ "สัญญาณ" ณ จุดนี้คุณสามารถเล่นซอกับการจัดการพลังงานได้หากคุณต้องการ แนวคิดของเซมาฟอร์คือถ้าค่าเป็น> 0 คุณต้องเรียกใช้ "main loop"

  4. ผู้บริหารทำงานวนรอบหลัก มันก็แค่รอสัญญาณที่จะกลายเป็นไม่ใช่ 0 (ฉันสรุปรายละเอียดนี้ออกไป) ณ จุดนี้คุณสามารถเล่นกับตัวนับเพื่อนับเห็บเหล่านี้ (เพราะคุณรู้อัตราเห็บ) และเพื่อให้คุณสามารถตั้งค่าสถานะที่แสดงว่าเห็บผู้บริหารปัจจุบันสำหรับช่วงเวลา 1 วินาที, 1 นาทีและช่วงเวลาทั่วไปอื่น ๆ ที่คุณ อาจต้องการใช้ เมื่อผู้บริหารรู้ว่าสัญญาณคือ> 0 มันจะส่งผ่านเดียวผ่านทุกฟังก์ชั่น "การประยุกต์ใช้" กระบวนการ "ปรับปรุง"

  5. กระบวนการแอปพลิเคชันจะทำงานร่วมกันอย่างมีประสิทธิภาพและเรียกใช้เป็นประจำด้วยการทำเครื่องหมาย "อัปเดต" นี่เป็นเพียงฟังก์ชั่นที่ผู้บริหารเรียกว่า นี่เป็นการทำงานแบบมัลติทาสกิ้งที่ไม่ดีกับ RTOS ที่ปลูกเองในบ้านง่าย ๆ ที่ต้องอาศัยแอพพลิเคชั่นทั้งหมดที่เข้ามาทำงานชิ้นเล็ก ๆ และออกจากงาน แอปพลิเคชันจำเป็นต้องรักษาตัวแปรสถานะของตนเองและไม่สามารถทำการคำนวณเป็นเวลานานได้เนื่องจากไม่มีระบบปฏิบัติการที่ว่างเปล่าเพื่อบังคับให้เกิดความเป็นธรรม โดยปกติแล้วเวลาทำงานของแอปพลิเคชั่น (รวมกัน) ควรมีขนาดเล็กกว่าช่วงเวลาที่เกิดเห็บหลัก

วิธีการด้านบนนั้นขยายได้อย่างง่ายดายดังนั้นคุณสามารถมีสิ่งต่าง ๆ เช่นสแต็คการสื่อสารที่เพิ่มขึ้นทำงานแบบอะซิงโครนัสและสามารถส่งข้อความ comms ไปยังแอปพลิเคชัน (คุณเพิ่มฟังก์ชั่นใหม่ แอปพลิเคชันใดที่จะส่งไป)

วิธีนี้ใช้ได้กับระบบการสื่อสารที่คุณสนใจตั้งชื่อ - มันสามารถ (และทำไปแล้ว) ทำงานกับระบบที่เป็นกรรมสิทธิ์หลายระบบมาตรฐานเปิดระบบ comms มันใช้งานได้กับ TCP / IP สแต็ค

นอกจากนี้ยังมีข้อได้เปรียบของการสร้างขึ้นในชิ้นส่วนแบบแยกส่วนที่มีอินเตอร์เฟซที่กำหนดไว้อย่างดี คุณสามารถดึงชิ้นส่วนเข้า ๆ ออกได้ทุกเวลาแทนที่ชิ้นส่วนต่าง ๆ ในแต่ละจุดตามวิธีที่คุณสามารถเพิ่มสายรัดทดสอบหรือตัวจัดการซึ่งสร้างจากชิ้นส่วนชั้นล่างที่รู้จักกันดี (สิ่งต่าง ๆ ด้านล่าง) ฉันพบว่าประมาณ 30% ถึง 50% ของการออกแบบสามารถได้รับประโยชน์จากการเพิ่มการทดสอบหน่วยการเขียนพิเศษซึ่งมักจะเพิ่มได้อย่างง่ายดาย

ฉันได้ดำเนินการนี้ไปอีกขั้นหนึ่ง (ความคิดที่ฉันได้รับจากคนอื่นที่ทำสิ่งนี้) และแทนที่ HAL layer ด้วยพีซีที่เทียบเท่า ตัวอย่างเช่นคุณสามารถใช้ C / C ++ และ winforms หรือคล้ายกันบนพีซีและโดยการเขียนรหัสอย่างละเอียดคุณสามารถเลียนแบบแต่ละอินเตอร์เฟส (เช่น EEPROM = ไฟล์ดิสก์ที่อ่านเข้าไปในหน่วยความจำพีซี) จากนั้นเรียกใช้แอปพลิเคชันฝังตัวทั้งหมดบนพีซี ความสามารถในการใช้สภาพแวดล้อมการดีบักที่เป็นมิตรสามารถประหยัดเวลาและความพยายามได้อย่างมากมาย เฉพาะโครงการขนาดใหญ่จริงๆเท่านั้นที่สามารถพิสูจน์ความพยายามนี้ได้

คำอธิบายข้างต้นเป็นสิ่งที่ไม่ซ้ำกับวิธีที่ฉันทำสิ่งต่าง ๆ บนแพลตฟอร์มแบบฝังตัว - ฉันเจอองค์กรการค้าจำนวนมากที่ทำสิ่งเดียวกัน วิธีการที่ทำมักจะแตกต่างกันอย่างมากในการนำไปใช้ แต่หลักการก็เหมือนกันมาก

ฉันหวังว่าข้างต้นให้รสชาติเล็กน้อย ... วิธีนี้ใช้ได้กับระบบฝังตัวเล็ก ๆ ที่ทำงานในไม่กี่ kB ด้วยการจัดการแบตเตอรี่ที่ก้าวร้าวผ่านมอนสเตอร์ที่มี 100K หรือมากกว่านั้นซึ่งเป็นแหล่งพลังงานที่ทำงานอย่างถาวร หากคุณเรียกใช้ "ฝังตัว" ในระบบปฏิบัติการขนาดใหญ่เช่น Windows CE หรืออื่น ๆ ทั้งหมดที่กล่าวมาข้างต้นนั้นไม่มีความหมายอย่างสมบูรณ์ แต่นั่นไม่ใช่การเขียนโปรแกรมแบบฝังตัวจริง แต่อย่างใด


2
อุปกรณ์ต่อพ่วงฮาร์ดแวร์ส่วนใหญ่ที่คุณไม่สามารถทดสอบผ่าน UART ได้เพราะบ่อยครั้งที่คุณสนใจลักษณะของเวลาเป็นหลัก หากคุณต้องการตรวจสอบอัตราตัวอย่าง ADC, รอบการทำงานของ PWM, พฤติกรรมของอุปกรณ์ต่อพ่วงอนุกรมอื่น ๆ (SPI, CAN ฯลฯ ) หรือเพียงแค่เวลาดำเนินการของบางส่วนของโปรแกรมของคุณคุณไม่สามารถทำได้ผ่านทาง UART การทดสอบเฟิร์มแวร์ฝังตัวที่ร้ายแรงรวมถึงออสซิลโลสโคป - คุณไม่สามารถตั้งโปรแกรมระบบฝังตัวได้หากไม่มี

1
โอ้ใช่อย่างแน่นอน ฉันแค่ลืมพูดถึงสิ่งนั้น แต่เมื่อคุณมี UART และใช้งานแล้วมันง่ายมากในการตั้งค่าการทดสอบหรือกรณีทดสอบ (ซึ่งเป็นคำถามที่เกี่ยวกับ) กระตุ้นสิ่งต่างๆอนุญาตให้ผู้ใช้ป้อนข้อมูลรับผลลัพธ์และแสดงผลในแบบที่เป็นมิตร CRO ของคุณ + นี้ทำให้ชีวิตง่ายขึ้น
quick_now

2

รหัสที่มีประวัติอันยาวนานของการพัฒนาที่เพิ่มขึ้นและการปรับให้เหมาะสมสำหรับหลายแพลตฟอร์มเช่นตัวอย่างที่คุณเลือกมักอ่านยาก

สิ่งที่เกี่ยวกับ C คือจริง ๆ แล้วมันมีความสามารถในการขยายแพลตฟอร์มบนความร่ำรวย API และประสิทธิภาพของฮาร์ดแวร์ที่หลากหลาย MacVim ทำงานอย่างมีการตอบสนองบนเครื่องที่มีหน่วยความจำน้อยกว่า 1,000 เท่าและประสิทธิภาพของโปรเซสเซอร์มากกว่าสมาร์ทโฟนทั่วไปในปัจจุบัน รหัสทับทิมของคุณสามารถ? นั่นเป็นหนึ่งในเหตุผลที่อาจดูง่ายกว่าตัวอย่าง C สำหรับผู้ใหญ่ที่คุณเลือก


2

ฉันอยู่ในตำแหน่งย้อนกลับของการใช้เวลาส่วนใหญ่ในช่วง 9 ปีที่ผ่านมาในฐานะโปรแกรมเมอร์ C และเพิ่งทำงานกับ Ruby on Rails front-end

สิ่งที่ฉันทำงานใน C เป็นระบบที่กำหนดเองขนาดกลางส่วนใหญ่สำหรับการควบคุมคลังสินค้าอัตโนมัติ (โดยทั่วไปมีค่าใช้จ่ายไม่กี่แสนปอนด์หรือสูงถึงสองล้านปอนด์) ตัวอย่างการทำงานคือฐานข้อมูลในหน่วยความจำที่กำหนดเองโดยเชื่อมต่อกับเครื่องจักรที่มีความต้องการเวลาตอบสนองสั้น ๆ และการจัดการระดับสูงของเวิร์กโฟลว์คลังสินค้า

ฉันสามารถพูดก่อนอื่นเราไม่ทำ TDD ฉันได้ลองหลายครั้งในการแนะนำการทดสอบหน่วย แต่ใน C เป็นปัญหามากกว่าที่ควรค่า - อย่างน้อยเมื่อพัฒนาซอฟต์แวร์ที่กำหนดเอง แต่ฉันจะบอกว่า TDD นั้นมีความต้องการน้อยกว่าใน C มากกว่าทับทิม สาเหตุหลักมาจากการคอมไพล์ C และถ้ามันคอมไพล์โดยไม่มีคำเตือนคุณได้ทำการทดสอบกับ rspec ที่สร้างขึ้นโดยอัตโนมัติใน Rails แล้ว ทับทิมที่ไม่มีการทดสอบหน่วยไม่สามารถทำได้

แต่สิ่งที่ฉันจะพูดก็คือ C ไม่จำเป็นต้องลำบากเหมือนที่บางคนทำ ไลบรารี่มาตรฐาน C ส่วนใหญ่มีระเบียบชื่อฟังก์ชั่นที่เข้าใจไม่ได้และโปรแกรม C จำนวนมากทำตามระเบียบนี้ ฉันดีใจที่จะบอกว่าเราทำไม่ได้และในความเป็นจริงมีจำนวนมากห่อสำหรับฟังก์ชั่นห้องสมุดมาตรฐาน (ST_Copy แทน strncpy, ST_PatternMatch แทน regcomp / regexec, CHARSET_Convert แทน iconv_open / iconv / iconv_close และอื่น ๆ ) โค้ด C ของเราอ่านได้ดีกว่าของฉันส่วนใหญ่ที่ฉันอ่าน

แต่เมื่อคุณพูดว่ากฎจากภาษาระดับสูงกว่าอื่น ๆ ดูเหมือนจะไม่ใช้ฉันจะไม่เห็นด้วย รหัส C ที่ดีจำนวนมาก 'รู้สึก' เป็นวัตถุ คุณมักจะเห็นรูปแบบของการเริ่มต้นหมายเลขอ้างอิงไปยังทรัพยากรเรียกบางฟังก์ชันผ่านตัวจัดการเป็นอาร์กิวเมนต์และในที่สุดปล่อยทรัพยากร อันที่จริงหลักการออกแบบของการเขียนโปรแกรมเชิงวัตถุส่วนใหญ่มาจากสิ่งที่ดีที่ผู้คนกำลังทำในภาษาขั้นตอน

เวลาที่ C มีความซับซ้อนมากมักจะทำสิ่งต่าง ๆ เช่นไดรเวอร์อุปกรณ์และเมล็ด OS ซึ่งเป็นระดับต่ำมาก เมื่อคุณเขียนระบบระดับสูงกว่าคุณสามารถใช้คุณสมบัติระดับสูงของ C และหลีกเลี่ยงความซับซ้อนระดับต่ำ

สิ่งหนึ่งที่น่าสนใจอย่างยิ่งที่คุณอาจต้องการดูคือซอร์สโค้ด C สำหรับ Ruby ในเอกสาร Ruby API (http://www.ruby-doc.org/core-1.9.3/) คุณสามารถคลิกและดูซอร์สโค้ดสำหรับวิธีการต่างๆ สิ่งที่น่าสนใจคือรหัสนี้ดูค่อนข้างดีและสง่างาม - มันดูไม่ซับซ้อนเท่าที่คุณคิด


" ... คุณสามารถใช้ฟีเจอร์ระดับสูงของ C ... " ได้เช่นกัน? ;-)
alk

ฉันหมายถึงระดับที่สูงกว่าการจัดการบิตและตัวชี้ไปยังตัวช่วยสร้างตัวชี้ที่คุณมักจะเห็นในรหัสประเภทไดรเวอร์อุปกรณ์! และถ้าคุณไม่กังวลเกี่ยวกับค่าใช้จ่ายในการเรียกใช้ฟังก์ชันสองสามครั้งคุณสามารถสร้างรหัส C ที่มีระดับสูงพอสมควร
asc99c

" ... คุณสามารถสร้างรหัส C ที่มีระดับสูงพอสมควร " อย่างแท้จริงฉันเห็นด้วยอย่างยิ่ง แต่ถึงแม้ว่า " ... คุณสมบัติระดับสูงกว่า ... " ไม่ใช่ของ C แต่อยู่ในหัวของคุณใช่มั้ย
alk

2

สิ่งที่ฉันทำคือแยกรหัสพึ่งพาอุปกรณ์ออกจากรหัสอุปกรณ์อิสระจากนั้นทดสอบรหัสอุปกรณ์อิสระ ด้วยโมดุลที่ดีและมีระเบียบวินัยคุณจะต้องจบลงด้วยการใช้ codebase ที่ผ่านการทดสอบเป็นอย่างดี


2

ไม่มีเหตุผลใดที่คุณทำไม่ได้ ปัญหาคืออาจไม่มีกรอบการทดสอบหน่วย "นอกชั้นวาง" ที่ดีอย่างที่คุณมีในการพัฒนาประเภทอื่น ไม่เป็นไร. หมายความว่าคุณต้องใช้แนวทาง "ทดสอบตัวเอง" เพื่อทดสอบ

ตัวอย่างเช่นคุณอาจต้องตั้งโปรแกรมการใช้เครื่องมือเพื่อผลิต "อินพุตปลอม" สำหรับตัวแปลง A / D ของคุณหรือคุณอาจต้องสร้างสตรีมของ "ข้อมูลปลอม" เพื่อให้อุปกรณ์ฝังตัวของคุณตอบสนอง

หากคุณเผชิญกับการต่อต้านการใช้คำว่า "TDD" เรียกมันว่า "DVT" (การทดสอบการตรวจสอบการออกแบบ) ที่จะทำให้ EE สะดวกสบายมากขึ้นกับความคิด


0

เป็นไปได้ไหมที่จะทำ TDD บนอุปกรณ์ฝังตัวหรือเมื่อพัฒนาไดรเวอร์หรือสิ่งต่าง ๆ เช่น bootloader แบบกำหนดเองเป็นต้น

เมื่อก่อนฉันต้องเขียน bootloader ระดับแรกสำหรับ ARM CPU อันที่จริงมีหนึ่งจากพวกที่ขายซีพียูนี้ และเราใช้รูปแบบที่ bootloader ของพวกเขาบูท bootloader ของเรา แต่สิ่งนี้ช้าเพราะเราต้องการแฟลชสองไฟล์เป็น NOR แฟลชแทนหนึ่งเราจำเป็นต้องสร้างขนาดของ bootloader ของเราเป็น bootloader แรกและสร้างใหม่ทุกครั้งเมื่อเราเปลี่ยน bootloader ของเราและอื่น ๆ

ดังนั้นฉันจึงตัดสินใจรวมฟังก์ชั่นของ bootloader ของพวกเขาเข้ากับเรา เพราะมันเป็นรหัสเชิงพาณิชย์ฉันต้องทำให้แน่ใจว่าทุกสิ่งทำงานได้อย่างที่คาดไว้ ดังนั้นฉันจึงปรับเปลี่ยนQEMUเพื่อเลียนแบบบล็อก IP ของ CPU นั้น (ไม่ใช่ทั้งหมดเท่านั้นที่สัมผัสกับ bootloader) และเพิ่มรหัสไปยัง QEMU เพื่อ "printf" ทั้งหมดอ่าน / เขียนลงทะเบียนที่ควบคุมสิ่งต่าง ๆ เช่น PLL, UART, คอนโทรลเลอร์ SRAM และ เป็นต้น จากนั้นฉันอัปเกรด bootloader ของเราเพื่อรองรับ CPU นี้และหลังจากนั้นเปรียบเทียบเอาต์พุตที่ให้ bootloader ของเรากับอีมูเลเตอร์ของเราสิ่งนี้ช่วยฉันจับข้อบกพร่องหลายอย่าง มันถูกเขียนขึ้นบางส่วนในแอสเซมเบลอร์ ARM ส่วนหนึ่งในซีหลังจากนั้น QEMU ที่ได้รับการแก้ไขช่วยให้ฉันจับข้อผิดพลาดหนึ่งซึ่งฉันไม่สามารถใช้ JTAG และซีพียู ARM จริงได้

ดังนั้นแม้ใช้ C และแอสเซมเบลอร์คุณก็สามารถใช้การทดสอบได้


-2

ใช่เป็นไปได้ที่จะทำ TDD ในซอฟต์แวร์ฝังตัว คนที่บอกว่ามันเป็นไปไม่ได้ไม่เกี่ยวข้องหรือไม่เกี่ยวข้องไม่ถูกต้อง มีค่าร้ายแรงที่จะได้รับจาก TDD ในตัวเช่นเดียวกับซอฟต์แวร์ใด ๆ

พวกเขาวิธีที่ดีที่สุดที่จะทำแม้ว่าจะไม่ใช้การทดสอบของคุณในเป้าหมาย แต่เพื่อสรุปการพึ่งพาฮาร์ดแวร์ของคุณและรวบรวมและเรียกใช้บนโฮสต์พีซีของคุณ

เมื่อคุณทำ TDD คุณจะสร้างและใช้การทดสอบจำนวนมาก คุณต้องการซอฟต์แวร์เพื่อช่วยในการทำเช่นนี้ คุณต้องการกรอบการทดสอบเพื่อให้การทำสิ่งนี้ทำได้อย่างรวดเร็วและง่ายดายด้วยการค้นหาการทดสอบอัตโนมัติและการสร้างจำลอง

ตัวเลือกที่ดีที่สุดสำหรับ C ตอนนี้คือ Ceedling นี่คือโพสต์เกี่ยวกับฉันเขียนเกี่ยวกับมัน:

http://www.electronvector.com/blog/try-embedded-test-driven-development-right-now-with-ceedling

และมันสร้างขึ้นในทับทิม! คุณไม่จำเป็นต้องรู้ทับทิมใด ๆเพื่อใช้งาน


คำตอบคาดว่าจะยืนอยู่คนเดียว การบังคับให้ผู้อ่านไปยังแหล่งข้อมูลภายนอกเพื่อค้นหาสารที่ถูกขมวดคิ้วที่ Stack Exchange ("อ่านบทความหรือตรวจสอบ Ceedling") พิจารณาแก้ไขไอเอ็นจีที่จะทำให้มันพอดีเว็บไซต์บรรทัดฐานที่มีคุณภาพ
ริ้น

Ceedling มีกลไกใด ๆ เพื่อรองรับเหตุการณ์อะซิงโครนัสหรือไม่ ด้านหนึ่งที่มีความท้าทายมากขึ้นของการใช้งานในเวลาจริงแบบฝังตัวที่พวกเขาได้รับการจัดการกับปัจจัยการผลิตจากระบบที่ซับซ้อนมากที่ตัวเองยากที่จะรูปแบบ ...
เจ Elston

@Jay มันไม่มีอะไรพิเศษที่จะสนับสนุนสิ่งนั้น อย่างไรก็ตามฉันประสบความสำเร็จในการทดสอบสิ่งต่าง ๆ ด้วยการล้อเลียนและโดยการตั้งค่าสถาปัตยกรรมเพื่อรองรับ ตัวอย่างเช่นเมื่อเร็ว ๆ นี้ฉันได้ทำงานในโครงการที่มีเหตุการณ์ที่ทำให้เกิดการขัดจังหวะถูกใส่ลงในคิว นี่เป็นเพียงฟังก์ชั่นที่ถูกเรียกเมื่อใดก็ตามที่มีเหตุการณ์เกิดขึ้น เมื่อทำการทดสอบฟังก์ชั่นนั้นฉันสามารถจำลองการเรียกฟังก์ชันที่ดึงเหตุการณ์ออกจากคิวและสามารถจำลองเหตุการณ์ใด ๆ ที่เกิดขึ้นในระบบ ทดสอบการขับขี่ก็ช่วยได้เช่นกัน
cherno
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.