Một giải pháp có thể là để triển khai sprintf
của riêng bạn mà có thể hoạt động với bộ đệm vòng. Thật không may điều này sẽ không giúp bạn về một vấn đề cơ bản hơn: Bạn sẽ làm gì nếu ringbuffer của bạn là đầy đủ và bạn gọi sprintf
?
Nếu tình trạng bộ nhớ của bạn có thể đủ khả năng đó, tôi muốn đề nghị một giải pháp cho vấn đề này:
ý tưởng này dựa trên hai danh sách liên kết của bộ đệm (một danh sách cho các bộ đệm miễn phí, một danh sách như hàng đợi truyền) . Các bộ đệm có kích thước bằng nhau để chúng có thể lưu trữ chuỗi có độ dài trường hợp xấu nhất. Các bộ đệm xây dựng một đống đơn giản, nơi phân bổ/deallocation chỉ dequeuing/enqueuing một phần tử hoặc từ miễn phí hoặc từ danh sách truyền.
Có bộ đệm có kích thước bằng nhau đảm bảo bạn không bị ảnh hưởng phân mảnh bên ngoài như "kiểm tra" trong khi phân bổ bộ nhớ động. Xây dựng heap của riêng bạn cho công việc này cũng sẽ cung cấp cho bạn toàn quyền kiểm soát tổng kích thước bộ đệm có sẵn cho nhiệm vụ truyền tải.
tôi có thể tưởng tượng chạy này như sau:
- Bạn phân bổ một bộ đệm từ danh sách miễn phí để render dữ liệu vào.
- Sử dụng làm chức năng (suchas sprintf) của bạn hiển thị các dữ liệu trong bộ đệm
- Nối các dữ liệu được gửi tới hàng đợi truyền (và kích hoạt một truyền nếu cần thiết)
Đối với DMA chuyển bạn xử lý IRQ kết thúc chuyển. Ở đó bạn di chuyển bộ đệm vừa chuyển sang "danh sách miễn phí" và thiết lập chuyển cho bộ đệm tiếp theo trong hàng đợi.
Giải pháp này sẽ không phải là bộ nhớ hiệu quả nhất nhưng hiệu suất thời gian chạy là tốt vì bạn chỉ ghi vào bộ nhớ một lần và phân bổ/deallocation chỉ tìm nạp/lưu trữ một con trỏ ở đâu đó. Tất nhiên bạn sẽ phải chắc chắn rằng bạn không nhận được điều kiện chủng tộc giữa ứng dụng của bạn và IRQ để phân bổ/deallocation.
Có lẽ ý tưởng này cung cấp cho bạn một nguồn cảm hứng để giải quyết các yêu cầu của bạn.
Yêu cầu thú vị, nhưng tôi không nghĩ bạn sẽ làm tốt hơn đáng kể so với 'định dạng thành đệm tạm thời, sau đó sao chép sang đệm tròn bằng chức năng sao chép thích hợp'. –