网页资讯视频图片知道文库贴吧地图采购
进入贴吧全吧搜索

 
 
 
日一二三四五六
       
       
       
       
       
       

签到排名:今日本吧第个签到,

本吧因你更精彩,明天继续来努力!

本吧签到人数:0

一键签到
成为超级会员,使用一键签到
一键签到
本月漏签0次!
0
成为超级会员,赠送8张补签卡
如何使用?
点击日历上漏签日期,即可进行补签。
连续签到:天  累计签到:天
0
超级会员单次开通12个月以上,赠送连续签到卡3张
使用连续签到卡
11月26日漏签0天
c语言吧 关注:801,312贴子:4,372,234
  • 看贴

  • 图片

  • 吧主推荐

  • 视频

  • 游戏

  • 9回复贴,共1页
<<返回c语言吧
>0< 加载中...

说说对C开发的一些经验吧,互相学习一下

  • 只看楼主
  • 收藏

  • 回复
  • ToFourier
  • 强能力者
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
要说的有些杂乱,想到哪说到哪。


  • 窃格瓦拉-
  • 超能力者
    9
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
顶


2025-11-26 17:07:32
广告
不感兴趣
开通SVIP免广告
  • ToFourier
  • 强能力者
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
我们一直说写程序写程序,可是程序怎么写呢?我觉得程序应该是一个(框架+算法+可靠性)。在这里我不说语法问题了,这个不属于讨论的范畴。我会基于项目开发的经验从下面几个方面说。


  • ToFourier
  • 强能力者
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
一、框架的重要性。
曾经做过一个项目,硬件平台是Atmel AT91SAM9G45,搭载wince6.0系统。采用win32编程。项目要求如下:
1. 定制wince内核;
2. 修改驱动;
3. 程序设计。这里面的任务有:(1)与TCP Server进行TCP通信,交换数据;(2)通过串口与模块通信,与终端进行通信,实现控制终端及接收终端数据;(3)实时响应外接stm32板的IO口变化;(4)界面显示,界面显示有三种方式可以控制,9G45外接触摸屏触摸控制、TCP Server发送的控制指令、stm32板IO口控制,逻辑必须统一;(5)数据实时处理。


  • ToFourier
  • 强能力者
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
第1我就不说了,第2是用C写的,但是驱动的修改并没有什么技术含量,这里略过不提。我们来说第3条。
一开始呢,也是写的一头乱麻,后来发现维护起来太麻烦,于是一切推倒重建。
程序分层:
1.底层:也就是硬件层,仅负责数据通信。
2.中间层:(1) 底层的数据通过回调函数,将数据向上存储;这里我建立了一个MemoryPool来存储数据。
3. 数据业务层:负责处理中间层存储的数据;这里我有一个线程在实时扫描MemoryPool中的新数据,根据协议对数据做不同的处理。
4. 界面层。界面层的显示根据不同的驱动方式做出反应,进行画面跳转。


  • ToFourier
  • 强能力者
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
1.负责底层数据通信的是3个线程。1个用于TCP通信,另外2个用于串口1和串口2通信。具体怎么实现的我不讲了,说说回调、回调是把程序分层的好工具。
在底层我声明了这样一个回调函数typedef void (CALLBACK *LPDataArriveProc)(pJl_uint8 data,Jl_int16 length);在我的中间层有一个函数static void CALLBACK RevDeviceBDdata(char *data,int length)负责数据的存储。退一步讲,如果以后改变了通信方式,那么依然可以在新的通信方式中调用这个回调向上存储信息,且底层和上层没有直接的依赖关系。
关于存储池memoropool,主要实现数据的存储,读取。本质上是一个数组,但是可以循环存储。
C++写的,但是不要紧,和C区别不大。况且这里主要是讲框架。
class CMemoryPool
{
//DECLARE_DYNAMIC(CMemoryPool);
public:
CMemoryPool(void);
~CMemoryPool(void);
// 分配多大的内存管理空间
void InitMemoryPool(Jl_uint32 bufsize);
// buf 从memory中取出来保存的内存,g_len buf的长度。 返回值为实际读到的值 rlen。
//-----------------------------------------------------------------------
UINT32 GetDataFromPool(pJl_uint8 buf,Jl_uint32 g_len);
//GetDataFromPool 实际读到的数据 送给rlen,成功解码出来的长度送给validFramlen,成功解码出来的长度要小于等于
//rlen
void SetFrameLen(Jl_uint32 ValidFramlen,Jl_uint32 rlen);
//-----------------------------------------------------------------------
void SaveDataToPool(pJl_uint8 buf,Jl_uint32 blen);
void ClearMemory();
private:
UINT8* buffer;
UINT8* InPoint;
UINT8* OutPoint;
UINT32 len;
UINT32 szBuffer;
};


  • ToFourier
  • 强能力者
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
经过第一步的分层,硬件通信已经独立开来。下一步就是数据的处理。这里依然有3个线程,各自实时扫描各自的存储池。根据不同的处理结果实现不同的操作。如果数据证据,那么执行Decode。比如下面,一层层的回调
/******************************************************************************************
// @fn: RecBDDataProc : 北斗数据接收处理函数
// @Param:
// CreateDate:2014.3.12 16:35
// Modify:
// Author:LFT
********************************************************************************************/
Jl_dword WINAPI CBDProtocol::RecBDDataProc(LPVOID lpParameter)
{
CBDProtocol* pProto=(CBDProtocol*)lpParameter;
Jl_uint8 CmdType;
Jl_int16 mFrameStart=0,CmdLen=0,ValidCode;
pJl_uint8 buf_lft = new Jl_uint8[600];
Jl_int16 buflen_lft;//buflen每次实际读取的字节数
while (!pProto->m_bIsExitBDProc)
{
buflen_lft=0;
memset(buf_lft,0,sizeof(buf_lft));
buflen_lft = m_BDMemory.GetDataFromPool((pJl_uint8)buf_lft,300);//包含命令字,命令长度信息
while ((ValidCode=pProto->IsValidBDFrame(buf_lft,buflen_lft,&CmdType,&mFrameStart,&CmdLen)) != NO_CMD_ERROR &&!pProto->m_bIsExitBDProc)
{
switch (ValidCode)
{
case NO_VALID_CMD_ERROR:
m_BDMemory.SetFrameLen(buflen_lft,buflen_lft);
Sleep(10);
memset(buf_lft,0,600);
buflen_lft = m_BDMemory.GetDataFromPool((pJl_uint8)buf_lft,300);
break;
case TOO_SHORT_ERROR://长度太短,无法进行计算
m_BDMemory.SetFrameLen(0,buflen_lft);
Sleep(10);
buflen_lft = m_BDMemory.GetDataFromPool((pJl_uint8)buf_lft,300);
break;
case GET_LENS_ERROR://长度计算错误
m_BDMemory.SetFrameLen(mFrameStart+5,buflen_lft);//跳过命令字
Sleep(10);
memset(buf_lft,0,600);
buflen_lft = m_BDMemory.GetDataFromPool((pJl_uint8)buf_lft,300);
break;
case CONTENT_LEN_ERROR:
m_BDMemory.SetFrameLen(0,buflen_lft);
Sleep(10);
buflen_lft = m_BDMemory.GetDataFromPool((pJl_uint8)buf_lft,CmdLen);
break;
case XOR_ERROR:
m_BDMemory.SetFrameLen(mFrameStart+CmdLen,buflen_lft);
Sleep(10);
memset(buf_lft,0,600);
buflen_lft = m_BDMemory.GetDataFromPool((pJl_uint8)buf_lft,300);
break;
default:
break;
}
}
m_BDMemory.SetFrameLen(mFrameStart+CmdLen,buflen_lft);
pProto->BDDecode(CmdType,buf_lft+mFrameStart,CmdLen);
Sleep(10);
}
delete[] buf_lft;
return 0;
}
/******************************************************************************************
// @fn: BDDecode : 解析北斗通信协议数据包
// @Param: buf 数据包内容buflen内容长度
//
// CreateDate:2014.3.12 16:35
// Modify:
// Author:LFT
// Other:
********************************************************************************************/
void CBDProtocol::BDDecode(Jl_uint8 CmdType,Jl_uint8 *buf, Jl_int16 buflen)
{
Jl_int16 ContentLen=0;
static Jl_int16 TmpCmdNb=-1;
//CSystemLog* pLog = new CSystemLog();
switch (CmdType)
{
case GET_ZJXX:
SetEvent(m_hZjxxEvt);
memcpy(g_glzk,buf+14,6);
g_WorkStatus.cSignalQu = g_glzk[0] + g_glzk[1] + g_glzk[2] + g_glzk[3]+g_glzk[4]+g_glzk[5];
break;
case GET_GLZK:
memcpy(g_glzk,buf+10,6);
//printf("%d %d %d %d %d %d\r",g_glzk[0],g_glzk[1],g_glzk[2],g_glzk[3],g_glzk[4],g_glzk[5]);
break;
case GET_GNPX:
//memcpy((Jl_uint8 *)&g_cmd_GNPX,buf,sizeof(g_cmd_GNPX));
break;
case GET_GNTX:
memcpy((Jl_uint8*)&g_cmd_GNTX,buf,sizeof(g_cmd_GNTX));
SetEvent(g_WorkStatus.m_hRecvBDTimeEvt);
break;
case GET_ICXX:
//memset(g_cmd_ICXX.CmdHead.UserAddr,0,sizeof(g_cmd_ICXX.CmdHead.UserAddr));
memcpy((Jl_uint8 *)&g_cmd_ICXX,buf,sizeof(g_cmd_ICXX));
RETAILMSG(LFT_DEBUG_MSG_OUT,(_T("User Addr=%ld "),(DWORD)(((g_cmd_ICXX.CmdHead.UserAddr[0]<<16)&0x00FF0000)+((g_cmd_ICXX.CmdHead.UserAddr[1]<<8)&0x0000FF00)+(g_cmd_ICXX.CmdHead.UserAddr[2]&0x000000FF))));
RETAILMSG(LFT_DEBUG_MSG_OUT,(_T("Freq==%d\r"),((g_cmd_ICXX.FreqService[0]<<8)&0xFF00)+g_cmd_ICXX.FreqService[1]));
//printf("User Addr=%ld\r",(DWORD)(((g_cmd_ICXX.CmdHead.UserAddr[0]<<16)&0x00FF0000)+((g_cmd_ICXX.CmdHead.UserAddr[1]<<8)&0x0000FF00)+(g_cmd_ICXX.CmdHead.UserAddr[2]&0x000000FF)));
//printf("Freq==%d\r",((g_cmd_ICXX.FreqService[0]<<8)&0xFF00)+g_cmd_ICXX.FreqService[1]);
SetEvent(m_hIcxxEvt);
break;
case GET_FKXX:
memcpy((Jl_uint8*)&g_cmd_FKXX,buf,sizeof(g_cmd_FKXX));
//RETAILMSG(LFT_DEBUG_MSG_OUT,(_T("FeedBackFlag == %x\r\n"),g_cmd_FKXX.FeedBackFlag));
if (g_cmd_FKXX.FeedBackFlag == 0x00 || g_cmd_FKXX.FeedBackFlag == 0x04)
{
SetEvent(m_hFKXXEvt);
}
else if(g_cmd_FKXX.FeedBackFlag ==0x02)
{
SetEvent(m_hSendFailEvt);
}
break;
case GET_SJXX:
//memset((char*)&g_cmd_SJXX,0,sizeof(g_cmd_SJXX));
memcpy((Jl_uint8*)&g_cmd_SJXX,buf,sizeof(g_cmd_SJXX));
SetEvent(g_WorkStatus.m_hRecvBDTimeEvt);
break;
case GET_TXXX:
{
//RETAILMSG(LFT_DEBUG_MSG_OUT,(_T("Begin=%ld\n"),GetTickCount()));
DWORD TXXX_Addr = ((buf[11]<<16)&0xFF0000) + ((buf[12]<<8)&0x00FF00) + (buf[13]&0x0000FF);
ContentLen = (((buf[16]<<8)&0xFF00) + (buf[17]&0x00FF))/8;
ContentLen-=1;
//RETAILMSG(LFT_DEBUG_MSG_OUT,(_T("\n[TXXX]")));
#if LFT_DEBUG_MSG_OUT
RETAILMSG(1,(_T("\n[From Terminal:%d]"),TXXX_Addr));
for(int i=0;i<ContentLen;i++)
{
RETAILMSG(1,(_T("%x "),buf[19+i]));
}
RETAILMSG(1,(_T("\n")));
#endif
g_Log.Printf_Log((pJl_int8)buf,buflen,RECVFROMEND);
RETAILMSG(1,(_T("BD Recv:%d\r\n"),GetTickCount()));
memset(g_cmd_Txxx.TextContent,0,sizeof(g_cmd_Txxx.TextContent));
memcpy(g_cmd_Txxx.TextContent,buf+19,ContentLen);
#if LFT_DEBUG_MSG_OUT
RETAILMSG(1,(_T("BD Receive ")));
for(int i=0;i<ContentLen;i++)
{
RETAILMSG(1,(_T("%x "),g_cmd_Txxx.TextContent[i]));
}
RETAILMSG(1,(_T("\r\n")));
#endif
m_lpEndDataProc(g_cmd_Txxx.TextContent,ContentLen,TXXX_Addr);//回调函数处理数据
//CmdDecode(g_cmd_Txxx.TextContent,ContentLen,TXXX_Addr);
}
break;
default:
break;
}
//delete pLog;
}


  • ToFourier
  • 强能力者
    7
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
数据业务层处理之后,界面就要根据数据向窗口发送消息,以实现界面上的画面跳转。众所周知,windows界面纯粹是由消息来驱动的,所需要做的只是根据不同的数据处理结果向窗口发送不同的消息即可。PS:双缓存绘图可有效降低画面闪烁。
框架的分明,好处就是易于修改易于维护。
说到底:底层硬件只管收发数据,向上存储。
数据层只负责数据处理,将结果以消息形式向窗口发送。
窗口只负责显示,由消息驱动。


2025-11-26 17:01:32
广告
不感兴趣
开通SVIP免广告
  • -黑丶洛-
  • 路人
    2
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
楼楼能帮我看几道题吗


登录百度账号

扫二维码下载贴吧客户端

下载贴吧APP
看高清直播、视频!
  • 贴吧页面意见反馈
  • 违规贴吧举报反馈通道
  • 贴吧违规信息处理公示
  • 9回复贴,共1页
<<返回c语言吧
分享到:
©2025 Baidu贴吧协议|隐私政策|吧主制度|意见反馈|网络谣言警示