2013年6月21日 星期五

Windows CE, GPRS.

實驗的筆記, 沒有在 ublox G350 以外的 GPRS modules 確認過.

首先的, ublox G350 它可以對 UART 的波型做相位修正的工作, 也就是 baud auto-detect, 所以這裡並沒有 UART 的通訊與控制等.

首先的要在 control-panel 裡設定網路 (Network and Dial-up Connections), 設定撥號 (Make new Connection),

  1. 設定電話簿名稱 (註: 這個名字十分重要, 請盡可能用英文名), Dial-up connection, next.
  2. 選擇好 COM (device properites 有些該注意的設定像 baud, data bits, parity, stop bits, flow-control 要注意, 還有第二頁的 "Extra settings" 請一定要在這裡設定好 APN 名稱指令, 如 +cgdcont=1,"IP","internet" ), next.
  3. 設定 phone number, 一般用 *99#, 但並不是所有的電信業者都一模一樣, 請注意.
因為在 code 裡面是呼叫電話簿來使用, 所以電話簿本身的設定正不正確, 直接影響 GPRS 能不能正常連線.

再來是 code.
//pwEntryName 就是電話簿名稱, 所以前面提這個名字非常重要.
//pRasConn 是之後連線狀況取得與斷線會用上的 handle, 必需保留.


int RAS_Dial(TCHAR pwEntryName[20], HRASCONN *pRasConn)
{
RASDIALPARAMS tRasDialParams = { 0 };
int nERR = 0;

tRasDialParams.dwSize = sizeof(RASDIALPARAMS);
_tcscpy_s(tRasDialParams.szEntryName, 20, pwEntryName);

RasGetEntryDialParams(pwEntryName, 0, 0);

nERR = (int)RasDial(0, 0, &tRasDialParams, (DWORD)-1, 0, pRasConn);

return nERR;
}

int RAS_HangUp(HRASCONN tRasConn)
{
return (int)RasHangUp(tRasConn);
}

int RAS_GetConnectState(HRASCONN tRasConn)
{
RASCONNSTATUS tStatus = { 0 };

RasGetConnectStatus(tRasConn, &tStatus);

if(tStatus.rasconnstate == RASCS_Connected)
{
return 1;
}

return 0;
}

其中比較奇怪的在 RasDial 這裡的 hwnd 要直接給它 null 不能傳入 cWnd 裡的 hwnd 參數, 否則無法工作, 這個不知道是為什麼.

純筆記.

2003/06/23 update:
如果覺的沒有撥號圖示感覺好像少了什麼似的, 的話, 來試試第二個方法. 第二個方法比較簡單:
rnapp.exe -m -n -p -eDIALUPNAME
DIALUPNAME 就是在電話簿裡取的名字.

以下就是可有可無的東西了, 但是很多...

這樣做通常還要再搭配另一個東西, windows-message receiver, 專門去接收 WM_NETCONNECT 這個訊息, 在 MFC 底下可以設定一個很簡單的訊息接收器, 像這樣:

.h
------------
#ifndef WM_NETCONNECT
#define WM_NETCONNECT 0x3feL
#endif

#ifndef RAS_MaxEntryName
#define RAS_MaxEntryName 20

#endif

typedef struct tagRNAAppInfo {
   DWORD dwSize;
   DWORD hWndRNAApp;
   DWORD Context;
   DWORD ErrorCode;
   TCHAR RasEntryName[RAS_MaxEntryName+1];
} RNAAPP_INFO, *PRNAAPP_INFO;

class Ctheapp : public CWnd
{
afx_msg LRESULT msg_NetConnect(WPARAM, LPARAM);
}
------------

.cpp
------------
BEGIN_MESSAGE_MAP(Ctheapp, CWnd)
ON_MESSAGE(MSG_UI_INIT, msg_NetConnect)
END_MESSAGE_MAP()

LRESULT Ctheapp::msg_NetConnect(WPARAM wParam, LPARAM lParam)
{
BOOL bConnect = (BOOL)wParam;
PRNAAPP_INFO pInfo = (PRNAAPP_INFO)lParam;

if(bConnect)
wprintf(L"connect to %s\n", pInfo->RasEntryName);
else
wprintf(L"%s Disconnect\n", pInfo->RasEntryName);

return 0;
}
------------

要斷線更麻煩, 要用 findwindow 去找到 rnaapp.exe 後對它發 message. 所以一開始就不使用 rnaapp 當撥接器..


2013年6月7日 星期五

Windows CE 下 flash memory raw data 操作

這個部份的操作, 其實在有 BSP code 時就有注意到了, 但是微軟有關 "IOCTL_FLASH_PDD" 方面的資料並不算很多, 網路上更是少的可以..
這是 FLASH_PDD 整個 driver 的架構一覽:
http://msdn.microsoft.com/en-us/library/bb821532.aspx
從這裡可以知道, FLASH PDD driver 其實是比一般 disk IO 更底層的 driver, 一般皆使用 DeviceIoControl 去操作, 在這裡有 CE 提供的既有功能:
http://msdn.microsoft.com/en-us/library/ee484253(v=winembedded.60).aspx

好的, 從這裡可以知道有哪些工具可以用. 至於這些 DeviceIoControl 用的 header, 其實要用 OpenStore() 去開, 而非 CreateFile 開 DSK?:
http://msdn.microsoft.com/en-US/library/ee489981(v=winembedded.60).aspx

到這裡, 才算是真正可以拿到 flash memory (可能是 NAND, 可能是 NOR, 不一定) 的 RAW data.

example code: (read only)

int GetNandAssignData(void *pvDstData, int nSectorAddr, int nSectorCount)
{ //for XP35C6, iVC1 only.
HANDLE hndDSK = 0;
int nERR = -1;
FLASH_PDD_TRANSFER
tPDDtrans;

FLASH_READ_STATUS
tPDDstate;

hndDSK = OpenStore(L"MSFlash");

if(!hndDSK || hndDSK == INVALID_HANDLE_VALUE) return -1;

tPDDtrans.pData = (unsigned char*)pvDstData;
tPDDtrans.pSpare = 0;
tPDDtrans.RegionIndex = 0;
tPDDtrans.SectorRun.StartSector = nSectorAddr;
tPDDtrans.SectorRun.SectorCount = nSectorCount;

nERR = (int)DeviceIoControl(
hndDSK, 
IOCTL_FLASH_PDD_READ_PHYSICAL_SECTORS,
&tPDDtrans,
sizeof(FLASH_PDD_TRANSFER),
&tPDDstate,
sizeof(ULONG),
0,
0);

CloseHandle(hndDSK);

if(nERR) return 0;
else return -2;
}

版權沒有, 僅管拿去用.

到這裡還需要的, 尚有:
1. BSP 設定的 flash memory map. 有這個地圖, 才會知道哪區擺的是哪個.
2. Flash 的 page size, spare size, block size.
3. NAND 需要 ECC 產生器, 而且必需要跟原本用的格式一樣.

目前試過 physical read 跟 block erase 沒有問題, 寫入因為欠 ECC 產生器作罷.

ps. 20130610後記: 在 FreeScale 官方 Windows CE BSP 上 page read/write 皆無 spare, spare 的部份設定只能借 block get/set (FLASH_BLOCK_STATUS_BAD, FLASH_BLOCK_STATUS_RESERVED) 得到或設定這個 flag.
別家的 SoC 的 BSP 有沒有把這部份 implement 的夠完整? 我不知道, 我也沒辦法做任何保證. 畢竟 BSP code 裡有多少地雷, 老闆跟 PM 不會知道也不會關心.