C ++ có phù hợp với các hệ thống nhúng không?


167

Một câu hỏi phổ biến, ở đây và ở nơi khác. C ++ có phù hợp với các hệ thống nhúng không?

Vi điều khiển? RTOSes? Lò nướng bánh? Máy tính nhúng?

OOP có hữu ích trên vi điều khiển không?

C ++ có loại bỏ các lập trình viên quá xa phần cứng để có hiệu quả không?

C ++ của Arduino (không có quản lý bộ nhớ động, các mẫu, ngoại lệ) có nên được coi là "C ++ thực" không?

(Hy vọng rằng wiki này sẽ là nơi chứa đựng cuộc chiến thần thánh tiềm năng này)


5
Câu hỏi nhanh: khi bạn nói nhúng , bạn có nghĩa là vi điều khiển? vi xử lý? nhúng x86 / nhúng PC?
J. Polfer

1
Tôi không có ý định gây ra một cuộc chiến thần thánh; mục đích là để tìm hiểu những gì lập luận của bạn chống lại nó.
J. Polfer

2
Nó xuất hiện trong một số câu hỏi trước đây, vì vậy tôi nghĩ rằng một vị trí trung tâm sẽ tốt.
Toby Jaffey

4
C ++ vs nhúng là một chủ đề gây tranh cãi. Tôi có một quan điểm mạnh mẽ, nhưng tôi không nghĩ thật công bằng khi đưa ra một câu hỏi và chơi ở việc ghi điểm. Tôi hy vọng rằng một wiki cộng đồng sẽ làm cho một cuộc thảo luận cân bằng hơn.
Toby Jaffey

13
Đây là một câu hỏi tồi vì "nhúng" là một thuộc tính vô nghĩa trong việc quyết định liệu một ngôn ngữ cụ thể và hành lý liên quan của nó có phù hợp hay không. Điểm quan trọng là các hệ thống nhỏ so với các hệ thống lớn, trong đó các hệ thống nhỏ không chạy HĐH, có bộ nhớ hạn chế, có thể không phải là von-Neuman, có thể có nhiều hạn chế phần cứng khác nhau đối với ngăn xếp cuộc gọi, ngăn xếp dữ liệu, bạn không thể tự động phân bổ Mb hoặc thậm chí là một kb, vv Hầu hết các bộ vi điều khiển là các hệ thống "nhỏ". Máy tính bảng đơn thường được nhúng, nhưng nói chung là các hệ thống "lớn".
Olin Lathrop

Câu trả lời:


135

Có, C ++ vẫn hữu ích trong các hệ thống nhúng. Như mọi người khác đã nói, nó vẫn phụ thuộc vào chính hệ thống, giống như một uC 8 bit có lẽ sẽ là không có trong cuốn sách của tôi mặc dù có một trình biên dịch ngoài kia và một số người làm điều đó (rùng mình). Vẫn có một lợi thế khi sử dụng C ++ ngay cả khi bạn thu nhỏ nó xuống thành một thứ như "C +" ngay cả trong thế giới vi mô 8 bit. "C +" nghĩa là gì? Ý tôi là không sử dụng mới / xóa, tránh ngoại lệ, tránh các lớp ảo có tính kế thừa, có thể tránh kế thừa tất cả cùng nhau, rất cẩn thận với các mẫu, sử dụng các hàm nội tuyến thay vì macro và sử dụng constcác biến thay vì #defines.

Tôi đã làm việc cả trong C và C ++ trong các hệ thống nhúng trong hơn một thập kỷ nay và một số nhiệt huyết tuổi trẻ của tôi đối với C ++ chắc chắn đã bị hao mòn do một số vấn đề trong thế giới thực làm rung chuyển một người ngây thơ. Tôi đã thấy điều tồi tệ nhất của C ++ trong một hệ thống nhúng mà tôi muốn gọi là "lập trình viên CS phát điên trong một thế giới EE". Trên thực tế, đó là điều mà tôi đang làm việc với khách hàng của mình để cải thiện một cơ sở mã này mà họ có trong số những người khác.

Sự nguy hiểm của C ++ là bởi vì nó là một công cụ rất mạnh giống như con dao hai lưỡi có thể cắt cả cánh tay và chân của bạn nếu không được giáo dục và kỷ luật đúng cách trong chính ngôn ngữ và lập trình chung. C giống một con dao một lưỡi, nhưng vẫn sắc bén như vậy. Với C ++, quá dễ dàng để có được mức độ trừu tượng rất cao và tạo ra các giao diện bị xáo trộn trở nên vô nghĩa trong thời gian dài và điều đó một phần do sự linh hoạt của C ++ trong việc giải quyết cùng một vấn đề với nhiều tính năng ngôn ngữ khác nhau (mẫu, OOP, thủ tục, Các mẫu RTTI, OOP +, quá tải, nội tuyến).

Tôi đã hoàn thành hai cuộc hội thảo kéo dài 4 giờ về Phần mềm nhúng trong C ++ của giáo sư C ++, Scott Meyers. Ông đã chỉ ra một số điều về các mẫu mà tôi chưa bao giờ xem xét trước đây và chúng có thể giúp tạo ra bao nhiêu mã an toàn. Điểm chính của nó là, bạn không thể có mã chết trong phần mềm phải đáp ứng các yêu cầu nghiêm ngặt về an toàn. Các mẫu có thể giúp bạn thực hiện điều này, vì trình biên dịch chỉ tạo mã mà nó cần khi khởi tạo các mẫu. Tuy nhiên, người ta phải được giáo dục kỹ lưỡng hơn trong việc sử dụng chúng để thiết kế chính xác cho tính năng này khó thực hiện hơn trong C vì các trình liên kết không luôn tối ưu hóa mã chết.

Scott Meyers là một người ủng hộ rất lớn cho các mẫu và sử dụng nội tuyến một cách hợp lý, và tôi phải nói rằng tôi vẫn còn hoài nghi về việc gung ho về các mẫu. Tôi có xu hướng né tránh họ, mặc dù anh ta nói rằng họ chỉ nên được áp dụng khi họ trở thành công cụ tốt nhất. Ông cũng đưa ra quan điểm rằng C ++ cung cấp cho bạn các công cụ để tạo ra các giao diện thực sự tốt, dễ sử dụng đúng và làm cho nó khó sử dụng sai. Một lần nữa, đó là phần khó khăn. Người ta phải đạt đến một mức độ thành thạo trong C ++ trước khi bạn có thể biết cách áp dụng các tính năng này theo cách hiệu quả nhất để trở thành giải pháp thiết kế tốt nhất.

Điều tương tự cũng xảy ra với OOP. Trong thế giới nhúng, bạn phải tự làm quen với loại mã mà trình biên dịch sẽ nhổ ra để biết liệu bạn có thể xử lý các chi phí thời gian chạy của đa hình thời gian chạy hay không. Bạn cần sẵn sàng thực hiện các phép đo cũng như để chứng minh thiết kế của bạn sẽ đáp ứng yêu cầu thời hạn. Có phải lớp InterruptManager mới sẽ làm cho độ trễ ngắt của tôi quá lâu không? Có nhiều dạng đa hình khác có thể phù hợp với vấn đề của bạn hơn, chẳng hạn như đa hình thời gian liên kết mà C có thể làm được, nhưng C ++ có thể thực hiện thông qua mẫu thiết kế Pimpl (Con trỏ mờ) .

Tôi nói rằng tất cả để nói rằng, C ++ có vị trí của nó trong thế giới nhúng. Bạn có thể ghét tất cả những gì bạn muốn, nhưng nó sẽ không biến mất. Nó có thể được viết theo cách rất hiệu quả, nhưng khó hơn để học cách làm đúng hơn so với C. Nó đôi khi có thể hoạt động tốt hơn C trong việc giải quyết vấn đề và đôi khi thể hiện một giao diện tốt hơn, nhưng một lần nữa, bạn đã phải Giáo dục bản thân và không ngại học cách.


1
Điều này phù hợp với những gì tôi đã đọc từ các chuyên gia tư vấn hệ thống nhúng khác. Tôi đã luôn được dạy rằng với C, bạn tự cắt mình theo những cách nhỏ bé liên tục, nhưng một lỗi trong C ++ sẽ hiếm hơn, nhưng khi bạn làm hỏng bạn sẽ bị mất một chân. Cảm ơn bạn đã viết một phản hồi rõ ràng với một số chuyên môn mà tôi không có.
Kortuk

3
Trên lưu ý của chuyên ngành Khoa học Máy tính đang phát điên ở vùng đất EE. Trong công việc của tôi, đoạn mã tồi tệ nhất mà chúng tôi đã được viết bởi một chuyên viên CS. Chúng tôi đã dành mãi mãi để cố gắng dạy cho anh ta phần cứng là gì. Ông đã tạo ra một hệ thống có cấu trúc bằng cách sử dụng UML và xây dựng toàn bộ hệ thống dựa trên hệ thống đó trong java bằng cách sử dụng kế thừa hợp lý và vv. Nó hoạt động, cho đến khi mọi thứ thay đổi, và sau đó là một công việc vá lỗi tồi để thêm các tính năng hoặc thiết kế lại hoàn chỉnh. Mã này gần như không thể sử dụng được vì làm thế nào triệt để anh ta làm xáo trộn toàn bộ sự kế thừa.
Kortuk

2
Đó không chỉ là những con bọ cắn bạn, mà là mã không thể nhầm lẫn cũng sẽ cắn bạn. Chắc chắn, khi bạn bắt đầu dự án đó bằng cách sử dụng các tính năng C ++ gọn gàng đó, mọi thứ sẽ trôi chảy, nhưng sau 2 hoặc 3 năm, entropy sẽ khởi động nếu không có nỗ lực nghiêm túc nào được đưa vào tái cấu trúc khi bạn phát triển. Đó là những gì tôi phải đối mặt ngay bây giờ..các mã phát triển nhanh hơn theo thời gian trong C ++.
Jay Atkinson

2
UML và stHRachines. Bạn thực sự cần phải xem xét nội dung của Miro Samek tại state-machine.com . Anh ta đã xây dựng một hệ thống hiệu quả, dễ dàng tái cấu trúc và thay đổi, nhưng phải mất một thời gian để tìm kiếm nó.
Jay Atkinson

