قسم الميكروكنترولر والروبوت ودوائر الاتصال بالحاسب الالي قسم المتحكمات الـ microcontroller و المعالجات microprocessor و التحكم الرقمي بالكمبيوتر CNC والانظمة الآلية والروبوت Robots

   

الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 08-06-2015, 02:35 PM المشاركة 9   
افتراضي



خدمات نظام RTOS :
خدمات نظام RTOS هى الخدمات utilities التى يتم توفيرها عن طريق النواة والتى تساعد المطورين على إنشاء مهام زمن حقيقى بكفاءة . على سبيل المثال ، مهمة يمكن أن تستخدم خدمات الوقت time للحصول على التاريخ والوقت الحالى . بعض هذه الخدمات هى :
• خدمات معالجة (مناولة) المقاطعة .
• خدمات الوقت .
• خدمات إدارة الأجهزة .
• خدمات إدارة الذاكرة .
• خدمات المدخلات والمخرجات .

أدوات التزامن والتراسل :
أدوات التزامن والتراسل هى بنيات النواة التى تساعد المطورين على إنشاء تطبيقات الوقت الحقيقى . بعض هذه الخدمات هى :
• أعمدة الإشارة (السيمافورات) Semaphores .
• أعلام (رايات) الحدث Event flags .
• صناديق البريد Mailboxes .
• الأنابيب Pipes .
• قوائم انتظار الرسائل Message queues .



نظام RTOS والمترجم CCS PIC C :


التعديل الأخير تم بواسطة : F.Abdelaziz بتاريخ 08-06-2015 الساعة 03:05 PM
اعلانات

الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 08-06-2015, 10:20 PM المشاركة 10   
افتراضي نظام RTOS والمترجم CCS PIC C :


نظام RTOS والمترجم CCS PIC C :
المترجم CCS PIC C هو واحد من مترجمات لغة السى الواسع الانتشار من أجل السلسلة PIC16 والسلسة PIC18 . بالإضافة إلى كونه مترجم ، فإنه يقدم العديد من الخدمات المفيدة الأخرى . بناء الجملة فى المترجم CCS C يختلف قليلا عن بناء الجملة مع المترجم mikroC ، لكن من لهم دراية بالميكروسى سوف يجدون أن CCS C سهل الاستخدام .
المترجم CCS C يدعم نظام RTOS للسلسلة PIC18 . هذا النظام يسمح للميكروكونترولر بتشغيل المهام بدون استخدام المقاطعات . عندما يتم جدولة المهمة للتشغيل ، فإنه يتم إعطاء السيطرة على المعالج لهذه المهمة . عندما يتم اكتمال المهمة أو لا تحتاج المعالج أكثر من ذلك ، فإن السيطرة تعود للدالة المرسلة ، والتى تعطى السيطرة على المعالج إلى المهمة المجدولة التالية . ولأن نظام RTOS لا يستخدم المقاطعات ولا هو استباقى (وقائى) ، فيجب على المستخدم التأكد من أنه لا يتم تشغيل مهمة إلى الأبد .للمزيد من المعلومات حول نظام RTOS ، يمكن الرجوع إلى دليل المستخدم للمترجم .
يوفر المترجم CCS C دوال نظام RTOS التالية ، بالإضافة إلى دوال لغة السى العادية :

كود:
rtos_run() 
Initiates the operation of RTOS. All task control operations are implemented after calling this function.

rtos_terminate() 
Terminates the operation of RTOS. Control returns to the original program without RTOS. In fact, this function is like a return from rtos_run().

rtos_enable() 
Receives the name of a task as an argument. The function enables the task so function rtos_run() can call the task when its time is due.

rtos_disable() 
Receives the name of a task as an argument. The function disables the task so it can no longer be called by rtos_run() unless it is re-enabled by calling rtos_enable().

rtos_ yield() 
When called from within a task, returns control to the dispatcher. All tasks should call this function to release the processor so other tasks can utilize the processor time.

