|
Tài trợ cho PIC Vietnam |
Bootloaders - Programmers - Debuggers - Emulators Những công cụ cần thiết để lập trình cho PIC/dsPIC |
|
Ðiều Chỉnh | Xếp Bài |
01-02-2008, 04:09 PM | #1 |
Nhập môn đệ tử
Tham gia ngày: Jan 2008
Bài gửi: 10
: |
ko chạy được application code sau khi download
Mình viết 1 trình bootloader (cho 18F67J10) và sẽ đặt nó ở vùng gần giữa của memory (bắt đầu từ 0x9000). Trong file linker mình sửa lại thành
CODEPAGE NAME=vectors START=0x0 END=0x29 CODEPAGE NAME=page START=0x9000 END=0x1FD3F // dòng này đc sửa CODEPAGE NAME=config START=0x1FFF8 END=0x1FFFD CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF Còn trong c18i.c vẫn giữ _entry_scn=0x000000. Sau khi nạp xong chương trình sẽ load application code thông qua hyperterminal. Application code sẽ được lưu ở địa chỉ 0x800. Trong linker file của application code mình sửa lại như sau: CODEPAGE NAME=boot START=0x9000 END=0x1FD3F protected CODEPAGE NAME=vectors START=0x0 END=0x29 protected CODEPAGE NAME=rvectors START=0x800 END=0x829 protected CODEPAGE NAME=page START=0x82A END=0x8000 còn trong file c18i.c , sửa lại _entry_scn=0x000800. File hexa cũng đc export với start address = 0x800 Sau khi download xong application code, bootloader sẽ nhảy đến vùng nhớ có chứa application code (0x800) để bắt đầu thực thi chương trình. Mình viết là: _asm clrf STKPTR, 0 goto 0x800 _endasm Đến đây thì chươgn trình ko chạy được nữa. Toàn bộ quá trình từ đầu đến sau khi download xong application code đều chạy tốt. (mình đã kiểm tra bằng cách đọc trên vùng nhớ của program memory thì thấy bootloader code và application code đều được đặt đúng chỗ) Ko phải là dân về vi điều khiển nhưng vì có project nên mình phải nhảy ngay vào PIC18 này. Mình vẫn chưa hiểu rõ được: - cơ chế hoạt động của reset vector và redirect nó như thế nào. - cách thiết lập chúng ra sao (rvector trong linker file có phải là redirect vector ko? Cách mình nêu ở trên có chỗ nào sai ko? Mong mọi người hướng dẫn giúp. Cám ơn nhiều |
02-02-2008, 04:45 AM | #2 |
Trưởng lão PIC bang
|
Xin được hỏi, dòng
Code:
CODEPAGE NAME=rvectors START=0x800 END=0x829 protected Theo tôi biết thì PIC18F không hỗ trợ redirect bảng vectơ ngắt. Bạn chỉnh lại c18i.c của chương trình ứng dụng xong thì có rebuild lại startup object file c18i.o hay không? Tôi không thấy cần thiết phải di chuyển bảng vectơ ngắt của chương trình ứng dụng để dùng với bootloader, nếu bootloader được viết một cách thích hợp. Bạn tham khảo tư duy thiết kế bootloader của Claudiu Chiculita ở đây: http://www.etc.ugal.ro/cchiculita/so...bootloader.htm (phần 'General info about Bootloaders', bạn có vẻ đang làm phức tạp hóa vấn đề). Thân,
__________________
Biển học mênh mông, sức người có hạn. Đang gặp vấn đề cần được giúp đỡ? Hãy dành ra vài phút đọc luồng sau: http://www.picvietnam.com/forum/showthread.php?t=1263 |
02-02-2008, 02:41 PM | #3 | ||
Nhập môn đệ tử
Tham gia ngày: Jan 2008
Bài gửi: 10
: |
Trích:
Trích:
Mình đã theo link đọc cách thiết kế của Claudiu Chiculita và cũng có ý định thiết kế bootloader cho mình tương tự vậy. Nhưng vì ko có kiến thức về cấu trúc của MCU (như mình đã nói ban đầu là mình phải nhảy gấp vào nó vì project) nên mình muốn hỏi là thiết lập địa chỉ cho các vector như thế nào để khi reset thì chương trình sẽ nhảy đến bootloader và từ bootloader sau khi download user program xong có thể nhảy đến user program? Như ở bài viết đầu, mình đặt bootloader ở địa chỉ 0x9000 còn usercode ở 0x800. Cám ơn. |
||
02-02-2008, 05:03 PM | #4 | |||
Trưởng lão PIC bang
|
Trích:
Trích:
http://ww1.microchip.com/downloads/e...ide_51288j.pdf Trích:
Thân,
__________________
Biển học mênh mông, sức người có hạn. Đang gặp vấn đề cần được giúp đỡ? Hãy dành ra vài phút đọc luồng sau: http://www.picvietnam.com/forum/showthread.php?t=1263 |
|||
02-02-2008, 09:12 PM | #5 |
Nhập môn đệ tử
Tham gia ngày: Jan 2008
Bài gửi: 10
: |
Bạn nói đúng, mình đã làm vấn đề phức tạp hơn nhiều.
Sau khi tham khảo link bạn đưa và bài viết tóm tắt nội dung tìm hiểu về Tiny bootloader của Nguyễn Trung Chính (link http://picvietnam.com/forum/showthread.php?t=439), mình đã hiểu thêm đc một số điều. Theo đó giờ mình sẽ trình bày lại chương trình đã đc sửa như sau (theo như cấu trúc của bootloader mà Claudiu Chiculita đưa ra): Bootloader sẽ được dịch với linker vectors = 0x00 - 0x07 (4 word cho reset vector để nhảy đến boot code) page = 0x9000 - 0x1FD3F còn c018i vẫn ko thay đổi. Khi download user code (dưới dạng 1 file binary),bootloader sẽ thực hiện cắt 4 word đầu tiên của file này, ghi vào ngay trên vùng nhớ chứa bootloader (0x8FF8), đồng thời thay thế vào đó 4 word đầu tiên của bộ nhớ (nằm tại vị trí 0x00). Sau đó toàn bộ user code đc ghi vào memory (từ vị trí 0x00) Sau khi ghi xong, mình sẽ chuyển program counter đến vùng nhớ chứa 4 word được ghi ngay trên bootloader (bằng lệnh goto 0x8FF8) . Tại đây theo mình biết thì program counter sẽ đọc instruction ở đó và nhảy đến user program, lại đọc các instruction và bắt đầu thực thi. Trong user program, mình cấu hình linker như sau: vector 0x00 - 0x29 page 0x2A - 0x1FFF Theo đó thì user program sẽ được ghi bắt đầu từ vị trí 0x2A. Còn các vector sẽ nằm trong khoảng 0x00-0x29. Ko biết mình làm vậy có đúng chưa? Mình vẫn chưa hiểu rõ tác dụng của file linker, và vai trò của _entry_scn trong c018i.c À, còn cái linker của PIC18F8722 thì mình tham khảo từ project về HPC của Microchip (http://www.microchip.com/stellent/id...&part=DM183022). Mình đọc file FAQ & trouble shooting, câu 11 có nhắc đến cái rvectors. Mình chỉ có kiến thức rất sơ đẳng về MCU nói chung, (viết C cho các ứng dụng đơn giản sử dụng interrupt, timer, I/O, USART), những cái khác mình đọc chỗ này một ít chỗ khác một ít nên ko thực sự hiểu rõ lắm. Với PIC thì mình mới làm quen vài tuần. Cheers |
03-02-2008, 03:28 AM | #6 |
Trưởng lão PIC bang
|
Bạn có thể sử dụng tiện ích của Microchip (cung cấp dạng mã nguồn cho AN851) hoặc có thể sử dụng một tiện ích của hãng thứ ba (như Tiny Bootloader chẳng hạn). Nếu bạn chọn giải pháp của Microchip, bạn làm theo những hướng dẫn của AN851 để viết bootloader và application code (nhưng theo tôi giải pháp của Microchip rườm rà một cách không cần thiết). Nếu bạn sử dụng Tiny Bootloader chẳng hạn, bạn chỉ cần làm theo quy ước mà Claudiu đã giới thiệu. Lấy ví dụ cụ thể cho PIC18F67J10 của bạn.
Với bootloader, bạn cần dành ra một phần nhỏ ở phía cuối bộ nhớ chương trình (chú ý không đè lên các từ cấu hình). Nếu viết bằng hợp ngữ thì kích thước của bootloader thường không quá 100 word. Nếu viết bootloader bằng C thì bạn có thể xác định kích thước của bootloader bằng cách dịch xong rồi xem vùng nhớ chương trình. Vậy trong linker script của bootloader bạn chỉ cần chỉnh phần dành cho page như sau (bootloader thông thường không sử dụng ngắt): Code:
CODEPAGE NAME=page START=(0x1FFF7-<kích thước của bootloader>) END=0x1FFF7 Với chương trình ứng dụng, bạn có thể dùng cho đến ô nhớ nằm ngay phía trước vùng nhớ dành cho bootloader, nghĩa là: Code:
CODEPAGE NAME=page START=0x0002A END=(0x1FFF7-<kích thước của bootloader>) Với cách làm của AN851, bạn thường phải chú thích 1 trong những dòng Code:
FILES c018i.o Code:
FILES c018i_e.o Phần rvectors trong ví dụ của HPC là phần ánh xạ lại các vectơ ngắt của chương trình ứng dụng, và nếu đọc tập tin 'bootload.asm' của họ thì bạn sẽ thấy họ vẫn phải đặt các lệnh rẽ nhánh ở các vectơ ngắt cứng 0x00008 và 0x00018 để nhảy đến các đoạn xử lý ngắt tương ứng trong mã của chương trình ứng dụng (nói chung cách làm này của Microchip khá rườm rà). Thân,
__________________
Biển học mênh mông, sức người có hạn. Đang gặp vấn đề cần được giúp đỡ? Hãy dành ra vài phút đọc luồng sau: http://www.picvietnam.com/forum/showthread.php?t=1263 |
19-02-2008, 10:24 AM | #7 |
Nhập môn đệ tử
Tham gia ngày: Jan 2008
Bài gửi: 10
: |
Chào Namqn, chúc năm mới vạn sự như ý. Thời gian qua mình về quê ăn Tết, sorry đã bỏ qua thread này khá lâu.
Mình đã thử viết theo mô hình của tiny bootloader. Hiện giờ chương trình của mình đã có thể nhảy đến phần start của user Main program sau khi bootloader download toàn bộ user code. Tuy nhiên đến đây thì con trỏ ko thực thi hết các instruction có trong user program. Dùng ICD2 debug thì mình thấy sau khi nhảy lên user main program, con trỏ chỉ đến opcode EE1E (LFSR 0x1, 0xe00) , tuy nhiên khi gõ F7 để execute instruction này thì con trỏ nhảy ngược về vùng nhớ của bootloader, trỏ đến ngay opcode EE1E (LFSR 0x1, 0xe00) và giống như bootloader đc chạy lại từ đầu. Và mình nghĩ có lẽ con trỏ đã nhảy ngược lại vùng _startup của bootloader. Linker của bootloader mình đã chỉnh là CODEPAGE NAME=vectors START=0x0 END=0x29 CODEPAGE NAME=page START=0x160 END=0x1FFF7 còn của user code là : CODEPAGE NAME=vectors START=0x0 END=0x29 PROTECTED CODEPAGE NAME=page START=0x2A END=0x15F _entry_scn của c18i.c ở cả hai file mình đều chọn _entry_scn = 0x0. Bổ sung thêm là khi debug thì thấy lệnh 'LFSR 0x1, 0xe00' là lệnh 'lfsr 1, _stack' trong file c18i.c. Xin hỏi làm thế nào để MCU có thể thực thi đc các lệnh ở ctrinh ứng dụng mà con trỏ đã nhảy đến? Cám ơn. thay đổi nội dung bởi: dvdsoul, 19-02-2008 lúc 05:58 PM. |
19-02-2008, 08:15 PM | #8 |
Trưởng lão PIC bang
|
Nhận xét: không gian cho user code của bạn quá nhỏ so với không gian dành cho bootloader (bootloader chiếm đến hơn 99.7% dung lượng flash).
Trước khi bàn tiếp, tôi có vài câu hỏi. 1. Bạn định dùng một bootloader nào đó cho ứng dụng của mình, hay bắt buộc phải tự viết bootloader? 2. Bạn đã dùng phần mềm nào trên host PC để giao tiếp với firmware? 3. Code trong firmware của bootloader để nhảy đến chương trình ứng dụng ra sao? Bootloader thường là một ứng dụng rất nhỏ, và có chức năng tương đối đặc biệt, do đó tốt nhất nên được viết bằng hợp ngữ. Chương trình ứng dụng thường phức tạp hơn, có thể viết bằng hợp ngữ hay ngôn ngữ cấp cao tùy theo khả năng của người lập trình. Thân,
__________________
Biển học mênh mông, sức người có hạn. Đang gặp vấn đề cần được giúp đỡ? Hãy dành ra vài phút đọc luồng sau: http://www.picvietnam.com/forum/showthread.php?t=1263 |
19-02-2008, 11:37 PM | #9 |
Nhập môn đệ tử
Tham gia ngày: Jan 2008
Bài gửi: 10
: |
Trả lời namqn:
1. mình bắt buộc viết 1 bootloader mới. Ko có kiến thức về assembly, lại fải viết thêm vài ứng dụng nhỏ dùng C nữa, nên mình xài MCC18. 2. Mình dùng Hyperterminal trên PC để download file xuống PIC 3. Sau khi download xong app code. Mình clear stack pointer và gọi lệnh goto <address của reset vector của app code>. Tại đây con trỏ sẽ đọc instruction cũng là lệnh goto <address của app code> và sẽ nhảy đến fần _startup của app code. Tại đây mình nghĩ nó bị reset nên tiếp theo nó nhảy đến _startup của bootcode (mà ko thực thi gì trong đoạn app code) Hiện mình mới đang thử test bootloader nên tạm thời đặt app code và bootloader code trong vùng nhớ nhỏ để dễ truy xuất và debug. Theo mình đc biết thì goto có thể nhảy đc trong vòng 64 kb cho 18F67J10 (hay 128kb nhỉ?? ) nên sau này sẽ đặt boot code gần cuối của program memory. Cám ơn. |
20-02-2008, 05:43 AM | #10 | |
Trưởng lão PIC bang
|
Trích:
+ Khả năng thứ nhất, bạn không ghi đè reset vector của chương trình ứng dụng lên reset vector của bootloader (reset vector của bootloader và chương trình ứng dụng là giống nhau và đều là 0x000000). Khi đó, lệnh goto đến địa chỉ reset vector của chương trình ứng dụng sẽ sử dụng reset vector của bootloader, và như vậy bootloader sẽ chạy lại, chứ không phải chương trình ứng dụng được gọi. + Khả năng thứ hai, bạn ghi đè reset vector của chương trình ứng dụng lên reset vector của bootloader. Khi đó, lệnh goto đến địa chỉ reset vector của chương trình ứng dụng sẽ chạy chương trình ứng dụng, nhưng reset vector của bootloader đã bị hỏng, dẫn đến lần reset tiếp theo của phần cứng sẽ không thể kích hoạt bootloader, mà chạy thẳng chương trình ứng dụng. Ở đây, vấn đề là bootloader phải được kích hoạt mỗi khi phần cứng được reset, và khi nạp chương trình ứng dụng vào flash của chip thì bootloader phải biết được địa chỉ bắt đầu của chương trình ứng dụng để lưu lại, sau đó sẽ chuyển điều khiển đến địa chỉ đó khi đã nạp xong chương trình ứng dụng vào flash. Theo nguyên tắc, địa chỉ bắt đầu của chương trình ứng dụng phải nằm trong 4 word đầu tiên của flash (tức là các địa chỉ 0x000000 - 0x000003), và nó là thành phần của một lệnh chuyển điều khiển như rcall, call, hay goto. Với Tiny Bootloader, phần công việc xác định địa chỉ bắt đầu của chương trình ứng dụng được phần mềm trên host PC đảm nhiệm (thông qua việc đọc tập tin .hex của chương trình ứng dụng, và phân tích các lệnh nằm trong vùng địa chỉ 0x000000 - 0x000003), do đó firmware của Tiny Bootloader có thể được viết ở mức độ rất đơn giản, với giao thức giữa phần mềm trên host PC và firmware được quy ước ở mức độ tương đối thấp. Với trường hợp của bạn, phần mềm trên host PC (Hyper Terminal) chỉ được dùng để truyền thông tin dạng ASCII đến bootloader, mọi công việc còn lại đều phải được hiện thực trong bootloader, từ việc phân tích tập tin .hex, xác định địa chỉ và giá trị của ô nhớ, đến việc xác định địa chỉ bắt đầu của chương trình ứng dụng cũng như bảo vệ vùng nhớ của bootloader khỏi việc bị ghi đè, ... Theo tôi, cách tiếp cận của Claudiu là hiệu quả nhất, và bạn hoàn toàn có thể tự tin khi phát biểu rằng bootloader là do bạn tạo ra, ngay cả khi bạn chỉ sửa lại mã hợp ngữ của firmware để có thể chạy trên PIC18F67J10 với cấu hình của riêng bạn. Nếu bạn vẫn muốn tiếp tục đi theo con đường hiện nay, bạn hãy tham khảo những gợi ý của tôi. Quan trọng nhất là xác định địa chỉ bắt đầu của chương trình ứng dụng, thông qua 4 từ lệnh của vùng 0x000000 - 0x000003 trong mã lệnh của chương trình ứng dụng, lưu địa chỉ đó lại, sau đó dùng lệnh goto đến địa chỉ đó, khi bootloader đã làm xong nhiệm vụ, chứ không nhảy đến reset vector của chương trình ứng dụng (tức là địa chỉ 0x000000). Thân,
__________________
Biển học mênh mông, sức người có hạn. Đang gặp vấn đề cần được giúp đỡ? Hãy dành ra vài phút đọc luồng sau: http://www.picvietnam.com/forum/showthread.php?t=1263 |
|
20-02-2008, 06:13 PM | #11 |
Nhập môn đệ tử
Tham gia ngày: Jan 2008
Bài gửi: 10
: |
Cám ơn Namqn rất nhiều về những hướng dẫn rất cặn kẽ và nhiệt tình từ đầu thread đến giờ. Đây cũng là một kinh nghiệm đáng nhớ của mình khi vừa mới tập tành trong lĩnh vực MCU.
Hôm nay mình đã trao đổi với supervisor và có vài thay đổi trong project. Những phần cần thiết phải dùng C mình sẽ ko tiếp tục nữa. Do vậy mình chuyển qua dùng bootloader sẵn có viết bằng hợp ngữ. Sau khi tham khảo mình quyết định dùng AN851 vì đã có sắn 1 sample project cho con pic8F67j10. Vấn đề còn lại là mình cần nắm nhanh được hợp ngữ để có thể điều chỉnh được chương trình theo những chức năng cần thiết của project. Mình nghĩ đi theo hướng này có thể sẽ dễ dàng hơn cho những trao đổi trên diễn đàn. Có gì thắc mắc mong mọi người cùng giúp mình với nhé. Một lần nữa xin cảm ơn namqn |
21-02-2008, 01:50 AM | #12 | |
Trưởng lão PIC bang
|
Trích:
Thân,
__________________
Biển học mênh mông, sức người có hạn. Đang gặp vấn đề cần được giúp đỡ? Hãy dành ra vài phút đọc luồng sau: http://www.picvietnam.com/forum/showthread.php?t=1263 |
|
25-02-2008, 08:43 AM | #13 |
Nhập môn đệ tử
Tham gia ngày: Jan 2008
Bài gửi: 10
: |
Uh, mình đang thực tập cho 1 công ty nhỏ ở Singapore. Task chính của mình là software nhưng lại được giao viết firmware (cụ thể là bootloader cho con PIC) Lĩnh vực này cũng mới với mình. Hỏi thăm vài người bạn thì được giới thiệu lên PICVIETNAM
Hân hạnh được làm quen. À, mà chắc namqn đã đi làm rồi phải k? thay đổi nội dung bởi: dvdsoul, 25-02-2008 lúc 08:51 AM. |
25-02-2008, 07:36 PM | #14 | |
Trưởng lão PIC bang
|
Trích:
Thân,
__________________
Biển học mênh mông, sức người có hạn. Đang gặp vấn đề cần được giúp đỡ? Hãy dành ra vài phút đọc luồng sau: http://www.picvietnam.com/forum/showthread.php?t=1263 |
|
26-02-2008, 01:44 PM | #15 |
Nhập môn đệ tử
Tham gia ngày: Jan 2008
Bài gửi: 10
: |
Vậy thì anh Nam lớn hơn em nhiều. Thất lễ quá.
Em cũng học BKHCM 2 năm trước khi qua Singapore, tính ra cũng được gần 3 năm rồi |
|
|