Search for posts tagged with: 心得

Avatar

最终目的是实现一个类似可运行程序的框架的东西。
难点:如何生成这个可运行的程序数据。1.函数的跳转使用一个固定的地址中的函数指针实现。2.将程序数据解析成一行行的执行代码。
同时应该同应用程序的编译平台的实现有着直接的联系。
现在看起来第二种方式的实现应该还是简单点,同时可以做到不同平台的开发。当一个应用调试完成后,可以使用特殊的处理将源文件生成一个数组,然后在不同的另一个平台上只需要对该数组进行一次解析,将对应的数据转化为对应的具体平台的函数调用就可以实现同开发平台上同样的运行效果了。

对于第一种实现方式,主要的难点是需要对所有可能调用的api都要进行地址固定。这个可以通过一个全局的函数指针数组来实现跳转,开发时必须使用函数指针进行。在进行平台移植时,这个函数指针数组必须指定一个绝对的地址,同时这个地址与开发的应用程序或动态加载系统实现的对应的lib中的地址必须要一致,否则函数会跳转到错误的地址上。
分析下来看来都是可以实现的,个人觉得第二种方式可能会简单一点。

Tagged with: .
Avatar

在Nucleus的等待事件函数EVC_Retrieve_Events中有这么一段函数

if (suspend)
{

/* Suspension is selected.  */

/* Increment the number of tasks waiting.  */
event_group -> ev_tasks_waiting++;

/* Setup the suspend block and suspend the calling task.  */
suspend_ptr =  &suspend_block;
suspend_ptr -> ev_event_group =              event_group;
suspend_ptr -> ev_suspend_link.cs_next =     NU_NULL;
suspend_ptr -> ev_suspend_link.cs_previous = NU_NULL;
task =                            (TC_TCB *) TCT_Current_Thread();
suspend_ptr -> ev_suspended_task =           task;
suspend_ptr -> ev_requested_events =         requested_events;
suspend_ptr -> ev_operation =                operation;

/* Link the suspend block into the list of suspended tasks on this
event group.  */
CSC_Place_On_List((CS_NODE **)
&(event_group -> ev_suspension_list),
&(suspend_ptr -> ev_suspend_link));

/* Finally, suspend the calling task. Note that the suspension call
automatically clears the protection on the event group.  */
TCC_Suspend_Task((NU_TASK *) task, NU_EVENT_SUSPEND,
EVC_Cleanup, suspend_ptr, suspend);

/* Pickup the return status and the actual retrieved events.  */
status =             suspend_ptr -> ev_return_status;
*retrieved_events =  suspend_ptr -> ev_actual_events;

}
else
..........

我们看到当task因为该事件而阻塞的代码

/* Finally, suspend the calling task. Note that the suspension call
automatically clears the protection on the event group.  */
TCC_Suspend_Task((NU_TASK *) task, NU_EVENT_SUSPEND,
EVC_Cleanup, suspend_ptr, suspend);

执行后紧接着的就是将等待事件的状态和接受到消息的变量进行了赋值,这是为什么呢,这样正确吗?
原来是这样的。当TCC_Suspend_Task被调用后当前task被挂起,这个函数以后的代码已经不会再接着执行了。等到这个task恢复时说明这个事件已经等到了,这个事件的值是在EVC_Set_Events函数中被设置的。

if (compare)
{

/* Decrement the number of tasks waiting counter.  */
event_group -> ev_tasks_waiting--;

/* Determine if consumption is requested.  */
if (suspend_ptr -> ev_operation & EV_CONSUME)

/* Keep track of the event flags to consume.  */
consume =  consume | suspend_ptr -> ev_requested_events;

/* Remove the first suspended block from the list.  */
CSC_Remove_From_List((CS_NODE **)
&(event_group -> ev_suspension_list),
&(suspend_ptr -> ev_suspend_link));

/* Setup the appropriate return value.  */
suspend_ptr -> ev_return_status =  NU_SUCCESS;
suspend_ptr -> ev_actual_events =
event_group -> ev_current_events;

/* Resume the suspended task.  */
preempt = preempt |
TCC_Resume_Task((NU_TASK *) suspend_ptr -> ev_suspended_task,
NU_EVENT_SUSPEND);

}

可以看到设置的返回值就是EVC_Retrieve_Events函数中的返回值。