2
Nó thực sự phụ thuộc vào hệ thống của bạn và dung lượng bộ nhớ bạn có sẵn. Bạn đang viết mã trên micro 8 bit có rất ít RAM? Sau đó, bạn có thể tốt hơn hết là tránh phát điên trên các giao diện trừu tượng. Nếu bạn đang viết một cái gì đó như các hệ thống nhúng 32 bit với các tấm bộ nhớ, hãy tìm nó. Bạn thực sự phải cân nhắc nó ra. Chẳng hạn, mỗi khi bạn gắn kết thế giới "ảo" trên lớp đó, bạn sẽ có thêm một con trỏ, có thể là 8 bit, 16 bit hoặc 32 bit tùy theo hệ thống, cho mỗi trường hợp bạn khai báo về đối tượng đó. Bạn thậm chí sẽ không nhận ra, và anh bạn,
Jay Atkinson

56

C ++ hoàn toàn phù hợp cho các hệ thống nhúng. Bây giờ tôi sử dụng sự hiện diện / vắng mặt của các công cụ phát triển tốt (hoặc thiếu chúng) làm tiêu chí chính của tôi cho việc có sử dụng bộ vi xử lý cụ thể hay không.

Các lĩnh vực của C ++ rất tốt để sử dụng trên các hệ thống nhúng vì chúng có chi phí tài nguyên thấp:

  • tính mô đun mang lại bằng cách sử dụng tốt các lớp / cấu trúc
  • các mẫu nếu trình biên dịch thực hiện tốt công việc biên dịch chúng một cách hiệu quả. Mẫu là một công cụ tốt để mang lại việc sử dụng lại các thuật toán cho các loại dữ liệu khác nhau.

Khu vực OK:

  • các hàm ảo - Tôi đã từng chống lại điều này, nhưng chi phí tài nguyên rất nhỏ (một vtable cho mỗi lớp , không phải cho mỗi đối tượng; một con trỏ tới vtable cho mỗi đối tượng; một thao tác hội thảo cho mỗi lệnh gọi hàm ảo) và lợi thế lớn của điều này là nó cho phép bạn có một mảng chứa một số loại đối tượng khác nhau mà không cần phải biết chúng là loại gì. Tôi đã sử dụng điều này gần đây để có một mảng các đối tượng đại diện cho một thiết bị I2C, mỗi đối tượng có các phương thức riêng biệt.

Các khu vực không được sử dụng, chủ yếu là do chi phí hoạt động không thể chấp nhận được trên các hệ thống nhỏ:

  • cấp phát bộ nhớ động - những người khác đã đề cập đến điều này, nhưng một lý do quan trọng khác không sử dụng phân bổ bộ nhớ động là nó thể hiện sự không chắc chắn về thời gian; nhiều lý do để sử dụng các hệ thống nhúng là cho các ứng dụng thời gian thực.
  • RTTI (thông tin loại thời gian chạy) - chi phí bộ nhớ khá lớn
  • trường hợp ngoại lệ - một rõ ràng không-không, bởi vì trong những hit tốc độ thực hiện

Cảm ơn các đầu vào. Thú vị và rất giống với những gì tôi đã đọc.
Kortuk

1
Trên thực tế phân bổ bộ nhớ động là tốt, và đôi khi không thể tránh khỏi. Đó là vấn đề DEallocation bộ nhớ động (và sử dụng lại sau đó) là vấn đề. RTTI là bộ nhớ hog, tôi đồng ý về điều đó. Nhưng vấn đề với các ngoại lệ là gì?
Wouter van Ooijen

1
@WoutervanOoijen: Vấn đề với các trường hợp ngoại lệ là nếu foocác cuộc gọi bartrong một khối try/ catchbartạo ra một số đối tượng và cuộc gọi boz, ném một ngoại lệ, hệ thống phải bằng cách nào đó gọi hàm hủy cho các đối tượng barđược tạo trước khi trả lại quyền điều khiển foo. Trừ khi các trường hợp ngoại lệ bị vô hiệu hóa hoàn toàn, barsẽ không có cách nào để biết liệu bozcó thể ném bất kỳ hay không, và do đó phải bao gồm mã bổ sung để cho phép khả năng đó. Tôi muốn thấy một biến thể của C ++ với "ngoại lệ được kiểm tra" để đối phó với điều đó; nếu thói quen đó có thể cho phép ngoại lệ đối với thoát ...
supercat

1
... Phải được khai báo như vậy, thì trình biên dịch chỉ cần bao gồm mã xử lý ngoại lệ trong các trình gọi của các thường trình đó. Để chắc chắn, việc phải thêm vào tất cả các tuyên bố cần thiết, trong khi hy vọng tránh những tuyên bố không cần thiết, sẽ hơi nặng nề, nhưng nó sẽ cho phép các ngoại lệ được sử dụng ở những nơi hữu ích, mà không cần thêm chi phí ở những nơi không có.
supercat

3
@WoutervanOoijen: Ngẫu nhiên, nếu tôi đang thiết kế ABI để xử lý ngoại lệ như vậy trên ARM, tôi sẽ chỉ định mã gọi một thói quen có thể thoát qua ngoại lệ nên có R14 trỏ đến địa chỉ hai byte trước địa chỉ trả lại mong muốn (điều này sẽ xảy ra một cách tự nhiên nếu người gọi tuân theo lệnh CALL với một từ 16 bit). Thói quen được gọi sau đó sẽ thoát bình thường thông qua add r15,r14,#2thay vì mov r15,r14; để thoát qua ngoại lệ , ldrhs r0,[r14] / add r15,r14,r0. Không có chi phí chu kỳ cho lối ra bình thường và không có hạn chế khung stack.
supercat

36

Có, C ++ chắc chắn phù hợp với các hệ thống nhúng. Trước tiên, hãy làm sáng tỏ một số quan niệm sai lầm về sự khác biệt giữa C và C ++:

Trong một vi nhúng, bạn sẽ luôn cần sử dụng các ngôn ngữ cấp cao một cách cẩn thận nếu bạn lo ngại về các hạn chế về thời gian hoặc không gian. Ví dụ, nhiều MCU không xử lý tốt con trỏ và do đó rất kém hiệu quả khi sử dụng ngăn xếp. Điều này có nghĩa là bạn phải cẩn thận về việc chuyển các biến cho các hàm, sử dụng mảng và con trỏ và đệ quy. Một dòng đơn giản của C như:

a[i] = b[j] * c[k];

có thể tạo ra khoảng 4 trang hướng dẫn tùy thuộc vào bản chất của các biến đó.

Bất cứ khi nào bạn đang sử dụng bất kỳ ngôn ngữ cấp cao nào và bạn lo ngại về các hạn chế về thời gian và không gian, thì bạn cần biết mọi tính năng của ngôn ngữ đó chuyển thành hướng dẫn máy trên MCU của bạn (ít nhất là mọi tính năng bạn sử dụng). Điều này đúng với C, C ++, Ada, bất cứ điều gì. Có lẽ tất cả các ngôn ngữ sẽ chứa các tính năng không dịch hiệu quả trên các MCU nhỏ. Luôn kiểm tra danh sách tháo gỡ để đảm bảo rằng trình biên dịch không tạo ra các luồng hướng dẫn cho một cái gì đó tầm thường.

C có phù hợp với MCU nhúng không? Có, miễn là bạn để mắt đến mã được tạo.
C ++ có phù hợp với MCU nhúng không? Có, miễn là bạn để mắt đến mã được tạo.

Đây là lý do tại sao tôi nghĩ rằng C ++ tốt hơn C ngay cả trên MCU 8 bit: C ++ cung cấp hỗ trợ được cải thiện cho:

  • Ẩn dữ liệu
  • Đánh máy / kiểm tra mạnh hơn
  • Độ trong suốt đa ngoại vi sử dụng các lớp
  • Mẫu (như mọi khi nếu được sử dụng cẩn thận)
  • Danh sách khởi tạo
  • hằng số

Không có tính năng nào trong số này nặng hơn tính năng tiêu biểu của C.

Khi bạn di chuyển lên tới MCU 16 hoặc 32 bit, thì việc sử dụng các tính năng nặng hơn của C (stack, heap, con trỏ, mảng, printf, v.v.) cũng giống như vậy, trên MCU mạnh hơn sẽ trở nên phù hợp để sử dụng các tính năng nặng hơn của C ++ (stack, heap, tham chiếu, STL, new / xóa).

Vì vậy, không cần phải rùng mình khi nghĩ về C ++ trên PIC16. Nếu bạn biết ngôn ngữ của bạn và MCU của bạn đúng cách, thì bạn sẽ biết cách sử dụng cả hai một cách hiệu quả cùng nhau.


3
Đây là một câu trả lời rất rõ ràng và hợp lý cho câu hỏi. Chúc mừng +1!
Abbeyatcu

1
" a[i] = b[j] * c[k];có thể tạo khoảng 4 trang hướng dẫn tùy thuộc vào bản chất của các biến đó." Nếu MCU / trình biên dịch của bạn làm điều này, đó là bởi vì bạn đang sử dụng một số CPU sở thích nhà để xe từ những năm 80.
Lundin

@Lundin - Thở dài. Không, điều đó có nghĩa là bạn đang sử dụng một MCU nhỏ giá rẻ được thiết kế nhỏ và rẻ nhất có thể, không có những thứ phức tạp như lập chỉ mục ngăn xếp.
Rocketmagnet

2
@Rocketmagnet Ok có thể vào những năm 1990? Ngày nay, 8 loại thuốc lá có giá tương đương với 32 loại. Chỉ có lý do còn lại để chọn trước đây là tiêu thụ hiện tại. Và liên quan đến những 8-bit cực kỳ nhảm nhí không có ngăn xếp: nếu bạn viết C thay vì trình biên dịch mã cho một MCU giới hạn như vậy, bạn có thể đã làm sai. Sau đó, 4 trang được tạo ra là lỗi của bạn khi viết các chương trình quá phức tạp cho CPU và về cơ bản C là công cụ sai cho tác vụ. (Tôi đã làm điều này trong quá khứ trên Freescale RS08, đó là một ý tưởng rất ngu ngốc.)
Lundin

@Lundin Bộ xử lý 32 bit không cần thiết nhanh hơn 16 bit. Đây là cách rõ ràng trở lại vào ngày khi quá trình chuyển đổi chương trình 16 đến 32 bit đang diễn ra trong thế giới PC.
Barleyman

24

