Avatar

帮同学宣传一下http://shop57644665.taobao.com/

在我的wordpress中,根据饭否提供的api,使用php写了一个读取饭否最新的一条消息。为什么不用饭否的wordpress插件呢?因为我只需要简单的读取,不需要那么复杂的应用。

代码如下

<?php
$url = 'http://api.fanfou.com/statuses/user_timeline.xml?count=1';
$ch = curl_init($url);
curl_setopt($ch,CURLOPT_USERPWD,"ilived.cn@gmail.com:XXXXXX");
ob_start();
curl_exec($ch);
curl_close($ch);
$content = ob_get_contents();
ob_end_clean();
preg_match("#<text>(.*?)</text>#s",$content,$matches);
?>

其中$matches[0]就是最新的消息文本。

例子见右边的About Me

Tagged with: .
Avatar

帮同学宣传一下http://shop57644665.taobao.com/

在Nucleus中timer的创建函数是NU_Create_Timer,其定义是

#define         NU_Create_Timer                 TMS_Create_Timer

通过其参数我们就可以看出如何设置一个timer。

STATUS  TMS_Create_Timer(NU_TIMER *timer_ptr, CHAR *name,
VOID (*expiration_routine)(UNSIGNED), UNSIGNED id,
UNSIGNED initial_time, UNSIGNED reschedule_time, OPTION enable)

timer -> tm_actual_timer.tm_timer_type =    TM_APPL_TIMER;
CSC_Place_On_List(&TMD_Created_Timers_List, &(timer -> tm_created));
TMD_Total_Timers++;

创建一个timer是很容易看懂的,我们主要分析timer时间到了之后的系统流程。

在TI平台中使用一个硬件晶振产生中断来作为系统的定时器,每次中断间隔时间作为操作系统的一个tick,也就是一个时间片。当中断发生时也就是产生了一个irq,在以前的irq流程中分析中我们可以知道每个irq都有一个自己的处理函数。在ti的平台的这个函数中我们可以发现如下代码

TMT_Timer_Interrupt();

这个函数就是Nucleus timer的接口函数,在这个函数中会检查是否有timer的时间到了,如果有timer active需要进行对应的操作,该函数会激活timer的HISR,这个HISR是在Nucleus初始化时TMI_Initialize函数中创建的。

status =  TCCE_Create_HISR((NU_HISR *) &TMD_HISR, "SYSTEM H",
TMC_Timer_HISR, (OPTION) TMD_HISR_Priority,
TMD_HISR_Stack_Ptr, TMD_HISR_Stack_Size);

在这个HISR的处理函数中,使用timer函数创建的timer的最主要的代码是

/* Determine if the task timer has expired.  */
if (TMD_Timer_State == TM_EXPIRED)

/* Resume the timer task.  */
TMC_Timer_Expiration();

在TMC_Timer_Expiration函数中

id =                  app_timer -> tm_expiration_id;
expiration_routine =  app_timer -> tm_expiration_routine;
//app_timer的tm_expiration_id和tm_expiration_routine就是创建函数TMS_Create_Timer传入的参数。
if (!done)
{

/* Determine which type of timer has expired.  */
if (type == TM_APPL_TIMER)
//类型为TM_APPL_TIMER,也就是task调用timer函数创建的类型。
//调用创建传入的timer超时时需要调用的函数。
/* Call application timer's expiration function.  */
(*(expiration_routine)) (id);
else
//这里是Nucleus进行task的时间片处理的部分。
/* Call the task timeout function in the thread control
function.  */
TCC_Task_Timeout((NU_TASK *) pointer);
}

基本上Nucleus的timer主要流程就是这些了。

Avatar

帮同学宣传一下http://shop57644665.taobao.com/

一般我们看到的m0,SHX文件格式都是摩托罗拉文件格式,TI编译系统最后生成的m0文件也就是摩托罗拉文件格式。
其相关资料如下:
The Motorola S-record format is an ASCII encoding for binary data. It is also known as the SREC or S19 format.
An SREC format file consists of a series of ASCII records. All hexadecimal (hex) numbers are Big Endian.
The records have the following structure:

