مطالب علمی

روش های اصولی و صحیح نوشتن کتابخانه

نوشتن یک کتابخانه صرف نظر از سخت افزار و پلتفرم کامپایلر مورد استفاده، میتونه از سه جنبه حائز اهمیت باشه.

1 – در نظر گرفتن یک قالب استاندارد [قراردادی] برای نوشتن کدها
2 – رعایت انعطاف پذیری و سازگاری سخت افزاری
3 – رعایت سازگاری در پلتفرم های متفاوت کامپایلرها

هر کدوم از این سه جنبه دارای ابعاد مختلفی هستند که در ادامه سعی میکنم که نقطه نظرات خودم رو در مورد اونها اعلام کنم.

در نظر گرفتن یک قالب استاندارد [قراردادی] برای نوشتن کدها

اولین اصل در کدنویسی، شناسنامه دار بودن کلیه فایل هاست که مثلا میتونه یک هدری به شکل زیر باشه که در اون مشخصات کلی فایل و توضیحات اولیه و در صورت لزوم، سابقه تغییرات در ورژن های مختلف، ذکر شده باشه. شاید در نظر اول، این موضوع بی اهمیت جلوه کنه، ولی به مرور متوجه خواهید شد که برعکس، از اهمیت خاصی برخورداره!

//-----------------------------------------------------------------------------
// Copyright:   
// Author:     
// Remarks:    
// known Problems: 
// Version:    
// Description:  
//                                 
//-----------------------------------------------------------------------------

نکته بعدی اینکه از اونجایی که ممکنه، هدر فایل ها در جاهای مختلفی فراخوانی ( یا اضافه ) بشن، حتما باید مکانیزمی در نظر گرفته بشه که یک هدر فایل بطور همزمان در چند جای مختلف فراخوانی نشه، برای این منظور، باید هدر فایل ها در شرطی مشابه شرط ذیل نوشته بشن :

#ifndef _SHN_UTILS_H_
    #define _SHN_UTILS_H_
 .
 .
 .
 .
 .
#endif    //_SHN_UTILS_H_

نوشتن کامنت های خلاصه و کلیدی در کلیه فایل ها  نکته پر اهمیت بعدی است! اهمیت این موضوع زمانی روشن میشه که بعد از مدتی میخواهید فایل هاتون رو بررسی و یا اصلاح کنید. مضاف بر اینکه این موضوع برای استفاده کننده های بعدی هم میتونه از جنبه راهنمایی و سهولت در استفاده مهم باشه.

لزومی نداره که همه فانکشن های یک کتابخونه در دسترس عموم باشند! برخی از روتین ها جنبه استفاده داخلی دارند و به عبارتی فانکشن های Low-Level محسوب میشن. بطور نمونه در کتابخونه در حال بررسی ( کتابخونه AD7715 ) روتین های AD7715_WriteToReg و AD7715_CS پس این روتین ها رو نباید در لیست فانکشن پروتوتایپ هدر فایل کتابخونه قرار بدیم.

یک کتابخونه کامل باید طوری نوشته بشه که استفاده کننده نیازی به دستکاری در متن اصلی کدها نداشته باشه، به همین منظور باید حتی الامکان پیش بینی های لازم صورت بگیره. بطور مثال، ست کردن پارامترهای Run-Time باید توسط ماکروها و یا فانکشن ها انجام بشه، ست کردن پارامترهای Static باید در تعاریف ثابت و در یک فایل جداگانه در دسترس استفاده کننده باشه.
در این راستا توصیه میشه که هر کتابخونه حداقل شامل سه فایل باشه، یک فایل C که کدهای اصلی در اون نوشته شده، یک هدر فایل اصلی که تعاریف پایه، ساختارها و پروتوتایپ ها در اون نوشته شده ( که معمولا نیازی به اعمال تغییرات توسط کاربر نداره ) و یک هدر فایل کانفیگ که تمامی پارامترهای ثابت، فلگ ها و تعاریف سخت افزاری و غیره در اون هست و توسط کاربر تنظیم خواهد شد. بحث و بررسی بیشتر در این زمینه رو به مبحث بعدی موکول میکنم.

رعایت انعطاف پذیری و سازگاری سخت افزاری

وقتی که یک کد و یا کتابخونه نوشته میشه، در خوش بینانه ترین حالت، ممکنه که افراد مختلفی با سخت افزار های مشابه، اما آرایش های سخت افزاری مختلف، بخواهند از اون کد و یا کتابخونه استفاده کنند. مثلا کدی برای AVR مگا 32 نوشته شده ولی قراره که روی مگا 8 استفاده بشه و در بدترین حالت، ممکنه که کدی برای AVR مگا 32 نوشته شده باشه ولی قرار باشه که روی یک میکروی PIC مورد بهربرداری قرار بگیره. در چنین شرایطی، اگر کد نوشته شده از انعطاف خوبی برخوردار نباشه، استفاده کننده عطاش رو به لقاش خواهد بخشید! ( فعلا به مورد مبحث سازگاری پلتفرم ها نمی پردازم! )