Tôi luôn tìm thấy những cuộc tranh luận để giải trí để đọc. Không quá nhiều cho các cuộc thảo luận trí tuệ về ưu và nhược điểm của các ngôn ngữ có sẵn khác nhau nhưng bởi vì bạn thường có thể đưa ra lập trường của ai đó về chủ đề dựa trên công việc / kinh nghiệm / lĩnh vực họ quan tâm. Đúng ở đó với các đối số "tối ưu hóa sớm" là các chuyên gia CS và lập trình viên bảo trì trích dẫn Knuth trái và phải và những người làm việc trong thế giới thực nơi các vấn đề về hiệu suất nghĩ rằng tất cả đều điên rồ (Tôi là thành viên của nhóm sau để có sự công bằng).

Vào cuối ngày, bạn có thể phát triển phần mềm xuất sắc bằng C hoặc C ++ hoặc chèn ngôn ngữ tại đây . Nó thuộc về khả năng của nhà phát triển chứ không phải ngôn ngữ. Trở thành một chuyên gia về ngôn ngữ thường chỉ được yêu cầu nếu bạn chọn sai ngôn ngữ để bắt đầu và bây giờ cần phải giải quyết vấn đề đó để giải quyết vấn đề của bạn, trong hầu hết các trường hợp, đây là những tình huống duy nhất mà bạn cần đi sâu vào các tính năng hoặc trình biên dịch tối nghĩa thủ thuật để hoàn thành mục tiêu.

Tôi thường nghe mọi người bắt đầu những cuộc tranh luận này là "Tôi là một chuyên gia về ngôn ngữ X và blah blah" Tôi thành thật ngay lập tức làm mất uy tín của những người này bởi vì, theo tôi, họ đã tiếp cận vấn đề từ góc độ sai lầm và mọi thứ sau đó bị xé nát bởi mong muốn sử dụng công cụ của họ để giải quyết vấn đề và cho thấy mức độ 'tuyệt vời' của nó.

Tôi thường xem các nhà phát triển chọn một công cụ được đặt trước và cố gắng uốn cong nó thành vấn đề thứ hai, điều này hoàn toàn sai và dẫn đến các giải pháp tào lao.

Như tôi đã đề cập trong một bình luận cho một câu trả lời khác, những cuộc chiến ngôn ngữ này thường đi sâu vào tranh luận rằng ngôn ngữ X cho phép lập trình viên làm những việc ngu ngốc hơn. Trong khi giải trí để đọc, tất cả những tuyên bố này thực sự có nghĩa là bạn gặp vấn đề khi thuê các nhà phát triển giỏi và cần giải quyết vấn đề đó trực tiếp thay vì cố gắng hỗ trợ tình hình bằng cách tiếp tục thuê các nhà phát triển tồi và chọn các công cụ để họ có thể làm ít thiệt hại càng tốt.

Theo tôi, các nhà phát triển giỏi, có thể là phát triển phần mềm hoặc phần cứng, nghiên cứu vấn đề, kiến ​​trúc sư một giải pháp và tìm các công cụ cho phép họ thể hiện giải pháp theo cách 'tốt nhất'. Sẽ không có vấn đề gì nếu công cụ cần thiết là thứ bạn chưa từng sử dụng trước đây, sau khi bạn sử dụng 3-4 ngôn ngữ / công cụ phát triển cho các dự án chọn một công cụ mới sẽ có tác động tối thiểu đến thời gian phát triển của bạn.

Tất nhiên, "cách tốt nhất" là một thuật ngữ chủ quan và cũng cần được xác định trong giai đoạn nghiên cứu. Người ta cần xem xét vô số vấn đề: hiệu năng, dễ thể hiện, mật độ mã, v.v dựa trên vấn đề hiện tại. Tôi không bao gồm khả năng duy trì trong danh sách đó vì một lý do, tôi không quan tâm bạn chọn ngôn ngữ nào, nếu bạn đã chọn công cụ phù hợp và dành thời gian để hiểu vấn đề này sẽ đến 'miễn phí'. Khó duy trì mã thường là kết quả của việc chọn sai công cụ hoặc cấu trúc hệ thống kém, điều này dẫn đến một mớ hỗn độn xấu xí để làm cho nó hoạt động.

Yêu cầu bất kỳ ngôn ngữ nào là 'tốt hơn' so với bất kỳ ngôn ngữ nào là ngớ ngẩn mà không xác định một vấn đề quan tâm cụ thể. Một cách tiếp cận hướng đối tượng không phải lúc nào cũng tốt hơn một cách tiếp cận chức năng. Có một số vấn đề cho vay rất tốt cho mô hình thiết kế hướng đối tượng. Có nhiều cái không. Tuyên bố tương tự có thể được đưa ra về nhiều tính năng ngôn ngữ mà mọi người dường như rất thích làm phiền.

Nếu bạn dành hơn 20% thời gian cho một vấn đề thực sự gõ mã, có lẽ bạn đang tạo ra một hệ thống rất kém hoặc có các nhà phát triển rất kém (hoặc bạn vẫn đang học). Bạn nên dành phần lớn thời gian của mình để lập sơ đồ hóa vấn đề và xác định các phần khác nhau của ứng dụng tương tác như thế nào. Gắn một nhóm các nhà phát triển tài năng trong một căn phòng với một bảng đánh dấu và một vấn đề cần giải quyết và nói với họ rằng họ không được phép viết bất kỳ mã nào hoặc chọn bất kỳ công cụ nào cho đến khi họ cảm thấy thoải mái với toàn bộ hệ thống sẽ làm nhiều hơn để cải thiện chất lượng của đầu ra và tốc độ phát triển hơn là chọn bất kỳ công cụ mới nóng nào được đảm bảo để cải thiện thời gian phát triển. (tra cứu phát triển scrum như một tài liệu tham khảo cho cực đối nghịch với lập luận của tôi)

Thông thường, thực tế không may là nhiều doanh nghiệp chỉ có thể đo lường giá trị của nhà phát triển bằng số lượng dòng được viết hoặc bằng cách xem 'sản lượng hữu hình'. Họ xem 3 tuần trong một căn phòng có bảng đánh dấu là mất năng suất. Các nhà phát triển thường bị buộc phải tăng tốc qua giai đoạn phát triển 'suy nghĩ' hoặc buộc phải sử dụng một công cụ do một số vấn đề chính trị đặt ra trong công ty, "Anh trai của sếp tôi làm việc cho IBM vì vậy chúng tôi chỉ có thể sử dụng các công cụ của họ", đó là loại rác rưởi . Hoặc tệ hơn, bạn nhận được một bộ yêu cầu thay đổi liên tục từ công ty vì họ không có khả năng thực hiện nghiên cứu thị trường phù hợp hoặc không hiểu tác động của những thay đổi trong chu kỳ phát triển.

Xin lỗi vì hơi lạc đề với câu nói này, tôi có ý kiến ​​khá mạnh mẽ về chủ đề này.


2
Bây giờ, tôi không gõ các bài kiểm tra đơn vị ở cấp độ ứng dụng (trình điều khiển trên) trên các hệ thống nhúng nhất định. Có một số giá trị của phản hồi tức thì của thử nghiệm đơn vị và loại bỏ các lỗi sớm trong giai đoạn phát triển, nhưng toàn bộ mô hình TDD để sinh ra thiết kế có vẻ hơi khó hiểu. Tôi thích dành một chút thời gian để "suy nghĩ" về vấn đề và vạch ra nó trong đầu, trên giấy hoặc trên bảng trắng, trước khi bắt đầu viết mã. Tôi cũng nghĩ TDD khuyến khích thị trường không thực hiện nghiên cứu trước về các yêu cầu, bởi vì nó được cho là giúp thay đổi yêu cầu liên tục.
Jay Atkinson

2
Và để ghi chú cuối cùng vào bình luận siêu dài của tôi .. Chúng tôi không cần các chuyên gia ngôn ngữ để thiết kế. Chúng tôi cần các nhà thiết kế chuyên gia có thể làm việc (các) ngôn ngữ.
Jay Atkinson

1
PRD = tài liệu yêu cầu sản phẩm, MRD = tài liệu yêu cầu tiếp thị, TRD = tài liệu yêu cầu kỹ thuật. TDD = Phát triển dựa trên thử nghiệm.
Jay Atkinson

1
@Mark - Tôi đồng ý với tình cảm thiết kế của bạn, nhưng chỉ ở một điểm. Tôi nghĩ rằng các công việc thiết kế nặng phía trước sẽ được đền đáp nếu a) các yêu cầu của bạn khá ổn định / được biết đến và b) các nhà phát triển thực hiện thiết kế có kinh nghiệm . Trong một trước. công việc, tôi được giao nhiệm vụ thiết kế và nó bị ảnh hưởng nặng nề bởi đội trưởng của tôi, và tôi nghĩ, "Thật là một việc ngu ngốc để làm! Thiết kế tiết kiệm tiền (xem cuốn sách Code Code) ??" Nhưng trong mã hóa, tôi phát hiện ra vô số thứ tôi không biết để tìm kiếm. Nếu tôi đã thực hiện nhiều thiết kế và giảm thiểu thời gian mã, nó sẽ là một sự lãng phí. JME.
J. Polfer

1
@sheepsimulator Tôi rõ ràng đồng ý ở điểm thứ hai, tôi cho rằng các kiến ​​trúc sư hệ thống dẫn đầu là những nhà phát triển có kinh nghiệm. Về điểm đầu tiên tôi thực sự không đồng ý. Tôi nghĩ rằng bạn càng mong đợi các yêu cầu thay đổi thì bạn càng nên dành nhiều thời gian hơn trong giai đoạn thiết kế bởi vì bạn cần phải tạo ra một thiết kế tốt, dễ thay đổi. Tôi biết một số triết lý đề xuất phát triển nhanh chóng. Trong một số trường hợp, điều này hoạt động tốt như nhiều lập trình viên xấu hoặc thiếu kinh nghiệm trong đội ngũ nhân viên. Tất cả những triết lý thiết kế này được đưa ra là "tôi không có cầu nguyện thiết kế một hệ thống linh hoạt, vì vậy, đừng lãng phí thời gian để thử".
Đánh dấu

17

Bất kỳ ngôn ngữ có thể phù hợp cho một hệ thống nhúng. Nhúng chỉ có nghĩa là: một phần của một bộ máy lớn hơn, trái ngược với một máy tính sử dụng miễn phí.

Câu hỏi có liên quan nhiều hơn khi được hỏi về một hệ thống tài nguyên giới hạn hoặc thời gian thực (cứng) .

