2440 5.0 串口移植到 6.0。
加载串口驱动后,启动出现INFO: CReg2440Uart::CReg2440Uart using processor frequency reported by the OAL (0).
然后系统就死了。
也就是这一段
CReg2440Uart::CReg2440Uart()中
if (!KernelIoControl(IOCTL_PROCESSOR_INFORMATION, NULL, 0, &procInfo, sizeof(PROCESSOR_INFO), &dwBytesReturned))
{
m_s3c2440_pclk = DEFAULT_S3C2440A_PCLK;
RETAILMSG(TRUE, (TEXT("WARNING: CReg2440Uart::CReg2440Uart failed to obtain processor frequency - using default value (%d).\r\n"), m_s3c2440_pclk));
}
else
{
m_s3c2440_pclk = procInfo.dwClockSpeed;
RETAILMSG(TRUE, (TEXT("INFO: CReg2440Uart::CReg2440Uart using processor frequency reported by the OAL (%d).\r\n"), m_s3c2440_pclk));
}
问题是KernelIoControl 通过OALIoCtlProcessorInformation 这个函数获取信息。为什么 procInfo.dwClockSpeed 会是0?是获取失败么? 要怎么改?
KernelIoControl会调用OEMIoControl, 你的OEMIoControl是怎么实现的?里面包含了读取外设时钟的代码吗?
我手头上的是没有实现的.
- case IOCTL_PROCESSOR_INFORMATION:
- if (!lpOutBuf) {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- if (sizeof(PROCESSOR_INFO) > nOutBufSize) {
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- return FALSE;
- } else {
- const WCHAR OEMProcCore[] = L"ARM";
- const WCHAR OEMProcName[] = L"ARM920";
- const WCHAR OEMProcVendor[] = L"SAMSUNG";
- PPROCESSOR_INFO pProcInfo = (PPROCESSOR_INFO)lpOutBuf;
-
- if (lpBytesReturned) *lpBytesReturned = sizeof(PROCESSOR_INFO);
- memset(pProcInfo, 0, *lpBytesReturned);
-
- pProcInfo->wVersion = 1;
-
- memcpy(pProcInfo->szProcessCore, OEMProcCore, (strlenW(OEMProcCore) + 1) * sizeof(WCHAR));
- memcpy(pProcInfo->szProcessorName, OEMProcName, (strlenW(OEMProcName) + 1) * sizeof(WCHAR));
- memcpy(pProcInfo->szVendor, OEMProcVendor, (strlenW(OEMProcVendor) + 1 ) * sizeof(WCHAR));
-
- pProcInfo->dwInstructionSet = 0;
-
- return TRUE;
- }
不过即使没有实现也不会出现死机的现象啊,你看看是不是后面的函数有什么问题.
引用: 引用 7 楼 flandy1982 的回复:
KernelIoControl会调用OEMIoControl, 你的OEMIoControl是怎么实现的?里面包含了读取外设时钟的代码吗?
我手头上的是没有实现的.
C/C++ codecase IOCTL_PROCESSOR_INFORMATION:if (!lpOutBuf) {
SetLastError(ERROR_INVALID_PARAMETER);return FALSE;
}if (sizeof(PROCESSOR_INFO)> nOutBufSize) {
SetLastError(ERROR_INSUFFICIENT_BUFFER);return FALSE;
}else {const WCHAR OEMProcCore[]= L"ARM";const WCHAR OEMProcName[]= L"ARM920";const WCHAR OEMProcVendor[]= L"SAMSUNG";
PPROCESSOR_INFO pProcInfo= (PPROCESSOR_INFO)lpOutBuf;if (lpBytesReturned)*lpBytesReturned=sizeof(PROCESSOR_INFO);
memset(pProcInfo,0,*lpBytesReturned);
pProcInfo->wVersion=1;
memcpy(pProcInfo->szProcessCore, OEMProcCore, (strlenW(OEMProcCore)+1)*sizeof(WCHAR));
memcpy(pProcInfo->szProcessorName, OEMProcName, (strlenW(OEMProcName)+1)*sizeof(WCHAR));
memcpy(pProcInfo->szVendor, OEMProcVendor, (strlenW(OEMProcVendor)+1 )*sizeof(WCHAR));
pProcInfo->dwInstructionSet=0;return TRUE;
}
不过即使没有实现也不会出现死机的现象啊,你看看是不是后面的函数有什么问题.
我的意見和ls這位牛人的意見是類似的。
不過我感覺你那個地方返回0有點問題。。。clockspeed是0.。。很奇怪了。。應該會有點值才對。
可能我對這個clockspeed的理解有錯誤
引用: 引用 4 楼 wndce 的回复:
引用 3 楼 xumercury 的回复:
这样我也改过,还是一样挂。
那要一步步追下去了。。。太晚了。明天再看。。圣诞快乐。
过了一个星期,今天又拿出来调了下
BOOL CReg2440Uart::Init()
{
if (m_pReg) { // Set Value to default.
Write_ULCON(0);
Write_UCON(0);
Write_UFCON(0);
Write_UMCON(0);
return TRUE;
}
即到这里首次写寄存器 就死了。。
m_pReg 是在 MapHardware()函数里面实现虚地址映射的
- if (TranslateBusAddr(m_hParent,(INTERFACE_TYPE)dwi.dwInterfaceType,dwi.dwBusNumber, ioPhysicalBase,&inIoSpace,&ioPhysicalBase)) {
- // Map it if it is Memeory Mapped IO.
- m_pRegVirtualAddr = MmMapIoSpace(ioPhysicalBase, dwi.memWindows[0].dwLen,FALSE);
- RETAILMSG(1, (TEXT("dwi.memWindows[0].dwBase TranslateBusAddr successfully.m_pRegVirtualAddr: %X !\n"), m_pRegVirtualAddr));
- }
.
dwi.memWindows[0].dwBase 打印出来 为50000000 即UART 控制寄存器的首地址。
m_pRegVirtualAddr 为D0500000,也是m_pReg的值,感觉是不是这里 地址映射出错了???