首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 其他相关 >

学习札记(无聊时的总结)

2012-08-07 
学习笔记(无聊时的总结)转载请标明是引用于 http://blog.csdn.net/chenyujing1234 欢迎大家拍砖! 平时在查

学习笔记(无聊时的总结)

转载请标明是引用于 http://blog.csdn.net/chenyujing1234 

欢迎大家拍砖!

 平时在查看代码中做的笔记,主要涉及嵌入式开发中的代码风格编译方法、技巧等。希望对大家有帮助。

 

1、把32位的数反转(高低位对调)

今天在查看TrueCrypt工程源码时(参考我的文章<<>>)看到位操作的算法,觉得很巧妙,这里做个总结。

unsigned __int32 MirrorBytes32 (unsigned __int32 x){unsigned __int32 n = (unsigned __int8) x;n <<= 8; n |= (unsigned __int8) (x >> 8);n <<= 8; n |= (unsigned __int8) (x >> 16);return (n << 8) | (unsigned __int8) (x >> 24);}

如下图所求,传进来的x是32位的ABCD(假设A为8位、B为8位、C为8位、D为8位),经过运算后得到DCBA。


学习札记(无聊时的总结)

 

2、自己封装memset函数

 由于在一些小型的嵌入式设备上(如uc/OSII 或STM32)用C语言写程序,很多C语言中的API不能用,或者效率过低,得自己封装一些函数。

下面介绍我们常用的memset的实现:

/***********************************************************************************************************                                        CLEAR A SECTION OF MEMORY** Description: This function is called by other uC/OS-II services to clear a contiguous block of RAM.** Arguments  : pdest    is the start of the RAM to clear (i.e. write 0x00 to)**              size     is the number of bytes to clear.** Returns    : none** Notes      : 1) This function is INTERNAL to uC/OS-II and your application should not call it.*              2) Note that we can only clear up to 64K bytes of RAM.  This is not an issue because none*                 of the uses of this function gets close to this limit.*              3) The clear is done one byte at a time since this will work on any processor irrespective*                 of the alignment of the destination.**********************************************************************************************************/void  OS_MemClr (INT8U *pdest, INT16U size){    while (size > 0) {        *pdest++ = (INT8U)0;        size--;    }}


用法:

OS_EXT  OS_EVENT          OSEventTbl[OS_MAX_EVENTS];/* Table of EVENT control blocks                   */#endifOS_MemClr((INT8U *)&OSEventTbl[0], sizeof(OSEventTbl)); /* Clear the event table                   */


以上能实现是因sizeof()计算出来的大小是以INT8U为单位的。

 

 

3、
typedef LONG(*PINTERRUPTSYNCROUTINE)( IN PVOID  DynamicContext );

 

这样才能进行 PINTERRUPTSYNCROUTINE pp; 变量的声明

4、

(*(volatile unsignedchar *const)(reg)) =

const和volatile放在一起的意义在于:
(1)本程序段中不能对reg作修改,任何修改都是非法的,或者至少是粗心,编译器应该报错,防止这种粗心;
(2)另一个程序段(如硬件)则完全有可能修改,因此编译器最好不要做太激进的优化。

5、这里的union后面可以加上union的名字
/* *//*  混合控制器*//* *//* */typedef struct tMIXERCONTROL {    DWORD           cbStruct;           /* MIXERCONTROL的大小*/    DWORD           dwControlID;        /* 为混频器的唯一的控制id */    DWORD           dwControlType;      /* MIXERCONTROL_CONTROLTYPE_xxx */    DWORD           fdwControl;         /* MIXERCONTROL_CONTROLF_xxx */    DWORD           cMultipleItems;     /* if MIXERCONTROL_CONTROLF_MULTIPLE set */    TCHAR           szShortName[MIXER_SHORT_NAME_CHARS];    TCHAR           szName[MIXER_LONG_NAME_CHARS];    union     {       struct        {           LONG    lMinimum;           /* 此控制器标记的最小*/           LONG    lMaximum;           /* 此控制器标记的最大*/       };       struct        {           DWORD   dwMinimum;          /* 此控制器未标记的最小*/           DWORD   dwMaximum;          /* 此控制器未标记的最大*/       };       DWORD       dwReserved[6];    } Bounds;    union     {       DWORD       cSteps;             /* 在最小和最大间的步数*/       DWORD       cbCustomData;       /* 通用数据的bytes大小*/       DWORD       dwReserved[6];      /* !!! needed? we have cbStruct.... */    } Metrics;} MIXERCONTROL, *PMIXERCONTROL, FAR *LPMIXERCONTROL;