Đối với hệ thống thời gian thực, C ++ là một trong những ngôn ngữ cao nhất vẫn phù hợp khi lập trình cho các ràng buộc thời gian nghiêm ngặt. Ngoại trừ việc sử dụng heap (toán tử miễn phí), nó không có cấu trúc nào có thời gian thực hiện không xác định, vì vậy bạn có thể kiểm tra xem chương trình của bạn có đáp ứng các yêu cầu về thời gian hay không, và với một số kinh nghiệm hơn bạn thậm chí có thể dự đoán được. Tất nhiên nên tránh sử dụng heap, mặc dù toán tử mới vẫn có thể được sử dụng để phân bổ một lần. Các cấu trúc mà C ++ cung cấp trên C có thể được sử dụng tốt trong một hệ thống nhúng: OO, ngoại lệ, mẫu.

Đối với các hệ thống rất hạn chế về tài nguyên (chip 8 bit, ít hơn một vài Kb RAM, không có ngăn xếp có thể chấp nhận được), C ++ có thể không phù hợp, mặc dù nó vẫn có thể được sử dụng như một 'C' tốt hơn.

Tôi nghĩ thật không may khi Ada dường như chỉ được sử dụng trong một số ngóc ngách. Theo nhiều cách, nó là một Pascal ++, nhưng không có gánh nặng tương thích với ngôn ngữ vốn đã là một mớ hỗn độn nghiêm trọng để bắt đầu. (chỉnh sửa: sự lộn xộn nghiêm trọng dĩ nhiên là C. Pascal là một ngôn ngữ đẹp nhưng hơi phi thực tế.)

================================================== ==============

EDIT: Tôi đã gõ một câu trả lời cho câu hỏi mới ("Trong trường hợp nào C ++ cần thiết khi chúng tôi đang lập trình vi điều khiển"?) Đã bị đóng khi đề cập đến câu hỏi này, vì vậy tôi sẽ thêm những gì tôi đã viết:

Không bao giờ có một lý do bao quát cho việc sử dụng bất kỳ ngôn ngữ lập trình nào , nhưng có thể có các đối số có trọng lượng nhiều hơn hoặc ít hơn trong một tình huống cụ thể. Có thể tìm thấy các cuộc thảo luận về vấn đề này ở nhiều nơi, với các vị trí được thực hiện trong phạm vi từ "không bao giờ sử dụng C ++ cho bộ điều khiển vi mô" đến "luôn luôn sử dụng C ++". Tôi nhiều hơn với vị trí cuối cùng. Tôi có thể đưa ra một số lập luận, nhưng bạn sẽ phải tự quyết định cân nặng của chúng trong một tình huống cụ thể (và theo hướng nào).

  • Trình biên dịch C ++ hiếm hơn trình biên dịch C; đối với một số mục tiêu (ví dụ PIC lõi 12 và 14 bit) không có trình biên dịch C ++ nào cả.
  • (tốt) Các lập trình viên C ++ hiếm hơn các lập trình viên C (tốt), đặc biệt trong số những người lập trình cũng (phần nào) am hiểu về điện tử.
  • C ++ có nhiều cấu trúc hơn C không phù hợp với các hệ thống nhỏ (như ngoại lệ, RTTI, sử dụng thường xuyên của heap).
  • C ++ có bộ thư viện (tiêu chuẩn) phong phú hơn C, nhưng hậu quả của điểm trước đó là các thư viện C ++ thường sử dụng các tính năng không phù hợp cho các hệ thống nhỏ và do đó không thể khắc phục được trên các hệ thống nhỏ.
  • C ++ có nhiều cấu trúc hơn C cho phép bạn tự bắn vào chân mình.
  • C ++ có nhiều cấu trúc hơn C cho phép bạn ngăn mình tự bắn vào chân mình (vâng, IMO cái này và cái trước đều đúng).
  • C ++ có một bộ cơ chế trừu tượng phong phú hơn, vì vậy nó cho phép các cách lập trình tốt hơn, đặc biệt là cho các thư viện.
  • Các tính năng ngôn ngữ C ++ (ví dụ: hàm tạo / hàm hủy, hàm chuyển đổi) làm cho việc xem qua mã để xem máy được tạo ra trở nên khó khăn hơn và do đó chi phí về không gian và thời gian của cấu trúc ngôn ngữ.
  • Cấu trúc ngôn ngữ C ++ khiến chúng ta không cần phải biết chính xác cách dịch chính xác sang mã máy vì chúng thực hiện 'điều đúng' theo cách trừu tượng hơn.
  • Chuẩn ngôn ngữ C ++ đang phát triển nhanh chóng và được các trình biên dịch lớn (gcc, clang, microsoft) áp dụng nhanh chóng. C đang phát triển khá mạnh mẽ và việc áp dụng một số tính năng mới hơn (mảng biến thể) là điều đáng sợ và thậm chí đã được hoàn nguyên trong một tiêu chuẩn sau này. Điểm này đặc biệt thú vị ở chỗ những người khác nhau sử dụng nó để hỗ trợ các vị trí ngược lại.
  • C ++ chắc chắn là một công cụ sắc nét hơn C. Bạn có tin tưởng các lập trình viên (hoặc chính mình) sử dụng một công cụ như vậy để tạo ra một tác phẩm điêu khắc đẹp, hoặc bạn sợ chúng làm tổn thương chính mình và bạn muốn giải quyết một sản phẩm ít đẹp hơn nhưng có rủi ro thấp hơn ? (Tôi nhớ lại rằng giáo viên điêu khắc của tôi từng nói với tôi rằng các công cụ cùn có thể trong một số trường hợp có nhiều nguy hiểm hơn so với những sắc nét.)

Blog của tôi có một số bài viết về việc sử dụng C ++ trên các hệ thống nhỏ (= bộ điều khiển vi mô).


15

Theo kinh nghiệm của tôi, C ++ thường không phù hợp với các hệ thống nhúng nhỏ. Ý tôi là, vi điều khiển và các thiết bị không có hệ điều hành.

Nhiều kỹ thuật OOP C ++ dựa vào phân bổ bộ nhớ động. Điều này thường bị thiếu trong các hệ thống nhỏ.

STL và Boost thực sự chứng minh sức mạnh của C ++, cả hai đều rất lớn về dấu chân.

C ++ khuyến khích lập trình viên trừu tượng hóa cỗ máy, trong đó trong các hệ thống bị hạn chế, nó phải được chấp nhận.

Năm ngoái, tôi đã chuyển một sản phẩm máy tính để bàn từ xa thương mại sang điện thoại di động. Nó được viết bằng C ++ và chạy trên Windows, Linux và OSX. Nhưng, nó phụ thuộc rất nhiều vào STL, bộ nhớ động và ngoại lệ C ++. Để có được nó trên WinCE, Symbian và các môi trường không có hệ điều hành, viết lại C là tùy chọn rõ ràng nhất.


Tôi đồng ý tham chiếu đến các hệ thống nhỏ, nhưng tôi nghĩ chúng ta có các định nghĩa khác nhau về các hệ thống nhỏ. Khi bạn có 1kB ROM và mã C được viết tốt sẽ lấy hết 1 byte ROM, đó là một hệ thống nhỏ.
Kortuk

6
Tôi không tranh luận rằng C không thể có dấu chân nhỏ hơn, nhưng bạn có thể đã sử dụng C ++ tĩnh và thu được kết quả rất giống nhau để thiết kế cho những gì vừa thảo luận. Tôi nghĩ vấn đề là hầu hết các lập trình viên OOP được sử dụng cho các hệ thống có bộ nhớ động và sử dụng các cấu trúc rất kém hiệu quả, dẫn đến mã hoàn toàn vô dụng cho các hệ thống năng lượng thấp hơn.
Kortuk

4
Vì vậy, những gì bạn nói là bạn không muốn sử dụng C ++, bạn muốn sử dụng một cái gì đó giữa C và C ++ (hãy gọi nó là C +?). Trong trường hợp đó, tôi đồng ý, có rất nhiều thứ nhảm nhí trong C ++ mọi người sử dụng chỉ vì nó có sẵn chứ không phải vì nó tối ưu. Hầu như bất kỳ ngôn ngữ nào cũng có khả năng tạo ra mã tốt, nhanh, vấn đề là nó được sử dụng như thế nào. Hầu hết các cuộc chiến tranh về ngôn ngữ không phải là kết quả của khả năng ngôn ngữ mà là một cuộc tranh cãi về việc một kẻ ngốc dễ dàng làm những điều ngu ngốc như thế nào, đó thực sự là một cuộc tranh luận ngu ngốc: p
Mark

2
"Hầu hết các cuộc chiến thần thánh đối với các ngôn ngữ không phải là kết quả của khả năng ngôn ngữ mà là một cuộc tranh cãi về việc một kẻ ngốc dễ dàng làm những điều ngu ngốc như thế nào, đó thực sự là một cuộc tranh luận ngu ngốc." Là một câu rất thú vị. Tôi cần họ của bạn để tôi có thể trích dẫn đó.
Kortuk

1
Tôi thực sự không sử dụng bộ nhớ động trong C mặc dù. Không có nơi nào tôi phải có nó. Về lâu dài tôi đã đọc được rằng nó có thể rất phân khúc và bắt đầu gây ra vấn đề. Tôi cần phải có các trường hợp được thiết kế rất rõ ràng để hết bộ nhớ và tôi cần có khả năng theo dõi chính xác số tiền còn lại.
Kortuk

11

Tôi hy vọng sẽ thêm nhiều ánh sáng hơn nhiệt cho cuộc thảo luận này về C ++ trên các hệ thống hạn chế tài nguyên và kim loại trần.

