เครื่องมือหรือมาตรฐานใดที่สามารถใช้เพื่อปรับปรุงความน่าเชื่อถือของรหัส C แบบฝัง


9

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


1
คุณใช้ภาษา C อย่างไร?
Brian Drummond

1
ฉันสามารถชักชวนให้เปลี่ยนไปใช้อย่างอื่นได้หากมีกรณีที่ดีมากที่ต้องทำ แต่มันจะต้องเป็นกรณีที่ดีมาก
สตีเฟ่น Collings

"เป็นกรณีที่ดีมาก" สำหรับการสลับจาก C ไม่สามารถทำได้อย่างรวดเร็วและสำหรับ PIC อาจยังไม่ได้เลย สำหรับ AVR, ARM หรือ MSP430, Ada จะคุ้มค่ากับรูปลักษณ์ที่จริงจัง (แม้จะมีการปฏิเสธที่ดึงดูดเช่นที่คุณเห็น!) และสำหรับ rel สูง SPARK มีค่าดู
Brian Drummond

คุณอาจพบว่าข้อมูลพื้นหลังที่น่าสนใจเหล่านี้: SPARK vs MISRA-C spark-2014.org/entries/detail/ ......และกรณีศึกษาต่อเนื่องนี้: spark-2014.org/uploads/Nosegearpaper_1.pdf
Brian Drummond

อาจเป็นการลงทุนที่ดีกว่าเพื่อสร้างเคสสำหรับการเปลี่ยนจาก PIC ไปเป็นสิ่งที่ทันสมัย ​​... โดยเฉพาะอย่างยิ่งถ้าคุณออกแบบระบบภารกิจสำคัญที่ MISRA และ SPARK มีจุดประสงค์เพื่อ
ลุนดิน

คำตอบ:


11

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

นี่คือแนวทางบางส่วนของฉัน:

  1. เขียนสเป็คถ้าไม่มี:ถ้าคุณไม่ได้เข้ารหัสสเป็คให้จดบันทึกรหัสของคุณว่าอะไรคืออินพุตที่ถูกต้องอะไรคือเอาท์พุทที่คาดหวังเอาท์พุทแต่ละครั้งควรใช้เวลานานเท่าไร การอุดตัน ฯลฯ - ทฤษฎีของการดำเนินงานผังงานอะไรดีกว่าไม่มีอะไร

  2. แสดงความคิดเห็นรหัสของคุณ:เพียงเพราะสิ่งที่ชัดเจนสำหรับคุณไม่ได้หมายความว่ามันชัดเจน (หรือถูกต้อง) กับคนอื่น ความคิดเห็นภาษาธรรมดามีความจำเป็นสำหรับทั้งการตรวจสอบและการบำรุงรักษารหัส

  3. การป้องกันโค้ด:อย่าใส่รหัสสำหรับอินพุตปกติ จัดการอินพุตที่ขาดหายไปอินพุทที่อยู่นอกระยะทางล้นทางคณิตศาสตร์ ฯลฯ - ยิ่งคุณครอบคลุมการออกแบบโค้ดมากเท่าไหร่ก็จะยิ่งมีอิสระมากขึ้นในการปรับใช้โค้ด

  4. ใช้เครื่องมือวิเคราะห์แบบคงที่:มันสามารถทำให้เครื่องมือที่บั๊กเช่น PC-lint สามารถหาได้ในโค้ดของคุณ พิจารณาการวิเคราะห์แบบสแตติกที่สะอาดเป็นจุดเริ่มต้นที่ดีสำหรับการทดสอบอย่างจริงจัง

  5. ความเห็นจากเพื่อนมีความสำคัญ:รหัสของคุณควรสะอาดและมีเอกสารเพียงพอที่จะสามารถตรวจสอบได้อย่างมีประสิทธิภาพโดยบุคคลที่เป็นอิสระ ตรวจสอบอัตตาของคุณที่ประตูและพิจารณาคำวิจารณ์หรือข้อเสนอแนะอย่างจริงจัง

  6. การทดสอบมีความสำคัญ:คุณควรทำการตรวจสอบความถูกต้องของคุณเองรวมถึงการตรวจสอบความถูกต้องของรหัสด้วยตนเอง คนอื่น ๆ สามารถทำลายรหัสของคุณในแบบที่คุณนึกไม่ออก ทดสอบทุกเงื่อนไขที่ถูกต้องและทุกเงื่อนไขที่ไม่ถูกต้องที่คุณสามารถนึกถึง ใช้ PRNG และป้อนข้อมูลขยะทำสิ่งที่คุณทำได้เพื่อทำลายสิ่งต่างๆจากนั้นซ่อมแซมและลองอีกครั้ง หากคุณโชคดีคุณจะสามารถเรียกใช้รหัสของคุณในโหมดแก้ไขข้อบกพร่องและดูที่การลงทะเบียนและตัวแปร - ถ้าไม่คุณจะต้องมีฝีมือและสลับไฟ LED / สัญญาณดิจิตอลเพื่อรับทราบสถานะของคุณ เครื่อง ทำทุกสิ่งที่จำเป็นเพื่อรับความคิดเห็นที่คุณต้องการ

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


