2010-03-18 27 views
6

Tôi nên quản lý bộ nhớ trong ứng dụng nhúng quan trọng của sứ mệnh của mình như thế nào?Tài nguyên để quản lý bộ nhớ trong ứng dụng nhúng

Tôi đã tìm thấy một số bài viết với google, nhưng không thể xác định hướng dẫn thực tế hữu ích thực sự.

DO-178b cấm phân bổ bộ nhớ động, nhưng bạn sẽ quản lý bộ nhớ như thế nào? Preallocate tất cả mọi thứ trước và gửi một con trỏ đến từng chức năng cần phân bổ? Phân bổ nó trên ngăn xếp? Sử dụng một phân bổ tĩnh toàn cầu (nhưng sau đó nó rất giống với phân bổ động)?

Câu trả lời có thể có dạng trả lời thông thường, tham chiếu đến tài nguyên hoặc tham chiếu đến hệ thống nhúng mã nguồn mở tốt chẳng hạn.

làm rõ: Vấn đề ở đây không phải là liệu quản lý bộ nhớ có khả dụng cho hệ thống được nhúng hay không. Nhưng một thiết kế tốt cho một hệ thống nhúng là gì, để tối đa hóa độ tin cậy.

Tôi không hiểu tại sao tĩnh preallocating một vùng đệm, và tự động nhận và thả nó, khác với phân bổ động bộ nhớ.

Trả lời

3

Là một người đã bị xử lý với các hệ thống nhúng, mặc dù không nghiêm khắc như vậy cho đến nay (Tôi đã đọc DO-178B, mặc dù):

  • Nếu bạn nhìn vào bootloader u-boot, rất nhiều là được thực hiện với cấu trúc được đặt trên toàn cầu. Tùy thuộc vào ứng dụng chính xác của bạn, bạn có thể có được với một cấu trúc toàn cầu và ngăn xếp. Tất nhiên, có sự ủy thác lại và các vấn đề liên quan ở đó không thực sự áp dụng cho bộ tải khởi động nhưng có thể cho bạn.
  • Preallocate, preallocate, preallocate. Nếu bạn có thể ở thời gian thiết kế liên kết kích thước của một mảng/danh sách cấu trúc/etc, khai báo nó như là một toàn cầu (hoặc tĩnh toàn cầu - nhìn Ma, đóng gói).
  • Ngăn xếp rất hữu ích, sử dụng nó khi cần - nhưng hãy cẩn thận, vì nó có thể dễ dàng tiếp tục phân bổ nó cho đến khi bạn không còn không gian ngăn xếp. Một số mã tôi từng thấy bản thân gỡ lỗi sẽ phân bổ bộ đệm 1k cho quản lý chuỗi trong nhiều chức năng ... đôi khi, việc sử dụng các bộ đệm sẽ nhấn không gian ngăn xếp của một chương trình khác, như kích thước ngăn xếp mặc định là 4k.
  • Trường hợp vùng đệm có thể phụ thuộc vào chính xác cách nó được triển khai. Nếu bạn biết bạn cần phải vượt qua các bộ đệm có kích thước cố định có kích thước được biết đến tại thời gian biên dịch, việc xử lý một vùng đệm có thể dễ dàng chứng minh tính đúng đắn hơn một bộ cấp phát động hoàn chỉnh. Bạn chỉ cần xác minh bộ đệm không thể bị mất và xác thực việc xử lý của bạn sẽ không thành công. Dường như có một số lời khuyên tốt ở đây: http://www.cotsjournalonline.com/articles/view/101217

Thực sự, tuy nhiên, tôi nghĩ rằng câu trả lời của bạn có thể được tìm thấy trong khi tham gia http://www.do178site.com/

0

Phân bổ tất cả mọi thứ từ ngăn xếp thường được thực hiện trong các hệ thống nhúng hoặc ở nơi khác mà khả năng xảy ra lỗi phân bổ là không thể chấp nhận. Tôi không biết DO-178b là gì, nhưng nếu vấn đề là malloc không có sẵn trên nền tảng của bạn, bạn cũng có thể tự thực hiện nó (thực hiện đống của riêng bạn), nhưng điều này vẫn có thể dẫn đến việc phân bổ không thành công khi bạn chạy ra khỏi không gian, tất nhiên.

+0

DO-178b là tiêu chuẩn cho phần mềm avionic. Vấn đề không phải là availiblity của malloc, nhưng một nhiệm vụ tốt thiết kế phần mềm quan trọng. –

1

