# Share several practical embedded C programs

## 1. Hexadecimal character to integer number

Function: convert hexadecimal string to hexadecimal number. I didn't find the corresponding library function, so I wrote a function manually with reference to the online code.

The commonly used functions are ATOI and Atol, which convert decimal digit strings into int or long types, so they are not applicable in some cases.

```/*=============================================================================
#     FileName: hex2dec.cpp
#         Desc: Convert a hex string to a int number
#       Author: Caibiao Lee
#      Version:
#   LastChange: 2018-11-26
#      History:
=============================================================================*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

int c2i(char ch)
{
// If it is a number, subtract 48 from the ASCII code of the number. If ch = '2', then '2' - 48 = 2
if(isdigit(ch))
return ch - 48;

// If it is a letter, but not A~F,a~f returns
if( ch < 'A' || (ch > 'F' && ch < 'a') || ch > 'z' )
return -1;

// If it is an uppercase letter, subtract 55 from the ASCII code of the number. If ch = 'A', then 'A' - 55 = 10
// If it is a lowercase letter, subtract 87 from the ASCII code of the number. If ch = 'a', then 'a' - 87 = 10
if(isalpha(ch))
return isupper(ch) ? ch - 55 : ch - 87;

return -1;
}

int hex2dec(char *hex)
{
int len;
int num = 0;
int temp;
int bits;
int i;
char str[64] = {0};

if(NULL==hex)
{
printf("input para error \n");
return 0;
}

if(('0'==hex[0])&&(('X'==hex[1])||('x'==hex[1])))
{
strcpy(str,&hex[2]);
}else
{
strcpy(str,hex);
}

printf("input num = %s \n",str);

// In this example, str = "1de" is 3 in length, and Hex is passed by the main function
len = strlen(str);

for (i=0, temp=0; i<len; i++, temp=0)
{
// First time: i=0, *(str + i) = *(str + 0) = '1', i.e. temp = 1
// The second time: I = 1, * (STR + I) = * (STR + 1) ='d ', i.e. temp = 13
// The third time: I = 2, * (STR + I) = * (STR + 2) ='d ', i.e. temp = 14
temp = c2i( *(str + i) );
// There are 3 bits in total, and one hexadecimal bit is saved with 4 bit s
// First time: '1' is the highest bit, so temp shifts left (len - i -1) * 4 = 2 * 4 = 8 bits
// Second time:'d 'is the second highest bit, so temp moves left (len - i -1) * 4 = 1 * 4 = 4 bits
// The third time: 'e' is the lowest bit, so temp shifts left (len - i -1) * 4 = 0 * 4 = 0 bits
bits = (len - i - 1) * 4;
temp = temp << bits;

// Here, you can also use num += temp; Accumulate
num = num | temp;
}

// Return results
return num;
}

int main(int argc, char **argv)
{
int l_s32Ret = 0;

if(2!=argc)
{
printf("=====ERROR!======\n");
printf("usage: %s Num \n", argv[0]);
printf("eg 1: %s 0x400\n", argv[0]);
return 0;
}

l_s32Ret = hex2dec(argv[1]);
printf("value hex = 0x%x \n",l_s32Ret);
printf("value dec = %d \n",l_s32Ret);
return 0;
}```

Operation results:

```biao@ubuntu:~/test/flash\$ ./a.out 0x400
input num = 400
value hex = 0x400
value dec = 1024
biao@ubuntu:~/test/flash\$ ```

## 2. String to integer

Function: convert the normally input hexadecimal or hexadecimal string to int data type.

```/*=============================================================================
#     FileName: hex2dec.cpp
#         Desc: Convert a hex/dec string to a int number
#       Author: Caibiao Lee
#      Version:
#   LastChange: 2018-12-03
#      History:
=============================================================================*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

int String2int(char *strChar)
{
int len=0;
const char *pstrCmp1="0123456789ABCDEF";
const char *pstrCmp2="0123456789abcdef";

char *pstr=NULL;
int uiValue=0;
int j=0;
unsigned int t=0;
int i=0;
if(NULL==strChar)
return -1;
if(0>=(len=strlen((const char *)strChar)))
return -1;
if(NULL!=(pstr=strstr(strChar,"0x"))||NULL!=(pstr=strstr(strChar,"0X")))
{
pstr=(char *)strChar+2;

if(0>=(len=strlen((const char *)pstr)))
return -1;
for(i=(len-1);i>=0;i--)
{
if(pstr[i]>'F')
{
for(t=0;t<strlen((const char *)pstrCmp2);t++)
{
if(pstrCmp2[t]==pstr[i])
uiValue|=(t<<(j++*4));
}
}
else
{
for(t=0;t<strlen((const char *)pstrCmp1);t++)
{
if(pstrCmp1[t]==pstr[i])
uiValue|=(t<<(j++*4));
}
}
}
}
else
{
uiValue=atoi((const char*)strChar);
}
return uiValue;
}

int main(int argc, char **argv)
{
int l_s32Ret = 0;

if(2!=argc)
{
printf("=====ERROR!======\n");
printf("usage: %s Num \n", argv[0]);
printf("eg 1: %s 0x400\n", argv[0]);
return 0;
}
l_s32Ret = String2int(argv[1]);
printf("value hex = 0x%x \n",l_s32Ret);
printf("value dec = %d \n",l_s32Ret);
return 0;
}```