+1 เสียงแนะนำทั้งหมด ฉันคาดหวังว่านักพัฒนามืออาชีพเฟิร์มแวร์จะยิ้มและพยักหน้าเมื่ออ่านข้อความนี้
Lundin

2
สิ่งสำคัญในการตรวจสอบโดยเพื่อนคือการตรวจสอบเป็นเรื่องเกี่ยวกับรหัสไม่ใช่เกี่ยวกับโปรแกรมเมอร์ หากคุณวิเคราะห์รหัสของคุณด้วยคำว่า "ก่อนอื่นฉันต้องทำเช่นนั้นฉันก็ทำอย่างนั้น" คุณอาจมีปัญหา "ก่อนอื่นให้ทำสิ่งนี้จากนั้นก็ทำอย่างนั้น" เป็นวิธีที่ถูกต้องในการคิด และเช่นเดียวกันกับผู้ตรวจสอบ: ไม่ใช่ "ทำไมคุณถึงทำเช่นนี้?" แต่ "ทำไมรหัสถึงทำเช่นนี้"
Pete Becker

คุณสามารถลองเพิ่ม: 1. ใช้การตรวจสอบความซับซ้อนของ Cyclomatic 2. ซอฟต์แวร์ควบคุมเวอร์ชัน
AlphaGoku

4

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

ฉันจะไม่ละทิ้ง C. ในขณะที่ภาษาเช่น Ada สามารถให้การรับรองเล็กน้อยบางอย่างมันง่ายที่จะตกหลุมพรางของการคิดว่าภาษาสัญญามากกว่าที่เป็นจริง


Valgrid อาจจะตาดบิตที่เกี่ยวข้องมากขึ้นสำหรับเครื่องคอมพิวเตอร์กว่า 8 บิต MCU แต่ :)
Lundin

น่าเสียดายที่เทคนิคบางอย่างในการสร้างซอฟต์แวร์ระดับพีซีที่ดีนั้นไม่ได้ใช้งานกับไมโครเล็ก ๆ และการปฏิบัติบางอย่างที่ถือว่าไม่ถูกต้องในพื้นที่พีซีนั้นเป็นที่ยอมรับอย่างสมบูรณ์ในสภาพแวดล้อมแบบฝังตัว
John U

3

MISRA-C นั้นมีประโยชน์มากในการปรับปรุงคุณภาพรหัสทั่วไปและลดข้อบกพร่อง เพียงให้แน่ใจว่าคุณอ่านและเข้าใจกฎทุกข้อส่วนใหญ่ดี แต่กฎบางข้อก็ไม่สมเหตุสมผล

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

เอกสาร MISRA-C มีสองเวอร์ชันที่อาจมี MISRA-C: 2004 ซึ่งยังคงเป็นมาตรฐานอุตสาหกรรมแบบฝังตัวในปัจจุบัน หรือ MISRA-C: 2012 ใหม่ซึ่งรองรับมาตรฐาน C99 หากคุณไม่เคยใช้ MISRA-C มาก่อนฉันจะแนะนำให้คุณใช้งานหลัง

โปรดทราบว่าผู้ขายเครื่องมือมักจะอ้างถึง MISRA-C: 2004 เมื่อพวกเขาบอกว่าพวกเขามีการตรวจสอบ MISRA (บางครั้งพวกเขาก็อ้างถึงรุ่น MISRA-C: 1998 ที่ล้าสมัย) เท่าที่ฉันรู้การสนับสนุนเครื่องมือสำหรับ MISRA-C: 2012 ยังมี จำกัด ฉันคิดว่ามีนักวิเคราะห์สแตติกเพียงบางส่วนเท่านั้นที่ได้นำไปใช้งาน: Klocwork, LDRA, PRQA และ Polyspace อาจมีมากขึ้น แต่คุณต้องตรวจสอบว่า MISRA รองรับเวอร์ชันใดอย่างแน่นอน

ก่อนที่จะตัดสินใจคุณสามารถเริ่มต้นด้วยการอ่านเอกสาร MISRA และดูว่ามีอะไรบ้าง สามารถซื้อได้ในราคา 10 ปอนด์จากmisra.orgราคาค่อนข้างไม่แพงเมื่อเทียบกับราคามาตรฐาน ISO


1

Mathworks (กลุ่ม MATLAB) มีเครื่องมือวิเคราะห์รหัสแบบคงที่ที่เรียกว่าPolyspace Polyspace

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

คุณอาจต้องการดูแนวทางในการออกแบบรหัสเพื่อความปลอดภัยที่สำคัญรวมถึง MISRA แต่ยังรวมถึงมาตรฐาน UL1998 และ IEC 61508


ฉันไม่แนะนำให้ไปใกล้ IEC 61508 เว้นแต่คุณจะต้อง มันพูดถึงซอฟต์แวร์ แต่ไม่มีแหล่งข้อมูลทางวิทยาศาสตร์ที่ทันสมัยสำหรับการอ้างสิทธิ์ มาตรฐานนั้นมาช้ากว่า 30 ปี - ถ้ามันเปิดตัวในยุค 70 เหมือนส่วนใหญ่ที่เรียกว่า "แหล่งที่มา" มันอาจจะมีประโยชน์
Lundin

