1. 程式人生 > >Keil RL-ARM學習筆記

Keil RL-ARM學習筆記

RL-ARM是Keil MDK自帶的Real-Time Library,其中包括RTX 核心(Real-Time eXecutive,實時作業系統)、RL-FlashFS(檔案系統)、RL-TCPnet(TCP/IP協議棧)、RL-CAN(CAN匯流排函式庫)和RL-USB(USB匯流排函式庫)。不過目前好像用的人不多。

1. (2011.12.26 11:17) 移植注意事項
    除了按幫助文件說的去做之外,還有以下幾點要注意(以STR912FAW4x為例):
    (1)需要使能VIC和TIM0的時鐘,並且要對硬體進行初始化:
 TIM_DeInit(TIM0);
 VIC_DeInit();
    (2)需要使用μVision4自帶的STR91x.s,目前我用的是μVision V4.23.00.0。STR91x.s的目錄在Keil\ARM\Startup\ST。
        由於使用了原來舊的STR91x.s檔案,原來關於內部Flash線上燒寫的程式碼暫時沒有包含進去,不知道以後會不會有問題。
    (3)需要將STR91x.s的“Setup Library Exception Handlers”選項禁止,即:
 LEH_SETUP       EQU     0

2. (2011.12.27 8:53) 昨天在RTX上跑MicriumLogo例子時,在畫線的時候宕機了。後來原因找到,後來在RTX_Conf_STR91x.c中把任務的棧加大就解決了。看來是任務棧溢位造成的。以後有空再優化。

3. (2011.12.17 9:07) 今天執行MicriumLogo時發現,如果任務後面不加while(1)或者os_tsk_delete_self()的話,就宕機了。原因待查。

4. isr中斷使用問題。是否應該加__irq?中斷巢狀或者重入(也是一種巢狀)會不會導致問題?這裡http://www.keil.com/forum/11760/有人提出類似疑問,但不是針對RTX的。

5. (2011.12.29 18:36) 發現STR912使用IRQ中斷的話,中斷函式需要加__irq,如果不加的話,核心會掛掉。

6. 《RL-ARM User's Guide》- FIFO Queue Buffer: 需要的快取大小,取決於所有IRQ中斷函式中呼叫isr_函式的總數。按照手冊的說法,似乎每個isr_函式佔用4 entries。而對於不呼叫isr_的中斷函式,不佔用該快取。

7. 今天看到這個帖子http://www.realview.com.cn/support/kb.asp?ID=2416說RTX166在任務切換時可能會將任務棧重新分配(也就是說棧的儲存地址會變!),於是不推薦對棧進行指標操作。不過後來又說RTX166 Full解決了這個問題。看帖子的時間是2005年,這麼久的事情,現在應該沒有這個問題了吧。而且我用的是RL-ARM裡面的RTX,應該沒有這個問題,否則這個核心就太不完善了。還沒有時間去試一下,不過以後要注意。

8. (2012.01.02 02:43) STDIO重定位完成,原封不動的使用\Keil\ARM\Startup\中的retarget.c,然後實現了sendchar和getkey這兩個函式:

int sendchar(int ch) {
    while (UART_GetFlagStatus(UART0, UART_FLAG_TxFIFOFull) == SET);
    UART_SendData(UART0, (u8)ch);
    return ch;
}
int getkey(void) {
    while (UART_GetFlagStatus(UART0, UART_FLAG_RxFIFOEmpty) == SET);
    return (UART_ReceiveData(UART0));
}

9. RL-ARM的手冊說,RL-FlashFS不能與MicroLIB同時使用。

10. (2012.01.04 13:01) 昨天調RL-FlashFS的時候,發現將FS_ARM_L.lib新增到專案後,printf就打印不出來了。找原因找了半天,最後看到這個帖子http://blog.csdn.net/xunpo/article/details/6996668說要在啟動檔案中將heap size改大,修改後果然好了。今天又看了看《Building Applications with RL-ARM - Getting Started》(http://download.csdn.net/detail/zoogar/3983085),其中說到了這一點:

Chapter 3. RL-Flash Introduction - Setting-Up the File System

The file system buffers data in dynamically allocated memory, so we must reserve heap space in the startup code.

11. 今天把RL-FlashFS實現了,可是對比Keil例程中的Retarget.c檔案,比如C:\Keil\ARM\Boards\Atmel\SAM3U-EK\RL\FlashFS\NAND_File\Retarget.c,為什麼沒有定義STDIO巨集?因為我試過如果直接拷貝,不加定義的話,printf是不會列印的。雖然這個疑問不影響我的使用,但是我還是想搞明白。又找了半天,終於發現原來在專案檔案裡面指定的:

12. (2012.01.06 09:08) 今天調RL-TCPnet的時候,發現採用\Keil\ARM\Startup\ST下的STR91x.s後,裸奔的中斷就進不去了。難道這個檔案是專門給RTX用的?

13. (2012.01.10 21:18) os_dly_wait和os_itv_wait的區別:os_dly_wait與通常用的delay的概念是一樣的,即從os_dly_wait函式呼叫時刻起等待一段指定的時間;而os_itv_wait的等待時間不是從os_itv_wait算起,而是指定的時間間隔。也就是說,如果os_itv_set設定的間隔為100ms,而os_itv_wait之前耗時80ms,那麼os_itv_wait呼叫之後等待20ms繼續執行。那麼最開始計時的時間點是哪個?手冊上沒有提到,應該是os_itv_set呼叫之後吧。

14. RL-ARM Getting Started任務同步的例子,以後可能有用:

os_sem Arrived1, Arrived2;
__task void task1 (void) {
  os_sem_init (Arrived1, 0);
  os_sem_init (Arrived2, 0);
  while (1) {
    FuncA1 ();
    os_sem_send (Arrived1);
    os_sem_wait (Arrived2, 0xFFFF);
    FuncA2 ();
  }
}
__task void task2 (void) {
  while (1) {
    FuncB1 ();
    os_sem_send (Arrived2);
    os_sem_wait (Arrived1, 0xFFFF);
    FuncB2 ();
  }
}

15. (2012.02.04 17:08) 使用RTX的互斥量出現問題。

Round-Robin模式開啟。
在高優先順序任務中定時寫快取:

os_itv_set(2);
while (1)
{
  os_itv_wait();
  os_mut_wait(mutex, 0xFFFF);
  write_buf(data, count);
  os_mut_release(mutex);
}


在低優先順序任務中不斷讀快取:

while (1)
{
  os_mut_wait(mutex, 0xFFFF);
  read_buf(data, count);
  os_mut_release(mutex);
}


資料讀取掛死了。
後來在讀快取中加延時就好了:

while (1)
{
  os_mut_wait(mutex, 0xFFFF);
  read_buf(data, count);
  os_mut_release(mutex);
  os_dly_wait(5);
}


雖然我的讀快取這樣寫不太妥當(應該加上事件通知),但是我還是對於讀取掛死感到疑惑。似乎是因為讀快取的任務不斷鎖住mutex,導致寫快取任務沒什麼機會獲得mutex。似乎還與Priority Inversion有關。試了一下用訊號量來實現,加延時和不加延時的結果與互斥量是一樣的。

16. (2012.02.09 16:15) STM32+RTX中斷配置的問題

因為中斷服務函式用到了isr_evt_set,因此在os_sys_init之前使能中斷是不合適的。而os_sys_init之後STM32運行於非特權模式(預設和推薦的方式),不能直接配置中斷。於是我按照RL-ARM手冊的SVC Functions小節寫了中斷配置函式,執行OK。可是我發現如果在中斷配置函式之前延時一段時間,系統就異常了:

os_tsk_create(task1, 1);
os_dly_wait(5000);                   //延時5秒
os_tsk_create(task_intr_rx, 201);    //中斷處理任務
os_dly_wait(5000);                   //延時5秒
svc_enable_intr();


如果不延時的話,什麼問題都沒有。

17. (2012.02.15 13:20) 今天上午打算在STM32+RTX平臺實現中斷方式的DMA,但是發現中斷無論如何都進不去。後來試了一下裸奔,正常。猛然想起RTX的啟動檔案與裸奔的不一樣,一檢視,明白了:由於版本不一樣,DMA的中斷服務程式在STM32F10x.s檔案裡是DMAChannel4_IRQHandler,而STM32F10x_it.c檔案裡卻是DMA1_Channel4_IRQHandler。可恨的是,編譯居然不出錯。將STM32F10x_it.c檔案裡的中斷服務程式名修改後,問題解決。

18. (2012.03.01 14:39) 昨天發現RTX+STM32使用中斷時出現數據異常。由於看了文件http://download.csdn.net/detail/zoogar/3983072第39頁說在RTX核心開始執行之前不能執行中斷,於是將中斷使能的程式碼放到了核心啟動之後的SVC程式碼中。而今天發現這是導致問題的原因。後來查看了《RL-ARM User's Guide》的RL-RTX -> Using RTX Kernel -> Usage Hints主題說“Before the kernel starts, never enable any IRQ interrupt that calls isr_ functions. ”,原來是核心啟動前不能使能呼叫了isr_函式的中斷。這是合理的。於是今天將中斷的配置放到核心啟動之前,而使用變數作為標誌,使得核心啟動之前,中斷函式不做任何操作,立即返回。問題解決。