1. Start code, one character, an S.
2. Record type, one digit, 0 to 9, defining the type of the data field.
3. Byte count, two hex digits, indicating the number of bytes (hex digit pairs) that follow in the rest of the record (in the address, data and checksum fields).
4. Address, four, six, or eight hex digits as determined by the record type for the memory location of the first data byte.
5. Data, a sequence of 2n hex digits, for n bytes of the data.
6. Checksum, two hex digits - the one’s complement of the least significant byte sum of the values represented by the two hex digit pairs for the byte count, address and data fields.

There are eight record types, listed below:

Record Description Address Bytes Data Sequence
S0 Block header 2 Yes
S1 Data sequence 2 Yes
S2 Data sequence 3 Yes
S3 Data sequence 4 Yes
S5 Record count 2 No
S7 End of block 4 No
S8 End of block 3 No
S9 End of block 2 No

The S0 record data sequence contains vendor specific data rather than program data. The record count in the S5 record is stored in the 2-byte address field. The address field of the S7, S8, or S9 records may contain a starting address for the program.

S00F000068656C6C6F202020202000003C
S11F00007C0802A6900100049421FFF07C6C1B787C8C23783C6000003863000026

S11F001C4BFFFFE5398000007D83637880010014382100107C0803A64E800020E9
S111003848656C6C6F20776F726C642E0A0042
S5030003F9

S9030000FC

Start code Record type Byte count Address Data Checksum

Tagged with: , .
Avatar

帮同学宣传一下http://shop57644665.taobao.com/

在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函数中的返回值。

Avatar

帮同学宣传一下http://shop57644665.taobao.com/

ARM是标准的RISC(Reduced Instruction Set Computing)即“精简指令集”,它的指令系统相对简单,它只要求硬件执行很有限且最常用的那部分指令,大部分复杂的操作则使用成熟的编译技术,由简单指令合成。
ARM7采用三级流水线结构。ARM9采用五级流水线结构。

ARM有七种处理器模式。
一般我们的程序都是在svc模式下运行的,当中断发生时arm会自动切换到相应的模式中去。
为什么我们的程序是在svc模式下运行呢?
Q: “Why does PLUS run all tasks in Supervisor mode instead of using User Mode for tasks and Supervisor mode for PLUS system calls? ”
A: Portability and ease of use. Without having to worry about User/Supervisor mode, the PLUS function calls can be function calls. Without it, you usually have to map all of the OS function calls into some type of software trap mechanism. This complicates the system and usually adds overhead that is not needed. Also, our PLUS is a Real Time Kernel, not a full blown OS. The distinction is that a Kernel needs to be small and efficient while still providing System Calls that are robust. A Trap mechanism adds code and hurts performance.
However, AT does provide an MMU support package for selected ports that does allow for memory protection of tasks and enables application tasks to run in User Mode while the kernel runs in Supervisor mode.
从以上我们可以知道,操作系统在运行时访问某些特定的资源,比如硬件寄存器等需要arm处在特权模式下,如果我们系统是在User Mode下运行那么就需要通过手动调用swi类似的指令切换到特权模式,而如果我们的系统直接运行在svc模式下就省去了很多不必要的操作。

ARM处理器总共有37个寄存器,各个模式下可以使用的处理器如下。

其中R0-R7是unbanked register,也就是各个模式下都是同一个物理寄存器。
R8-R14是banked register,也就是各个模式都是不同的物理寄存器。一般R13做SP使用,R14为LR。
R15是PC。
ARM有一个在所有处理器模式下都可以访问的CPSR(current program status register)当前运行状态寄存器和一个在异常模式下的SPSR(saved program status register)保存的状态寄存器。我们可以通过调用MSR指令改变CPSR来手动切换处理器模式,也可以通过MRS来读取当前的处理器模式和上次保存的处理器模式。

ARM的异常及其处理
我们以一个中断发生来看ARM会做什么操作。

可见当异常发生时ARM会自动设置当前处理器模式以及自动跳转到相应地址。
各个异常的优先级是
Reset>Data Abort>FIQ>IRQ>Prefetch Abort>Undefined instruction>SWI