## 3. Create files and populate with fixed data

Function: create a fixed size file and fill the file with fixed data.

```/*=============================================================================
#     FileName: CreateFile.cpp
#         Desc: Create a fixed size file and fill it with fixed data
#       Author: Caibiao Lee
#      Version:
#   LastChange: 2018-11-26
#      History:
=============================================================================*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

//#define FILL_DATA_VALUE  0xff
#define FILL_DATA_VALUE  0x30 //char 0

int c2i(char ch)
{
if(isdigit(ch))
return ch - 48;

if( ch < 'A' || (ch > 'F' && ch < 'a') || ch > 'z' )
return -1;

if(isalpha(ch))
return isupper(ch) ? ch - 55 : ch - 87;

return -1;
}

int hex2dec(char *hex)
{
int len;
int num = 0;
int temp;
int bits;
int i;
char str[64] = {0};

if(NULL==hex)
{
printf("input para error \n");
return 0;
}

if(('0'==hex[0])&&(('X'==hex[1])||('x'==hex[1])))
{
strcpy(str,&hex[2]);
}else
{
strcpy(str,hex);
}

printf("input num = %s \n",str);

len = strlen(str);

for (i=0, temp=0; i<len; i++, temp=0)
{
temp = c2i( *(str + i) );

bits = (len - i - 1) * 4;
temp = temp << bits;

num = num | temp;
}
return num;
}

int main(int argc, char **argv)
{
FILE *l_pFile = NULL;
int  l_s32Rest = 0;
unsigned int l_WriteLen = 0;
unsigned int l_FileLen = 0;
unsigned char TempData[1024] = {FILL_DATA_VALUE};

if(3!=argc)
{
printf("usage: %s FileName  FileLen \n ", argv[0]);
printf("eg: %s ./Outfile.bin 0x400 \n ", argv[0]);
return 0;
};

const char *l_pFileName = argv[1];
if(NULL==l_pFileName)
{
printf("input file name is NULL \n");
return -1;
}

if(('0'==argv[2][0])&&(('X'==argv[2][1])||('x'==argv[2][1])))
{
l_FileLen = hex2dec(argv[2]);

}else
{
l_FileLen = atoi(argv[2]);
}

printf("Need To Write Data Len %d \n",l_FileLen);
printf("Fill Data Vale = 0x%x \n",FILL_DATA_VALUE);

for(int i=0;i<1024;i++)
{
TempData[i] = FILL_DATA_VALUE;
}

l_pFile = fopen(l_pFileName,"w+");
if(l_pFile==NULL)
{
printf("open file %s error \n",l_pFileName);
return -1;
}

while(l_WriteLen<l_FileLen)
{
if(l_FileLen<1024)
{
l_s32Rest = fwrite(TempData,1,l_FileLen,l_pFile);

}
else
{
l_s32Rest = fwrite(TempData,1,1024,l_pFile);
}

if(l_s32Rest <= 0)
{
break;
};

l_WriteLen +=l_s32Rest;
}

if(NULL!=l_pFile)
{
fclose(l_pFile);
l_pFile = NULL;
}

return 0;

}```

Operation results:

```biao@ubuntu:~/test/flash\$ gcc CreateFile.cpp
biao@ubuntu:~/test/flash\$ ls
a.out  CreateFile.cpp  hex2dec.cpp  main.cpp  out.bin
biao@ubuntu:~/test/flash\$ ./a.out ./out.bin 0x10
input num = 10
Need To Write Data Len 16
Fill Data Vale = 0x30
biao@ubuntu:~/test/flash\$ ls
a.out  CreateFile.cpp  hex2dec.cpp  main.cpp  out.bin
biao@ubuntu:~/test/flash\$ vim out.bin
1 0000000000000000                          ```

