Những công cụ hoặc tiêu chuẩn nào có thể được sử dụng để cải thiện độ tin cậy của mã C nhúng?


9

Tôi thường lập trình PIC trong C, thường cho các bộ chuyển đổi chế độ chuyển đổi. Tôi đã nghe nói về các công cụ và tiêu chuẩn phân tích tĩnh khác nhau như MISRA C có thể được sử dụng để giúp cải thiện độ tin cậy của mã. Tôi muốn biết thêm. Những tiêu chuẩn hoặc công cụ nào có thể phù hợp với bối cảnh của tôi?


1
Làm thế nào bạn thiết lập ngôn ngữ C?
Brian Drumond

1
Tôi có thể bị thuyết phục để chuyển sang một thứ khác nếu có một trường hợp rất tốt được thực hiện cho nó. Nhưng nó sẽ phải là một trường hợp rất tốt.
Stephen Collings

"Một trường hợp rất tốt" để chuyển đổi từ C không thể được thực hiện nhanh chóng và đối với PIC, có thể chưa hoàn toàn. Đối với AVR, ARM hoặc MSP430, Ada sẽ có giá trị nghiêm túc (bất chấp sự tiêu cực mà nó thu hút, như bạn có thể thấy!) Và đối với độ tin cậy cao, SPARK đáng để xem xét.
Brian Drumond

Bạn có thể tìm thấy những thông tin thú vị này như thông tin cơ bản: SPARK vs MISRA-C spark-2014.org/entries/detail/ và nghiên cứu trường hợp đang diễn ra này: spark-2014.org/uploads/Nosegearapers_1.pdf
Brian

Có thể nên đầu tư thời gian tốt hơn để tạo ra một trường hợp chuyển từ PIC sang một thứ gì đó hiện đại ... Đặc biệt nếu bạn đang thiết kế loại hệ thống quan trọng cho nhiệm vụ mà MISRA và SPARK ban đầu dự định.
Lundin

Câu trả lời:


11

Xác thực mã nhúng là khó khăn, đặc biệt là khi xử lý các phần tài nguyên giới hạn như PIC. Bạn thường không có sự sang trọng của mã hóa trong các trường hợp thử nghiệm do các ràng buộc ghi nhớ của bộ phận và chương trình "thời gian thực" thường được thực hiện trên các loại thiết bị này.