1

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

ดังนั้นเริ่มต้นด้วยข้อกำหนดและเขียนและตรวจสอบสิ่งเหล่านั้น หากคุณไม่มีเอกสารข้อกำหนดให้ชี้ไปที่บรรทัดของโค้ดแบบสุ่มและถามตัวเองว่า "เหตุใดจึงต้องมีบรรทัดนั้น" ความต้องการโค้ดในบรรทัดใด ๆ ในที่สุดควรตรวจสอบย้อนกลับไปยังข้อกำหนดได้แม้ว่าจะง่าย / ชัดเจนเหมือนกับ "แหล่งจ่ายไฟจะส่งออก 5VDC หากอินพุตอยู่ระหว่าง 12-36VDC" วิธีหนึ่งในการคิดเกี่ยวกับสิ่งนี้คือถ้าบรรทัดของโค้ดนั้นไม่สามารถตรวจสอบข้อกำหนดได้คุณจะรู้ได้อย่างไรว่าเป็นโค้ดที่ถูกต้องหรือจำเป็นต้องใช้เลย?

ถัดไปตรวจสอบการออกแบบของคุณ มันก็โอเคถ้ามันอยู่ในโค้ดอย่างสมบูรณ์ (เช่นในคอมเม้นท์) แต่มันทำให้ยากที่จะรู้ว่าถ้าโค้ดนั้นทำในสิ่งที่มีความหมายจริงๆ ตัวอย่างเช่นรหัสอาจมีสายที่อ่านoutput = 3 * setpoint / (4 - (current * 5)); คือcurrent == 4/5การป้อนข้อมูลที่ถูกต้องที่อาจก่อให้เกิดความผิดพลาดหรือไม่? ในกรณีนี้ควรทำอย่างไรเพื่อป้องกันการหารด้วยศูนย์? คุณหลีกเลี่ยงการดำเนินการทั้งหมดหรือลดเอาต์พุตแทนหรือไม่? การมีหมายเหตุทั่วไปในเอกสารการออกแบบของคุณเกี่ยวกับวิธีจัดการกับเคสแบบขอบทำให้ง่ายต่อการตรวจสอบการออกแบบในระดับที่สูงขึ้น ดังนั้นตอนนี้การตรวจสอบรหัสทำได้ง่ายขึ้นเพราะมันเป็นเรื่องของการตรวจสอบว่ารหัสถูกต้องใช้การออกแบบที่

นอกจากนั้นการตรวจสอบรหัสควรตรวจสอบข้อผิดพลาดทั่วไปที่ IDE ของคุณไม่ได้รับ (คุณใช้ IDE ใช่ไหม) เช่น '=' เมื่อคุณหมายถึง '==' วงเล็บปีกกาที่หายไปซึ่งเปลี่ยนความหมายของ 'ถ้า งบ, อัฒภาคที่พวกเขาไม่ควรเป็นต้น

ขณะที่ฉันเขียนสิ่งนี้เกิดขึ้นกับฉันว่ามันยากจริงๆที่จะสรุปการฝึกอบรม / ประสบการณ์ด้านคุณภาพซอฟต์แวร์ในปีเดียวในโพสต์เดียว ฉันเขียนโค้ดสำหรับอุปกรณ์การแพทย์และด้านบนเป็นบทสรุปที่ง่ายมากของวิธีที่เราเข้าหามัน


ความเข้าใจของฉันคือส่วนรหัสในอุปกรณ์ทางการแพทย์ได้รับการทดสอบเกือบจะเหมือนกับว่ามันเป็นอุปกรณ์แยกต่างหาก ถูกต้องหรือไม่
Scott Seidman

@ScottSeidman มีโอกาสมากขึ้นที่จะได้รับการทดสอบตามความต้องการตามที่ระบุไว้ในคำตอบนี้ สำหรับความต้องการแต่ละอย่างคุณควรมีโมดูลโค้ดและสำหรับโมดูลโค้ดนั้น ๆ คุณควรจะทำการทดสอบ ดังนั้นแต่ละข้อกำหนดมีการทดสอบที่สอดคล้องกันและรหัสคือค่าเฉลี่ยเพื่อตอบสนองความต้องการ การติดตามความต้องการชนิดนี้เป็นวิธีปฏิบัติทั่วไปในระบบที่มีความสำคัญต่อภารกิจนานก่อนที่ buzzword "TDD" จะผุดขึ้นมา
Lundin

ฉันอ้างถึงคำแนะนำขององค์การอาหารและยาโดยเฉพาะเช่นfda.gov/downloads/RegulatoryInformation/Guidances/ucm126955.pdf ซอฟต์แวร์จริง ๆ แล้วต้องการมากกว่าที่คุณคิดว่าเป็นส่วนหนึ่งของอุปกรณ์ทางการแพทย์เริ่มต้นจากขั้นตอนการวางแผนและการควบคุมการออกแบบ
Scott Seidman

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