Các vấn đề trong C ++:

  • Các trường hợp ngoại lệ đặc biệt là vấn đề về RAM vì "bộ đệm khẩn cấp" bắt buộc (ví dụ như có ngoại lệ bộ nhớ) có thể lớn hơn RAM có sẵn và chắc chắn là một sự lãng phí đối với bộ vi điều khiển. Để biết thêm thông tin, xem n4049n4234 . Chúng nên được tắt (hiện đang là hành vi không xác định để chắc chắn và không bao giờ ném). SG14 hiện đang làm việc trên những cách tốt hơn để làm điều này.

  • RTTI có lẽ không bao giờ có giá trị trên không, nó nên được tắt

  • Xây dựng gỡ lỗi lớn, mặc dù đây không phải là vấn đề trong phát triển máy tính để bàn cổ điển nếu việc gỡ lỗi không phù hợp với chip, nó có thể là một vấn đề. Vấn đề phát sinh từ mã templated hoặc các lệnh gọi hàm bổ sung được thêm vào cho rõ ràng. Các cuộc gọi chức năng bổ sung này sẽ được loại bỏ một lần nữa bởi trình tối ưu hóa và sự rõ ràng hoặc linh hoạt được thêm vào có thể là một lợi thế lớn, tuy nhiên trong các bản dựng gỡ lỗi, đây có thể là một vấn đề.

  • Phân bổ đống. Mặc dù STL cho phép sử dụng các cấp phát tùy chỉnh, điều này có thể phức tạp đối với hầu hết các lập trình viên. Phân bổ heap là không xác định (nghĩa là thời gian thực không khó) và sự phân mảnh có thể dẫn đến các tình huống bộ nhớ bất ngờ xảy ra mặc dù đã làm việc trong thử nghiệm. Việc giữ sách cần thiết cho đống để theo dõi không gian trống và kích thước khác nhau có thể là một vấn đề với các đối tượng nhỏ. Nó thường tốt hơn để sử dụng phân bổ nhóm (cả trong C và C ++) nhưng điều này có thể bất thường đối với các lập trình viên C ++ được sử dụng để chỉ sử dụng heap.

  • Đa hình thời gian chạy và các cuộc gọi gián tiếp khác thường là một cú hích hiệu suất lớn, vấn đề thường là nhiều hơn vì trình tối ưu hóa có thể nhìn xuyên qua chúng nhiều hơn so với tìm nạp thực tế và nhảy đến địa chỉ. Cần tránh các cuộc gọi gián tiếp vì lý do này trong C và C ++, vì trong C ++, chúng ăn sâu hơn vào văn hóa (và khá hữu ích trong các lĩnh vực khác).

  • giao tiếp ngầm với clib có thể có vấn đề. Có thể phản tác dụng rằng các vấn đề clib nằm trong danh mục C ++ nhưng vấn đề phát sinh từ việc chia sẻ tài nguyên ngầm trong các môi trường đồng thời (chia sẻ rõ ràng hơn trong C). Việc sử dụng triển khai newLib phổ biến thường kéo theo rất nhiều sự phình to thường không cần thiết trong uCs, mặt khác newLibNanno không được cấp lại nên việc truy cập vào nó phải được tuần tự hóa (quá mức ở đây). Đây cũng là một vấn đề đối với C nhưng việc truy cập rõ ràng hơn. Theo nguyên tắc thông thường, về cơ bản, người ta không nên sử dụng gì từ không gian tên std trong ngữ cảnh ISR trừ khi bạn chắc chắn rằng nó không truy cập trạng thái trong clib bằng cách nào đó (ví dụ như errorno hoặc heap). Nó cũng quan trọng nếu bạn đang sử dụng các chủ đề (tôi thích RTC) để ghi đè mới và xóa để đồng bộ hóa quyền truy cập vào malloc và miễn phí.

Tóm lại, C ++ có một số vấn đề nhưng về cơ bản chúng đều có thể sửa chữa hoặc tránh được.

Bây giờ cho C, ở đây vấn đề là thứ tự cao hơn. Tôi không có khả năng cú pháp trong C để trừu tượng hóa mọi thứ theo cách mà tôi có thể thực hiện tối ưu hóa hoặc kiểm tra các bất biến tại thời gian biên dịch. Do đó, tôi không thể gói gọn mọi thứ theo cách mà người dùng không cần biết chúng hoạt động như thế nào để sử dụng chúng và hầu hết việc phát hiện lỗi của tôi được thực hiện trong thời gian chạy (không chỉ quá muộn mà còn tăng thêm chi phí). Về cơ bản, cách duy nhất để chung chung trong C là thông qua dữ liệu, tôi chuyển một chuỗi định dạng sang printf hoặc scanf được đánh giá trong thời gian chạy chẳng hạn. Sau đó, trình biên dịch khá khó để chứng minh rằng tôi không sử dụng một số tùy chọn có thể về mặt lý thuyết khi truyền đúng dữ liệu, điều đó có nghĩa là tiềm năng tạo mã chết và mất tiềm năng tối ưu hóa.

Tôi biết rằng tôi có thể đang phát hành một shitstorm ở đây nhưng kinh nghiệm của tôi về vi điều khiển 32 bit là trong một so sánh táo với C và C ++ được viết bởi các chuyên gia (như trong C ++ có khả năng tạo khuôn mẫu cao) C ++ là ngôn ngữ hiệu quả hơn ngay khi bất cứ điều gì cũng cần phải chung chung (như trong bất kỳ thư viện nào) và về cơ bản chúng tương đương nhau trong các trường hợp không chung chung. Người mới cũng dễ dàng tận dụng chuyên môn của một người triển khai thư viện chuyên gia trong C ++.

Đồng thời thực sự có rất ít chức năng mà tôi không thể truyền dữ liệu không chính xác, ngay khi đầu vào không phải là int mà là tình somethingcờ tôi sử dụng int như một phương thức biểu diễn thì có tiềm năng có được nó sai (vượt qua một giá trị không hợp lệ hoặc 'otherThing' thay vì 'cái gì đó'). Trong C phương pháp duy nhất của tôi để kiểm tra xem người dùng có hiểu sai hay không là trong thời gian chạy. Trong C ++, tôi có khả năng thực hiện một số kiểm tra, không phải tất cả các kiểm tra mà là một số kiểm tra tại thời gian biên dịch miễn phí.

Vào cuối ngày, một đội C thường mạnh như lập trình viên yếu nhất và lợi ích của mã kết quả có nhiều người chơi là 1 hoặc hình phạt hiệu suất. Ý tôi là đây là hiệu suất cao cho một và chỉ một công việc duy nhất trong môi trường duy nhất của các quyết định thiết kế duy nhất hoặc nó đủ chung để sử dụng trong nhiều môi trường (vi điều khiển khác, chiến lược quản lý bộ nhớ khác, độ trễ khác so với đánh đổi thông lượng, v.v.) nhưng có chi phí hiệu suất vốn có.

Trong C ++, mọi thứ có thể được các chuyên gia gói gọn và sử dụng trong nhiều môi trường nơi biên dịch mã thời gian thích ứng với tác vụ cụ thể và kiểm tra tĩnh giúp người dùng không làm những việc ngu ngốc với chi phí bằng không. Ở đây chúng ta có ít sự đánh đổi giữa việc chung chung và nhanh chóng và do đó, cuối cùng từ quan điểm chi phí so với lợi ích là ngôn ngữ hiệu quả hơn, an toàn hơn và hiệu quả hơn.

Một phê bình hợp lệ là vẫn còn thiếu rất nhiều thư viện C ++ tốt để nhúng, điều này có thể dẫn đến các quyết định thực dụng khi sử dụng chủ yếu C trên trình biên dịch C ++. Các quyết định chỉ sử dụng C trong một dự án về cơ bản là do ý thức hệ, không cần hỗ trợ di sản hoặc thừa nhận rằng nhóm không đủ kỷ luật để kiềm chế một tập hợp những điều ngu ngốc mà người ta có thể làm trong C ++ nhưng không phải trong C ++ và đồng thời đủ kỷ luật để không làm bất kỳ điều ngu ngốc nào lớn hơn nhiều mà người ta không thể chống lại trong C nhưng có thể trong C ++.


Thêm vào câu trả lời của tôi :) Người yêu C ++ bí ẩn này sẽ là ai? Hồ sơ của ông nói "Rõ ràng, người dùng này thích giữ một không khí bí ẩn về họ." (tiếng Anh kém, BTW) NHƯNG AHA địa điểm là "Bochum, Đức" ..... Hẹn gặp bạn tại hội nghị!
Wouter van Ooijen

À vâng đã cập nhật hồ sơ của tôi;) rất vui khi biết bạn đến với emBO ++, đây sẽ là một đám đông tốt
odinthenerd

10

Nền tảng của tôi: vừa ra khỏi trường đào tạo dưới các lập trình viên cũ của Bell Labs; đã làm việc được 3 năm, 2 về dự án nghiên cứu đại học; thu thập dữ liệu / kiểm soát quá trình trong VB.NET. Đã dành 1,5 năm để làm việc trên một ứng dụng cơ sở dữ liệu doanh nghiệp trong VB6. Hiện đang làm việc trên dự án cho PC nhúng với 2GB dung lượng lưu trữ, RAM 512 MB, CPU x86 500 MHz; một số ứng dụng chạy đồng thời được viết bằng C ++ với cơ chế IPC ở giữa. Vâng, tôi còn trẻ.

Ý kiến ​​của tôi: Tôi nghĩ C ++ có thể hoạt động hiệu quả với môi trường mà tôi đã viết ở trên . Phải thừa nhận rằng, hiệu suất thời gian thực cứng không phải là một yêu cầu đối với ứng dụng tôi đang bật và trong một số ứng dụng nhúng, đó có thể là một vấn đề. Nhưng đây là những điều tôi học được:

  • C ++ về cơ bản khác với C (nghĩa là không có C / C ++). Mặc dù mọi thứ hợp lệ C đều hợp lệ C ++, C ++ là một ngôn ngữ rất khác và người ta cần học cách lập trình trong C ++, chứ không phải C, để sử dụng hiệu quả nó trong mọi tình huống. Trong C ++, bạn cần lập trình hướng đối tượng, không theo thủ tục và không kết hợp cả hai (các lớp lớn có nhiều hàm). Nói chung, bạn nên tập trung vào việc tạo các lớp nhỏ với một vài chức năng và kết hợp tất cả các lớp nhỏ lại với nhau thành một giải pháp lớn hơn. Một trong những đồng nghiệp của tôi đã giải thích với tôi rằng tôi đã từng lập trình theo thủ tục trong các đối tượng, đó là một mớ hỗn độn lớn và khó bảo trì. Khi tôi bắt đầu áp dụng các kỹ thuật hướng đối tượng hơn, tôi thấy khả năng duy trì / khả năng đọc của mã của tôi tăng lên.

  • C ++ cung cấp các tính năng bổ sung dưới dạng phát triển hướng đối tượng có thể cung cấp cách đơn giản hóa mã để dễ đọc / bảo trì hơn . Thành thật mà nói, tôi không nghĩ rằng có nhiều cách ứng biến hiệu quả / không gian hiệu quả trong việc thực hiện OOP. Nhưng tôi nghĩ OOP là một kỹ thuật có thể giúp phân chia một vấn đề phức tạp thành nhiều mảnh nhỏ. Và điều đó hữu ích cho những người làm việc về mã, một yếu tố của quy trình này không nên bỏ qua.

  • Nhiều đối số chống lại C ++ chủ yếu liên quan đến phân bổ bộ nhớ động. C cũng có vấn đề tương tự. Bạn có thể viết một ứng dụng hướng đối tượng mà không cần sử dụng bộ nhớ động, mặc dù một trong những lợi ích của việc sử dụng các đối tượng là bạn có thể phân bổ các thứ này một cách linh hoạt một cách dễ dàng. Giống như trong C, bạn phải cẩn thận về cách quản lý dữ liệu để giảm rò rỉ bộ nhớ, nhưng kỹ thuật RAII làm cho điều này trở nên đơn giản hơn trong C ++ (làm cho bộ nhớ động tự động phá hủy bằng cách đóng gói nó trong các đối tượng). Trong một số ứng dụng, trong đó mọi vị trí bộ nhớ đều được tính, điều này có thể quá hoang dã & khó kiểm soát.

