PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   dsPIC - Bộ điều khiển tín hiệu số 16-bit (http://www.picvietnam.com/forum/forumdisplay.php?f=29)
-   -   Khai Báo Biến trong MPLAB C30 (http://www.picvietnam.com/forum/showthread.php?t=6482)

lybao_huy 06-06-2010 02:05 PM

Khai Báo Biến trong MPLAB C30
 
Hiện tại mình cũng không hiểu có gì khác nhau giữa các cách khai báo biến sau:

a/ int x __attribute__ ((aligned (8))) ; và int x;

b/ int x __attribute__ ((aligned )) ; và int x;

c/ int x __attribute__ ((packed)); và int x;

mong bạn giải thích dùm

lybao_huy 07-06-2010 04:21 PM

int x __attribute__ ((aligned (A))), A phải là mũ của 2, tại sao không phải là bội của.

mấy cái này thật khó hiểu.

truongtam2008 22-06-2010 01:04 AM

Đại khái theo tớ hiểu là như thế này:
int x __attribute__ ((aligned (16))) nó sẽ cấp phát một vùng nhớ 16byte trong bộ nhớ cho biến toàn cục kiểu int. Người ta làm như thế là để truy cập các câu lệnh DSP ấy mà.

lybao_huy 22-06-2010 10:24 PM

cảm ơn, lời giải đáp của bạn. Còn Các bạn khác thì sao, có thể giúp tôi được không

bien_van_khat 23-06-2010 09:58 AM

Trích:

Nguyên văn bởi lybao_huy (Post 36570)
Hiện tại mình cũng không hiểu có gì khác nhau giữa các cách khai báo biến sau:

a/ int x __attribute__ ((aligned (8))) ; và int x;

b/ int x __attribute__ ((aligned )) ; và int x;

c/ int x __attribute__ ((packed)); và int x;

mong bạn giải thích dùm

1 - aligned để sắp xếp biến được khai báo tại vị trí có địa chỉ là bội của 1 giá trị nhất định. Còn tại sao giá trị đó phải là lũy thừa của 2 thì mình ko rõ.
VD: Bạn khai báo
Code:

char a;
char str[128];

Biến a có địa chỉ = 0, str trỏ tới địa chỉ = 1. str là byte-aligned. Kiến trúc của dsPIC ko cho phép truy xuất WORD theo byte-aligned. Tức là nếu bạn thực hiện biểu thức:
Code:

int *wptr = (int*)str;
(*wptr)++;

sẽ xảy ra trap address error.
Trong trường hợp này bạn phải khai báo
Code:

char a;
char str[128] __attribute__ ((aligned(2))) ;

Bây giờ con trỏ str sẽ trỏ tới địa chỉ là 2 thay vì 1. Các aligned cao hơn chỉ dành cho các hàm DSP.

2 - packed ngược lại với aligned để giảm align tới mức thấp nhất có thể. Thường dùng với struct
VD:
Code:

struct{
        char a;
        int i;
}s;

địa chỉ của field a = 0, và địa chỉ của field i = 2 vì biến i cần word-aligned. Và sizeof(s) = 4. Tuy nhiên nếu bạn khai báo
Code:

struct __attribute__ ((packed)){
        char a;
        int i;
}s;

Khi đó địa chỉ của field i = 1. và sizeof(s) = 3. Nhưng bây giờ ko thể truy xuất biến i theo word vì nó misaligned.

lybao_huy 23-06-2010 09:14 PM

Ồ, cảm ơn bạn nhiều lắm. thật tình mình đọc nhiều tài liệu rồi mà cũng không hiểu nhiều cho lắm. Mình chỉ hiểu là biến kiểu WORD thì phải có địa chỉ bắt đầu là chẵn(canh lề đúng). Hôm nay nhờ có bạn mà mình lại biết thêm. Vô cũng cảm ơn bạn, để mình coi tài liệu kĩ lại, rồi hỏi bạn cho xong cái quái quỷ này.

lybao_huy 23-06-2010 09:30 PM

À trong tài liệu MPLAB_C_Compiler_dsPIC có nói:
Note: The device architecture requires that words be aligned on even byte
boundaries, so care must be taken when using the packed attribute to
avoid run-time addressing errors.
vậy khai báo như sau sẽ vô nghĩa vì addressing error
struct foo
{
char a;
int x[2] __attribute__ ((packed));
};

vậy thì dùng packed Attribute chi cho mệt

lybao_huy 23-06-2010 09:50 PM

vd:
#define _XBSS(N) __attribute__((space(xmemory), aligned(N))).
có gì khác nhau giữa 2 khai báo sau không:
a-int xbuf[16] _XBSS(32) ;
b-int xbuf[16] _XBSS(2) ;

Xin bạn giải thích dùm.

bien_van_khat 24-06-2010 01:09 PM

Trích:

Nguyên văn bởi lybao_huy (Post 36914)
vd:
#define _XBSS(N) __attribute__((space(xmemory), aligned(N))).
có gì khác nhau giữa 2 khai báo sau không:
a-int xbuf[16] _XBSS(32) ;

xbuf sẽ được cấp phát để trỏ tới 1 trong các địa chỉ 0, 32, 64, 96.....
Trích:

b-int xbuf[16] _XBSS(2) ;
xbuf sẽ được cấp phát để trỏ tới 1 trong các địa chỉ 0, 2, 4, 6, 8....

lybao_huy 25-06-2010 12:59 AM

cảm ơn bạn nhiều lắm

lybao_huy 01-07-2010 11:03 PM

Trích:

Nguyên văn bởi bien_van_khat (Post 36918)
xbuf sẽ được cấp phát để trỏ tới 1 trong các địa chỉ 0, 32, 64, 96.....

xbuf sẽ được cấp phát để trỏ tới 1 trong các địa chỉ 0, 2, 4, 6, 8....

Tôi có khai báo như sau:
a-unsigned int f[4] __attribute__((aligned(8)));
b-unsigned int ff[4] __attribute__((aligned(2)));
Tôi không thấy sự khác biệt giữa 2 cách khai báo trên
a-
tôi thấy mảng f được phân bố trong bộ nhớ như sau:
f: ở địa chỉ 2746
f+1: ở địa chỉ 2748
f+2: ở địa chỉ 2750
f+3: ở địa chỉ 2752

b- và mảng ff được phân bố trong bộ nhớ như sau:
ff: ở địa chỉ 2856
ff+1: ở địa chỉ 2858
ff+2: ở địa chỉ 2860
ff+3: ở địa chỉ 2862

Mong Bạn giải thích dùm.

bien_van_khat 02-07-2010 10:14 AM

2 Attachment(s)
source code của bạn như thế nào?

bạn xem 2 file đính kèm, chú ý mảng dummy được khai báo 2 lần với 2 kích thước khác nhau để cố tình thay đổi vị trí của mảng f.

Nhưng trong cả 2 lần địa chỉ mảng f ko thay đổi, luôn nằm ở vị trí 0xD10, chia hết cho 8.

lybao_huy 02-07-2010 10:20 AM

Cảm ơn nhiều, mình đang xem

lybao_huy 02-07-2010 12:01 PM

Tức quá Modem bị trục trặc!
À, mình thực hiện lại rồi thấy như sau:

Nếu f[4] và ff[4] được khai báo toàn cục thì ok.
Còn nếu f[4] và ff[4] khai báo trong hàm main() thì bị trục trặc vd:
void main(){
unsigned int f[4] __attribute__((aligned(1024)));
unsigned int ff[4] __attribute__((aligned(4096)));
}
Sao kì vậy

bien_van_khat 02-07-2010 12:26 PM

Về nguyên tắc, attribute align là chỉ thị cho trình liên kết để sắp xếp biến. Trong khi biến cục bộ được được tạo ra khi chạy (run-time) và nằm trong stack chứ ko phải khi liên kết (link-time) do đó bạn ko thể yêu cầu linker làm cái việc mà nó ko thể làm được.

[updated]
Sticky để mọi người quan tâm có thể đọc.


Múi giờ GMT. Hiện tại là 04:52 AM.

Tên diễn đàn: vBulletin Version 3.8.11
Được sáng lập bởi Đoàn Hiệp.
Copyright © PIC Vietnam