Đây là một ý kiến / nhận xét nhiều hơn là một câu trả lời.
Bạn không muốn và không nên lập trình trong C. C ++, khi được sử dụng đúng cách , vượt trội hơn nhiều. (OK, tôi phải thừa nhận, khi sử dụng sai cách, nó còn tệ hơn nhiều so với C.) Điều đó giới hạn bạn với các chip có trình biên dịch C ++ (hiện đại), gần như là mọi thứ được GCC hỗ trợ, bao gồm cả AVR (với Một số hạn chế, filo đề cập đến các vấn đề của không gian địa chỉ không đồng nhất), nhưng loại trừ gần như tất cả các PIC (PIC32 có thể được hỗ trợ, nhưng tôi chưa thấy cổng nào tốt cả).
Khi bạn đang lập trình các thuật toán trong C / C ++, sự khác biệt giữa các lựa chọn bạn đề cập là nhỏ (ngoại trừ việc chip 8 hoặc 16 bit sẽ gặp bất lợi nghiêm trọng khi bạn thực hiện nhiều phép tính số học 16, 32 hoặc cao hơn). Khi bạn cần hiệu suất cuối cùng, có thể bạn sẽ cần sử dụng trình biên dịch chương trình (mã của riêng bạn hoặc mã do nhà cung cấp hoặc bên thứ ba cung cấp). Trong trường hợp đó, bạn có thể muốn xem xét lại chip bạn đã chọn.
Khi bạn đang mã hóa phần cứng, bạn có thể sử dụng một số lớp trừu tượng (thường được cung cấp bởi nhà sản xuất) hoặc tự viết (dựa trên bảng dữ liệu và / hoặc mã ví dụ). Các tóm tắt C hiện tại của IME (mbed, cmsis, ...) thường có chức năng (gần như) chính xác, nhưng không thành công khủng khiếp (kiểm tra oldfarts về 6 lớp cảm ứng cho hoạt động của bộ pin), tính khả dụng và tính di động. Họ muốn tiết lộ tất cả chức năng của con chip cụ thể cho bạn, trong hầu hết các trường hợp bạn sẽ không cần và không quan tâm, và nó khóa mã của bạn cho nhà cung cấp cụ thể đó (và có thể là con chip cụ thể đó).
Đây là C ++ có thể làm tốt hơn nhiều: khi được thực hiện đúng cách, một bộ pin có thể đi qua 6 lớp trừu tượng trở lên (vì điều đó làm cho giao diện (di động!) Tốt hơn và mã ngắn hơn có thể), nhưng cung cấp giao diện độc lập với mục tiêu đối với các trường hợp đơn giản và vẫn dẫn đến mã máy giống như bạn viết trong trình biên dịch chương trình .
Một đoạn của phong cách mã hóa mà tôi sử dụng, có thể khiến bạn say mê hoặc quay lưng lại với nỗi kinh hoàng:
// GPIO part of a HAL for atsam3xa
enum class _port { a = 0x400E0E00U, . . . };
template< _port P, uint32_t pin >
struct _pin_in_out_base : _pin_in_out_root {
static void direction_set_direct( pin_direction d ){
( ( d == pin_direction::input )
? ((Pio*)P)->PIO_ODR : ((Pio*)P)->PIO_OER ) = ( 0x1U << pin );
}
static void set_direct( bool v ){
( v ? ((Pio*)P)->PIO_SODR : ((Pio*)P)->PIO_CODR ) = ( 0x1U << pin );
}
};
// a general GPIO needs some boilerplate functionality
template< _port P, uint32_t pin >
using _pin_in_out = _box_creator< _pin_in_out_base< P, pin > >;
// an Arduino Due has an on-board led, and (suppose) it is active low
using _led = _pin_in_out< _port::b, 27 >;
using led = invert< pin_out< _led > >;
Trong thực tế có một số lớp trừu tượng hơn. Tuy nhiên, việc sử dụng cuối cùng của đèn led, giả sử bật nó lên, không cho thấy sự phức tạp hoặc chi tiết của mục tiêu (đối với một arduin uno hoặc một viên thuốc màu xanh ST32, mã sẽ giống hệt nhau).
target::led::init();
target::led::set( 1 );
Trình biên dịch không bị đe dọa bởi tất cả các lớp đó và vì không có chức năng ảo nào liên quan đến trình tối ưu hóa nhìn xuyên qua mọi thứ (một số chi tiết, được bỏ qua, như bật đồng hồ ngoại vi):
mov.w r2, #134217728 ; 0x8000000
ldr r3, [pc, #24]
str r2, [r3, #16]
str r2, [r3, #48]
Đó là cách tôi đã viết nó trong trình biên dịch chương trình - NẾU tôi đã nhận ra rằng các thanh ghi PIO có thể được sử dụng với các offset từ một cơ sở chung. Trong trường hợp này có lẽ tôi sẽ làm, nhưng trình biên dịch tốt hơn nhiều trong việc tối ưu hóa những thứ như vậy hơn tôi.
Theo như tôi có câu trả lời, đó là: viết một lớp trừu tượng cho phần cứng của bạn, nhưng hãy làm nó trong C ++ (khái niệm, mẫu) hiện đại để nó không gây hại cho hiệu suất của bạn. Với vị trí đó, bạn có thể dễ dàng chuyển sang chip khác. Bạn thậm chí có thể bắt đầu phát triển trên một số chip ngẫu nhiên mà bạn đã đặt xung quanh, là familiair với, có các công cụ sửa lỗi tốt, v.v. và hoãn lựa chọn cuối cùng cho đến sau này (khi bạn có thêm thông tin về bộ nhớ cần thiết, tốc độ CPU, v.v.).
IMO, một trong những yếu tố quan trọng của sự phát triển được đặt ra là chọn chip trước tiên (đó là câu hỏi thường được hỏi trên diễn đàn này: tôi nên chọn chip nào cho .... Câu trả lời tốt nhất nói chung là: không thành vấn đề.)
(chỉnh sửa - phản hồi cho "Vì vậy, hiệu suất khôn ngoan, C hoặc C ++ sẽ ở cùng cấp độ?")
Đối với các cấu trúc giống nhau, C và C ++ là như nhau. C ++ có nhiều cấu trúc hơn cho sự trừu tượng hóa (chỉ một vài: lớp, mẫu, constexpr) có thể, giống như bất kỳ công cụ nào, được sử dụng cho mục đích tốt hoặc xấu. Để làm cho các cuộc thảo luận trở nên thú vị hơn: không phải ai cũng đồng ý điều gì là tốt hay xấu ...