## 4. Batch processing pictures

Function: delete the fixed number of bytes in front of the picture in batch.

```/*=============================================================================
#     FileName: CutFile.cpp
#         Desc: Batch processing, delete the fixed bytes in front of the picture
#       Author: Caibiao Lee
#      Version:
#   LastChange: 2018-11-26
#      History:
=============================================================================*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>

#define PHOTO_START_TIME  83641
//l_s32PhotoTime = 92809;

int Cut_file(char * InputFile)
{
FILE *l_pFileInput = NULL;
FILE *l_pFileOutput = NULL;
char l_ars8OutputName[128] = {0};
unsigned char l_arru8TempData[1024] = {0};
int l_s32Ret = 0;
static unsigned int ls_u32Num = 0;

if(NULL== InputFile)
{
goto ERROR;
}

//sprintf(l_ars8OutputName,"./outfile/_%s",&InputFile[8]);
sprintf(l_ars8OutputName,"./outfile/00%d.jpg",ls_u32Num++);

//printf("out file name %s \n",l_ars8OutputName);

l_pFileInput = fopen(InputFile,"rb+");
if(NULL==l_pFileInput)
{
printf("input file open error\n");
goto ERROR;
}

l_pFileOutput = fopen(l_ars8OutputName,"w+");
if(NULL==l_pFileOutput)
{
printf("out file open error\n");
goto ERROR;
}

while(!feof(l_pFileInput))
{
if(l_s32Ret<0)
{
break;
}

l_s32Ret = fwrite(l_arru8TempData,1,l_s32Ret,l_pFileOutput);
if(l_s32Ret<0)
{
break;
}
}

ERROR:
if(NULL!=l_pFileOutput)
{
fclose(l_pFileOutput);
l_pFileOutput =NULL;
};

if(NULL !=l_pFileInput);
{
fclose(l_pFileInput);
l_pFileInput =NULL;
}
}

int main(void)
{
char l_arrs8InputName[128] = {0};
char l_s8PhotoChannel = 0;
int  l_s32PhotoTime = 0;

l_s8PhotoChannel = 3;
l_s32PhotoTime = PHOTO_START_TIME;

/**Starting from the first channel**/
for(int j=1;j<l_s8PhotoChannel;j++)
{

for(int i=l_s32PhotoTime;i<235959;i++)
{
memset(l_arrs8InputName,0,sizeof(l_arrs8InputName));
sprintf(l_arrs8InputName,"./image/%dY%06d.jpg",j,i);

if(0==access(l_arrs8InputName,F_OK))
{
printf("%s\n",l_arrs8InputName);
Cut_file(l_arrs8InputName);
}
}
}
}```

Operation results:

```biao@ubuntu:~/test/photo\$ gcc CutFile.cpp
biao@ubuntu:~/test/photo\$ ls
a.out  CutFile.cpp  image  outfile
biao@ubuntu:~/test/photo\$ ./a.out
./image/1Y083642.jpg
./image/1Y083714.jpg
./image/1Y083747.jpg
./image/1Y083820.jpg
./image/1Y083853.jpg
./image/1Y083925.jpg
./image/1Y084157.jpg
./image/1Y084228.jpg
./image/1Y084301.jpg
./image/1Y084334.jpg
./image/1Y084406.jpg
./image/1Y084439.jpg
./image/1Y084711.jpg
./image/1Y084742.jpg
./image/1Y173524.jpg
./image/1Y173556.jpg
./image/1Y173629.jpg
./image/1Y173702.jpg
./image/1Y173933.jpg
./image/1Y174004.jpg
./image/1Y174244.jpg
./image/1Y174315.jpg
./image/1Y174348.jpg
./image/1Y174420.jpg
./image/1Y174454.jpg
./image/1Y174733.jpg
biao@ubuntu:~/test/photo\$ tree
.
├── a.out
├── CutFile.cpp
├── image
│   ├── 1Y083642.jpg
│   ├── 1Y083714.jpg
│   ├── 1Y083747.jpg
│   ├── 1Y083820.jpg
│   ├── 1Y083853.jpg
│   ├── 1Y083925.jpg
│   ├── 1Y084157.jpg
│   ├── 1Y084228.jpg
│   ├── 1Y084301.jpg
│   ├── 1Y084334.jpg
│   ├── 1Y084406.jpg
│   ├── 1Y084439.jpg
│   ├── 1Y084711.jpg
│   ├── 1Y084742.jpg
│   ├── 1Y173524.jpg
│   ├── 1Y173556.jpg
│   ├── 1Y173629.jpg
│   ├── 1Y173702.jpg
│   ├── 1Y173933.jpg
│   ├── 1Y174004.jpg
│   ├── 1Y174244.jpg
│   ├── 1Y174315.jpg
│   ├── 1Y174348.jpg
│   ├── 1Y174420.jpg
│   ├── 1Y174454.jpg
│   └── 1Y174733.jpg
└── outfile
├── 000.jpg
├── 0010.jpg
├── 0011.jpg
├── 0012.jpg
├── 0013.jpg
├── 0014.jpg
├── 0015.jpg
├── 0016.jpg
├── 0017.jpg
├── 0018.jpg
├── 0019.jpg
├── 001.jpg
├── 0020.jpg
├── 0021.jpg
├── 0022.jpg
├── 0023.jpg
├── 0024.jpg
├── 0025.jpg
├── 002.jpg
├── 003.jpg
├── 004.jpg
├── 005.jpg
├── 006.jpg
├── 007.jpg
├── 008.jpg
└── 009.jpg

2 directories, 54 files
biao@ubuntu:~/test/photo\$ ```