ARM的指令集
ARM拥有32位的ARM指令集和16为的thumb指令集。
Thumb代码所需的存储空间约为ARM代码的60%~70% - Thumb代码使用的指令数比ARM代码多约30%~40% - 若使用32位的存储器,ARM代码比Thumb代码快约40% - 若使用16位的存储器,Thumb代码比ARM代码快约40%~50% - 与ARM代码相比较,使用Thumb代码,存储器的功耗会降低约30% 显然,ARM指令集和Thumb指令集各有其优点,若对系统的性能有较高要求,应使用32位的存储系统和ARM指令集,若对系统的成本及功耗有较高要求, 则应使用16位的存储系统和Thumb指令集。
在TI平台和MTK平台中除了bootloader外一般都是使用16位来编译源文件的。

Tagged with: .
Avatar

帮同学宣传一下http://shop57644665.taobao.com/

强烈推荐 片翼の天使 Cosmos Chaos THE MESSANGER

Title in EN :  Dissidia -Final Fantasy- Original Soundtrack
Title in JP :  ディシディア ファイナルファンタジー オリジナル.サウンドトラック

Composed by :  Takeharu Ishimoto (石元丈晴), Tsuyoshi Sekito (関戸剛), Mitsuto Suzuki (鈴木光人), Nobuo Uematsu (植松伸夫), Minoru Tsuchihashi (土橋稔)

101 「DISSIDIA-opening-」from DISSIDIA FINAL FANTASY
102 「プレリュード-menu-」from DISSIDIA FINAL FANTASY
103 「DISSIDIA-menu-」from DISSIDIA FINAL FANTASY
104 「守るべき秩序」from DISSIDIA FINAL FANTASY
105 「Cosmos」from DISSIDIA FINAL FANTASY
106 「胜利ファンファーレ-Cosmos-」from DISSIDIA FINAL FANTASY
107 「メインテーマ-arrange-」from FINAL FANTASY Ⅰ
108 「戦闘シーン-arrange-」from FINAL FANTASY Ⅰ
109 「ダンジョン-arrange-」from FINAL FANTASY Ⅰ
110 「メインテーマ-arrange-」from FINAL FANTASY Ⅱ
111 「戦闘シーン1-arrange-」from FINAL FANTASY Ⅱ
112 「戦闘シーン2-arrange-」from FINAL FANTASY Ⅱ
113 「光の戦士達」from DISSIDIA FINAL FANTASY
114 「悠久の风-arrange-」from FINAL FANTASY Ⅲ
115 「バトル2-arrange-」from FINAL FANTASY Ⅲ
116 「最后の死闘-arrange-」from FINAL FANTASY Ⅲ
117 「临戦」from DISSIDIA FINAL FANTASY
118 「ファイナルファンタジーⅣ メインテーマ-arrange-」from FINAL FANTASY Ⅳ
119 「ゴルベーザ四天王とのバトル-arrange-」from FINAL FANTASY Ⅳ
120 「バトル2-arrange-」from FINAL FANTASY Ⅳ
121 「胜利ファンファーレ-Chaos-」from DISSIDIA FINAL FANTASY
122 「4つの心-arrange-」from FINAL FANTASY Ⅴ
123 「ビッグブリッヂの死闘-arrange-」from FINAL FANTASY Ⅴ
124 「バトル1-arrange-」from FINAL FANTASY Ⅴ
125 「思惑の果て」from DISSIDIA FINAL FANTASY
126 「ティナのテーマ-arrange-」from FINAL FANTASY Ⅵ
127 「决戦-arrange-」from FINAL FANTASY Ⅵ
128 「死闘-arrange-」from FINAL FANTASY Ⅵ
129 「胎动」from DISSIDIA FINAL FANTASY
130 「进军」from DISSIDIA FINAL FANTASY

201 「F.F.7 メインテーマ-arrange-」from FINAL FANTASY Ⅶ
202 「片翼の天使-orchestra version-」from FINAL FANTASY Ⅶ
203 「更に闘う者达-arrange-」from FINAL FANTASY Ⅶ
204 「一时の安息」from DISSIDIA FINAL FANTASY
205 「Blue Fields-arrange-」from FINAL FANTASY Ⅷ
206 「Don’t be Afraid-arrange-」from FINAL FANTASY Ⅷ
207 「The Extreme-original-」from FINAL FANTASY Ⅷ
208 「敗北ファンファーレ」from DISSIDIA FINAL FANTASY
209 「あの丘を越えて-arrange-」from FINAL FANTASY Ⅸ
210 「Battle1-arrange-」from FINAL FANTASY Ⅸ
211 「Battle2-original-」from FINAL FANTASY Ⅸ
212 「マンボ de チョコボ-original-」from FINAL FANTASY Ⅴ
213 「萌动-arrange-」from FINAL FANTASY Ⅹ
214 「Otherworld-original-」from FINAL FANTASY Ⅹ
215 「ノーマルバトル-original-」from FINAL FANTASY Ⅹ
216 「勝利のファンファーレ-original-」from FINAL FANTASY Ⅴ
217 「The federation of Windurst-original-」from FINAL FANTASY XI
218 「Battle in the Dungeon #2-original-」from FINAL FANTASY XI
219 「帝国のテーマ-original-」from FINAL FANTASY XⅡ
220 「Boss Battle-original-」from FINAL FANTASY XⅡ
221 「Answer」from DISSIDIA FINAL FANTASY
222 「Chaos-Last Battle 1-」from DISSIDIA FINAL FANTASY
223 「FINAL FANTASY」from DISSIDIA FINAL FANTASY
224 「DISSIDIA-ending-」from DISSIDIA FINAL FANTASY
225  THE MESSANGER

最终幻想 纷争 OST APE格式

http://zt.tgbus.com/dff/download/2008/12/19/1505014011.shtml

Tagged with: , .
Avatar

帮同学宣传一下http://shop57644665.taobao.com/

Nucleus Task的中断与恢复

以下是以TI的源代码进行的分析
一般来说最有可能中断Task的就是irq中断了。在ARM下到有中断发生时,ARM会自动切换到IRQ模式,此时ARM的寄存器已经是IRQ模式下的寄存器了。

INT_IRQ
STMDB   sp!,{r0-r5}                 ; Save a1-a4 on temporary IRQ stack
MRS     a1,spsr                     ; check for the IRQ bug:
TST     a1,#080h                    ; if the I - flag is set,
BNE     IRQBUG                      ; then postpone execution of this IRQ
SUB     r4,lr,#4                    ; Save IRQ's lr (return address)
注意r4的内容lr-4(被中断的PC,-4是因为ARM放入的是下一条指令+4)
BL      _TCT_Interrupt_Context_Save ; Call context save routine
BL      _IQ_IRQ_isr             ; Call  int. service routine
B       _TCT_Interrupt_Context_Restore

;BUG correction 2nd part  ------------------
IRQBUG: LDMFD  sp!,{r0-r5}                  ; return from interrup. Fix for locosto reset problem. We have pushed 6 regs and popping 4.
SUBS   pc,r14,#4
;BUG correction 2nd part end  --------------

以上就是一个irq的完整的处理过程了,我们慢慢来分析。 Read the rest of this post »

Avatar

帮同学宣传一下http://shop57644665.taobao.com/

Task的创建与调度

Nucleus的系统入口函数是

VOID  INC_Initialize(VOID  *first_available_memory)
{

。。。。。。。。
/* Invoke the application-supplied initialization function.  */
Application_Initialize(first_available_memory);

/* Indicate that initialization is finished.  */
INC_Initialize_State =  INC_END_INITIALIZE;

/* Start scheduling threads of execution.  */
TCT_Schedule();
}

Application_Initialize(first_available_memory);这个函数是留给平台用来初始化系统框架和创建task用的。
Task的创建一般如下

if ( NU_Create_Task (&TaskTable[Handle].TaskCB.TCB, Name, os_TaskEntry,
Handle, (VOID *)NULL,
(void*)(TaskTable[Handle].Stack+1), (ULONG) StackSize, (UCHAR) Priority,
#ifndef _TARGET_
10,
#else
0,
#endif
NU_PREEMPT, NU_NO_START) != NU_SUCCESS )
#define         NU_Resume_Task                  TCCE_Create_Task

最关键的实现是 Read the rest of this post »

Page 1 of 212»