标签:c style class blog code java
本文以windows实时拓展Kithara RTS安装目录下的smp文件夹内的TaskSimple项目为例,解读Kithara RTS的实时多任务编程方法。
该项目只有一个工程TaskSimple,工程内的TaskSimple.cpp文件实现了主要功能,使用了Kithara RTS的kernel模块和Task模块
TaskSimple.cpp文件主要由5部分组成,共享内存结构体,三个任务回调函数,一个主函数runSample
共享内存结构体:
//------ CallBackData ------ struct CallBackData { Handle hTaskA_; Handle hTaskB_; Handle hTaskC_; Handle hPipe_; };
CallBackData内部有3个任务句柄和一个用于数据交互的hPipe_对象。
///////////////////////////////////////////////////////////////////////////
runSample函数的主要功能代码:
ksError = KS_openDriver(//打开驱动,这是使用Kithara RTS的第一步 pCustomerNumber); // Customer number if (ksError) { outputErr(ksError, "KS_openDriver", "Maybe incorrect customer number?"); return; } //------------------------------------------------------------------------------------------------------------ // Allocation of Sharedmem //------------------------------------------------------------------------------------------------------------ CallBackData* pAppPtr; CallBackData* pSysPtr; ksError = KS_createSharedMem(//创建共享内存 (void**)&pAppPtr, // App Pointer,应用层指针,只能在应用层中使用 (void**)&pSysPtr, // Sys Pointer,内核层指针,只能在内核层中使用 NULL, // Name,名称 sizeof(CallBackData), // Size,共享内存空间大小 0); // Flags,标志位,这里设置为0即可 //注意如果内核层使用了pAppPtr或者应用层使用了pSysPtr会造成系统崩溃 if (ksError != KS_OK) { outputErr(ksError, "KS_createSharedMem", "Failed to allocate shared memory"); KS_closeDriver(); return; } //------------------------------------------------------------------------------------------------------------ // For data transfer we use a pipe. //------------------------------------------------------------------------------------------------------------ ksError = KS_createPipe(//创建数据管道,用于任务之间的数据交互 &pAppPtr->hPipe_, // Pipe Handle ,句柄,在共享内存中 "MyTaskSimplePipe", // Name,名称 sizeof(char), // Item size, here size of pointer,单位大小 9, // Item count,管道长度 NULL, // Object to signal,触发对象,没有使用设置为null(空) 0); // Flags,标志位设置为0 if (ksError != KS_OK) { outputErr(ksError, "KS_createPipe", "Unable to create pipe!"); KS_closeDriver(); return; } //------------------------------------------------------------------------------------------------------------ // Now we create the callbacks. The callback contains the KSF_DIRECT_EXEC: - execution on kernel level //------------------------------------------------------------------------------------------------------------ //下面将3个函数体映射为3个回调函数, Handle hCallbackA; ksError = KS_createCallBack(//创建回调函数 &hCallbackA, // Address of callback handle,回调函数句柄 _callBackA, // Callback function,回调函数本体 pSysPtr, // Reference parameter to the callback,回调函数的参数 KSF_DIRECT_EXEC, // Flags,直接执行 0); // Priority (only on user level) if (ksError != KS_OK) { outputErr(ksError, "KS_createCallBack", "Failed to create callback"); KS_closeDriver(); return; } //参数pSysPtr对应回调函数的pArgs,由于回调函数运行在内核层因此其实用的参数也必须位于内核层 //pSysPtr是内核层参数,pAppPtr是用户层参数 Handle hCallbackB; ksError = KS_createCallBack( &hCallbackB, // Address of callback handle _callBackB, // Callback function pSysPtr, // Reference parameter to the callback KSF_DIRECT_EXEC, // Flags 0); // Priority (only on user level) if (ksError != KS_OK) { outputErr(ksError, "KS_createCallBack", "Failed to create callback"); KS_closeDriver(); return; } Handle hCallbackC; ksError = KS_createCallBack( &hCallbackC, // Address of callback handle _callBackC, // Callback function pSysPtr, // Reference parameter to the callback KSF_DIRECT_EXEC, // Flags 0); // Priority (only on user level) if (ksError != KS_OK) { outputErr(ksError, "KS_createCallBack", "Failed to create callback"); KS_closeDriver(); return; } //------------------------------------------------------------------------------------------------------------ // Create the tasks // Task B and Task C are created with KSF_DONT_START, so they are suspended. // Task A executes immediately after creation. //------------------------------------------------------------------------------------------------------------ outputTxt(" "); outputTxt("Creating tasks."); //创建任务 ksError = KS_createTask( &pAppPtr->hTaskB_, // Address of task handle,任务句柄 hCallbackB, // Callback handle,回调函数 250, // Priority,优先级 KSF_DONT_START); // Flags, don‘t start now,标志位,不立即启动 //任务句柄存入共享内存结构体中,任务执行的本质是执行hCallbackB回调函数 //优先级为250(数值越大优先级越高) //以下两个任务的创建过程与本例相似,但是优先级不同 if (ksError != KS_OK) { outputErr(ksError, "KS_createTask", "Failed to create task"); KS_closeDriver(); return; } ksError = KS_createTask( &pAppPtr->hTaskC_, // Address of task handle hCallbackC, // Callback handle 150, // Priority KSF_DONT_START); // Flags, don‘t start now if (ksError != KS_OK) { outputErr(ksError, "KS_createTask", "Failed to create task"); KS_closeDriver(); return; } ksError = KS_createTask( &pAppPtr->hTaskA_, // Address of task handle hCallbackA, // Callback handle 200, // Priority 0); // Flags, start immediately立即启动 if (ksError != KS_OK) { outputErr(ksError, "KS_createTask", "Failed to create task"); KS_closeDriver(); return; } waitTime(1000 * ms);//延时1s,等待3个任务都执行完毕 outputTxt(" "); outputTxt("The tasks completed their work."); char pBuf[10]; int length; KS_getPipe(//读取pipe数据到pBuf中 pAppPtr->hPipe_, // Pipe handle pBuf, // Pointer to buffer 9, // Buffer size &length, // Pointer to int to write gotten length 0); // Flags pBuf[length] = 0; outputTxt("Expected output : ABBBCBBAC"); outputTxt("Actual output : ", false); outputTxt(pBuf);//打印pBuf中的字符串 outputTxt(" ");
//三个回调函数
首先TaskA运行,TaskA激活TaskB,由于TaskB优先级比TaskA高,因此TaskB运行
然后TaskB挂起TaskA,激活TaskC,然后挂起自身,此时只有低优先级的TaskC可以执行
然后TaskC激活TaskB,TaskB优先级比TaskC高,此时TaskB执行,然后激活TaskA,但是TaskA优先级比TaskB低因此不会被立即执行
TaskB执行完毕之后,由于TaskA优先级比TaskC高,此时TaskA执行
TaskA执行完毕之后,TaskC执行,最后三个任务都执行完成。
等待1s后,打印输出任务执行过程中向pipe写入的数据“ABBBCBBAC”
//------ _callBackA ------ static Error __stdcall _callBackA(void* pArgs, void* pContext) { CallBackData* pData = (CallBackData*)pArgs; const char chr = ‘A‘; KS_putPipe(//向pipe中写入‘A‘ pData->hPipe_, // Pipe handle &chr, // Address of packet 1, // One item NULL, // Number of bytes transmitted 0); // Flags, here none KS_triggerTask(//激活任务b,由于b优先级比a高,调到b中执行 pData->hTaskB_); // Task handle KS_putPipe(pData->hPipe_, &chr, 1, NULL, 0);//写入‘a’ KS_exitTask(//退出当前任务,此时a,b都执行完毕,则调到c中执行 NULL, // Task handle, null for current task 0); // Exit code return KS_OK; } //------ _callBackB ------ static Error __stdcall _callBackB(void* pArgs, void* pContext) { CallBackData* pData = (CallBackData*)pArgs; const char chr = ‘B‘; KS_putPipe(pData->hPipe_, &chr, 1, NULL, 0);//向pipe中写入‘B’ KS_triggerTask(//激活c,但是c优先级低,不能被执行 pData->hTaskC_); // Task handle KS_putPipe(pData->hPipe_, &chr, 1, NULL, 0);//继续写入‘b’ KS_suspendTask(//将任务A挂起 pData->hTaskA_); // Task handle KS_putPipe(pData->hPipe_, &chr, 1, NULL, 0);//继续写入‘b’ KS_suspendTask(//把自身挂起,即把b挂起,此时A也挂起,因此调到c中执行 NULL); // Task handle, null for current task KS_putPipe(pData->hPipe_, &chr, 1, NULL, 0);//写入‘b’ KS_resumeTask(//恢复a pData->hTaskA_); // Task handle KS_putPipe(pData->hPipe_, &chr, 1, NULL, 0);//写入‘b‘ return KS_OK;//此时TaskB执行完毕,而a和c都处于就绪状态,而a优先级高于c,因此调到a中执行 } //------ _callBackC ------ static Error __stdcall _callBackC(void* pArgs, void* pContext) { CallBackData* pData = (CallBackData*)pArgs; const char chr = ‘C‘; KS_putPipe(pData->hPipe_, &chr, 1, NULL, 0);//向pipe中写入‘c’ KS_resumeTask(//激活TaskB,由于TaskB优先级比TaskC优先级高,调到TaskB中执行 pData->hTaskB_); // Task handle KS_putPipe(pData->hPipe_, &chr, 1, NULL, 0);//写入‘c’ KS_exitTask(//退出任务,至此3个任务都执行完毕 NULL, // Task handle, null for current task 0); // Exit code return KS_OK; }
多任务编程----Kithara RTS工程源码解析,布布扣,bubuko.com
标签:c style class blog code java
原文地址:http://www.cnblogs.com/sunvhao/p/3770613.html