6、

分配多个变量大小的区域,然后根据区域大小分配给各自使用

PCSP_PIN pCsPin = NULL;PCSMULTIPLE_ITEM pCSDataRangeItems = NULL;PCS_DATARANGE_VIDEO pCSDataRangeVideo = NULL;DWORD dwStructSize = sizeof(CSP_PIN) + sizeof(CSMULTIPLE_ITEM) + sizeof(CS_DATARANGE_VIDEO); pCsPin = (PCSP_PIN) malloc(dwStructSize);    if (NULL == pCsPin)    {        RETAILMSG(CAMAPP_ERROR_MSG, (TEXT("ChangeResolution: Malloc memory failed!\r\n")));        bRetVal = FALSE;        goto __exit;    }    pCsPin->Property = IOCTLInput;    pCsPin->PinId = pinId;    pCSDataRangeItems = (PCSMULTIPLE_ITEM) (pCsPin + 1);    pCSDataRangeItems->Count = 1;    pCSDataRangeItems->Size = sizeof(CSMULTIPLE_ITEM) + sizeof(CS_DATARANGE_VIDEO);    pCSDataRangeVideo = (PCS_DATARANGE_VIDEO) (pCSDataRangeItems + 1);    memcpy(pCSDataRangeVideo, pPinDataRange, sizeof(CS_DATARANGE_VIDEO));