rtos_msg_send() 
Receives a task name and a byte as arguments. The function sends the byte to the specified task, where it is placed in the task’s message queue.

rtos_msg_read() 
Reads the byte located in the task’s message queue.

rtos_msg_ poll() 
Returns true if there is data in the task’s message queue. This function should be called before reading a byte from the task’s message queue.

rtos_signal() 
Receives a semaphore name and increments that semaphore.

rtos_wait() 
Receives a semaphore name and waits for the resource associated with the semaphore to become available. The semaphore count is then decremented so the task can claim the resource.

rtos_await() 
Receives an expression as an argument, and the task waits until the expression evaluates to true.

rtos_overrun() 
Receives a task name as an argument, and the function returns true if that task has overrun its allocated time.

rtos_stats()
Returns the specified statistics about a specified task. The statistics can be the minimum and maximum task run times and the total task run time. The task name and the type of statistics are specified as arguments to the function.

التحضير لنظام RTOS :

اعلانات اضافية ( قم بتسجيل الدخول لاخفائها )

الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 08-06-2015, 10:23 PM المشاركة 11   
افتراضي التحضير لنظام RTOS :


التحضير لنظام RTOS :
بالإضافة إلى الدوال السابقة ، يجب أن يتم تحديد التوجيه #use rtos() فى بداية البرنامج قبل استدعاء أى من دوال نظام RTOS . صيغة هذا التوجيه كما يلى :

كود:
#use rtos(timer=n, minor_cycle=m)

حيث بارامتر المؤقت timer يكون بين “0” و “4” ويحدد مؤقت المعالج الذى سوف يستخدم بواسطة نظام RTOS ، والبارامتر minor_cycle هو أطول زمن سوف يتم خلاله تشغيل أى مهمة . العدد المدخل هنا يجب أن يكون متبوعا بأى من التميزات التالية s, ms, us, ns ، كما يلى :

كود:
#use rtos(timer=0,minor_cycle=100ms)
// this tells the compiler that the rtos functionality will be needed, that
// timer0 will be used as the timing device, and that the minor cycle for
// all tasks will be 100 miliseconds
بالإضافة إلى ذلك ، فإن خيار الاحصائيات statistics يمكن أن يتم تحديده بعد الخيار minor_cycle ، وفى هذه الحالة فإن المترجم سوف يحافظ على تتبع مسار الحد الأدنى والحد الأقصى لأزمنة المعالج التى تستخدمها المهمة عند كل استدعاء وعلى الزمن الكلى المستخدم .


إعلان المهمة Declaring a Task :


الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 08-06-2015, 10:26 PM المشاركة 12   
افتراضي إعلان المهمة Declaring a Task :


إعلان المهمة Declaring a Task :
يتم إعلان المهمة تماما مثل إعلان أى وظيفة أخرى ، لكن المهام فى تطبيق متعدد المهام لا يكون لديه أى وسائط arguments ولا تعيد return أى قيم . قبل أن يتم الإعلان عن المهمة ، هناك حاجة لتوجيه قبل المعالج #task لتحيد خيارات المهمة . صيغة هذا التوجيه كما يلى :

كود:
#task(rate=n, max=m, queue=p)
حيث “rate” يحدد كيفية استدعاء المهمة / العدد المحدد يجب أن يكون متبوعا بالتمييز s, ms, us, ns . و “max” يحدد كم كم من وقت المعالج سوف تستخدمه المهمة فى تنفيذ المهمة لمرة واحدة . الزمن المحدد هنا يجب أن يكون مساويا أو أقل من الزمن المحدد بواسطة minor_cycle . و “queue” هو اختيارى ، وإذا وجد فإنه يحدد عدد البايتات التى تكون محجوزة للمهمى لتستقبل الرسائل من المهام الأخرى ، القيمة الافتراضية هى الصفر .
فى المثال التالى ، مهمة تسمى my_ticks تكون كل 20ms ومن المتوقع ألا تستخدم أكثر من 100ms من زمن المعالج . هذه المهمة يتم تحديدها مع عدم وجود الخيار queue :

كود:
#task(rate=20ms, max=100ms)
void my_ticks()
{
...........
...........
}

المشروع الأول : وميض ليدات :


الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 08-06-2015, 10:34 PM المشاركة 13   
افتراضي المشروع الأول : وميض ليدات :


المشروع الأول : وميض ليدات :
فى هذا المشروع البسيط القائم على نظام RTOS ، يتم توصيل أربعة ليدات بالبتات الأدنى للمنفذ PORTB للميكروكونترولر PIC18F452 . يتكون البرنامج من أربعة مهام ، حيث كل مهمة تومض ليد عند معدل مختلف :
• المهمة الأولى تسمى task_B0 ، تومض الليد المتصل بالطرف RB0 بمعدل 250ms .
• المهمة الثانية تسمى task_B1 ، تومض الليد المتصل بالطرف RB1 بمعدل 500ms .
• المهمة الثالثة تسمى task_B2 ، تومض الليد المتصل بالطرف RB2 مرة كل ثانية .
• المهمة الرابعة تسمى task_B3 ، تومض الليد المتصل بالطرف RB3 مرة كل 2 ثانية .
الشكل التالى يبين الدائرة الكهربية للمشروع :



فى هذه الدائرة يتم استخدام كريستال بتردد 4MHz ، وتوصيل الليدات الأربعة خلال مقاومات تحديد التيار إلى الأطراف RB0-RB3 للمنفذ POERB .
البرنامج قائم على المترجم CCS C ، ويسمى RTOA1.C كما هو مبين أدناه :

كود:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SIMPLE RTOS EXAMPLE
// This is a simple RTOS example. 4 LEDs are connected to lower half of
// PORTB of a PIC18F452 microcontroller. The program consists of 4
// tasks:
// Task task_B0 flashes the LED connected to port RB0 every 250ms.
// Task task_B1 flashes the LED connected to port RB1 every 500ms.
// Task task_B2 flashes the LED connected to port RB2 every second
// Task task_B3 flashes the LED connected to port RB3 every 2 seconds.
// The microcontroller is operated from a 4MHz crystal
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <18F452.h>
#use delay (clock=4000000)
// Define which timer to use and minor_cycle for RTOS
#use rtos(timer=0, minor_cycle=10ms)
//////////////////////////////////////////////////////////////
// Declare TASK 1 - called every 250ms 
#task(rate=250ms, max=10ms)
void task_B0()
{
output_toggle(PIN_B0); // Toggle RB0
}
////////////////////////////////////////////////////////
// Declare TASK 2 - called every 500ms
#task(rate=500ms, max=10ms)
void task_B1()
{
output_toggle(PIN_B1); // Toggle RB1
}
//////////////////////////////////////////////////////////////////
// Declare TASK 3 - called every second
//
#task(rate=1s, max=10ms)
void task_B2()
{
output_toggle(PIN_B2); // Toggle RB2
}
///////////////////////////////////////////////////////////////////////
// Declare TASK 4 - called every 2 seconds
//
#task(rate=2s, max=10ms)
void task_B3()
{
output_toggle(PIN_B3); // Toggle RB3
}
/////////////////////////////////////////////////////////////
// Start of MAIN program
//
void main()
{
set_tris_b(0); 		// Configure PORTB as outputs
rtos_run(); 		// Start RTOS
}
////////////////////////////////////////////////////////////////////////////
البرنامج الرئيسى يكون عند نهاية البرنامج ، وداخل البرنامج الرئيسى :
• يتم إعلان أطراف المنفذ PORTB كمخارج ،
• ويتم بدء نظام RTOS عن طريق استدعاء الدالة rtos_run() .

كود:
// Start of MAIN program
//
void main()
{
set_tris_b(0); 		// Configure PORTB as outputs
rtos_run(); 		// Start RTOS
}
////////////////////////////////////////////////////////////////////////////
رأس (مقدمة) البرنامج :
• الملف الذى يحتوى إعلانات نظام RTOS للمترجم CCS C يجب أن يتم تضمينه عند بداية البرنامج .
• التوجيه #use delay يخبر المترجم بأننا نستخدم ساعة بتردد 4MHz .
• بعد ذلك يتم إعلان مؤقت نظام RTOS على أنه المؤقت Timer 0 ، وإعلان زمن minor_cycle بالقيمة 10ms وذلك باستخدام التوجيه #use rtos .


كود:
#include <18F452.h>#use delay (clock=4000000)
// Define which timer to use and minor_cycle for RTOS
#use rtos(timer=0, minor_cycle=10ms)
يتكون البرنامج من أربعة مهام متماثلة :
• المهمة الأولى task_B0 تومض الليد المتصل بالطرف RB0 بمعدل 250ms . وبالتالى فإن الليد تكون ON لفترة 250ms ، ثم تكون OFF لفترة 250ms . عبارة output_toggle ، للمترجم CCS C ، تستخدم لتغيير حالة الليد فى كل مرة يتم فيها استدعاء المهمة . فى المترجم CCS C تستخدم PIN_B0 للإشارة إلى الطرف RB0 .

كود:
//////////////////////////////////////////////////////////////
// Declare TASK 1 - called every 250ms
#task(rate=250ms, max=10ms)
void task_B0()
{
output_toggle(PIN_B0); // Toggle RB0
}
////////////////////////////////////////////////////////
لاحظ وجود التوجيه #task يليه مباشرة دالة المهمة المرتبطة بهذا التوجيه .

• المهمة الثانية task_B1 تومض الليد المتصل بالطرف RB1 بمعدل 500ms بنفس الطريقة السابقة .

كود:
// Declare TASK 2 – called every 500ms
//
#task(rate=500ms, max=10ms)
void task_B1()
{
output_toggle(PIN_B1); // Toggle RB1
}
//////////////////////////////////////////////////////////////////
• المهمة الثالثة task_B2 تومض الليد المتصل بالطرف RB2 كل واحد ثانية بنفس الطريقة .

كود:
// Declare TASK 3 – called every second
//
#task(rate=1s, max=10ms)
void task_B2()
{
output_toggle(PIN_B2); // Toggle RB2
}
///////////////////////////////////////////////////////////////////////
• وأخيرا ، المهمة الرابعة task_B3 تومض الليد المتصل بالطرف RB3 كل 2 ثانية بنفس الطريقة .

كود:
// Declare TASK 4 – called every 2 seconds
//
#task(rate=2s, max=10ms)
void task_B3()
{
output_toggle(PIN_B3); // Toggle RB3
}
/////////////////////////////////////////////////////////////

البرنامج المذكور أعلاه هو برنامج متعدد المهام ، حيث وميض الليدات يكون مستقلا عن بعضه البعض وفى وقت واحد (متزامن) .

النتيجة :






التعديل الأخير تم بواسطة : F.Abdelaziz بتاريخ 08-06-2015 الساعة 10:38 PM

الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 09-06-2015, 01:14 AM المشاركة 14   
افتراضي المشروع الثانى : مولد رقم عشوائى :