Dưới đây là một số hướng dẫn của tôi:

  1. Viết một thông số nếu không có: Nếu bạn không mã hóa thông số kỹ thuật, hãy ghi lại mã của bạn là gì, đầu vào hợp lệ là gì, đầu ra dự kiến ​​là gì, mỗi thói quen nên mất bao lâu, những gì có thể và không thể nhận được bị đóng băng, vv - một lý thuyết về hoạt động, sơ đồ, bất cứ điều gì tốt hơn không có gì.

  2. Nhận xét mã của bạn: Chỉ vì một cái gì đó rõ ràng đối với bạn không có nghĩa là nó rõ ràng (hoặc chính xác) với người khác. Nhận xét bằng ngôn ngữ đơn giản là cần thiết cho cả đánh giá và khả năng duy trì mã.

  3. Mã phòng thủ: Không chỉ bao gồm mã cho đầu vào bình thường. Xử lý các đầu vào bị thiếu, các đầu vào nằm ngoài phạm vi, tràn toán học, v.v. - bạn càng bao quát các góc của thiết kế mã của mình, mã sẽ càng ít tự do hơn khi triển khai.

  4. Sử dụng các công cụ phân tích tĩnh: Có thể khiêm tốn chỉ có bao nhiêu công cụ lỗi như PC-lint có thể tìm thấy trong mã của bạn. Xem xét một phân tích tĩnh sạch chạy như một điểm khởi đầu tốt cho thử nghiệm nghiêm trọng.

  5. Đánh giá ngang hàng là rất cần thiết: Mã của bạn phải sạch sẽ và được ghi chép đầy đủ để có thể được xem xét một cách hiệu quả bởi một bên độc lập. Kiểm tra cái tôi của bạn ở cửa và nghiêm túc xem xét bất kỳ lời chỉ trích hoặc đề xuất nào.

  6. Kiểm tra là điều cần thiết: Bạn nên thực hiện xác nhận của riêng mình, cũng như xác thực mã độc lập. Những người khác có thể phá mã của bạn theo những cách bạn không thể tưởng tượng được. Kiểm tra mọi điều kiện hợp lệ và mọi điều kiện không hợp lệ bạn có thể nghĩ đến. Sử dụng PRNG và nạp dữ liệu rác vào. Làm bất cứ điều gì bạn có thể để phá vỡ mọi thứ, sau đó sửa chữa và thử lại. Nếu bạn may mắn, bạn sẽ có thể chạy mã của mình ở chế độ gỡ lỗi và xem lén các thanh ghi và biến - nếu không, bạn sẽ cần phải xảo quyệt và chuyển đổi đèn LED / tín hiệu số để có ý tưởng về trạng thái của bạn thiết bị. Làm bất cứ điều gì cần thiết để có được thông tin phản hồi bạn cần.

  7. Nhìn bên dưới mui xe: Đừng ngại nhìn vào mã máy được tạo bởi trình biên dịch C của bạn. Bạn có thể (sẽ?) Tìm những nơi mà mã C đẹp đẽ của bạn đã bị nổ tung thành hàng chục nếu không phải là hàng trăm thao tác, nơi nào đó an toàn (vì chỉ có một dòng mã, phải không?) Mất nhiều thời gian để thực hiện nhiều ngắt đã sa thải và vô hiệu hóa các điều kiện. Nếu một cái gì đó trở nên không hiệu quả khủng khiếp, hãy cấu trúc lại nó và thử lại.


+1 Tất cả lời khuyên âm thanh. Tôi mong đợi bất kỳ nhà phát triển phần mềm chuyên nghiệp nào chỉ mỉm cười và gật đầu khi đọc nó.
Lundin

2
Một khía cạnh quan trọng của đánh giá ngang hàng là đánh giá là về mã chứ không phải về lập trình viên. Nếu bạn phân tích mã của mình bằng các thuật ngữ như "đầu tiên tôi làm điều này, sau đó tôi làm điều đó", có lẽ bạn đang gặp rắc rối. "Đầu tiên mã làm điều này, sau đó nó làm điều đó" là cách đúng đắn để suy nghĩ về nó. Và điều tương tự cũng áp dụng cho người đánh giá: không phải "tại sao bạn làm điều này?", Mà là "tại sao mã lại làm điều này?".
Pete Becker

Bạn cũng có thể xem xét thêm: 1. Sử dụng kiểm tra độ phức tạp theo chu kỳ 2. Phần mềm kiểm soát phiên bản
AlphaGoku

4

Hầu hết các kỹ thuật tương tự để tạo phần mềm đáng tin cậy trên PC cũng có thể áp dụng cho phát triển nhúng. Rất hữu ích để tách các thuật toán của bạn khỏi mã dành riêng cho phần cứng và kiểm tra riêng các thuật toán đó bằng các thử nghiệm đơn vị, mô phỏng, phân tích tĩnh và các công cụ như Valgrind. Bằng cách đó, có ít mã hơn chỉ được kiểm tra trên phần cứng.

Tôi sẽ không từ bỏ C. Mặc dù các ngôn ngữ như Ada có thể đưa ra một số đảm bảo nhỏ, nhưng thật dễ dàng để rơi vào cái bẫy nghĩ rằng ngôn ngữ hứa hẹn nhiều hơn thực tế.


Valgrid có thể phù hợp với PC hơn một chút so với MCU 8 bit, tuy nhiên :)
Lundin

Thật không may, một số kỹ thuật để tạo ra phần mềm cấp PC tốt rất không phù hợp với các máy vi tính nhỏ và một số thực tiễn được coi là Xấu và Sai trong đất PC hoàn toàn có thể chấp nhận được trong môi trường nhúng.
John U

