4. Working With C
4.1 Structure and Pointer Primer
#include <stdio.h>
#include <string.h>
typedef struct Person_struct {
char firstName[20];
char lastName[20];
int age;
} Person;
void updatePerson(Person *person) {
strcpy(person->firstName, "Bob");
strcpy(person->lastName, "Fisher");
person->age = 35;
}
void exclamIt(char * phrase){
strcat(phrase, "!");
}
void app_main(void)
{
Person person;
char phrase[20] ={"Hello world"};
exclamIt(phrase);
printf("function output: %s\n", phrase);
updatePerson(&person);
printf("person: %s %s is %d years old\n", person.firstName, person.lastName, person.age);
}
输出:
4.2 Function Pointers
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct Person_struct
{
char firstName[20];
char lastName[20];
int age;
void (*DoWork)(char *dataRetrieved)
} Person;
void updatePerson(Person *person, char * dataRetrieved)
{
strcpy(person->firstName, "data from dataRetrieved");
strcpy(person->lastName, "data from dataRetrieved");
person->age = 35;
}
void connectAndGetInfo(char * url,void (*DoWork)(char *dataRetrieved))
{
//connect to wireless
// connect to endpoint
// allocate memory
char *dataRetrieved = (char *)malloc(1024);
// fill buffer with data: getRequest(&dataRetrieved);
// do work and get a person object
DoWork(dataRetrieved);
// clean up memory and other resources
free((void *)dataRetrieved);
}
void DoWorkForPerson(char *dataRetrieved)
{
Person person;
updatePerson(&person, dataRetrieved);
printf("person: %s %s is %d years old\n", person.firstName, person.lastName, person.age);
}
void app_main(void)
{
connectAndGetInfo("http://getperson.com",DoWorkForPerson);
}
输出为:
4.3 Referencing C and H files
main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "module.h"
void app_main(void)
{
moduleFunction(2, 3);
printf("value id %d\n",result);
}
module.h
#ifndef _MODULE_H
#define _MODULE_H
void moduleFunction(int a, int b);
extern int result;
#endif
module.c
int result;
void moduleFunction(int a, int b)
{
result = a + b;
}
然后注意要把 CMakerLists.txt 里面加上 module.c,我的原来是这样:
idf_component_register(SRCS "hello_world_main.c"
INCLUDE_DIRS "")
我改成了
idf_component_register(SRCS "hello_world_main.c" "module.c"
INCLUDE_DIRS "")
其实也可以这样,设置当前目录是 srcdirs ,这样就不用一个个设置文件,在文件多的时候很方便:
set(COMPONENT_SRCDIRS ".")
set(COMPONENT_ADD_INCLUDEDIRS ".")
register_component()
如果不改 CMakeLists.txt ,idf 就只知道要编译 main.c ,会编译出错
运行后得到结果:
4.4 IDF Components - Other Source Files
这一个小节比较重要。ESP-IDF 中可以使用 component,这样可以很好的进行复用,格式如下:
有几个配置文件需要更改:
-
myModule 里面的 CMakeLists.txt
set(COMPONENT_ADD_INCLUDEDIRS “.”) 要改成 set(COMPONENT_ADD_INCLUDEDIRS “include”) -
myModule 里面的 components.mk
要加上 COMPONENT_ADD_INCLUDEDIRS := include -
main 里面的 CMakeLists.txt
set(COMPONENT_ADD_INCLUDEDIRS “.” ) 要改成 set(COMPONENT_ADD_INCLUDEDIRS “…/components/myModule/include” )
这样编译才能成功,结果为: