Số sê-ri PIC có thể chỉnh sửa trong tệp HEX


8

Hiện tại tôi có một số sê-ri được mã hóa cứng trong phần sụn cho thiết kế tôi đang làm việc. Phần sụn có thể đọc và báo cáo lại số sê-ri. Điều đó làm việc tốt cho những gì tôi cần. Vấn đề là mỗi số sê-ri mới yêu cầu tôi thay đổi mã và biên dịch lại. Điều này là cồng kềnh khi có rất nhiều đơn vị được xây dựng, có khả năng giới thiệu lỗi và là thực tiễn xấu xung quanh. Các số sê-ri được cấp cho tôi và thiết kế phần cứng được đặt chính xác, vì vậy tôi không thể thêm bất kỳ tính năng nào trong phần cứng để tuần tự hóa các đơn vị (EEPROM / Silicon ID Chip / Pull-Ups). Những gì tôi muốn làm là định vị số sê-ri tại một địa chỉ cố định, biên dịch mã một lần, sau đó chỉnh sửa địa chỉ đó trong tệp HEX đã biên dịch cho mỗi số sê-ri mới. Số được tham chiếu ở một số nơi, vì vậy lý tưởng nhất, tôi muốn xác định và định vị nó một lần, sau đó tham chiếu "biến" đó ở mọi nơi khác trong mã của tôi. Có ai biết cách định vị dữ liệu không đổi tại một vị trí bộ nhớ địa chỉ cụ thể mà tôi chọn, sử dụng Trình biên dịch C18 không? Có cách nào tốt hơn bất cứ ai có thể đề nghị?


1
Khoảng một nửa số PIC18 có bất cứ nơi nào từ 128 byte đến 1K EEPROM được tích hợp trong đó. Tôi giả sử từ câu hỏi của bạn PIC18 của bạn là một trong 50% không có EEPROM?
tcrosley

Câu trả lời:


4

Cụ thể để giải quyết câu hỏi về các biến liên kết với các địa chỉ cụ thể trong bộ nhớ flash trên PIC18 với trình biên dịch C18, vui lòng tham khảo phần "Thực tế" trong hlpC18ug.chm trong thư mục doc nơi cài đặt trình biên dịch.

Để làm điều này, bạn cần xác định một "phần" mới trong bộ nhớ và liên kết nó với một địa chỉ bắt đầu để

#pragma romdata serial_no_section=0x1700

