转自:http://blog.csdn.net/sky_ting/article/details/72956975?locationNum=11&fps=1
这编博客是为了记录自己编程的心路历程,固件编程一直是自己的短板,身为一个硬件工程师偏偏经常接到写固件的活,其实我的内心是拒绝的
。但是,这想让自己的短板变成平板并不冲突~所以该好好学就好好用功
。总结的只是一些这段时间下来的心得~不喜请轻喷~有什么问题欢迎指出
。
(以下是基于stm32的编程)
One:
在编程中常常要调用其它文件(如.c)中的参数,往往设置为全局变量会让各个独立的函数产生不必要的相关性,所以在任务函数中,实时改变另一个函数的参数。可通过 调用函数的办法间接改变参数。
//******Main.c********//
Task(){
Set_ip_addr();
}
//******Eth_ip.c*******//
Void set_ip_addr(){
Local_ip_address.m_addr[3] = ReadDip();
}
Two:
在定义一个变量的时候根据需要常常会定义不位数的变量,如8、16位等。 当将一个16位的变量强制转换为一个8位变量的数组时,存储顺序往往容易忽略。
u16 word = 0xabcd1234
u8 *p = (u8 *) &word;
p[0] p[1] p[2] p[3]存储顺序应该是 34 12 cd ab
Three:
在中断中调取写入队列的函数,然后在实际应用(任务函数中调用)时从队列取出
中断队列接收和调用可写在一个.c函数中。
多个struct层层叠加层层解析,根据自己想要的方式来解析一组数据
Four:
数组命令匹配调用参数或者函数:
typedef int (*DebugCmdHANDLE) (const char *); //const只分配一次内存//
//定义了一个返回类型为int DebugCmdHANDLE的函数指针
//函数占一段连续的内存区域 函数名被转换为首地址与数组类似
//即函数名可以传递给函数指针
Ps://什么是指针函数?就是返回类型为指针的函数
// int *DebugCmdHANDLE (const char *)这样定义的是返回值为int指针的函数
typedef struct tg_debug_cmd_handle_tab{
char *m_pCmdStr;
DebugCmdHANDLE m_Handel;
char *m_pHelpStr;
} CmdHandleTAB
//命令表
static const CmdHandleTAB handle_tab[]=
{
{“ledon”, ledon_handle, 0},
{“ledoff”, ledoff_handle, 0}
};
//传递handle_tab[]出去比较,用函数传递比较好
const CmdHandleTAB *cmd_handle_tab(void)
{
Return handle_tab;
}
//调用的函数
Int ledon_handle(const char *pData)
{
//
}
Five:
调用原始函数是一个很好的办法,比如我在使用的时候调用了atoi();直接将char *所代表的123,转换成了int 的123!
Six:
//const 请作为常量使用把,并且肯定是个常量 但是把地址给别人通过别人的地址是可以修改的
//volatile 请不要做不靠谱的优化,这值很可能改变掉
//const与volatile并不矛盾
//static
1)在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。
2) 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。
3) 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。
Seven:
int b =1; int *p=&b; int **a=&p;
int **a中a表示的是指针的地址,也就是地址(指针所指对向的地址)的地址(指针的地址);*a则表示前一个地址,a则表示后一个地址。
用到int **的情况是需要对指针的地址进行加减操作并且赋值的。
Eight:
键盘上的ENTER在ASCII中表示 0x0d、13、某些语言中为’\r’。
在Linux系统中ENTER用’\n’表示,Windows系统中用”\r\n”两个字符表示。