3

MISRA-C thực sự rất hữu ích để cải thiện chất lượng mã chung và giảm thiểu lỗi. Chỉ cần chắc chắn rằng bạn đọc và hiểu mọi quy tắc, hầu hết chúng đều tốt, nhưng một vài trong số chúng không có ý nghĩa gì.

Một cảnh báo ở đây. Tài liệu MISRA giả định rằng người đọc là người có kiến ​​thức sâu rộng về ngôn ngữ C. Nếu bạn không có cựu chiến binh C cứng rắn như vậy trong nhóm của mình, nhưng quyết định lấy một bộ phân tích tĩnh và sau đó làm theo một cách mù quáng mọi cảnh báo được đưa ra, rất có thể sẽ dẫn đến mã chất lượng thấp hơn , vì bạn có thể giảm khả năng đọc và đưa ra lỗi do tai nạn. Tôi đã thấy điều này xảy ra rất nhiều lần, chuyển đổi mã thành tuân thủ MISRA không phải là một nhiệm vụ tầm thường.

Có hai phiên bản của tài liệu MISRA-C có thể áp dụng. MISRA-C: 2004, vẫn là tiêu chuẩn thực tế của ngành công nghiệp nhúng hiện tại. Hoặc MISRA-C: 2012 mới hỗ trợ tiêu chuẩn C99. Nếu bạn chưa bao giờ sử dụng MISRA-C trước đây, tôi sẽ khuyên bạn nên thực hiện sau.

Tuy nhiên, hãy lưu ý rằng các nhà cung cấp công cụ thường đề cập đến MISRA-C: 2004 khi họ nói rằng họ đã kiểm tra MISRA (đôi khi họ thậm chí còn đề cập đến phiên bản MISRA-C: 1998 đã lỗi thời). Theo tôi biết, công cụ hỗ trợ cho MISRA-C: 2012 vẫn còn hạn chế. Tôi nghĩ rằng chỉ có một số máy phân tích tĩnh đã triển khai nó cho đến nay: Klocwork, LDRA, PRQA và Polyspace. Có thể nhiều hơn, nhưng bạn chắc chắn cần kiểm tra phiên bản MISRA mà nó hỗ trợ.

Trước khi quyết định, tất nhiên bạn có thể bắt đầu bằng cách đọc tài liệu MISRA và xem những gì nó đòi hỏi. Nó có thể được mua với giá £ 10 từ misra.org , khá phải chăng so với giá cho các tiêu chuẩn ISO.


1

Mathworks (folks MATLAB) có một công cụ phân tích mã tĩnh gọi là Polyspace .

Cũng như phân tích mã tĩnh, lint và như vậy, tôi sẽ đề nghị định nghĩa và thiết kế cẩn thận các giao diện (với quy trình xem xét chính thức) và phân tích độ bao phủ mã.

Bạn cũng có thể muốn xem hướng dẫn về thiết kế mã quan trọng về an toàn, bao gồm MISRA, nhưng cả các tiêu chuẩn UL1998 và IEC 61508.


Tôi không khuyên bạn nên đến gần IEC 61508 trừ khi bạn phải làm vậy. Nó không đề cập đến phần mềm, nhưng thiếu các nguồn khoa học, hiện đại cho tuyên bố của mình. Tiêu chuẩn đó đã xuất hiện 30 năm quá muộn - nếu nó được phát hành vào những năm 70 giống như hầu hết cái gọi là "nguồn", nó có thể hữu ích.
Lundin

1

Để có câu trả lời hoàn chỉnh cho câu hỏi này, tôi sẽ loại bỏ suy nghĩ về "độ tin cậy của mã" và thay vào đó hãy nghĩ về "độ tin cậy của thiết kế", bởi vì mã chỉ là biểu thức cuối cùng của thiết kế.