BIÊN TẬP:

  • WRT câu hỏi "Arduino C ++" : Tôi cho rằng C ++ không có quản lý bộ nhớ động vẫn có thể hữu ích. Bạn có thể sắp xếp mã của mình thành các đối tượng và sau đó đặt các đối tượng đó vào các vị trí khác nhau trong ứng dụng của bạn, thiết lập giao diện gọi lại, v.v. Bây giờ tôi đã phát triển trong C ++, tôi có thể thấy nhiều cách mà một ứng dụng có tất cả dữ liệu được phân bổ trên ngăn xếp vẫn có thể hữu ích với các đối tượng. Mặc dù vậy, tôi sẽ thừa nhận - tôi chưa bao giờ thực sự viết một ứng dụng nhúng như thế cho Arduino, vì vậy tôi không có bằng chứng nào đằng sau yêu cầu của mình. Tôi có một số cơ hội để thực hiện một số phát triển Arduino trong một dự án sắp tới - hy vọng tôi có thể kiểm tra yêu cầu của mình ở đó.

2
Tôi muốn bình luận về điểm thứ hai của bạn, bạn nói rằng nó giúp chia nhỏ một vấn đề phức tạp thành nhiều mảnh nhỏ và tính năng đó nên được bỏ qua. Đây là lý do chính xác mà tôi rất ủng hộ C ++. Một nhóm nghiên cứu lớn về lập trình cho thấy rằng sự tăng trưởng tuyến tính trong quy mô chương trình mang lại sự tăng trưởng theo cấp số nhân trong thời gian phát triển. điều này diễn ra theo cách ngược lại, nếu bạn có thể phân chia một chương trình đúng cách thì bạn có thể đưa ra sự phân rã theo cấp số nhân trong thời gian phát triển. Đây là điều quan trọng nhất.
Kortuk

về điểm thứ hai của bạn là tốt: Đơn giản chỉ cần sử dụng phương pháp thiết kế OOP sẽ không tạo ra nhiều mã hơn. Có một thiết kế cơ sở tốt, làm thế nào một người thể hiện thiết kế đó được để lại cho nhà phát triển. OOP không xác định rằng bạn tách mã của mình đúng cách, nó cung cấp tùy chọn khác và hơn thế nữa, ngoại hình mà bạn đã làm như vậy, nhưng, chắc chắn nó không thực thi thiết kế tốt, tùy thuộc vào nhà phát triển.
Đánh dấu

Điều đó luôn đúng. Tôi chưa bao giờ nghe nói về một ngôn ngữ thực thi thiết kế tốt. Tôi nghĩ rằng chúng tôi chủ yếu ngụ ý rằng đó là công việc của các nhà phát triển và C ++ giúp dễ dàng sử dụng và thực hiện theo cách có tổ chức.
Kortuk

@Mark - Tôi đồng ý. Nó đã là một quá trình học tập đối với tôi.
J. Polfer

7

Có, vấn đề với C ++ là dấu chân của mã tăng lên.

Trong một số hệ thống, bạn đang đếm byte và trong trường hợp đó, bạn sẽ phải chấp nhận một chi phí chạy gần với giới hạn của hệ thống của bạn là tăng chi phí phát triển của C.

Nhưng, ngay cả trong C, đối với một hệ thống được thiết kế tốt, bạn cần giữ mọi thứ được gói gọn. Các hệ thống được thiết kế tốt rất khó và C ++ cung cấp cho các lập trình viên một nơi cho một phương pháp phát triển rất có cấu trúc và có kiểm soát. Có chi phí để học OOP và nếu bạn muốn chuyển sang sử dụng nó, bạn chấp nhận nó và trong nhiều trường hợp, ban quản lý thà tiếp tục với C và không trả chi phí, vì rất khó để đo lường kết quả của một công tắc tăng năng suất. Bạn có thể xem một bài viết của chuyên gia hệ thống nhúng Jack Ganssle tại đây .

Quản lý bộ nhớ động là ma quỷ. Không thực sự, ma quỷ là tự động định tuyến, quản lý bộ nhớ động hoạt động tốt trên PC, nhưng bạn có thể mong đợi khởi động lại PC ít nhất vài tuần một lần. Bạn sẽ thấy rằng khi một hệ thống nhúng tiếp tục hoạt động trong 5 năm, việc quản lý bộ nhớ động có thể thực sự bị hỏng và thực sự bắt đầu thất bại. Ganssle thảo luận về những thứ như stack và heap trong bài viết của mình.

Có một số điều trong C ++ dễ gây ra sự cố và sử dụng nhiều tài nguyên, loại bỏ quản lý bộ nhớ động và các mẫu là những bước lớn để giữ dấu chân của C ++ gần với dấu chân của C. Đây vẫn là C ++, bạn không cần năng động quản lý bộ nhớ hoặc các mẫu để viết C ++ tốt. Tôi không nhận ra họ đã loại bỏ ngoại lệ, tôi coi ngoại lệ là một phần quan trọng trong mã của tôi mà tôi xóa trong bản phát hành, nhưng sử dụng cho đến thời điểm đó. Trong thử nghiệm hiện trường, tôi có thể có ngoại lệ tạo thông báo để thông báo cho tôi về một ngoại lệ bị bắt.


1
Tôi đã từng đồng ý rằng dấu chân mã là một vấn đề, nhưng gần đây có vẻ như kích thước flash có ảnh hưởng rất lớn đến giá của vi điều khiển, ít hơn nhiều so với kích thước RAM hoặc số lượng chân IO.
Wouter van Ooijen

Đối số trên bộ nhớ động là IMO quan trọng hơn. Tôi đã thấy các hệ thống công nghiệp có thể chạy trong nhiều tuần không ngừng, nhưng lớp chẩn đoán (được viết bằng C ++) sẽ giới hạn thời gian khởi động lại trong khoảng 12 giờ.
Dmitry Grigoryev

6

Tôi nghĩ rằng bài hát chống C ++ này của Linus Torvalds rất thú vị.

Một trong những tính năng tồi tệ nhất tuyệt đối của C ++ là cách nó tạo ra rất nhiều thứ phụ thuộc vào ngữ cảnh - điều đó chỉ có nghĩa là khi bạn nhìn vào mã, một khung nhìn cục bộ hiếm khi cung cấp đủ ngữ cảnh để biết điều gì đang xảy ra.

Anh ta không nói về thế giới hệ thống nhúng, mà là phát triển nhân Linux. Đối với tôi, sự liên quan đến từ điều này: C ++ đòi hỏi phải hiểu một bối cảnh lớn hơn và tôi có thể học cách sử dụng một bộ các mẫu đối tượng, tôi không tin tưởng mình sẽ nhớ chúng khi tôi phải cập nhật mã trong vài tháng.

(Mặt khác, tôi hiện đang làm việc trên một thiết bị nhúng sử dụng Python (không phải C ++, nhưng sử dụng cùng một mô hình OOP) sẽ có vấn đề chính xác. Theo tôi, đó là một hệ thống nhúng đủ mạnh để được gọi là PC 10 năm trước.)


5
Chúng tôi có thể khác nhau, nhưng tôi thấy rằng chỉ cần mở bất kỳ dự án nào tôi không thể biết điều gì đang diễn ra ngay lập tức, nhưng nếu tôi biết điều gì đó đang làm và tôi có một cái gì đó được mã hóa tốt trong C và một cái gì đó được mã hóa tốt trong C ++ thì C ++ luôn có vẻ nhiều hơn thông thoáng. Bạn vẫn cần thực hiện đóng gói để phát triển tốt trong C, điều mà C ++ làm rất dễ thực hiện. Việc sử dụng đúng các lớp có thể làm cho nó rất rõ ràng nơi các giao diện của bạn và chúng có thể được xử lý hoàn toàn thông qua một đối tượng.
Kortuk

Hoàn toàn đồng ý về đóng gói và các lớp học. Toán tử quá tải và kế thừa, không quá nhiều.
pingswept

1
Haha, vâng, quá tải toán tử có thể được sử dụng để làm xáo trộn chức năng của mã. Nếu ai đó đang vận hành quá tải thì cần phải có lý do rõ ràng hoặc không được thực hiện. Kế thừa chỉ nên được sử dụng trong các trường hợp cụ thể mà bạn thực sự đang làm một cái gì đó giống như cha mẹ với một vài bổ sung. Tôi nghĩ rằng tôi sẽ không sử dụng bất kỳ chức năng nào trong OOP. Tôi đã sử dụng cả hai, nhưng trong một hệ thống nhúng, tôi không thể nghĩ ra trường hợp nào. Giống như tôi nghĩ rằng một trình biên dịch có giới hạn 80 ký tự cho các tên biến nên bị loại bỏ ngay lập tức.
Kortuk

2
Tôi chỉ thốt lên trong miệng một chút khi nghĩ đến việc lập trình MCU bằng Python ...
Abbeyatcu

Bạn không phải là người duy nhất, nhưng nếu nó hoạt động tốt và hiệu quả, tôi có thể tha thứ.
Kortuk

6

Tôi nghĩ rằng các câu trả lời khác đã tạo ra một trường hợp khá tốt cho các ưu và nhược điểm và các yếu tố quyết định, vì vậy tôi chỉ muốn tóm tắt và thêm một vài nhận xét.

