Thông báo

Collapse
No announcement yet.

Về tối ưu bộ biên dịch và biến volatile!

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • Về tối ưu bộ biên dịch và biến volatile!

    Chào các bạn!
    Mình đang sử dụng Keil để lập trình 8051. Mình có một số thắc mắc:
    1. Mình sử dụng volatile cho biến trong hàm ngắt, nhưng khi truy cập đến biến trên trong chương trình chính thì giá trị biến đó ko thay đổi. Như vậy hàm volatile không có tác dụng báo hiệu cho trình biên dich biết biến trong hàm ngắt đã bị thay đổi? Trong khi đó nếu đổi kiểu dữ liệu thành DATA thì lại có thể truy cập được bình thường( mình cấu hình biên dịch bộ nhớ là XDATA). Như vậy có phải là khi biên dịch các biến sẽ mặc định trong XDATA nên biến trong hàm ngắt nên đặt ở DATA, như vậy thì giá trị biến đó sẽ thay đổi sau khi thực hiện xong hàm ngắt?
    2. Khi tối ưu ở mức cao (level 8-9) thì hàm delay() với vòng lặp for(i=0;,i<10000;i++) {} thì trình biên dịch vẫn nhận biết được và không tối ưu. Tại sao lại có hiện tượng này?

  • #2
    1. Bạn viết code thế nào thì trình biên dịch sẽ biên dịch như vậy.
    Theo mình biết thì biến volatile giúp trình biên dịch nhận biết và không tối ưu code khi gặp biến đó, thích hợp cho việc share dữ liệu giữa chương trình chính và chương trình ngắt.
    Bạn thử khai báo biến toàn cục với chỉ thị volatile, rồi extern nó ra những file có truy cập đến biến đó.
    2. vụ hàm delay thì mình không chắc, có thể là nó hết tối ưu được nữa rồi cũng nên

    Comment


    • #3
      Hello viettoan!
      Mình có xem một số diễn đàn thì người ta bảo Kiel thường tối ưu manh(cái này chưa kiểm chứng với các compiler khác). Vòng lặp for( và biến không sử dụng( chỉ để tăng hoặc giảm trong ngắt) cũng bị tối ưu, chính vì thế nên đặt volatile trước các biến có thay đổi ngoài chương trình chính. Còn về đặt kiểu biến DATA, có lẽ do khi biên dịch mình đặt memory model là XDATA nên khi khởi tạo biến DATA, compiler ko tối ưu.
      Rất lạ là khi mình để optimization level 0 thì hàm delay() ko chạy đc. Nhưng khi để level 8 thì nó vẫn chạy vào hàm delay() mà ko tối ưu.
      Còn một chỗ mình ko rõ lắm : Theo mình extern có tác dụng như biến toàn cục, mục đích là để sử dụng cho nhiều file khác nhau. Vậy nếu như hàm volatile ko có tác dụng thì biến extern volatile có tác dụng như thế nào? Bạn có thể giải thích thêm được không?

      Comment


      • #4
        mình nhớ cứ để cấu hình mặc định, chọn đúng ic, thì keil biên dịch ok luôn. Mình lập trình cũng không quan tâm tới bộ nhớ là DATA hay XDATA, cứ khai báo
        volatile int x;
        rồi dùng biến x trong cả chương trình main và chương trình ngắt. Còn việc extern, là khi bạn muốn dùng biến x trong source file khác.
        Vấn đề của bạn mình vẫn không rõ lắm, nhất là khi bạn nhắc đến "hàm volatile".
        Khi bạn nói không chạy được hàm delay, mình nghĩ đến các khả năng:
        - bạn chưa chọn đúng ic.
        - bạn chưa chọn đúng file linker của ic đó.
        - bạn đã chỉnh sửa không đúng memory mapping của linker.
        Việc không gọi được hàm delay -> có thể hàm interrupt của bạn không được gọi khi ngắt xảy ra

        Comment


        • #5
          bạn có thể debug chương trình của mình bằng Proteus, hoặc xuất led trong các hàm delay(), interrupt để kiểm tra xem các hàm này có được gọi hay không.

          Comment


          • #6
            Hi viettoan! Minh viet nhầm cái "hàm volatile" ở đây đang nói về biến volatile thôi. Trong Keil thì chỉnh chon file liker cho Ic ở đâu vậy bạn?và bạn nói đến mapping memory cho ic có phải như kiểu phân vùng bộ nhớ trên ic?

            Comment


            • #7
              Đúng là mình ko gọi chạy được interrupt. ic mình đang dùng là CC2510 của TI. Nhiều lúc chương trình chạy ko đúng như ý. Có lẽ mình chưa cấu hình compiler đầy đủ cho con IC này. Mặc dù Keil có thư viện cho con này.

              Comment


              • #8
                ^^ tiếp cận chip TI nhanh nhất là bạn đăng ký một acc trên TI, rồi download thư viện hỗ trợ cho con ic đó.
                Sau đó thử các example từ dễ đến khó.
                Mình nghĩ bạn dùng keil + jtag thì ok con dê luôn, cứ import project example vào, rồi debug, trace từng dòng lệnh thôi.

                Comment


                • #9
                  đừng thử tự viết code trước, nó sẽ làm bạn bị rối lên.
                  thử xem code viết sẵn, kết hợp datasheet để hiểu

                  Comment


                  • #10
                    Bạn có thể nói rõ hơn về memory mapping và cấu hình linker đc ko? Vì TI chỉ support IAR cho con chip này. nên khi chuyển sang KEIL mình cần hiểu rõ cấu hình compiler trong KEIL như thế nào? Code thì mình cũng đẽ test và chạy được gần hết.

                    Comment


                    • #11
                      ^^ sorry bạn nha, mình không có làm với con chip này
                      Mình có vòng vòng trên mạng thì có một số thông tin, bạn xem có giúp ích gì không nhé:
                      - CC2510 và CC1010 kiến trúc như nhau, cả về CPU, và mapping memory
                      - Keil hiện không có sẵn con chip CC2510 (mình thấy có trang này Texas Instruments CC2510F32), nhưng có con CC1010.
                      - Ngay trong IAR, người ta cũng chỉ có 1 file linker cho cả 2 con này http://www.ti.com/lit/ug/swru038/swru038.pdf, bạn xem trang 6/29

                      Vậy, mình có hướng tiếp như sau (không biết là bạn đã thử chưa )
                      - bạn tạo project trong keil với CC1010.
                      - trong các project của bạn, bạn include header file mà keil cung cấp(mình đề cập ở trên)
                      (Mình thấy nhiều người cũng gặp trường hợp đó, mà chưa thấy cách giải quyết! Nên có thể bạn sẽ gặp vấn đề với debug.)
                      - Nếu như vẫn chưa được, bạn thử manual chỉnh off chip code và xdata trong chỗ Target

                      Comment


                      • #12
                        Hello viettoan! cảm ơn bạn nhé.

                        Mình đoán có lẽ do Keil ko nhận đủ các vùng nhớ hoặc địa chỉ vùng nhớ không chuẩn nên khi khởi tạo biến toàn cục mình có tiền tố data thì biến dùng được, trong khi volatile ko dùng được. Do mình chọn memory model là large(variable in xdata) nên khi khởi tạo biến, tự động đưa về xdata,có lẽ nào data mới khác biệt.
                        Đến đây mình lại ko rõ, vì vùng nhớ data nằm trong xdata, như vậy nếu truy cập được đến xdata sẽ truy cập đc data đúng ko, nếu dùng xdata có chèn lên vùng dữ liệu data ko? có lẽ nào do sai địa chỉ vùng nhớ, nên xdata ko sử dụng nhủ bt đc? Mình xem qua offchip xdata memory trong Keil , và đoán là phải tự đánh địa chỉ bằng tay.
                        Mình thử cách của bạn chỉnh trong xdata memory nhưng vẫn ko được, các biến vẫn không thể truy cập từ các hàm khác của chương trình.
                        Dù sao cũng cảm ơn bạn nhiều!
                        Hiện giờ mình dã giải quyết được bằng cách dùng biến data, nhưng dung luơng có hạn, có cách nào để mở rộng vùng nhớ data vào vùng xdata ko?

                        Comment

                        Về tác giả

                        Collapse

                        nobody123 Tìm hiểu thêm về nobody123

                        Bài viết mới nhất

                        Collapse

                        Đang tải...
                        X