C and 嵌入式tips

目录
c语言基础知识:
嵌入式常见问题
正文
第一部分 c语言基础知识
1 存储int,char,uchar没区别,只有提取的时候有区别
#include "stdio.h"
main () {
        unsigned char u=127; unsigned char u0=48;
        char c=127,c0=48; int i=127,i0=48;
        printf("u=%d;u0=%d;u=%c;u0=%c;bin=%x\n",u,u0,u,u0,u);
        printf("c=%d;c0=%d;c=%c;c0=%c;bin=%x\n",c,c0,c,c0,c);
        printf("i=%d;i0=%d;i=%c;i0=%c;bin=%x\n",i,i0,i,i0,i);
}
2 c的define 函数,这个东东类似c++ inline 函数,后者多些编译检测等
3  变长参数
va_start(vp, fmt); point to current parameter ,eg: print %c\n.
va_arg(vp,int) point to next parameter ,eg: c
va_end set null
参见:va_list、va_start、va_arg、va_end的原理与使用 va_list、va_start、va_arg、va_end的原理与使用 - 浪迹天涯 - C++博客
4  char *p;
char *p="";
两者不一样,第一个p=0 ,没有分配内存;
第二个p分配了地址,内容是一个字符\0
5 回调函数

回调函数必须是全局函数或者静态成员函数,因为普通的成员函数会隐含着一个传递函数作为参数,也就是this指针。因此如果使用普通成员函数作为回调函数的话会导致函数参数个数不匹配,因此编译失败。这也是线程函数是多为静态函数的原因。
使用实例:例子1
回调函数注册:l2注册
L3LapbProxy::L3LapbProxy(void): L3Base()
{     lapbCallbacks.handleInData   = lapbDataInCallback;   ......}
回调函数调: l2调用
void dl_api_callback_DL_DA_IN(
    appCallbackIf->handleInData((uchar FAR*)p_data, data_size, nai);
}
回调函数实现: l3 实现
void L3LapbProxy::lapbDataInCallback(unsigned char* p_data, int data_size, unsigned int nai)
{
    pL3LapbProxy = L3LapbProxy::getInstance(L3_INSTANCE_REC_IDX);
    pL3LapbProxy->lapbDataInCallbackExt(nai, DAL_HEADER_NO_FEATURE, p_data, data_size);
}
实例分析:lapbCallbacks.handleInData   = lapbDataInCallback;
(notes:static void lapbDataInCallback(unsigned char *p_data, int data_size, unsigned int nai);)
里面的二次回调不用static的,而且是private的。即调用外壳是static的.
pL3LapbProxy->lapbDataInCallbackExt(nai, DAL_HEADER_NO_FEATURE, p_data, data_size);
private:void lapbDataInCallbackExt(unsigned int extsrc, unsigned int feature, unsigned char *p_data, int data_size);

例子2: 回调函数就是函数指针;
 SipCallCallBackT *pSipCallCallBack;
 //the struct like class, it include function point
 typedef struct
{
 struct EvNewCallParamT
    { 
  ............

   bool (*OnEvTransactionChange)(int nStep); //global function define , it is also function point
    }
}SipCallCallBackT;
//pSipCallCallBack is struct point; (*OnEvTransactionChange) is functi
 pSipCallCallBack->OnEvTransactionChange(-1);

这篇文章写得很好:1 定义一 2 定义二 3 用法 3.1 声明 3.2 示例  4 应用http://blog.csdn.net/jackystudio/article/details/11720325

编译错误:
1 issue: build warning for /home/exunhng/zf/interview/veritas/set/1.C
1.c:5: error: 'aa' was not declared in this scope
1.c: At global scope:
1.c:8: error: ISO C++ forbids declaration of 'aa' with no
solution : 居然是aa();没写void。应该是 void aa();

==================================================================
第二部分  嵌入式常见问题

1 为啥不用int而用UCHAR
主要是省空间应该  dcs和ecp之间交互的message太多 怕overload吧 尽量节省空间
UCHAR opt_len,
UCHAR *opt_parm,
uchar 是int,uchar *p,是string
这个看你需求了? uchar是用8bit去表示一个数字
如果你printf %d打出来的就是0- 1111 1111之间的数字
unsigned char a = 98;
unsigned char b = 'a';
printf("%d,%c,%d,%c\n", a, a, b, b);
98,b,97,a
就是看你想打印出啥来了 主要是咱们code里面为了省空间有的时候不用一个完整的int去存数字
----是这样,我说why不用int定义呢
主要是省空间应该  dcs和ecp之间交互的message太多 怕overload吧 尽量节省空间
2 字节对齐
typedef packed struct
{
USHORT msg_id PK_MBR; /* message type */
  UCHAR   padding PK_MBR;
  UCHAR   cpu_id PK_MBR;
ULONG result PK_MBR;
ULONG addl_info PK_MBR;
} CBC_TX_BUFFER;
ushort 2
uchar 1
uchar 1 
ulong 8
ulong 8
para pragna align 1 不补位对齐。站位共20个字节。
para pragna align 0 补位对齐。就是8字节对齐。站位24个字节。
不补位才能网源传输,因为对端是对等协议。如果补位的话,在读取result的时候,就从补位的4个0开始读取了。
对端之根据协议进行,不管补位.(所有开发的规定,对端来回换,不同cpu优化方式不同,历史造成都是不优化,也是最合理的。
两边对等采用优化读写,类似local读写。理论上也是可以的)
再如:
ifdef GNU
para pragna align 1---- 表示字节不对齐
struct aa {
int a;
char b;
int c;
}AA
endif
传4,1,4;对端根据协议严格按照4,1,4获得。
如果不加限制,则编译器会优化成4,4,4.造成对方接收错误。
3 根据协议补位
struct CBC_RX_STATE {
UCHAR a;
UCHAR fill[7];
UCHAR b;
UCHAR fill2[7];
}
why要补位,直接传2个UCHAR,对端也用两个数组,不就完了吗。多传2个补位数组干嘛。
因为根据协议。补位数组是option。以便各个公司扩展的。
4 跳转到指定地址执行
Main()
{
Typedef void (*ff)();
Ff aa;
aa=(ff)(0x10000);
(*aa)();
}
这个是将函数地址,强制转化成函数指针,然后调用函数指针,执行函数.即跳转到0x10000地址

Linux C编程一站式学习
https://akaedu.github.io/book/index.html
和菜鸟一起学c之函数中堆栈及运行内存情况 和菜鸟一起学c之函数中堆栈及运行内存情况_东月之神-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值