Đối với vi điều khiển nhỏ (8 bit), không có cách nào. Bạn chỉ đang yêu cầu làm tổn thương chính mình, không có lợi ích và bạn sẽ từ bỏ quá nhiều tài nguyên.

Đối với các bộ vi điều khiển cao cấp (ví dụ: 32-bit, 10 hoặc 100 MB cho RAM và lưu trữ) có hệ điều hành tốt, điều đó hoàn toàn ổn và, tôi dám nói, thậm chí còn được khuyến nghị.

Vì vậy, câu hỏi là: ranh giới ở đâu?

Tôi không biết chắc chắn, nhưng một khi tôi đã phát triển một hệ thống cho uC 16 bit với RAM 1 MB và 1 MB lưu trữ trong C ++, chỉ để hối tiếc về sau. Vâng, nó đã làm việc, nhưng công việc làm thêm tôi đã không xứng đáng. Tôi phải làm cho nó phù hợp, đảm bảo những thứ như ngoại lệ sẽ không bị rò rỉ (hỗ trợ OS + RTL khá lỗi và không đáng tin cậy). Hơn nữa, một ứng dụng OO thường thực hiện rất nhiều phân bổ nhỏ và chi phí lớn cho những thứ đó là một cơn ác mộng khác.

Với kinh nghiệm đó, tôi cho rằng các dự án trong tương lai tôi sẽ chỉ chọn C ++ trong các hệ thống ít nhất 16 bit và với ít nhất 16 MB cho RAM & lưu trữ. Đó là một giới hạn tùy ý và có thể sẽ thay đổi tùy theo những thứ như loại ứng dụng, kiểu mã hóa và thành ngữ, v.v. Nhưng với những cảnh báo, tôi đề nghị một cách tiếp cận tương tự.


2
Tôi phải không đồng ý ở đây, không có gì bất ngờ khi C ++ trở nên chấp nhận được do tài nguyên hệ thống, thực hành thiết kế tốt có thể giữ dấu chân của C ++ nơi có dấu chân của C. Điều này dẫn đến mã với các thiết kế OOP có cùng không gian. C viết kém có thể tệ như vậy.
Kortuk

1
Vâng, nó phụ thuộc vào mức độ lớn của ứng dụng của bạn và mức độ bạn sử dụng một số tính năng nhất định cần nhiều không gian hơn (như mẫu và ngoại lệ). Nhưng cá nhân tôi thà sử dụng C hơn là phải giới hạn bản thân trong một C ++ bị hạn chế. Nhưng ngay cả khi đó bạn sẽ có chi phí hoạt động của RTL lớn hơn, thunks phương thức ảo, lời gọi chuỗi hàm tạo / hàm hủy ... những hiệu ứng này có thể được giảm thiểu bằng mã hóa cẩn thận, nhưng sau đó bạn mất lý do chính cho việc sử dụng, trừu tượng hóa C ++ và quan điểm cấp cao.
fceconel

4

Có một số tính năng của C ++ rất hữu ích trong các hệ thống nhúng. Có những cái khác, như ngoại lệ, có thể đắt tiền, và chi phí của chúng có thể không phải lúc nào cũng rõ ràng.

Nếu tôi có máy khoan của mình, sẽ có một ngôn ngữ phổ biến kết hợp tốt nhất của cả hai thế giới, và bao gồm một số tính năng thiếu cả hai ngôn ngữ; một số nhà cung cấp bao gồm một vài tính năng như vậy, nhưng không có tiêu chuẩn. Một vài điều tôi muốn thấy:

  1. Xử lý ngoại lệ giống như Java hơn một chút, trong đó các hàm có thể ném hoặc rò rỉ ngoại lệ phải được khai báo như vậy. Mặc dù yêu cầu khai báo như vậy có thể hơi khó chịu từ góc độ lập trình, nhưng nó sẽ cải thiện tính rõ ràng của mã trong trường hợp hàm có thể trả về một số nguyên tùy ý nếu thành công, nhưng cũng có thể thất bại. Nhiều nền tảng có thể xử lý mã này không tốn kém bằng cách ví dụ có giá trị trả về trong một thanh ghi và dấu hiệu thành công / thất bại trong cờ mang.
  2. Quá tải các chức năng tĩnh và nội tuyến; sự hiểu biết của tôi là các cơ quan tiêu chuẩn cho C đã tránh quá tải chức năng để tránh sự cần thiết phải xáo trộn tên. Việc cho phép quá tải các hàm tĩnh và nội tuyến chỉ tránh được vấn đề đó và sẽ mang lại 99,9% lợi ích của việc quá tải các hàm bên ngoài (vì các tệp .h có thể xác định quá tải nội tuyến theo các hàm ngoài được đặt tên khác)
  3. Quá tải cho các giá trị tham số hằng số biên dịch tùy ý hoặc thời gian biên dịch cụ thể. Một số hàm có thể nội tuyến rất hiệu quả khi được truyền với bất kỳ giá trị không đổi nào, nhưng nội tuyến rất kém nếu được truyền một biến. Mã lần khác có thể là tối ưu hóa nếu giá trị không đổi có thể là bi quan nếu không. Ví dụ:
    void void copy_uint32s (uint32_t * Dest, const uint32_t * src, __is_const int n)
    {
      nếu (n <= 0) trở lại;
      khác if (n == 1) {mệnh [0] = src [0];}
      khác if (n == 2) {mệnh [0] = src [0]; mệnh [1] = src [1];}
      khác if (n == 3) {mệnh [0] = src [0]; mệnh [1] = src [1]; mệnh [2] = src [2];}
      khác if (n == 4) {mệnh [0] = src [0]; mệnh [1] = src [1]; mệnh [2] = src [2]; mệnh [3] = src [3];}
      other memcpy ((void *) Dest, (const void *) src, n * sizeof (* src));
    }
    
    Nếu 'n' có thể được đánh giá tại thời gian biên dịch, đoạn mã trên sẽ hiệu quả hơn so với lệnh gọi memcpy, nhưng nếu 'n' không thể được đánh giá tại thời điểm biên dịch, mã được tạo sẽ lớn hơn và chậm hơn mã đơn giản gọi là memcpy.

Tôi biết cha đẻ của C ++ không quá quan tâm đến phiên bản chỉ nhúng của C ++, nhưng tôi nghĩ nó có thể cung cấp một số cải tiến đáng kể so với việc chỉ sử dụng C.

Bất cứ ai cũng biết nếu bất cứ điều gì như trên đang được xem xét cho bất kỳ loại tiêu chuẩn?



@Joby Taffey: Tôi đoán tôi đã chỉnh sửa bài đăng của mình để bỏ qua đề cập rằng người tạo C ++ không thích một tập hợp con được nhúng; Tôi biết rằng đã có những nỗ lực, nhưng theo sự hiểu biết của tôi, họ đã không thực sự đạt được đến nay. Tôi nghĩ rằng sẽ có việc sử dụng nhất định cho một ngôn ngữ được tiêu chuẩn hóa có thể tuân theo bộ xử lý 8 bit và các tính năng như tôi mô tả ở trên có vẻ hữu ích trên mọi nền tảng. Bạn đã nghe nói về bất kỳ ngôn ngữ cung cấp những thứ như # 3 ở trên? Nó có vẻ rất hữu ích, nhưng tôi chưa bao giờ thấy bất kỳ ngôn ngữ nào cung cấp nó.
supercat

"Cha đẻ của C ++" không có kinh nghiệm về lập trình hệ thống nhúng, vậy tại sao mọi người lại quan tâm đến ý kiến ​​của anh ấy?
Lundin

@Lundin: Việc một số người có ảnh hưởng dường như quan tâm đến ý kiến ​​của anh ấy về các vấn đề khác nhau dường như là lý do, về bản thân, cho những người khác làm như vậy. Tôi nghĩ rằng vì tôi đã viết ở trên, sức mạnh ngày càng tăng của các mẫu có thể đã thêm các khả năng mới cho việc quá tải dựa trên những hằng số có thể được giải quyết tại thời điểm biên dịch, mặc dù ít sạch hơn so với việc một thứ như vậy được hỗ trợ như một công cụ biên dịch- Tính năng thời gian (theo những gì tôi hiểu, người ta sẽ chỉ định một mẫu sẽ thử nhiều thứ theo thứ tự và đi với cái đầu tiên không thất bại ...
supercat

... nhưng điều đó sẽ đòi hỏi trình biên dịch phải lãng phí một chút công sức để biên dịch các thay thế tiềm năng mà cuối cùng sẽ bị loại bỏ. Có thể nói rõ ràng hơn "Nếu đây là một hằng số, hãy làm điều này, nếu không thì làm điều này" mà không có bất kỳ "khởi đầu sai" nào có vẻ là một cách tiếp cận sạch hơn.
supercat

3

C ++ là một ngôn ngữ lập trình:

a) Đó là ngôn ngữ "tốt hơn" C b) Đó là ngôn ngữ hướng đối tượng c) Đó là ngôn ngữ cho phép chúng tôi viết chương trình chung

Mặc dù tất cả các tính năng này có thể được sử dụng riêng nhưng kết quả tốt nhất đạt được khi ba trong số chúng được sử dụng cùng một lúc. Tuy nhiên, nếu bạn chọn chỉ chọn một trong số đó, chất lượng của phần mềm nhúng sẽ tăng lên.

a) Đó là C "tốt hơn"

C ++ là một ngôn ngữ đánh máy mạnh mẽ; mạnh hơn C. Các chương trình của bạn sẽ được hưởng lợi từ tính năng này.

Một số người sợ con trỏ. C ++ bao gồm các tài liệu tham khảo. Chức năng quá tải.

Và đáng để nói: Không có tính năng nào trong số này phát sinh trong các chương trình lớn hơn hoặc chậm hơn.

b) Đó là một ngôn ngữ hướng đối tượng

Ai đó đã nói trong bài đăng này rằng trừu tượng hóa máy trong vi điều khiển không phải là một ý tưởng tốt. Sai lầm! Tất cả chúng tôi, các kỹ sư nhúng, đã luôn trừu tượng hóa máy, chỉ với các sintax khác của C ++. Vấn đề tôi thấy với lập luận này là một số lập trình viên không quen nghĩ về các đối tượng, đó là cách họ không thấy được lợi ích của OOP.