Điều này tạo ra một phần mới gọi là "serial_no_section" bắt đầu tại địa chỉ 0x1700 trong bộ nhớ flash (chương trình) (vì chúng tôi đã định nghĩa "romdata" trong #pragma).

Ngay sau dòng #pragma, hãy xác định (các) biến của bạn để:

#pragma romdata serial_no_section=0x1700
const rom int mySerialNumber = 0x1234;
#pragma romdata

Bây giờ bạn có 0x12 tại địa chỉ 0x1700 và 0x34 tại địa chỉ 0x1701 trong bộ nhớ (vì PIC18 sử dụng mô hình endian nhỏ). "Const rom" đảm bảo rằng trình biên dịch biết rằng đây là loại biến const và biến đó nằm trong bộ nhớ "rom" và do đó cần phải được truy cập thông qua hướng dẫn đọc bảng.

Câu #pragma romdatalệnh cuối cùng đảm bảo rằng mọi khai báo biến sau đây được liên kết với các phần bộ nhớ mặc định khi trình liên kết thấy phù hợp thay vì theo dõi trong phần "serial_no_section".

Bây giờ tất cả các mã có thể chỉ cần tham chiếu biến "mySerialNumber" và bạn biết chính xác địa chỉ nào có thể tìm thấy số sê-ri trong bộ nhớ.

Chỉnh sửa mã HEX có thể hơi khó khăn khi bạn cần tính toán tổng kiểm tra cho mỗi dòng bạn chỉnh sửa. Tôi đang làm việc trên một lớp C ++ để giải mã và mã hóa các tệp Intel HEX, điều này sẽ giúp việc này dễ dàng hơn, nhưng vẫn chưa kết thúc. Giải mã tập tin hoạt động, mã hóa lại chưa được thực hiện. Dự án (nếu bạn quan tâm) có tại đây https://github.com/codinghead/Intel-HEX-Class

Hi vọng điêu nay co ich


4

Tôi đã thực hiện số sê-ri (viết tắt là s / n) theo cách tương tự như những gì Joel đang mô tả. Tôi đã sử dụng trình biên dịch PIC18F4620 và CCS. Vị trí của s / n trong bộ nhớ Flash đã buộc đến 4 byte cuối cùng. Vì tôi chỉ sử dụng 80% Flash, trình biên dịch và trình liên kết của tôi sẽ không viết mã thực thi trong 4 byte cuối cùng.

Sau đó, tôi đã có 2 cách khác nhau để thực sự viết s / n thành các đơn vị riêng lẻ:

  • Trình gỡ lỗi trong mạch CCS (ICD) có một tính năng cho phép thao tác bất kỳ vị trí nào trong Flash. Đó là một hack hữu ích. Trong các phiên bản sau, họ đã gỡ bỏ nó, thật không may.
  • PIC có một liên kết nối tiếp đến PC. s / n đã được tải lên thông qua nó. Phần sụn có một thói quen sẽ nhận s / n và lưu nó trong Flash.

Trả lời bình luận của Joel

Không biết về C18, nhưng trình biên dịch CCS đi kèm với các chức năng thư viện write_program_eeprom(...)read_program_eeprom(...). Đây là những gì họ trông giống như trong lắp ráp.

.................... write_program_eeprom (i_ADDR, iWord);
EF84: BSF FD0.6
EF86: CLRF FF8
EF88: MOVLW 7F
EF8A: MOVWF FF7
EF8C: MOVLW F0
EF8E: MOVWF FF6
EF90: MOVLB 0
EF92: BRA EF24
EF94: MOVLW F0
EF96: MOVWF FF6
EF98: PHIM 490, FF5
EF9C: TBLWT * +
EF9E: PHIM 491, FF5
EFA2: TBLWT *
EFA4: BCF FA6.6
EFA6: BSF FA6.4
EFA8: RCALL EF3C
EFAA: RCALL EF3C
EFAC: CLRF FF8
EFAE: CLRF FF8
.................... iWord = read_program_eeprom (i_ADDR); 
EF60: CLRF FF8
EF62: MOVLW 7F
EF64: MOVWF FF7
EF66: MOVLW F0
EF68: MOVWF FF6
EF6A: TBLRD * +
EF6C: MOVF FF5, W
EF6E: TBLRD *
EF70: PHIM FF5,03
EF74: CLRF FF8
EF76: PHIM 4
EF78: MOVWF x90
EF7A: PHIM 03,491

1
Vâng, đây chính xác là những gì tôi đang yêu cầu! Bạn có thể mô tả những thuộc tính mã nào bạn đã sử dụng để đóng gói S / N của bạn vào một vài byte flash cuối cùng không?
Joel B

"Phần sụn có một thói quen sẽ nhận s / n và lưu trữ nó trong Flash" write_program_eeprom(...)read_program_eeprom(...). EEPROM và Flash là hai thứ khác nhau!
m.Alin

@ m.Alin Đó là cách các hàm "đóng hộp" đi kèm với trình biên dịch CCS được gọi. Họ thực sự sẽ viết và đọc Flash.
Nick Alexeev

2

Tôi đã làm điều này một vài lần. Thông thường tôi xác định vùng thông tin phần sụn ở một vị trí cố định trong bộ nhớ chương trình, sau đó viết chương trình tạo tệp HEX được tuần tự hóa từ tệp HEX mẫu. Đây là tất cả những điều dễ dàng để làm.

Trong sản xuất, bạn chạy chương trình tuần tự hóa một lần sau khi tất cả các bài kiểm tra đã qua. Nó tạo tệp HEX tạm thời với số sê-ri duy nhất, được lập trình vào PIC, sau đó tệp HEX tạm thời bị xóa.

Tôi sẽ không để vị trí có thể di dời, sau đó phải tìm nó. Điều đó có thể thay đổi mọi bản dựng khi trình liên kết di chuyển mọi thứ xung quanh. Tôi đã làm điều đó cho các PIC rất nhỏ như loạt 10F trong đó các hằng số này là một phần của hướng dẫn MOVLW. Trong những trường hợp đó, tôi đã đọc tệp MAP khi đang di chuyển để xác định vị trí của những vị trí đó. Tôi có mã phân tích tệp MPLINK MAP trong thư viện chỉ với mục đích đó.

Để đặt một cái gì đó vào một vị trí cố định, xác định một phân khúc tại một địa chỉ cố định. Trình liên kết sẽ đặt các phân đoạn tuyệt đối như vậy trước, sau đó là các phân đoạn có thể di chuyển xung quanh nó. Đừng quên sử dụng CODE_PACK thay vì chỉ CODE trên PIC 18, nếu không, bạn sẽ xử lý toàn bộ các từ cảm ứng thay vì từng byte riêng lẻ. Ví dụ: (chỉ cần nhập, không chạy qua trình biên dịch):

.fwinfo code_pack h'1000 '; khu vực thông tin phần sụn tại địa chỉ đã biết cố định
         db h'FFFFFFFF '; số sê-ri, được điền bởi chương trình sản xuất
         db fwtype; loại ID của phần sụn này
         db fwver; số phiên bản
         db fwseq; xây dựng số thứ tự

2

Tôi sẽ đề nghị lưu trữ số sê-ri trong một địa chỉ cố định. Tùy thuộc vào trình biên dịch / trình liên kết của bạn và phần được đề cập, có một vài cách tiếp cận bạn có thể thực hiện:

  1. Xác định phần có thể định vị lại sẽ chứa số sê-ri, sử dụng lệnh #pragma trong mã của bạn để buộc số sê-ri vào phần đó và buộc địa chỉ của phần đó trong thông số liên kết.
  2. Đối với các phần có thể đọc bộ nhớ mã trực tiếp, loại trừ một vùng bộ nhớ khỏi vùng liên kết được phép sử dụng (nghĩa là phần đó ví dụ như bốn byte nhỏ hơn thực tế), sau đó đọc số sê-ri trong mã bằng cách sử dụng một cái gì đó như `((không dấu dài const *) 0x3FFC)`.
  3. Đối với các phần không thể đọc bộ nhớ mã trực tiếp, bạn có thể đặt các hướng dẫn "RETLW" tại một số địa chỉ cố định và sau đó thuyết phục trình liên kết rằng có các hàm có thể gọi được trả về 'byte' tại các địa chỉ đó. Sau đó, người ta sẽ nói ví dụ: "out_hex (ser_byte0 ()); out_hex (ser_byte1 ()); out_hex (ser_byte2 ()); để xuất các byte của số sê-ri.

Tất cả PIC 18F có thể đọc bộ nhớ chương trình của họ thông qua cơ chế đọc bảng.
Olin Lathrop

Điều đó đúng. Một số phần 14 bit cũng có thể đọc bộ nhớ chương trình. Tuy nhiên, ngay cả trên các PIC có thể đọc bộ nhớ chương trình, retlwcách tiếp cận thường nhanh hơn nhiều (trên PIC 18 bit, một callđến retlwsẽ mất tổng cộng bốn chu kỳ; sử dụng clrf TBLPTRU/movlw xx/movwf TBLPTRH/movlw xx/movwf TBLPTRL/tblrd *+/movf TABLAT,wsẽ mất tám).
supercat

1

Tôi sẽ làm ngược lại: biên dịch và liên kết mã, sau đó tìm ra nơi giá trị được lưu trữ từ tệp liên kết. Bạn có thể cần xác định vị trí biến rõ ràng trong một phân đoạn được ánh xạ tới flash.

Không yêu cầu điều này, nhưng phần mềm PC tôi cung cấp cho lập trình viên Wisp648 của tôi có khả năng đọc tệp .hex, sửa đổi một vị trí cụ thể và ghi lại tệp .hex (vào cùng tệp hoặc tệp khác). Không cần phải có lập trình viên của tôi. Nguồn có sẵn (bằng Python), giấy phép cho phép tất cả sử dụng: www.voti.nl/xwisp Có thể có ích khi bạn giải quyết vấn đề chính của mình.


Cảm ơn @Wouter van Ooijen! Tôi đang cố gắng tránh cách tiếp cận "tìm nơi lưu trữ giá trị", vì điều đó rất có thể có nghĩa là giá trị được di chuyển trên các biên dịch liên tiếp và yêu cầu tôi (hoặc một số người buồn đứng sau tôi) tìm ra giá trị ở đâu được đặt lại, chắc chắn giới thiệu vấn đề.
Joel B
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.