13.8.08

Tipe data kernel internal

(bagian 2 dari 7 artikel - ke artikel utama - bagian 3)

Ketika membuat program yang portabel, perlu diperhatikan benar jumlah byte dari variabel yang digunakan di dalam program. Berbagai prosesor mempunyai jumlah byte berbeda untuk tipe data int dan long. Ada juga perbedaan cara menentukan apakah variabel signed atau unsigned. Jadi kalau program yang dibuat harus menggunakan jumlah bit tertentu, dan harus tegas signed atau unsigned, maka Anda harus menggunakan tipe data yang sudah built-in. Typedefs berikut ini dapat dipakai di sembarang tempat dalam program kernel dan didefinisikan dalam berkas header linux/types.h.

 u8    unsigned byte (8 bit)
u16 unsigned word (16 bit)
u32 unsigned 32-bit
u64 unsigned 64-bit

s8 signed byte (8 bit)
s16 signed word (16 bit)
s32 signed 32-bit
s64 signed 64-bit

Sebagai contoh, driver i2c mempunyai beberapa fungsi yang digunakan untuk mengirim dan menerima data melalui bus i2c:

s32 i2c_smbus_write_byte(struct i2c_client *client, u8 value);
s32 i2c_smbus_read_byte_data(struct i2c_client *client,
u8 command);

s32 i2c_smbus_write_byte_data(struct i2c_client *client,
u8 command, u8 value);

Semua fungsi di atas mempunyai output nilai 32 bit signed dan mempunyai input nilai 8 bit unsigned untuk semua parameternya. Dengan menggunakan tipe data seperti ini, program di atas portabel untuk semua prosesor.

Jika ingin agar variabel dapat diakses melalui program di wilayah user (user-space), maka harus digunakan tipe data exportabel di bawah ini. Contoh tipe data ini terdapat dalam struktur data yang di-passing saat memanggil perintah ioctl(). Tipe data ini didefinisikan di berkas header linux/types.h.

__u8   unsigned byte (8 bit)
__u16 unsigned word (16 bit)
__u32 unsigned 32-bit
__u64 unsigned 64-bit

__s8 signed byte (8 bit)
__s16 signed word (16 bit)
__s32 signed 32-bit
__s64 signed 64-bit

Sebagai contoh, berkas header usbdevice_fs.h mempunyai beberapa struktur data untuk digunakan berkomunikasi dengan piranti USB (USB device) melalui program di wilayah user (user space). Berikut adalah definisi ioctl yang digunakan mengirim pesan kontrol USB ke piranti:

struct usbdevfs_ctrltransfer {
__u8 requesttype;
__u8 request;
__u16 value;
__u16 index;
__u16 length;
__u32 timeout; /* in milliseconds */
void *data;
};
#define USBDEVFS_CONTROL_IOWR('U', 0,
# struct usbdevfs_ctrltransfer)

Pada mesin 64-bit, ada satu hal yang sering menimbulkan problem yaitu bahwa jumlah byte pointer tidak sama dengan jumlah byte unsigned integer. Jumlah byte pointer sama dengan unsigned long seperti terlihat pada get_zeroed_page():

extern unsigned long FASTCALL
(get_zeroed_page(unsigned int gfp_mask))

Fungsi get_zeroed_page() membuat halaman memori kosong (free memory) yang isinya sudah dinolkan semua. Fungsi ini mempunyai output unsigned long yang harus diubah (typecast) ke tipe data lain yang sesuai. Potongan program drivers/char/serial.c dalam fungsi rs_open() berikut ini memperlihatkan caranya (catatan: kode ini dari kernel 2.4.x).

static unsigned char *tmp_buf;
unsigned long page;

if (!tmp_buf) {
page = get_zeroed_page(GFP_KERNEL);
if (!page)
return -ENOMEM;
if (tmp_buf)
free_page(page);
else
tmp_buf = (unsigned char *)page;
}
Terdapat beberapa tipe data kernel yang dapat digunakan sebagai pengganti tipe data unsigned long, misalnya pid_t, key_t, gid_t, size_t, ssize_t, ptrdiff_t, time_t, clock_t, dan caddr_t. Gunakan tipe data ini untuk menghindari permasalahan portabilitas.

Tidak ada komentar: