網頁

2014年8月20日 星期三

[EZ-USB FX3] Memory map


FX3 的 memory, 基本上可以分成三類, D-TCM/I-TCM/System memory. TCM 是 Tightly-coupled memory 的縮寫, 它是 low-latency memory, 可以提供快速的記憶體存取.

D-TCM

D-TCM 是資料 (data) 用的 TCM. FX3 有 8 K 的 D-TCM. SDK 預設把這一塊記憶體, 分配給系統的堆疊.
modes address size  
SYS MODE STACK 0x10000000-0x10000800 2 K  
ABT MODE STACK 0x10000800-0x10000900 256 B  
UND MODE STACK 0x10000900-0x10000A00 256 B  
FIQ MODE STACK 0x10000A00-0x10000C00 512 B  
IRQ MODE STACK 0x10000A00-0x10001000 1 K  
SVC MODE STACK 0x10000A00-0x10002000 4 K  

I-TCM

I-TCM 是 instruction TCM. FX3 有 16 K 的 I-TCM. SDK 預設把這一塊記憶體, SDK 主要分配給 Interrupt Handler, 以及 Exception Vector.
usage address size  
Execption  Vector 0x00000000-0x00000100 256 B Fixed
Interrupt Handler 0x00000100-0x00004000 16 K – 256 B  

System memory

不同的 FX3 型號, system memory 的 size 可能有所不同, 有 256K/512K 的差別. 以下以 512 K 作說明.
usage address size  
DMA descriptor 0x40000000-0x40003000 12 K Fixed
Code Area 0x40003000-0x40030000 180 K  
Data Area 0x40030000-0x40037000
0x40030000-0x40038000
28 K
32 K
(with Compiler Heap)
(without Compiler Heap)
Compiler Heap 0x40030000-0x40037000 4 K (if used)
RTOS Heap 0x40038000-0x40040000 32 K  
DMA Buffer Area 0x40040000-0x40080000 256 K  

 

2014年8月19日 星期二

[EZ-USB FX3] firmware framework –1 Initialization


以下說明 FX3 firmware application 的啟動過程.

Hardware reset

在系統重置, 或是上電時, 所有的處理器都會進入一個硬體重置的階段, 雖然硬體重置的動作/順序/需要時間各自有差異, 不過它的目的都是準備處理器, 以進行之後的運算任務. 粗略的來說, 它會有一些任務要執行.
  • register reset : 在電源開始供電之前, 處理器內部的暫存器, 它的內容都應該視為未知. 因此, 它需要一些時間讓它回到預設值.
  • peripheral reset : 處理器需要周邊的元件來進行處理. 譬如, 需要 RAM 來儲存資料, IO 和外界溝通或交換資料. 這些元件也需要進入工作狀態.
  • 載入初始的指令 : 處理器要執行指令, 第一個要執行的指令, 要放在指令暫存器的預設的位址. 也就是說, reset 後,  指令暫存器的內容會還原成預設值. 而這預設值就是第一個要執行的指令的位址.

Device configuration

FX3 在 CPU rest 之後, 第一個執行的指令是在內部的 boot-ROM, 它的位址是 0xFFFF0000. 也可以稱為第一 Boot Loader. 根據文件, 它執行以下動作:
  • 根據 PMODE pin 的設定, 判斷 firmware 的來源. FX3 可以支援 USB Boot/I2C boot/SPI Boot/GPIF Boot.
  • 從 firmware 的來源, download firmware 的映像到系統的記憶體.
  • 從 firmware entry location ( 0x40000000) 指向的地方開始執行
firmware entry location 的位址 ( 0x40000000) , 存放的是 firmware reset address. 也就是 firmware 第一個指令的位置. 通常是在 0x40003000, 也就是 CyU3PFirmwareEntry() 這個程序.
CyU3PFirmwareEntry() 在清除 BSS 段的資料後, 會呼叫 main() 這個 function. 這也是 firmware application 第一個會執行到的指令.  

Clock Setup

通常, 在 main() 中, 首先要設定 clock. 這會呼叫到 CyU3PDeviceInit ()
/* Initialize the device */
CyU3PSysClockConfig_t clockConfig;
clockConfig.setSysClk400  = CyTrue;
clockConfig.cpuClkDiv     = 2;
clockConfig.dmaClkDiv     = 2;
clockConfig.mmioClkDiv    = 2;
clockConfig.useStandbyClk = CyFalse;
clockConfig.clkSrc         = CY_U3P_SYS_CLK;
status = CyU3PDeviceInit (&clockConfig);

MMU and cache management

FX3 不支援 virtual memory. 實體記憶體是和虛擬記憶體是1對1的對應. 這需要設定 MMU. 另外, MMU 也用來 enable 系統的 cache. /* Initialize the caches. Enable both Instruction and Data caches. */
status = CyU3PDeviceCacheControl (CyTrue, CyTrue, CyTrue);
if (status != CY_U3P_SUCCESS)
{
    goto handle_fatal_error;
}


RTOS Kernel

當完成這前述的步驟後, 程式的執行權會交給 RTOS. 也就是透過呼叫 CyU3PKernelEntry (). RTOS 在完成 RTOS 自己的啟始動作後, 會再呼叫 CyFxApplicationDefine 這個 FX3 已經定義的 callback function, application 在這個地方定義自己的 thread, 由 RTOS 分配時間來執行.



2014年8月18日 星期一

[EZ-USB FX3] include/library path


FX3 SDK 預設的 IDE 是 Eclipse. 雖然 Eclipse 很常見, 但是因為它可以客製化, 有些細節的地方還是要摸索一下. 例如說, include 和 library 的路徑設定.

include path

在專案瀏覽畫面, 在要設定的專案名稱上按右鍵, 會跳出專案選單, 選擇最下面的 Properties, 打開專案屬性視窗.image
在以下的專案屬性視窗中, 依序進入 include 設定:
  1. 在左邊的選項中, 選擇 “C/C++ Build”, 以及其下的 “Settings”.
  2. 在中間的 Settings 窗格, 選擇 “Tool Settings” 分頁.
  3. 在“Tool Settings” 分頁中, 選擇 “ARM Sourcery Windows GCC Compiler”, 以及其下的 “Directories”
  4. 按右上角的加號, 加入新的 include path
image

library path

  1. 在左邊的選項中, 選擇 “C/C++ Build”, 以及其下的 “Settings”.
  2. 在中間的 Settings 窗格, 選擇 “Tool Settings” 分頁.
  3. 在“Tool Settings” 分頁中, 選擇 “ARM Sourcery Windows GCC Linker”, 以及其下的 “Miscellaneos”
  4. 在右邊的窗格, 捲到最下面, 可以看到 “Other flags”, 在這邊可以輸入要用到的 library 的路徑及檔名.
image

Notice :

Library 的設定, 似乎要在 ${FX3_INSTALL_PATH} 才可以, 這部份沒有深入去探討, 有問題的時候, 可以試試看放在這個地方.

2014年7月5日 星期六

[DirectShow] Install VS2010 + DirectShow on Windows 7

 

最近遇到工作上需要用到 DirectShow 來做 moive 的顯示, 但是在 setup 環境的時候, 遇到一些問題, 參考一些資料, 再加上自己 try and error 之後, 終於搞定了. 在這邊把過程記錄下來, 供自己及有需要的人參考.

DirectShow 原本叫做ActiveMovie, 做為 MicroSoft 對抗 QuickTime 的技術. 後來又改名為 DirectShow, 作為 DirectX 的一部份. 在一段時間之後, DirectShow 被移出 DirectX SDK, 而整合到 Window SDK 之中.

Windows SDK 則有另一段故事. Windows SDK 原本是 MicroSoft 對不同版本的作業系統所發布的 SDK, 以提供開發人員利用新的作業系統所提供的 API, 開發新的應用. 在 Windows 98 之後, 這個 SDK 改名為 Platform SDK, 在 Windows Vista 時改名為 Windows SDK.

安裝準備

由於工作需求, 安裝的環境是 Windows 7, VS 2010 + VS2010 SP1 + Windows SDK 7.1

由於之前安裝的 VS2005, VS2008, VS2012, Windows SDK 6.0/Windows SDK 7.0, 安裝過程中一再遇到問題, 後來決定整個移除掉. 但是 MicroSoft 並沒有很簡便可以移除這一堆東西的方法, 只能從控制台/程式集/程式和功能/解除安裝程式中, 有 2005/2008/2012/SDK 這些字樣的部份一個一個移除.

可以的話, 建議儘量用沒有安裝過 Visual Studio 和 SDK 的系統, 可以省不少不必要的麻煩.

安裝 Visual 2010

安裝 VS2010 其實很簡單, 一直按就可以了. 這邊的貼圖只是用來強調 MicroSoft 在安裝 Visual Studio 的時候, 附帶安裝了多少想都想不到的元件. 譬如說, VC 9.0 runtime.

01-setup

選擇 Full 安裝

02-setup

Visual Studio 安裝元件列表一

03-setup

Visual Studio 安裝元件列表二

04-setup

Visual Studio 安裝元件列表三

05-setup

有消息指出, 如果 Microsoft Visual C++ 2010 runtime 的版本高於 10.0.3019 需要移除 (如果已經安裝 SP1 的話, 有可能出現). 運氣很好, 剛好是一樣的, 所以不需移除.

06-vc-runtime

安裝 Windows SDK 7.1

Windows SDK 7.1 有兩種安裝方式,

1. web install, 在以下 link , 下載 winsdk_web.exe, 下載完直接安裝

http://www.microsoft.com/en-us/download/details.aspx?id=8279

2. iso install, 在以下 link, 下載 iso 檔安裝.

http://www.microsoft.com/en-us/download/details.aspx?id=8442

需要注意的是, 這裡有 3 個檔案,

GRMSDK_EN_DVD.iso 這是 for x86 的環境 ( 作業系統 Windows 的版本)
GRMSDKX_EN_DVD.iso 這是 for x64 的環境 ( 作業系統 Windows 的版本)
GRMSDKIAI_EN_DVD.iso 這是 for Intel Itanium ( IA-64) 的環境

07-sdk

安裝過程就只是比較久而已

08-sdk-license

09-sdk-selection

010-sdk-install

安裝 VS2010 SP1

執行 SP1 中的 setup.exe

11-vc2010-sp1

 

12-vc2010-sp1-setup

安裝 KB2519277

Windows SDK 7.1 適用的 Microsoft Visual C++ 2010 Service Pack 1 編譯器更新

http://www.microsoft.com/zh-tw/download/details.aspx?id=4422

到這邊, 安裝的部份已經完成. 接下來要修改 DirectShow 的建置環境

Build strmbasd.lib for DirectShow

打開 D:\Program Files\Microsoft SDKs\Windows\v7.1\Samples\multimedia\directshow\baseclasses 的這個 project, 在 Property\Configuration Properties\General\Target name 改成 strmbasd.

strmbasd.lib 會是 DirectShow 大部份的應用會用到的 library.

13-dshow

14-dshow

這樣就完成了建置的工作.

2014年6月11日 星期三

[Visual Studio 2012] Common controls 不見了

 

用 MFC 來寫一些對話盒, 執行一些簡單的動作, 是很方便的事. MFC 提供的一些 common control, 讓這些動作變得更簡單. 如果 common control 不能使用, 那根本是全殘了. 不知道為什麼發生這種事, 不過如果遇到, 可以參考以下的解決辦法.

image

解決的辦法是刪除 C:\Documents and Settings\[username]\Local Settings\Application Data\Microsoft\VisualStudio\11.0, 裡面的 .tbd 檔案.

不過, 這個說來簡單, 但是做起來會有一些小麻煩.

1. 找不到 Documents and Settings 這個目錄. 在 Windows 中, 這個目錄預設是隱藏的. 在控制台中, 選擇 外觀及個人化, 裡面的資料夾選項 : 取消隱藏保護的作業系統檔案, 並勾選顯示隱藏的檔案, 資料夾及磁碟機. 這樣就可以在 Windows 安裝的磁碟, 看到 Documents and Settings 的目錄了.

image

 

2. 打不開 Documents and Settings 這個目錄.

image

在 Documents and Settings 這個目錄上按右鍵, 以啟動資料夾選項, 切換到安全性的分頁

image

按進階, 以進入進階設定

image

按變更權限, 以變更存取權限

image

選擇 “Everyone” , 也就是被拒絕的那一個, 並按下編輯,把原本拒絕那一欄打勾的列出資料夾/讀取資料

image

然後按很多次套用和確定, 回到資料夾. 在到達目標資料夾前, 還會遇到幾次的拒絕存取, 用同樣的方法過關. 最後終於到達目的地.

 image

殺掉 2 個 .tbd 檔案, 以及 2 個 .dat 檔案. 重新開啟 Visual 2012, common control 回來了.

image

[EZ-USB FX3] Create new project


雖然 FX3 SDK 提供了很多 example, 但是當要進行自己的工作時, 還是會想要建一個自己的專案, 至少專案名稱是自己想要的.
不過, FX3 在這方面不太好操作, 自己 create 出來的專案, 完全不能用. 以下說明如何以手動的方式建立一個新的專案

建立專案資料夾

在 FX3 的範例目錄下, ex: C:\Program Files (x86)\Cypress\EZ-USB FX3 SDK\1.3\firmware\basic_examples, 建立一個新的資料夾, 資料夾名稱就是專案名稱. 在這個例子中是 CxTest
image

複製專案檔案

從一個已經存在的專案範本中, 複製專案內容. 以下是從 cyfxbulksrcsink 複製. 將 cyfxbulksrcsink 下的檔案, 都複製到 CxTest 的目錄.
image

重新命名專案檔案

將 cyfxbulksrcsink.c 重新命名成 CxTest.c
將 cyfxbulksrcsink.h 重新命名成 CxTest.h
將 cyfxbulkdscr.c 重新命名成 CxTestDscr.h
其他的檔案是每一個專案都有, 而且內容一樣的.

修改專案檔案內容

1. 修改 CxTest.c
將 #include "cyfxbulksrcsink.h" 修改為 #include "CxTest.h" 
2. 修改 CxTestDscr.c
將 #include "cyfxbulksrcsink.h" 修改為 #include "CxTest.h"
3. 修改 .project
將 cyfxbulksrcsink 全部取代成 CxTest
4. 修改 .cproject
將 cyfxbulksrcsink 全部取代成 CxTest

import 專案範例

在 File/Import/Existing Projects into Workspace
image
瀏覽至 C:\Program Files (x86)\Cypress\EZ-USB FX3 SDK\1.3\firmware\basic_examples\CxTest
image
然後就可以在 project explorer 中, 看到新增加的專案
image

2014年6月3日 星期二

[EZ-USB FX3] UART on Development Kit


從 Uart 印一些 message 作 debug 用, 是 firmware 常用的開發技巧. FX3 所附的範例中, 也有一些有印出 debug message, 不過, 實際上操作, Uart 卻是一片空白. 以下用一步一步的操作, 來確認 Uart 的問題.

1. 檢查 Uart 裝置.

現在很多電腦都沒有 Uart/RS232/COM port 這樣的介面, 取而代之的, 是 Uart-USB 的裝置很容易取得. 以下就使用 Uart-USB 來代替 UART 的輸出.
在控制台, 裝置管理員, 可以看到連接埠, 下圖中的 COM10, 就是我們要用的 Uart port.
image

2. 開啟 PC 端的終端機.

不管是用 Hyper Terminal, 或是其他隨便什麼軟體, Uart 都有一些設定要做, 不過很簡單.Port name (COM10), Speed/baud rate (115200), Data bits (8), Stop bits (1), Parity (None),Flow control (None )
image

3. 設定 DVK ( developmen kit ) 上面的 jumper.

J101 1 and 2, GPIO_46=UART_RTS, J101 用來設定 GPIO 46 當作 UART_RTS
J102 1 and 2, GPIO_47=UART_CTS, J102 用來設定 GPIO 47 當作 UART_CTS
J103 1 and 2, GPIO_48=UART_TX, J103 用來設定 GPIO 48 當作 UART_TX
J104 1 and 2, GPIO_49=UART_RX, J104 用來設定 GPIO 49 當作 UART_RX 實際上, CTS/RTS 現在已經很少用到, 所以只跳 J103/J104 也是可以的.
image

4. 開啟 USBDebug 範例. Build 完 project.

update 到 DVK 上, 嗯, 還是不 work.
image

5. 修改 USBDebug 範例.

1. cyfxusbdebug.c 的 main()
UART 的 GPIO 的設定應該和以下的程式碼相同. 如果都沒有改過, 應該是一樣的.
/* No LPP or GPIO is being used. */
io_cfg.isDQ32Bit = CyFalse;
io_cfg.s0Mode = CY_U3P_SPORT_INACTIVE;
io_cfg.s1Mode = CY_U3P_SPORT_INACTIVE;
io_cfg.useUart   = CyTrue;
io_cfg.useI2C    = CyFalse;
io_cfg.useI2S    = CyFalse;
io_cfg.useSpi    = CyFalse;
io_cfg.lppMode   = CY_U3P_IO_MATRIX_LPP_UART_ONLY;
/* No GPIOs are enabled. */
io_cfg.gpioSimpleEn[0]  = 0;
io_cfg.gpioSimpleEn[1]  = 0;
io_cfg.gpioComplexEn[0] = 0;
io_cfg.gpioComplexEn[1] = 0;
status = CyU3PDeviceConfigureIOMatrix (&io_cfg);
if (status != CY_U3P_SUCCESS)
{
    goto handle_fatal_error;
}
以上是設定的 Uart 的 IO. 但是 UART 的 config 卻沒有設, 因此要加入一個 function CyFxDebugInit ()
2. 加入 CyFxDebugInit ()
/* This function initializes the debug module. The debug prints
* are routed to the UART and can be seen using a UART console
* running at 115200 baud rate. */
void CyFxDebugInit (void)
{
    CyU3PUartConfig_t uartConfig;
    CyU3PReturnStatus_t apiRetStatus = CY_U3P_SUCCESS;
    /* Initialize the UART for printing debug messages */
    apiRetStatus = CyU3PUartInit();
    if (apiRetStatus != CY_U3P_SUCCESS)
    {
        /* Error handling */
        CyFxAppErrorHandler(apiRetStatus);
    }
    /* Set UART configuration */
    CyU3PMemSet ((uint8_t *)&uartConfig, 0, sizeof (uartConfig));
    uartConfig.baudRate = CY_U3P_UART_BAUDRATE_115200;
    uartConfig.stopBit = CY_U3P_UART_ONE_STOP_BIT;
    uartConfig.parity = CY_U3P_UART_NO_PARITY;
    uartConfig.txEnable = CyTrue;
    uartConfig.rxEnable = CyFalse;
    uartConfig.flowCtrl = CyFalse;
    uartConfig.isDma = CyTrue;
    apiRetStatus = CyU3PUartSetConfig (&uartConfig, NULL);
    if (apiRetStatus != CY_U3P_SUCCESS)
    {
        CyFxAppErrorHandler(apiRetStatus);
    }
    /* Set the UART transfer to a really large value. */
    apiRetStatus = CyU3PUartTxSetBlockXfer (0xFFFFFFFF);
    if (apiRetStatus != CY_U3P_SUCCESS)
    {
        CyFxAppErrorHandler(apiRetStatus);
    }
    /* Initialize the debug module. */
    apiRetStatus = CyU3PDebugInit (CY_U3P_LPP_SOCKET_UART_CONS, 8);
    if (apiRetStatus != CY_U3P_SUCCESS)
    {
        CyFxAppErrorHandler(apiRetStatus);
    }
    CyU3PDebugPreamble (CyFalse); }
3. 呼叫 CyFxDebugInit()
在 ApplnThread_Entry() 中, 呼叫 CyFxDebugInit () /* Entry function for the AppThread. */
void
ApplnThread_Entry ( uint32_t input)
{
    CyFxDebugInit();
    /* Initialize the logger application */
    CyFxApplnInit();
    for (;;)
    {
        CyU3PThreadSleep (1000);
        if (glIsApplnActive)
        {
            CyU3PDebugPrint (2, "USB Debug logger: time from start in ticks: %d\n", CyU3PGetTime ());
        }
        CyU3PDebugPrint (2, "USB Debug Hello: %d\n", CyU3PGetTime ());
    }
}
到這邊應該就可以在 PC 上看到 debug message 了, 不過, 還有一些地方要注意  

Note

1. FX3 的 Uart 不會立刻顯示. 大約要幾秒鐘之後, PC 上才會開始看到字. 並不是 delay, 而是 Uart 要過幾秒鐘才有作用. 2. 文字偏移, 沒有回到左邊界. 如果 PC 的軟體沒有自動把“\n” 取代成 “\r\n” 就會造成文字一直偏移. 這時可以自己加. 例如 :
CyU3PDebugPrint (2, "USB Debug Hello: %d\n", CyU3PGetTime ());
改成
CyU3PDebugPrint (2, "USB Debug Hello: %d\r\n", CyU3PGetTime ());