Hệ thống quan trọng trong thời gian thực, chạy dài, nhiệm vụ không được phân bổ động và giải phóng bộ nhớ khỏi heap. Nếu bạn cần và không thể thiết kế xung quanh nó để viết lược đồ quản lý hồ bơi được phân bổ và cố định của riêng bạn. Có, được phân bổ cố định trước khi có thể. Bất cứ điều gì khác là yêu cầu cho sự cố cuối cùng.

0

Không có cách nào chắc chắn 100%.

Bạn có thể xem các ví dụ về bộ cấp phát bộ nhớ của FreeRTOS. Những người sử dụng hồ bơi tĩnh, nếu tôi không nhầm.

+0

Nhưng bộ nhớ được cấp phát động có sử dụng các hồ tĩnh có thể chấp nhận được trong các ứng dụng quan trọng của sứ mệnh không? –

+0

Có và không. Cũng giống như trong trường hợp của bất kỳ loại phân bổ động, có một cơ hội chạy ra khỏi hồ bơi. Bạn cần phải tự hỏi mình nếu bạn có thể chịu đựng được điều đó. Ngoài ra, có một loạt các vấn đề liên quan đến việc thực hiện phân bổ tùy chỉnh (phân mảnh, tối ưu hóa, yada yada) –

0

Bạn có thể tìm thấy this question thú vị là tốt, phân bổ động thường bị cấm trong không gian cứng cài đặt (thực sự, bộ nhớ lõi vẫn còn hữu ích ở đó).

Thông thường, khi malloc() không có sẵn, tôi chỉ sử dụng ngăn xếp. Như Tronic cho biết, toàn bộ lý do đằng sau việc không sử dụng malloc() là nó có thể thất bại. Nếu bạn đang sử dụng một pool tĩnh toàn cầu, có thể hiểu rằng việc thực hiện malloc() nội bộ của bạn có thể được thực hiện bằng chứng không thành công.

Nó thực sự, thực sự, thực sự phụ thuộc vào nhiệm vụ ở bàn tay và những gì hội đồng quản trị sẽ được tiếp xúc với.

+0

Tôi thực sự thực sự thực sự không hiểu làm thế nào malloc thực hiện nội bộ của bạn có thể được thực hiện thất bại. Nếu bạn thực sự cố gắng tính toán điều gì đó (nói, hãy đánh số đường dẫn mà rô bốt của bạn cần để đạt đến đích) và bạn có quá nhiều đầu vào, bạn có thể chạy không gian để lưu trữ tất cả các bước mà rô bốt cần thực hiện. Bạn phải quan tâm đến điều đó, cho dù bạn đang sử dụng phân bổ bộ nhớ động hoặc tĩnh. –

+0

@Elazar Leibovich: Nếu bạn có một hồ bơi tĩnh phân bổ, bạn _know_ bạn có bộ nhớ để thực hiện nhiệm vụ, với những hạn chế thiết kế của bất cứ điều gì bạn đang làm việc trên. Một robot phải vượt qua một lục địa sẽ gợi ý một cấu hình phần cứng hoàn toàn khác với cấu hình phải đi từ phòng này sang phòng khác. Ngoài ra, tôi có lẽ sẽ không thực hiện một malloc nội bộ() trên một bảng cứng rad. Câu hỏi của bạn là tốt, nhưng thay vì nói chung là những vấn đề này có xu hướng đặc biệt là nhiệm vụ cụ thể. –

+0

Đủ công bằng, bạn phải có đủ bộ nhớ để thực hiện tác vụ cụ thể mà phần cứng nhúng của bạn được yêu cầu thực hiện. Nhưng đôi khi bạn thấy mình viết các đoạn mã chung, có thể có liên quan đến các dự án nhúng khác. Ví dụ, bạn đang triển khai Dijkstra. Mục đích chung của bạn Dijkstra có thể cần phải phân bổ bộ nhớ, và nên thất bại nếu nó không có đủ bộ nhớ. Tất nhiên hệ thống sẽ không bao giờ thất bại, vì nó sẽ không sử dụng Dijkstra nếu nó không có đủ bộ nhớ cho nó, nhưng bản thân Dijkstra có thể thất bại. –

1

Tuyên bố từ chối trách nhiệm: Tôi chưa làm việc cụ thể với DO-178b, nhưng tôi đã viết phần mềm cho các hệ thống được chứng nhận.