7、请注意X86时的给寄存器赋值的方法
VOID WRITE_PORT_UCHAR(PUCHAR  Port, UCHAR   Value){#if defined(x86)    __asm {mov         dx, word ptr Portmov         al, Valueout         dx, al}#else*(volatile UCHAR * const)Port = Value;#endif}


 

8、
Register I = rEP3_DMA_CON;For(I = 0; I < 10; i++);

 

Register是variable的一种存储类型,叫做寄存器型号。

一个变量要是被定义为这种类型,他就会被存储在通用寄存器中,所以存储速度快。

 

9、通过读回来来强制出现写, 当循环重启时提供更多时间
static voidmaebsa_reset (PDRVCONTEXT pDrv, int reset){AU13XX_VSSCTRL *vss = pDrv->vss;volatile uint32 junk;if (reset){vss->bsa.clkrst = 3;}else{vss->bsa.clkrst = 2;}// 通过读回来来强制出现写, 当循环重启时提供更多时间junk = vss->bsa.clkrst;}


 

10、

// pSMB->evnt =pSMB->evnt;

staticBOOL WriteData( PDEVICE_INSTANCE DeviceInstance,              SMBUS_TRANSFER   *pTransfer ){    PSC_SMB *pSMB = DeviceInstance->pSMB;    ULONG i;    BOOL status = FALSE;    EnterCriticalSection(&DeviceInstance->ControlMutex);    // 清除之前的状态    pSMB->evnt = pSMB->evnt;

11、在宏里定义了一个禁用警告,再把警告打开

第一点:

// 在宏里定义了一个禁用警告,再把警告打开

第二点:像下面的语句就会产生4309警告。

编译后提示为:warning C4309: “初始化”: 截断常量值

原因是因为特定的类型转换操作导致常量超出被分配的空间,需要使用更大的数据类型来保存该常量.

int main(){char c = 128; char x = (char)128;return 0;}
// #pragma warning(default: 4309) 把警告打开#if EDID_SAMPLE#pragma warning(disable: 4309)static char edid_sample[] ={0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x22,0x64,0x0B,0x19,0x48,0x07,0x00,0x00,0x2A,0x12,0x01,0x03,0x80,0x3B,0x25,0x78,0xEA,0x9E,0x71,0xA6,0x54,0x4C,0x9F,0x24,0x10,0x51,0x57,0xBF,0xEF,0x80,0xD1,0x00,0xB3,0x00,0xA9,0x40,0x95,0x00,0x90,0x40,0x81,0x80,0x81,0x40,0x71,0x4F,0x28,0x3C,0x80,0xA0,0x70,0xB0,0x23,0x40,0x30,0x20,0x36,0x00,0x62,0x5E,0x21,0x00,0x00,0x1A,0x00,0x00,0x00,0xFF,0x00,0x31,0x38,0x36,0x34,0x0A,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00,0xFD,0x00,0x38,0x4B,0x18,0x50,0x0F,0x00,0x0A,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00,0xFC,0x00,0x48,0x46,0x32,0x38,0x39,0x48,0x0A,0x20,0x20,0x20,0x20,0x20,0x20,0x01,0xD4};#pragma warning(default: 4309)  // disable warning for "no return value"#endif


 

11、

设置VS2008文本编辑中高亮显示相关的变量的颜色的设置:

选项->字体和颜色->VA X Find Reference-》
注:前提是你装了VS助手

 

12、 32 bit 对齐宏
// 32 bit 对齐宏#define ALIGN(size) ((size & 0xfffffffc) + ((size & 3) ? 4 : 0))pHTTPSession = (P_HTTP_SESSION)malloc(ALIGN(sizeof(HTTP_SESSION)));/*0xfffffffc  : 1111 1111 1111 1111 1111 1111 1111 1100         3  :  0000 0000 0000 0000 0000 0000 0000 0011*/



 

13、在except中用GetExceptionCode()来决断异常类型

在KavteP51中有serialhw.c文件中有

try{//USR1OUTREG32(&pHWHead->pUartReg->USR1,CSP_BITFVAL(UART_USR1_PARITYERR, UART_USR1_PARITYERR_SET) |CSP_BITFVAL(UART_USR1_RTSD, UART_USR1_RTSD_SET) |CSP_BITFVAL(UART_USR1_ESCF, UART_USR1_ESCF_SET) |CSP_BITFVAL(UART_USR1_FRAMERR, UART_USR1_FRAMERR_SET) |CSP_BITFVAL(UART_USR1_AGTIM, UART_USR1_AGTIM_SET) |CSP_BITFVAL(UART_USR1_DTRD, UART_USR1_DTRD_SET) |CSP_BITFVAL(UART_USR1_AIRINT, UART_USR1_AIRINT_SET) |CSP_BITFVAL(UART_USR1_AWAKE, UART_USR1_AWAKE_SET));//USR2OUTREG32(&pHWHead->pUartReg->USR2,CSP_BITFVAL(UART_USR2_ADET, UART_USR2_ADET_SET) |CSP_BITFVAL(UART_USR2_DTRF, UART_USR2_DTRF_SET) |CSP_BITFVAL(UART_USR2_IDLE,UART_USR2_IDLE_SET) |CSP_BITFVAL(UART_USR2_ACST, UART_USR2_IDLE_SET) |CSP_BITFVAL(UART_USR2_RIDELT, UART_USR2_RIDELT_SET) |CSP_BITFVAL(UART_USR2_IRINT, UART_USR2_IRINT_SET) |CSP_BITFVAL(UART_USR2_WAKE, UART_USR2_WAKE_SET) |CSP_BITFVAL(UART_USR2_DCDDELT, UART_USR2_DCDDELT_SET) |CSP_BITFVAL(UART_USR2_RTSF, UART_USR2_RTSF_SET) |CSP_BITFVAL(UART_USR2_BRCD, UART_USR2_BRCD_SET) |CSP_BITFVAL(UART_USR2_ORE, UART_USR2_ORE_SET));}except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)


 

13、

在Platform\KavteP51\SRC\DRIVERS\BLOCK\NANDFMD\dll\sources文件中有

TARGETLIBS=\

    $(_SYSGENSDKROOT)\lib\$(_CPUINDPATH)\coredll.lib \

    $(_SYSGENOAKROOT)\lib\$(_CPUINDPATH)\ceddk.lib \

$(_TARGETPLATROOT)\lib\$(_CPUDEPPATH)\cspddk.lib

即会链接到这些以上 lib文件中.所以如果在

C:\WINCE600\PUBLIC\COMMON\OAK\LIB\ARMV4I\RETAIL下没有coredll.lib文件时编译会报:

不知怎么编译coredll.lib

---------   \WINCE600\OSDesigns\OSKavteP51\OSKavteP51\Wince600中的文件是可以从类似于C:\WINCE600\PUBLIC\COMMON\OAK\LIB\ARMV4I\RETAIL这样的public编出来的

14、

BOOL SHInitExtraControls(void);

 

 

 

 

CAygshellHelper::CAygshellHelper(void )

{

    if( m_hAygshellDLL = LoadLibrary( L"aygshell.dll" ) )

    {

       BOOL (*SHInitExtraControls)() =NULL;  //  把函数指针置空

 

15、按以下方式定义字符串
const char c_szASXHeaderFormat[] = "<ASX version = \"3.0\">\n""    <PARAM name = \"Last Entry\" value = \"%d\"/>\n""    <PARAM name = \"Generator\" value = \"CEPlayer\"/>\n";


 

16、以下的判断方法挺好的
bool IsBadFilenameChar(TCHAR c){    if (c < 32 || NULL != _tcschr(TEXT("\"/\\[]:;|=,?*<>"), c))    {        return true;    }     return false;}


 

17、

请注意以下红色的地方:类CplaylistMgr中的结构体list_t中的成员是类CplaylistMgr中的成员

class CPlaylistMgr{    // two-way linked list manages playlists    struct list_t    {       list_t() :     pPlaylist(NULL),       pNext(NULL),       pPrev(NULL),       pDupNames(NULL)    { }     ~list_t()    {       RemoveDupName();       delete pPlaylist;       pNext = NULL;       pPrev = NULL;       pDupNames = NULL;    }    CPlaylist * pPlaylist;    list_t    * pNext;    list_t    * pPrev;    duplist_t * pDupNames;


 

18、

通过定义结构体中的类型为 volatile 来使此结构体变量为可变的

#ifndef ASSEMBLERtypedef volatile struct{    uint32 rxdata;    uint32 txdata;    uint32 inten;    uint32 intcause;    uint32 fifoctrl;    uint32 linectrl;    uint32 mdmctrl;    uint32 linestat;    uint32 mdmstat;    uint32 reserved0;    uint32 clkdiv;    uint32 reserved1[53];    uint32 enable;    uint32 mdmen;    uint32 bidir;} AU1X00_UART;#endif


 

 

19、

#pragma warning 指令允许有选择性的修改编译器的警告消息的行为,格式如下:

#pragma warning( arning-specifier : warning_number-list[; warning

#pragma warning(push [ , n])

#pragma warning (pop)

主要用到的警告表示有如下:

Once : 只显示一次(警告/错误)消息

Default: 重置编译器的警告行为到默认状态

1,2,3, 4: 四个警告级别

Disable:禁用指定的警告信息

Error: 将指定的警告信息作为错误报告

Eg:

  #pragma   warning(once:4385)                 //   4385号警告信息仅报告一次#pragma   warning(error:164)                 //   把164号警告信息作为一个错误。      #pragma   warning(   push   )//保存所有警告信息的现有的警告状态。        #pragma   warning(   push,   n)//保存所有警告信息的现有的警告状态,并且把全局警告等级设定为n。           #pragma   warning(   pop   )//向栈中弹出最后一个警告信息,在入栈和出栈之间所作的一切改动取消。  #pragma warning(push)#pragma warning(disable: 4115 4201 4204 4214)#include <windows.h>#pragma warning(pop)


 

 

20、采用下面的方法来查看写进去的数据是否起效了
data = *psrc;       flash[0x555] = 0x00AA;       flash[0x2AA] = 0x0055;       flash[0x555] = 0x00A0;       *pdst = data;       while (*pdst != data && (--timeout)) ;


 

21、在source insight中把字体改为中文后写中文就不会空一个空格了

 

22、通过指针指向的数据的大小来新建空间,并把地址返回给此指针
pci = (PCODECINST)LocalAlloc(LPTR, sizeof(*pci));

23、采用%a打印出来的是以科学计算法来计算的数字

热点排行