یک نکته اساسی و قابل تامل اینه که کد نویسی به زبان C در تمامی احوالات ( بجز اندک موارد استثنا ) حالتی استاندارد و مستقل از کامپایلر داره ولی متاسفانه، دوستان همیشه مقوله زبان برنامه نویسی و کامپایلر رو با هم خلط میکنند. پس سعی کنیم که از این پس این دو موضوع رو با هم قاطی نکنیم! این یعنی اینکه منی که با C برای AVR کد مینویسم، از همون قواعدی استفاده میکنم که یک نفر برای کد نویسی با C برای PIC و غیره استفاده میکنه.

یک کد و یا کتابخونه ای که اصولی نوشته شده باشه، حتی الامکان سعی میکنه که از آمیختگی اصول و قواعد کد نویسی زبان برنامه نویسی با اصول و قواعد کامپایلر جلوگیری کنه. اولین قدم در این خصوص اینه که تنظیمات و تعاریف سخت افزاری از کدهای پردازشی و محاسباتی تفکیک بشه.
فرض کنید که یک LED سبز قراره که روی پین PORTD.3 تعریف و خاموش و روشن بشه. اگر به این منظور، در متن برنامه مبادرت به مقدار دهی مستقیم به اون پین بشه، چند مشکل بروز خواهد کرد. مشکل اول اینه که اگر بخواهیم موقعیت LED مورد نظر رو تغییر بدیم، باید در متن برنامه جستجو کرده و تغییرات مورد نظر رو اعمال کنیم، این امر موجب صرف وقت و احتمال بروز خطا خواهد بود. حال اگر بخواهیم منطق روشن و خاموش شدن LED مزبور رو تغییر بدهیم، مشکل دوچندان خواهد شد. و اگر پلتفرم سخت افزاری و یا کامپایلر تغییر کند، در اینصورت بهتر است که برنامه را مجددا بازنویسی کنیم!!! این مشکل ممکن است در کتابخانه در حال بررسی ( کتابخونه AD7715 ) در مورد پین CS آی سی AD7715 بروز کند. پس راهکار مناسب چیست؟

همانطور که قبلا هم اشاره شد، در این خصوص بهتر است کلیه تعاریف سخت افزاری و حتی مکانیزم های کنترلی اصلی در یک هدر فایل کانفیگ انجام و به پروژه الحاق شود. برای LED مورد مثال به شکل زیر عمل میکنیم :

//----------- Green LED (output)
#define GLED_PRT       PORTD
#define GLED_DDR       DDRD
#define GLED_BIT       3

//------------------------------------
#define GLED_init()     sbi(GLED_DDR, GLED_BIT);    sbi(GLED_PRT, GLED_BIT)

//------------------------------------
#define GLED(x)       (x ? (cbi(GLED_PRT, GLED_BIT)) : (sbi(GLED_PRT, GLED_BIT)))

در این حالت، در صورت تغییر سخت افزار و یا کامپایلر، فقط کافی است که این تعاریف اصلاح شوند و دیگر نیازی به اعمال تغییرات در متن برنامه وجود ندارد. ( جهت روشن تر شدن موضوع، پیشنهاد میکنم که در ادامه، کتابخانه AD7715 را با توجه به این توضیحات بازنگری کنیم )

این موضوع زمانی مهم تر میشود که در کدهای نوشته شده از مواردی مثل روتین های اینتراپت هم استفاده شده باشد.نوشتن کد ها و کتابخونه های کامل معمولا موجب پیچیدگی کدها و بالا رفتن حجم نهایی برنامه خواهد شد.
با پیچیدگی کدها معمولا نمیشه کاری کرد ولی برای کم کردن حجم نهایی میشه فکری کرد!
راهکاری که توصیه میشه، در نظر گرفتن فلگ هایی است که به فراخور نیاز استفاده کننده، موجب کامپایل شدن و یا نشدن برخی از قسمت های کد بشه ( این فلگ ها رو میشه در ترکیبی با دستورات شرطی کامپایلر مورد استفاده قرار داد ) استفاده از تکنیک های مشابه، بعضا موجب استفاده بهینه و صرفه جویی در منابع سیستم هم خواهد شد.

 

نویسنده: مهندس شهرام نوربخش راد

ادامه مطلب در انجمن: http://www.eca.ir/forums/thread41661.html

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا