Merhaba arkadaşlar. Şu an kullandığım RTOS sistemi üzerine incelemeler yapacağım.
NOT: Öğrenmek amacı ile yapıyorum katkılarınızı bekliyorum.
Sistemi incelerken ana main fn- olması gerektiğini düşündüm aradım buldum ve sistem çalışırken main fn-umuz şu şekilde çalışmaya başlıyor.
Öncelikle projemizin üstten görünümüne bakalım.
(http://s15.postimg.cc/kdrk3b71n/Ads_z.png)
xMain içeriğine girerek ana main fn-umuza bakarsak..
//#define, #ifdef kısımlarını koymadım kalabalık yapmasın.
int main( void )
{
// Turn off interrupts
osal_int_disable( INTS_ALL );
// Initialization for board related stuff such as LEDs
HAL_BOARD_INIT();
// Make sure supply voltage is high enough to run
xmain_vdd_check();
// Initialize board I/O
InitBoard( OB_COLD );
// Initialze HAL drivers
HalDriverInit();
// Initialize NV System
osal_nv_init( NULL );
// Initialize the MAC
xMacInit();
// Initialize the operating system
osal_init_system();
// Allow interrupts
osal_int_enable( INTS_ALL );
// Final board initialization
InitBoard( OB_READY );
// Display information about this device
xmain_dev_info();
/* Display the device info on the LCD */
#ifdef LCD_SUPPORTED
xmain_lcd_init();
#endif
#ifdef WDT_IN_PM1
/* If WDT is used, this is a good place to enable it. */
WatchDogEnable( WDTIMX );
#endif
osal_start_system(); // No Return from here
return 0; // Shouldn't get here.
}
Sistem tüm kurulum ayarları vs.. yaptıktan sonra osal_start_system() fn-u içerisine girmekte. Bu fonksiyona bakarsak;
void osal_start_system( void )
{
#if !defined ( ZBIT ) && !defined ( UBIT )
for(;;) // Forever Loop
#endif
{
osal_run_system();
}
}
Bildiğimiz sonsuz döngü ....
(oldukça basit rtos kodları inceledim, göz gezdirdim ama nedense hepsi sonsuz döngü için for( ; ; ) kullanmış. İnsanları while(1) kullanmaktan alıkoyan şeyi merak etmekteyim.)
Bu fn-umuzun nasil çalıştigini inceleyelim...
void osal_run_system( void )
{
uint8 idx = 0;
osalTimeUpdate();
Hal_ProcessPoll();
do {
if (tasksEvents[idx]) // Task is highest priority that is ready.
{
break;
}
} while (++idx < tasksCnt);
if (idx < tasksCnt)
{
uint16 events;
halIntState_t intState;
HAL_ENTER_CRITICAL_SECTION(intState);
events = tasksEvents[idx];
tasksEvents[idx] = 0; // Clear the Events for this task.
HAL_EXIT_CRITICAL_SECTION(intState);
activeTaskID = idx;
events = (tasksArr[idx])( idx, events );
activeTaskID = TASK_NO_TASK;
HAL_ENTER_CRITICAL_SECTION(intState);
tasksEvents[idx] |= events; // Add back unprocessed events to the current task.
HAL_EXIT_CRITICAL_SECTION(intState);
}
#if defined( POWER_SAVING )
else // Complete pass through all task events with no activity?
{
osal_pwrmgr_powerconserve(); // Put the processor/system into sleep
}
#endif
/* Yield in case cooperative scheduling is being used. */
#if defined (configUSE_PREEMPTION) && (configUSE_PREEMPTION == 0)
{
osal_task_yield();
}
#endif
}
Şimdi burada task, event vb. RTOS kavramları işin içine giriyor ve kopuyorum. Yazılan bir fn-un bu tasklardan birisine girmesi için OSAL_xXx.c fn-una ek yapıyoruz. Nasıl dersek..
#include "MyApp.h" //yazdıgimiz uygulama MyApp.c ve .h iceriyor yanlizca
/*********************************************************************
* GLOBAL VARIABLES
*/
// The order in this table must be identical to the task initialization calls below in osalInitTask.
const pTaskEventHandlerFn tasksArr[] = {
macEventLoop,
nwk_event_loop,
Hal_ProcessEvent,
#if defined( MT_TASK )
MT_ProcessEvent,
#endif
APS_event_loop,
xDApp_event_loop,
MyApp_ProcessEvent
};
const uint8 tasksCnt = sizeof( tasksArr ) / sizeof( tasksArr[0] );
uint16 *tasksEvents;
/*********************************************************************
* FUNCTIONS
*********************************************************************/
/*********************************************************************
* @fn osalInitTasks
*
* @brief This function invokes the initialization function for each task.
*
* @param void
*
* @return none
*/
void osalInitTasks( void )
{
uint8 taskID = 0;
tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);
osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));
macTaskInit( taskID++ );
nwk_init( taskID++ );
Hal_Init( taskID++ );
#if defined( MT_TASK )
MT_TaskInit( taskID++ );
#endif
APS_Init( taskID++ );
xDApp_Init( taskID++ );
MyApp_Init( taskID );
}
/*********************************************************************
*********************************************************************/
Anladığım kadarı ile yazdığım uygulama için bir task açtım ve taskID verdim. MyApp.c fn-umun içerisinde ise
uint16 MyApp_ProcessEvent( uint8 task_id, uint16 events )
{
(void)task_id; // Intentionally unreferenced parameter
if ( events & SYS_EVENT_MSG )
{
msgStrSomething= (struct_something_t *)osal_msg_receive( Widget_TaskID );
while ( msgStrSomething )
{
//
// Do someting...
//
// Release the memory
osal_msg_deallocate( (uint8 *)MSGpkt );
// Next
msgStrSomething= (struct_something_t *)osal_msg_receive( Widget_TaskID );
}
// return unprocessed events
return (events ^ SYS_EVENT_MSG);
}
// Send a message out - This event is generated by a timer
// (setup in MyApp_Init()).
if ( events & MYAPP_SEND_MSG_EVT )
{
// Send "the" message
MyApp_SendTheMessage();
// Setup to send message again
osal_start_timerEx( MyApp_TaskID,
MYAPP_SEND_MSG_EVT,
MYAPP_SEND_MSG_TIMEOUT );
// return unprocessed events
return (events ^ MYAPP_SEND_MSG_EVT);
}
// Discard unknown events
return 0;
}
yapı bu şekilde. Buradan sistemin çalışması bakımından kısaca bahsetmek isteyen var mı? Aslında bir uygulama için son girdiğim uint16 MyApp_ProcessEvent( uint8 task_id, uint16 events ) fn-u içerisine istediğimi yazarak RTOS'a çok bulaşmadan birşeyler yapabiliyorsunuz...
Ben bulaşmak istiyorum.. Birşeyler öğrendikçe eklerim artık
Bunu bende düşündüm de mimari 8051.... freeRTOS ve TinyOS seçeneklerim var şimdilik, kullanmış oldugum protokollere uygun stack yapıları da var. Öncelikle bu basit osal'den başlayıp biraz deneyim kazanmak istedim, konuya hakim olmadığımdan klasik rtos sistemin hangi özelliklerini desteklediğini yada desteklemediğini bilmiyorum.
Birde yapılan iş her bir chip için belli protokolde çalışmak. Bir kaç kitap karıştırıyorum öğrenmek için. Hocam yeni olduğum için bunu rtos zannettim...
Keil'in 8051 için RTX RTOS'u mevcut onu deneyebilirsiniz.