Before running, you need to create two directories. image is used to store the pictures to be processed, and outfile is used to store the processed files. This batch file processing method is very violent, and it can be used occasionally.

## 5. IO control applet

In order to save space, embedded device systems generally cut the system, so many useful commands will be deleted. It is also troublesome to debug code in embedded devices. Generally, you can only see serial port printing. Now I have written a small program to view and control the IO level status of Hisilicon Hi3520DV300 chip.

```/*=============================================================================
#     FileName: Hi3520_IO_CTRL.cpp
#         Desc: Hi3520DV300 IO Write and  Read
#       Author: Caibiao Lee
#      Version:
#   LastChange: 2018-11-30
#      History:
=============================================================================*/
#include <stdio.h>
#include <stdlib.h>
#include "hstGpioAL.h"

int PrintfInputTips(char *ps8Name)
{
printf("=========== error!!! ========\n\n");
printf("usage Write: %s GPIO bit value \n", ps8Name);
printf("usage Read : %s GPIO bit \n", ps8Name);
printf("eg Write 1 to GPIO1_bit02  :     %s 1 2 1\n", ps8Name);
printf("eg Read  GPIO1_bit02 Value :     %s 1 2 \n\n", ps8Name);

printf("=============BT20==================\n")
printf("USB HUB    GPIO_0_2  1_UP; 0_Down \n");
printf("RESET_HD   GPIO_13_0 0_EN; 1_disEN\n");
printf("Power_HD   GPIO_13_3 1_UP; 0_Down \n");
return 0;
}

int main(int argc, char **argv)
{
if((3!=argc)&&(4!=argc))
{
PrintfInputTips(argv[0]);
return -1;
}

unsigned char l_u8GPIONum = 0;
unsigned char l_u8GPIOBit = 0;
unsigned char l_u8SetValue = 0;

GPIO_GROUP_E  l_eGpioGroup;
GPIO_BIT_E   l_eBit;
GPIO_DATA_E   l_eData;

l_u8GPIONum   = atoi(argv[1]);
l_u8GPIOBit   = atoi(argv[2]);

if(l_u8GPIONum<14)
{
l_eGpioGroup = (GPIO_GROUP_E)l_u8GPIONum;
}else
{
printf("l_u8GPIONum error l_u8GPIONum = %d\n",l_u8GPIONum);
return -1;
};

if(l_u8GPIOBit<8)
{
l_eBit = (GPIO_BIT_E)l_u8GPIOBit;
}else
{
printf("l_u8GPIOBit error l_u8GPIOBit = %d\n",l_u8GPIOBit);
return -1;
}

if(NULL!=argv[3])
{
l_u8SetValue = atoi(argv[3]);
if(0==l_u8SetValue)
{
l_eData = (GPIO_DATA_E)l_u8SetValue;
}else if(1==l_u8SetValue)
{
l_eData = (GPIO_DATA_E)l_u8SetValue;
}else
{
printf("l_u8SetValue error l_u8SetValue = %d\n",l_u8SetValue);
}
}

if(3==argc)
/**set input**/
HstGpio_Set_Direction(l_eGpioGroup, l_eBit, GPIO_INPUT);

char l_s8bit_val = 0;
HstGpio_Get_Value(l_eGpioGroup, l_eBit, &l_s8bit_val);

}else if(4==argc)
{/**write**/
printf("Write GPIO %d; Bit %d; Value %d\n",l_u8GPIONum,l_u8GPIOBit,l_u8SetValue);

/***set IO output*/
HstGpio_Set_Direction(l_eGpioGroup, l_eBit, GPIO_OUPUT);

/**Write To IO**/
HstGpio_Set_Value(l_eGpioGroup,l_eBit,l_eData);
}else
{

}

return 0;

}```