Trên các hệ thống chứng nhận mà tôi đã được một nhà phát triển, ...

  1. phân bổ động bộ nhớ là có thể chấp nhận CHỈ trong giai đoạn khởi tạo.
  2. Phân bổ bộ nhớ động không bao giờ được chấp nhận.

này lại cho chúng ta với các tùy chọn sau ...

  • Sử dụng cấu trúc tĩnh được phân bổ.
  • Tạo một nhóm cấu trúc và sau đó lấy/giải phóng chúng từ/quay lại hồ bơi.
  • Để linh hoạt, chúng tôi có thể tự động phân bổ kích thước của các hồ bơi hoặc số lượng cấu trúc trong giai đoạn khởi tạo. Tuy nhiên, một khi qua giai đoạn init đó, chúng tôi đã mắc kẹt với những gì chúng tôi có.

Công ty của chúng tôi nhận thấy rằng các hồ cấu trúc và sau đó lấy/giải phóng từ/trở lại vào hồ là hữu ích nhất. Chúng tôi đã có thể giữ cho mô hình, và giữ cho mọi thứ xác định với các vấn đề tối thiểu.

Hy vọng điều đó sẽ hữu ích.

+1

Nhưng không nhận được/giải phóng các bộ nhớ tương đương với việc thực hiện phân bổ động? –

+2

No. Chúng tương tự nhưng không tương đương. Phân bổ động bằng cách sử dụng malloc() và free() dẫn đến phân mảnh bộ nhớ, và khả năng malloc() thất bại do sự phân mảnh. Do đó, các hệ thống được chứng nhận tránh nó vì nó là một PITA của hoàng gia để chứng nhận. Các mục trong hồ bơi có thể được phân tán, nhưng mục có được thường xuyên được đảm bảo để thành công được cung cấp có các mục không sử dụng. Nó không quan trọng như thế nào phân tán các mục trong hồ bơi. – Sparky

+0

Tôi không phải là chuyên gia về hệ điều hành, vì vậy hãy sửa tôi nếu tôi sai, nhưng, giả sử chỉ có một chủ đề sử dụng malloc() và free(), sẽ không có phân mảnh nếu bạn thực sự miễn phí ' ing tất cả mọi thứ bạn malloc'd? Và trong trường hợp bạn không làm, dĩ nhiên, dĩ nhiên, bạn sẽ gặp rắc rối ... Dù sao thì, hai chủ đề sử dụng cùng một hồ bơi thực sự là một vấn đề lớn với việc quản lý bộ nhớ truyền thống. –

2

Tôi đã làm việc trong một môi trường DO-178B (hệ thống cho máy bay). Những gì tôi đã hiểu, là lý do chính cho việc không cho phép phân bổ động chủ yếu là chứng nhận. Chứng nhận được thực hiện thông qua các bài kiểm tra (đơn nhất, bảo hiểm, tích hợp, ...). Với những bài kiểm tra đó, bạn phải chứng minh rằng hành vi của chương trình của bạn là 100% có thể dự đoán được, gần đến mức mà dấu chân bộ nhớ của quá trình của bạn giống nhau từ một lần thực thi đến lần tiếp theo. Khi phân bổ động được thực hiện trên heap (và có thể thất bại), bạn không thể dễ dàng chứng minh điều đó (tôi tưởng tượng nó sẽ có thể nếu bạn nắm vững tất cả các công cụ từ phần cứng tới bất kỳ đoạn mã nào được viết, nhưng ...). Bạn không có vấn đề này với phân bổ tĩnh. Đó cũng là lý do tại sao C++ không được sử dụng tại thời điểm này trong các môi trường như vậy. (khoảng 15 năm trước, điều đó có thể đã thay đổi ...)

Thực tế, bạn phải viết nhiều cấu trúc và chức năng phân bổ để đảm bảo rằng bạn có một thứ xác định. Bạn có thể tưởng tượng rất nhiều giải pháp. Điều quan trọng là bạn phải chứng minh (với TẤN các bài kiểm tra) một mức độ cao của hành vi xác định.Nó dễ dàng hơn để chứng minh rằng bàn tay của bạn crafted developpement làm việc xác định rằng để chứng minh rằng linux + gcc là xác định trong phân bổ bộ nhớ.

Chỉ 2 xu của tôi. Nó đã được một thời gian dài trước đây, mọi thứ có thể đã thay đổi, nhưng liên quan đến chứng nhận như DO-178B, điểm là để chứng minh ứng dụng của bạn sẽ làm việc bất cứ lúc nào trong bất kỳ bối cảnh nào.

Các vấn đề liên quan