C/C++在工作中de笔记以及Debug历程


文中有错误的地方,也请指出,我也会进一步改正,大家互相学习,谢谢~

笔记

C/C++中函数指针的定义以及使用:
typedef (返回值类型) (*pFunction)(参数);
  • 运用函数指针,建立函数列表,以及调用方式
//定义函数指针
typedef void (*pFunction)(unsigned char *pMsg,unsigned short length);
//定义函数
void Function_01(unsigned char *pMsg,unsigend short length);
void Function_02(unsigned char *pMsg,unsigend short length);
void Function_03(unsigned char *pMsg,unsigend short length);
...
//定义结构体,将函数和索引进行绑定
typedef struct funcList
{
	unsigned int	index;
	pFcuntion		pFunc;
}
//定义函数列表
funcList FunctionList[] = 
{
	{ 0x01 ,&Function_01 }
	{ 0x02 ,&Function_02 }
	{ 0x03 ,&Function_03 }
	...
}
//函数列表中函数数量
unsigned int NumOfFunc = sizeof(FunctionList)/sizeof(FunctionList[0]);

//函数列表的使用
//检索函数索引,匹配对应项
for (int i = 0; i < NumOfFunc; i++)
{
	if (index == FunctionList[i].index)
	{
		//索引配对,this指针指向相应函数,完成调用
		(this->*FunctionList[i].pFunc)(pMsg, length);
		break;
	}
}

STM32的Bootloader的使用

通过使用BootLoader,可以使得同一芯片中,包含多套程序,并实现程序跳转。

//定义APP所在地址
#define AddressOfApplication	0x08002800

void (*AppFunction)(void);

__ASM void MSR_MSP(unsigned int address)
{
	MSR	MSP,	r0
	BX	r14
};

void JumpToApp(unsigned int address)
{
	//先判断地址合法性
	if(((*(__IO unsigned int*)address) & 0x2FFE0000) == 0x20000000)
	{
		//将函数指针指向App的中断向量表
		//(address)是App程序的起始地址
		//(address + 4)是App的中断向量表的地址
		AppFunction = (void(*)())*(__IO unsigned int*)(address + 4);
		//此处分割成 (void(*)()) 和 *(__IO unsigned int*)(address + 4)
		//这么看会好理解点
		MSR_MSP(*(__IO unsigned int*)address);
		for(int i = 0;i < 8;i++)
		{
			//关闭中断
			NVIC->ICER[i] = 0xFFFFFFFF;
			NVIC->ICPR[i] = 0xFFFFFFFF;
		}
		//跳转至App的中断向量表
		AppFunction();
	}
}

程序中的AddressOfApplication的地址值根据实际程序烧写地址来决定
Project 菜单中的 Option for Target ‘xxxx’… 选项里的 Target 选项卡里左下方勾选的IROM1的地址决定。
比如我这里的设定是:

defaulton-chipStartSizeStartup
IROM1:0x0800 00000x0000 2800·

那我的BootLoader的起始地址是0x0800 0000,占用空间是0x0000 2800(10KB),那我的Application的程序在烧写时,地址就设在0x0800 2800开始或者之后,则我的Application在这里填写的值就为:

defaulton-chipStartSizeStartup
IROM1:0x0800 28000x0002 0000·

BootLoader和Application两套程序烧写完后,运行起来,BootLoader运行完后跳转就会跳到Application继续运行了。

还可以在BootLoader里面对Application的程序进行更新升级,根据外设的不同,可以进行远程升级,OTA升级等等的。

联合体和结构体的搭配使用的妙用
union Example
{
	unsigned char someBytes[6];
	struct
	{
		//第一个字节
		unsigned char ByteOne_A		: 1;
		unsigned char ByteOne_B		: 2;
		unsigned char ByteOne_C		: 3;
		unsigned char ByteOne_D		: 1;
		//第二个字节
		unsigned char ByteTwo_A		: 3;
		unsigned char ByteTwo_B		: 2;
		unsigned char ByteTwo_C		: 3;
		//第三~六字节
		unsigned int Byte3To6;
	}detail;
};

首先做一些概念的解释
联合体(union),简单讲就是联合体内的各个成员共用一段内存空间,这段空间的长度有该联合体内使用长度最长的决定。
结构体(struct),由一系列具有相同类型或不同类型的数据构成的数据集合

这里通过两者的嵌套使用以及":"的使用,使得可以精确到位进行操作,例如:

Example temp;

temp.detail.ByteOne_A = 0x01;
temp.detail.ByteTwo_A = 0x03;
temp.detail.ByteTwo_C = 0x02;
temp.detail.Byte3To6 = 0x12345678;

for(int i = 0;i < 6;i++)
{
	printf("%X ",temp.someBytes[i]);
}

结果会打印出

80 C2 12 34 56 78
ARM-Linux下App写日志

va_list 是在C语言中解决变参问题的一组宏,用于获取不确定个数的参数。
使用时需包含头文件 stdarg.h
通过使用va可以轻松实现和printf基本一致的功能,但是我们此时要的不是仅仅打印在屏幕上,而是写入到本地日志文件中,建立一套自己的日志文件系统。

#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;

#include "time.h"
#include "stdarg.h"

void WriteLog(const char *stringData, ...)
{
	va_list va;
	
	time_t timeTemp;
	struct tm *timer;

	char buff[1024];

	timeTemp = time(NULL);
	timer = localtime(&timeTemp);

	ofstream fout;
	fout.open("./log/log.txt",ios::app);
	
	va_start(va,stringData);
	vsnprintf(buff,1024,stringData,va);

	fout << endl;
	//写入写日志的时间
	fout << timer->tm_year + 1900 << "-" << setw(2) << timer->tm_mon +  1 << "-" << setw(2) << timer->tm_mday << " ";
	fout << setw(2) << timer->tm_hour << ":" << setw(2) << timer->tm_min << ":" << setw(2) << timer->sec << " :";
	//写日志数据
	fout << buff << endl;
	fout << "\t\t\t 版本号 : " << "Ver x.x.x" << endl;

	va_end;

	fout.close();
}
C++检测文件大小
int CheckSizeOfFile(const char *filename)
{
	ifstream fin;
	fin.open(filename);
	if(!fin.is_open())
	{
		fin.close();
		return 0;
	}
	fin.seekg(0,ios::end);
	streampos sp = fin.tellg();
	return (int)sp;
}
ARM-Linux多线程以及线程锁

Debug

segment fault

持续更新,敬请期待。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值