المشروع الثانى : مولد رقم عشوائى :
هذا المشروع أكثر تعقيدا قليلا ، وفيه يتم توليد رقم عشوائى بين 0 و 255 . يتم توصيل 8 ليدات بالمنفذ PORTB للميكروكونترولر PUC18F452 . باإضافة إلى توصيل زر ضاغط إلى الطرف RD0 ، وليد بالطرف RD7 .
فى هذا المشروع يتم استخدام 3 مهام :
• المهمة الأولى Live يتم تشغيلها كل 200 ميكروثانية ، وتقوم بعمل وميض لليد المتصل بالطرف RD7 للإشارة إلى أن النظام يعمل .
• المهمة الثانية Generator ، وتقوم بتزايد متغير من 0 إلى 255 بشكل مستمر واختبار حالة الزر الضاغط . عندما يتم الضغط على الزر الضاغط ، يتم إرسال قيمة العد الحالى إلى مهمة العرض Display باستخدام قائمة انتظار الرسائل .
• المهمة الثالثة Display وتقوم بقراءة الرقم من قائمة انتظار الرسائل وإرسال البايت المستقبل إلى الليدات المتصلة بالمنفذ PORTB . وبالتالى ، فإن الليدات تعرض نموذج عشوائى فى كل مرة يتم فيها الضغط على الزر الضاغط .
الشكل التالى يبين المخطط الصندوقى ، يليه الدائرة الكهربية :







البرنامج :


الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 09-06-2015, 01:20 AM المشاركة 15   
افتراضي البرنامج :


البرنامج :

كود:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SIMPLE RTOS EXAMPLE - RANDOM NUMBER GENERATOR
// This is a simple RTOS example. 8 LEDs are connected to PORTB
// of a PIC18F452 microcontroller. Also, a push-button switch is
// connected to port RC0 of PORTC, and an LED is connected to port
// RC7 of the microcontroller. The push-button switch is normally at logic 1.
// The program consists of 3 tasks called "Generator", "Display", and "Live".
// Task "Generator" runs in a loop and increments a counter from 0 to 255.
// This task also checks the state of the push-button switch. When the
// push-button switch is pressed, the task sends the value of the count to the
// "Display" task using messaging passing mechanism. The “Display” task
// receives the value of count and displays it on the PORTB LEDs.
// Task "Live" flashes the LED connected to port RC7 at a rate of 250ms.
// This task is used to indicate that the system is working and is ready for
// the user to press the push-button.
// The microcontroller is operated from a 4MHz crystal
//////////////////////////////////////////////////////////////////////////////////
#include <18F452.h>
#use delay (clock=4000000)
int count;
///////////////////////////////////////////////
// Define which timer to use and minor_cycle for RTOS
#use rtos(timer=0, minor_cycle=1ms)
/////////////////////////////////////////////////////
// Declare TASK "Live" - called every 200ms
// This task flashes the LED on port RC7
#task(rate=200ms, max=1ms)
void Live()
{
output_toggle(PIN_D7);
}
////////////////////////////////////////////////////////
// Declare TASK "Display" - called every 10ms
#task(rate=10ms, max=1ms, queue=1)
void Display()
{
if(rtos_msg_poll() > 0) // Is there a message ?
{
output_b(rtos_msg_read()); // Send to PORTB
}
}
///////////////////////////////////////////////////////////////////
// Declare TASK "Generator" - called every millisecond
#task(rate=1ms, max=1ms)
void Generator()
{
count++; // Increment count
if(input(PIN_D0) == 0) // Switch pressed ?
{
rtos_msg_send(Display,count); // send a message
}
}
//////////////////////////////////////////////////
// Start of MAIN program
//
void main()
{
set_tris_b(0); // Configure PORTB as outputs
set_tris_d(1); // RD0=input, RD7=output
rtos_run(); // Start RTOS
}
////////////////////////////////////////////////////////////
البرنامج الرئيسى :
يأتى فى نهاية البرنامج ، وفيه يتم أعاداد أطراف المنفذ PORTB كمخارج . أيضا إعداد الطرف RD0 كمدخل وباقى أطراف المنفذ PORTD مخارج .

كود:
//////////////////////////////////////////////////
// Start of MAIN program
//
void main()
{
set_tris_b(0); // Configure PORTB as outputs
set_tris_d(1); // RD0=input, RD7=output
rtos_run(); // Start RTOS
}
///////////////////////////////////////////////////////////
رأس (مقدمة) البرنامج :
يتم استخدام المؤقت Timer 0 كمؤقت لنظام RTOS ، ويتم تحديد الزمن minor_cycle بواحد ثانية :