Bất cứ khi nào bạn sẵn sàng sử dụng thiết bị ngoại vi của vi điều khiển, có khả năng thiết bị ngoại vi đã được trừu tượng hóa cho chúng tôi (từ chính bạn hoặc bên thứ ba) dưới dạng trình điều khiển thiết bị. Như tôi đã nói trước đó, trình điều khiển đó sử dụng sintax C, như ví dụ tiếp theo hiển thị (được lấy trực tiếp từ ví dụ NXP LPC1114):

/ * Thiết lập hẹn giờ cho khớp và ngắt tại TICKRATE_HZ * /

Chip_TIMER_Reset (LPC_TIMER32_0);

Chip_TIMER_MatchEnableInt (LPC_TIMER32_0, 1);

Chip_TIMER_SetMatch (LPC_TIMER32_0, 1, (timerFreq / TICKRATE_HZ2));

Chip_TIMER_ResetOnMatchEnable (LPC_TIMER32_0, 1);

Chip_TIMER_Enable (LPC_TIMER32_0);

Bạn có thấy sự trừu tượng? Vì vậy, khi sử dụng C ++ cho cùng một mục đích, sự trừu tượng hóa được đưa lên cấp độ tiếp theo thông qua cơ chế trừu tượng hóa và đóng gói của C ++, với chi phí bằng không!

c) Đó là ngôn ngữ cho phép chúng tôi viết chương trình chung chung

Các chương trình chung được thực hiện thông qua các mẫu và các mẫu cũng không có chi phí cho các chương trình của chúng tôi.

Bên cạnh đó, đa hình tĩnh đạt được với các mẫu.

Phương pháp ảo, RTTI và ngoại lệ.

Có một sự thỏa hiệp khi sử dụng các phương thức ảo: phần mềm tốt hơn so với một số hình phạt trong hiệu suất. Tuy nhiên, hãy nhớ rằng liên kết động có khả năng được thực hiện bằng cách sử dụng bảng ảo (một mảng các con trỏ hàm). Tôi đã làm điều tương tự ở C rất nhiều lần (ngay cả trong một cơ sở thường xuyên), vì vậy tôi không thấy những hạn chế trong việc sử dụng các phương thức ảo. Hơn nữa, các phương thức ảo trong C ++ thanh lịch hơn.

Cuối cùng, một lời khuyên về RTTI và các trường hợp ngoại lệ: KHÔNG SỬ DỤNG THEM trong các hệ thống nhúng. Tránh chúng bằng mọi giá !!


2

Nền của tôi, được nhúng (mcu, pc, unix, other), thời gian thực. An toàn quan trọng. Tôi đã giới thiệu một chủ nhân trước đây cho STL. Tôi không làm điều đó nữa.

Một số nội dung ngọn lửa

C ++ có phù hợp với các hệ thống nhúng không?

Meh. C ++ là một nỗi đau để viết và một nỗi đau để duy trì. C + là loại ổn (không sử dụng một số tính năng)

C ++ trong Vi điều khiển? RTOSes? Lò nướng bánh? Máy tính nhúng?

Một lần nữa tôi nói Meh. C + không quá tệ, nhưng ADA ít đau đớn hơn (và điều đó thực sự nói lên điều gì đó). Nếu bạn may mắn như tôi, bạn có thể thực hiện nhúng Java. Kiểm tra truy cập mảng và không có số học con trỏ làm cho mã rất đáng tin cậy. Trình thu gom rác trong Java nhúng không phải là ưu tiên cao nhất và có sử dụng lại bộ nhớ và đối tượng trong phạm vi, do đó mã được thiết kế tốt có thể chạy mãi mãi mà không cần có GC.

OOP có hữu ích trên vi điều khiển không?

Chắc chắn là. UART là một đối tượng ..... DMAC là một đối tượng ...

Máy trạng thái đối tượng rất dễ dàng.

C ++ có loại bỏ các lập trình viên quá xa phần cứng để có hiệu quả không?

Trừ khi đó là PDP-11, C không phải là CPU của bạn. C ++ ban đầu là một tiền xử lý của C vì vậy Bjarne Stroustrup sẽ không bị cười vì có các mô phỏng Simula chậm khi ở AT & T. C ++ không phải là CPU của bạn.

Đi lấy một MCU chạy mã byte java. Chương trình trong Java. Cười vào những kẻ C.

C ++ của Arduino (không có quản lý bộ nhớ động, các mẫu, ngoại lệ) có nên được coi là "C ++ thực" không?

Không. giống như tất cả các trình biên dịch C khốn cho MCU.

Forth, Java nhúng hoặc ADA nhúng được chuẩn hóa (ish); tất cả những thứ khác là nỗi buồn.


2
Có dễ tìm thấy các bộ vi điều khiển hỗ trợ Java không? Tôi nghĩ rằng điều này sẽ hạn chế các lựa chọn đáng kể. Và kinh nghiệm của bạn về hình phạt hiệu suất (vì trong uC bạn thường không có JIT)? Điều gì về tác động của tính khó lường của GC trong các hệ thống thời gian thực?
fceconel

2
MCU nào hiện có hỗ trợ Java nhúng?
J. Polfer

www.ajile.com cho người mới bắt đầu.
Tim Williscroft

+1 cho Ada. Nó có rất nhiều thứ cho nó được nhúng, bao gồm cả Arduinos.
Brian Drumond

java VM di động cho micros được viết bằng c là nguồn mở. dmitry.co/index.php?p=./04.Thoughts/ từ
Tim Williscroft

-2

Các hệ thống nhúng được thiết kế để thực hiện một số tác vụ cụ thể, thay vì là một máy tính có mục đích chung cho nhiều tác vụ. Một hệ thống nhúng là sự kết hợp giữa phần cứng và phần mềm máy tính. C là mẹ của tất cả các ngôn ngữ hiện đại. Đó là một ngôn ngữ cấp thấp nhưng đầy sức mạnh và xử lý tất cả các loại phần cứng. Vì vậy, C / C ++ là một lựa chọn tối ưu để phát triển phần mềm cho hệ thống nhúng, nó được sử dụng rất đầy đủ cho mọi hệ thống nhúng. Vì chúng tôi biết C là ngôn ngữ đang phát triển. Hệ điều hành UNIX được viết bằng C. Vì phát triển phần mềm thành công thường xuyên về việc chọn ngôn ngữ tốt nhất cho một dự án nhất định, thật đáng ngạc nhiên khi thấy ngôn ngữ C / C ++ đã chứng minh rằng nó phù hợp với cả bộ xử lý 8 bit và 64 bit ; trong các hệ thống có byte, kilobyte và bộ nhớ megabyte. C có lợi ích độc lập với bộ xử lý, cho phép các lập trình viên tập trung vào các thuật toán và ứng dụng, thay vì các chi tiết về kiến ​​trúc bộ xử lý cụ thể. Tuy nhiên, nhiều trong số những lợi thế này áp dụng như nhau cho các ngôn ngữ cấp cao khác. Nhưng C / C ++ đã thành công khi mà rất nhiều ngôn ngữ khác đã thất bại phần lớn?


6
Tôi thực sự không chắc những gì nó thêm vào cuộc thảo luận.
Dave Tweed

-3

<rant>

Tôi nghĩ rằng C ++ là một ngôn ngữ nhảm nhí ngay từ đầu. Nếu bạn muốn sử dụng OOP, hãy viết các chương trình Java. C ++ không làm gì để thực thi các mô hình OOP, vì quyền truy cập bộ nhớ trực tiếp hoàn toàn nằm trong khả năng của bạn (ab) sử dụng.

Nếu bạn có MCU, bạn đang nói về bộ nhớ flash ít nhất là 100kB. Bạn muốn lập trình bằng một ngôn ngữ có sự trừu tượng của bộ nhớ là: khi tôi khai báo một biến hoặc một mảng, nó sẽ có bộ nhớ, dấu chấm; malloc (còn gọi là từ khóa "mới" trong C ++) nên ít nhiều bị cấm sử dụng trong phần mềm nhúng, ngoại trừ có lẽ trong một số trường hợp hiếm khi một cuộc gọi trong khi khởi động chương trình.

Chết tiệt, có (thường xuyên) trong lập trình nhúng trong đó C không đủ mức độ thấp và bạn cần thực hiện những việc như phân bổ biến cho các thanh ghi và viết cụm lắp ráp nội tuyến để thắt chặt các thói quen dịch vụ ngắt (ISR) của bạn. Các từ khóa như "dễ bay hơi" trở nên khá quan trọng để hiểu. Bạn dành nhiều thời gian để thao tác bộ nhớ ở cấp độ bit chứ không phải cấp độ đối tượng .

Tại sao bạn lại muốn ảo tưởng rằng mọi thứ đơn giản hơn thực tế?

</ rant>


Vấn đề của tôi ở đây chỉ đơn giản là, tại sao tôi muốn biết sự phức tạp của trình điều khiển được viết để kiểm soát USART1 nếu nó đã được phát triển đầy đủ để xử lý giao diện.
Kortuk

1
Tôi đã không bỏ phiếu cho bạn, nhưng tôi muốn chỉ ra rằng C ++ không cần thực thi OOP, chỉ cần cung cấp các công cụ để làm điều đó. Thực thi các tiêu chuẩn mã hóa tốt là công việc của nhà phát triển. Nó có thể giúp nếu ngôn ngữ làm cho nó dễ dàng hơn, nhưng ngôn ngữ sẽ không bao giờ tự làm được. C có thể không đọc được trong một số trường hợp.
Kortuk

1
Tất cả các ngôn ngữ là tốt cho một cái gì đó. C ++ rất nhanh. OOP, nếu được thực hiện tốt, giúp nhiều nhà phát triển làm việc song song và mã hóa cho những điều chưa biết dễ dàng hơn nhiều. Tôi nghĩ đây là lý do tại sao nó có quá nhiều lực kéo trong phát triển trò chơi.
Toby Jaffey

1
Vâng tôi đồng ý. Lý do tôi thấy nó cho thế giới nhúng là vì số lượng lớn các tính năng và chức năng được thêm vào rất nhiều hệ thống khác nhau đã có và các hệ thống mới đang được phát triển. Dự án ngày càng lớn hơn. Hoặc là chúng tôi mất nhiều thời gian hơn để phát triển chúng hoặc chúng tôi bắt đầu áp dụng và mâu thuẫn với những gì thế giới CS đã làm trên PC.
Kortuk

5
Một người khác không hiểu C ++ đúng cách. Nó luôn làm tôi ngạc nhiên có bao nhiêu.
Rocketmagnet
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.