最近做的一个项目,需要不同模块之间通信,MCU-(OS驱动)-DLL-EXE,
由于需要arm将触摸驱动和音频设备开关信息发送给MCU处理
我在touch驱动和wavmain中加入了postmessage
message发给应用层,应用再通过串口发给MCU处理
下面看看具体的代码
1 BOOL getTouchCoordinate(USHORT *x, USHORT *y) 2 { 3 ULONG trytimes = 0; 4 5 *x = *y = MAX_ADC_VAL; 6 7 RETAILMSG(0, (TEXT("++++sampleADC!\r\n"))); 8 9 while (trytimes++ < TIMEOUT_VAL)10 {11 if (!TouchSocIsPenDown())12 {13 return FALSE;14 }15 16 #if COORDINATE_MODE17 18 if (TouchSocSampleCooCoordinate(x, y))19 {20 break;21 }22 23 24 #else // COORDINATE_MODE25 26 if (!TouchSocSampleCoordinate(x, TRUE))27 {28 continue;29 }30 31 32 // sampling Y coordinate33 34 if (TouchSocSampleCoordinate(y, FALSE))35 {36 break;37 }38 39 40 #endif // COORDINATE_MODE41 } // while42 43 RETAILMSG(1, (TEXT("x=%x, y=%x \r\n"), *x, *y));44 //下面是我添加的45 if(((xx-(*x))>50)||(((*x)-xx)>50)||((yy-(*y))>50)||(((*y)-yy)>50))46 {47 ::PostMessage(HWND_BROADCAST, ::RegisterWindowMessage(_T("UWM_TO_MCU_TOUCH-{7049499B-0480-44f9-BF71-4AE91FA0443C}")),*x,*y);48 }49 xx=(*x);50 yy=(*y);51 //添加结束52 if (trytimes > TIMEOUT_VAL)53 {54 RETAILMSG(1, (TEXT("timeout sampling coordinates\r\n")));55 }56 57 58 TouchSocPreInit();59 return TRUE;60 }
可以看到我添加的地方就是post一个消息,消息是注册表注册的一个信息,也可以用其他数字什么的,但是注册的信息能保证唯一性
其次推荐用post不用send,因为post是异步的。
其次再看看audio的message,这个就有点纠结了,弄了我很久
先发个错误的
1 case WODM_OPEN: 2 { 3 RETAILMSG(1, (_T("WODM_OPEN"))); 4 ::PostMessage(HWND_BROADCAST, ::RegisterWindowMessage(_T("UWM_TO_AUDIO_OPEN-{7049499B-0480-44f9-BF71-4AE91FA0443C}")),0,0); 5 DeviceContext *pDeviceContext = g_pHWContext->GetOutputDeviceContext(uDeviceId); 6 7 8 if (!(dwParam2 & WAVE_FORMAT_QUERY)) 9 {10 g_pHWContext->AudioPowerOn(FALSE);11 }12 13 14 dwRet = pDeviceContext->OpenStream((LPWAVEOPENDESC)dwParam1, dwParam2, (StreamContext **)dwUser);15 16 break;17 }18 19 case WIDM_OPEN:20 {21 22 RETAILMSG(1, (_T("WIDM_OPEN")));23 if (!(dwParam2 & WAVE_FORMAT_QUERY))24 g_pHWContext->AudioPowerOn(FALSE);25 26 DeviceContext *pDeviceContext = g_pHWContext->GetInputDeviceContext(uDeviceId);27 28 dwRet = pDeviceContext->OpenStream((LPWAVEOPENDESC)dwParam1, dwParam2, (StreamContext **)dwUser);29 break;30 }31 32 case WODM_CLOSE:33 {34 RETAILMSG(1, (_T("WODM_CLOSE")));35 ::PostMessage(HWND_BROADCAST, ::RegisterWindowMessage(_T("UWM_TO_AUDIO_CLOSE-{7049499B-0480-44f9-BF71-4AE91FA0443C}")),0,0);36 37 DeviceContext *pDeviceContext = g_pHWContext->GetOutputDeviceContext(uDeviceId);38 39 40 }
第四行和35行就是我添加的代码,编译后烧进板子后触摸无效,其实不是触摸无效,而是系统挂在一个地方了
原因就是这个地方跑进临界区,不能使用postMessage这种涉及到多线程的函数
下面发正确的修改:
1 DWORD dwRet = MMSYSERR_NOERROR; 2 3 //lishiqi insert 20120808 4 if(uMsg == WODM_OPEN) 5 { 6 ::PostMessage(HWND_BROADCAST, ::RegisterWindowMessage(_T("UWM_TO_AUDIO_OPEN-{7049499B-0480-44f9-BF71-4AE91FA0443C}")),0,0); 7 } 8 else if(uMsg == WODM_CLOSE) 9 {10 ::PostMessage(HWND_BROADCAST, ::RegisterWindowMessage(_T("UWM_TO_AUDIO_CLOSE-{7049499B-0480-44f9-BF71-4AE91FA0443C}")),0,0);11 }12 13 14 g_pHWContext->Lock();15 16 switch (uMsg)17 {18 case WIDM_OPEN_AUDIO_PHYSICAL_INPUT:19 {20 g_pHWContext->Codec_PowerInput(TRUE, dwParam1);21 g_pHWContext->Codec_InMute(FALSE, dwParam1);22 break;23 }
3-11行就是我添加的,之所以前面那段加入switch里错误了,就是因为14行的lock函数
这个函数的定义就是进入临界区进行多线程的禁止和内存保护。所以以后要长个教训,不是什么地方都可以乱插入函数
本文仅仅是作者个人观点,本人菜鸟,希望大家一起共同进步