## 6. Insert data in fixed location of file

Insert fixed data in the fixed position of the file.

```#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BASIC_FILE_NAME  "./nandflash.bin"
#define UBOOT_FILE_NAME  "./u-boot.bin"
#define KERNEL_FILE_NAME "./kernel.bin"
#define ROOTFS_FILE_NAME "./rootfs.bin"
#define APP_FILE_NAME  "./app.bin"

#define UBOOT_POSITION  0x00
#define KERNEL_POSITION  0x100000
#define ROOTFS_POSITION  0x500000
#define APP_POSITION  0x2700000

int InsertData(FILE *pfBasic,FILE *psInsert,int s32Position)
{
int l_S32Ret = 0;
unsigned char l_arru8Temp[1024] = {0xff};

fseek(pfBasic,s32Position,SEEK_SET);
fseek(psInsert,0,SEEK_SET);
while(1)
{
if(l_S32Ret > 0)
{
l_S32Ret = fwrite(l_arru8Temp,1,l_S32Ret,pfBasic);
if(l_S32Ret<=0)
{
printf("line %d error l_S32Ret = %d \n",__LINE__,l_S32Ret);
return -1;
}
}else
{
break;
}
}

return 0;
}

int main(void)
{
int l_s32Ret = 0;
FILE *l_pfBasec = NULL;
FILE *l_pfUboot = NULL;
FILE *l_pfKernel = NULL;
FILE *l_pfRootfs = NULL;
FILE *l_pfApp = NULL;

l_pfBasec = fopen(BASIC_FILE_NAME,"r+");
if(NULL==l_pfBasec)
{
printf("line %d error \n",__LINE__);
goto ERROR;
}

l_pfUboot = fopen(UBOOT_FILE_NAME,"r");
if(NULL==l_pfUboot)
{
printf("line %d error \n",__LINE__);
goto ERROR;
}

l_pfKernel = fopen(KERNEL_FILE_NAME,"r");
if(NULL==l_pfKernel)
{
printf("line %d error \n",__LINE__);
goto ERROR;
}

l_pfRootfs = fopen(ROOTFS_FILE_NAME,"r");
if(NULL==l_pfRootfs)
{
printf("line %d error \n",__LINE__);
goto ERROR;
}

l_pfApp = fopen(APP_FILE_NAME,"r");
if(NULL==l_pfApp)
{
printf("line %d error \n",__LINE__);
goto ERROR;
}

if(0> InsertData(l_pfBasec,l_pfUboot,UBOOT_POSITION))
{
printf("line %d error \n",__LINE__);
goto ERROR;
}

if(0> InsertData(l_pfBasec,l_pfKernel,KERNEL_POSITION))
{
printf("line %d error \n",__LINE__);
goto ERROR;
}

if(0> InsertData(l_pfBasec,l_pfRootfs,ROOTFS_POSITION))
{
printf("line %d error \n",__LINE__);
goto ERROR;
}

if(0> InsertData(l_pfBasec,l_pfApp,APP_POSITION))
{
printf("line %d error \n",__LINE__);
goto ERROR;
}

ERROR:
if(NULL!=l_pfBasec)
{
fclose(l_pfBasec);
l_pfBasec = NULL;
}

if(NULL!=l_pfUboot)
{
fclose(l_pfUboot);
l_pfUboot = NULL;
}

if(NULL!=l_pfKernel)
{
fclose(l_pfKernel);
l_pfKernel = NULL;
}

if(NULL!=l_pfRootfs)
{
fclose(l_pfRootfs);
l_pfRootfs = NULL;
}

if(NULL!=l_pfApp)
{
fclose(l_pfApp);
l_pfApp = NULL;
}

return 0;
}```

## 7. Get local IP address

To obtain the local IP address in linux devices, you can use the following program to support devices with three network ports on the largest host. Of course, the number of network cards can be modified.

```#include <stdio.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>

int get_local_ip(char *ps8IpList)
{
int l_s32IPCount = 0;

{
{
{
if(l_s32IPCount == 0)
{
} else
{
}
l_s32IPCount++;
}
}
}

return l_s32IPCount;
}

int main()
{