كود:
///////////////////////////////////////////////
// Define which timer to use and minor_cycle for RTOS
#use rtos(timer=0, minor_cycle=1ms)
/////////////////////////////////////////////////////

يتكون البرنامج من 3 مهام :
• المهمة الأولى Live ويتم تشغيلها كل 200 ملى ثانية ، وتقوم بوميض الليد المتصل بالطرف RD0 . هذه الليد تشير إلى أن النظام يعمل :

كود:
/////////////////////////////////////////////////////
// Declare TASK "Live" - called every 200ms
// This task flashes the LED on port RC7
#task(rate=200ms, max=1ms)
void Live()
{
output_toggle(PIN_D7);
}
////////////////////////////////////////////////////////
• المهمة الثانية Generator ويتم تشغيلها كل ملى ثانية وتقوم بتزايد متغير بايت يسمى count بصفة مستمرة . عندما يتم الضغط على الزر الضاغط فإن الطرف RD0 يذهب للحالة المنخفضة . عند حدوث ذلك فإن قيمة العداد الحالية يتم إرسالها إلى المهمة الثالثة Display باستخدام دالة نظام RTOS المسماه rtos_msg_send(display, count) ، حيث display هو اسم المهمة التى يتم إرسال الرسالة إليها ، و count هو البايت المرسل .

كود:
///////////////////////////////////////////////////////////////////
// Declare TASK "Generator" - called every millisecond
#task(rate=1ms, max=1ms)
void Generator()
{
count++; // Increment count
if(input(PIN_D0) == 0) // Switch pressed ?
{
rtos_msg_send(Display,count); // send a message
}
}
//////////////////////////////////////////////////

• المهمة الثالثة Display : ويتم تشغيلها كل 10 ملى ثانية . هذه المهمة تقوم باختبار ما إذا كان هناك رسالة فى قائمة انتظار الرسائل . إذا كان هناك رسالة ، يتم استخراج الرسالة باستخدام دالة نظام RTOS المسماة call rtos_msg_read() ، ويتم أرسال البايت الذى تم قراءته إلى الليدات المتصلة بالمنفذ PORTB :

كود:
////////////////////////////////////////////////////////
// Declare TASK "Display" - called every 10ms
#task(rate=10ms, max=1ms, queue=1)
void Display()
{
if(rtos_msg_poll() > 0) // Is there a message ?
{
output_b(rtos_msg_read()); // Send to PORTB
}
}
///////////////////////////////////////////////////////////////////
وهكذا ، فإن الليدات تعرض القيمة الثنائية للعداد كلما تم الضغط على الزر الضاغط . قائمة انتظار الرسائل يجب التحقق منها بواسطة استخدام الدالة rtos_msg_poll() ، لأن محاولة قراءة قائمة الانتظار بدون وجود أى بايتات فى القائمة قد يجمد البرنامج .
النتيجة :




somood
:: مهندس جيد ::
تاريخ التسجيل: Jan 2011
الدولة: نابلس
المشاركات: 221
نشاط [ somood ]
قوة السمعة:
قديم 09-06-2015, 01:34 PM المشاركة 16   
افتراضي


السلام عليكم
يعطيك العافية مهندس فتح الله

بالنسبة للباراميتر rate إللي بكون بالتوجيه .. بقدر أخليه متغير ولا لازم يكون رقم محدد من البداية



الساعة معتمدة بتوقيت جرينتش +3 الساعة الآن: 04:40 PM
موقع القرية الالكترونية غير مسؤول عن أي اتفاق تجاري أو تعاوني بين الأعضاء
فعلى كل شخص تحمل مسئولية نفسه إتجاه مايقوم به من بيع وشراء وإتفاق وأعطاء معلومات موقعه
التعليقات المنشورة لا تعبر عن رأي موقع القرية الالكترونية ولايتحمل الموقع أي مسؤولية قانونية حيال ذلك (ويتحمل كاتبها مسؤولية النشر)