Vì vậy, bắt đầu với các yêu cầu và viết và kiểm tra những yêu cầu. Nếu bạn không có tài liệu yêu cầu, hãy chỉ vào một dòng mã ngẫu nhiên và tự hỏi "tại sao dòng đó lại cần thiết?" Nhu cầu về bất kỳ dòng mã nào cuối cùng cũng có thể truy nguyên theo yêu cầu, ngay cả khi nó đơn giản / rõ ràng như "nguồn cung cấp sẽ xuất ra 5VDC nếu đầu vào nằm trong khoảng 12-36VDC." Một cách nghĩ về điều này là nếu dòng mã đó không thể được truy tìm theo yêu cầu, thì làm sao bạn biết đó là mã đúng, hay nó hoàn toàn cần thiết?

Tiếp theo, xác minh thiết kế của bạn. Sẽ ổn nếu nó hoàn toàn nằm trong mã (ví dụ: trong các bình luận), nhưng điều đó làm cho khó biết liệu mã đó có đang thực sự có ý nghĩa gì không. Ví dụ: mã có thể có dòng ghi output = 3 * setpoint / (4 - (current * 5));current == 4/5Đầu vào hợp lệ có thể gây ra sự cố? Nên làm gì trong trường hợp này để ngăn chia cho 0? Bạn có tránh các hoạt động hoàn toàn hoặc làm giảm sản lượng thay thế? Có một lưu ý chung trong tài liệu thiết kế của bạn về cách xử lý các trường hợp cạnh như vậy giúp việc xác minh thiết kế ở mức cao hơn dễ dàng hơn nhiều. Vì vậy, bây giờ kiểm tra mã dễ dàng hơn vì đó là vấn đề kiểm tra xem mã có thực hiện đúng thiết kế đó không.

Cùng với đó, kiểm tra mã phải kiểm tra các lỗi phổ biến mà IDE của bạn không mắc phải (bạn đang sử dụng IDE phải không?), Chẳng hạn như '=' khi bạn có nghĩa là '==', thiếu dấu ngoặc làm thay đổi ý nghĩa của 'nếu 'báo cáo, dấu chấm phẩy nơi họ không nên, v.v.

Khi tôi viết bài này, tôi nhận thấy rằng thật khó để tóm tắt nhiều năm đào tạo / kinh nghiệm về chất lượng phần mềm trong một bài viết. Tôi viết mã cho các thiết bị y tế và ở trên là một bản tóm tắt cực kỳ đơn giản về cách chúng ta tiếp cận nó.


Sự hiểu biết của tôi là phần mã trong một thiết bị y tế được kiểm tra gần như là một thiết bị riêng biệt. Điều đó có chính xác không?
Scott Seidman

@ScottSeidman Nhiều khả năng, nó được thử nghiệm trên cơ sở yêu cầu, như đã đề cập trong câu trả lời này. Đối với mỗi yêu cầu, bạn nên có một mô-đun mã và đối với mỗi mô-đun mã như vậy, bạn nên có một thử nghiệm. Vì vậy, về cơ bản, mỗi yêu cầu có một thử nghiệm tương ứng và mã là giá trị trung bình để thực hiện yêu cầu. Loại truy tìm yêu cầu này là thông lệ phổ biến trong bất kỳ hệ thống quan trọng nào, trước khi từ thông dụng "TDD" xuất hiện.
Lundin

Tôi đã đề cập cụ thể đến hướng dẫn của FDA, chẳng hạn như fda.gov/doads/RegulatoryIn information / Guidances / ucm126955.pdf Phần mềm thực sự đòi hỏi nhiều hơn bạn nghĩ nếu là một phần của thiết bị y tế, bắt đầu từ giai đoạn lập kế hoạch và kiểm soát thiết kế.
Scott Seidman

Scott, tôi chưa bao giờ nghĩ về nó theo cách đó, nhưng bạn đã đúng. Người đảm bảo chất lượng phần mềm của chúng tôi xác minh phần mềm tách biệt với phần còn lại của hệ thống (càng nhiều càng tốt) trước khi chuyển phần mềm sang một nhóm khác chịu trách nhiệm Xác minh và Xác thực hệ thống.
lyndon
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.