当前位置:网站首页>03 - programming framework: Division of application layer, middle layer and driver layer in bare metal programming
03 - programming framework: Division of application layer, middle layer and driver layer in bare metal programming
2022-06-30 07:16:00 【Oil splashed sliced noodles】
03- Programming framework : Application layer in bare metal programming 、 Middle layer 、 Driver layer division
1. Frame design level
《 The code of 》 In chapter five , Program design is divided into four levels :
- software system , It's the whole system 、 Whole procedure
- Break down into subsystems or packages . For example, we can split it into : Input subsystem 、 Display subsystem 、 Business system
- Decompose into classes .C There are no classes in the language , You can use structures to describe subsystems
- Decompose into subroutines : Implement those structures ( There are function pointers in the structure )
2. Programming —— Press the key to control LED For example
2.1 Basic function realization , Coupling is too serious
void main(void)
{
GPIO_PinState key;
while (1)
{
key = GPIO_ReadPin(GPIOX, GPIO_PIN_X);
if (key == GPIO_PIN_RESET)
GPIO_WritePin(GPIOX, GPIO_PIN_X, GPIO_PIN_RESET);
else
GPIO_WritePin(GPIOX, GPIO_PIN_X, GPIO_PIN_SET);
}
}
- This type of code is the most common , stay stm32 I am learning , This kind of writing is particularly common , In small projects, you can , Once the function is complex, it is difficult to troubleshoot problems .( Of course, this kind of code is simple , Minimum storage space , There is no problem in writing this in a relatively simple task )
- Problems with the code :
- Too many details : It needs to be combined with schematic diagram ( Check pin )、 Hardware knowledge is required ( Pin high and low level detection )、 SCM library functions /HALL Knowledge
- Code can't be reused : Change chip / Pin , A lot of code changes
- Can't develop : For example, if you want to light the lamp by long pressing ," Long press " This action is not easy to expand
2.2 Use sub functions
// main.c
void main(void)
{
int key;
while (1)
{
key = read_key();
if (key == UP)
led_on();
else
led_off();
}
}
// key.c
int read_key(void)
{
GPIO_PinState key;
key = GPIO_ReadPin(GPIOX, GPIO_PIN_X);
if (key == GPIO_PIN_RESET)
return 0;
else
return 1;
}
// led.c
void led_on(void)
{
GPIO_WritePin(GPIOX, GPIO_PIN_X, GPIO_PIN_RESET);
}
void led_off(void)
{
GPIO_WritePin(GPIOX, GPIO_PIN_X, GPIO_PIN_SET);
}
- By placing the read pin 、 Switch lights are packaged in different .c Inside the subfunction , stay main The readability of the contents written in the function is improved , Even without hardware knowledge , You can also understand the role of the code
- There's a problem with the code :
- The function cannot be expanded ( The functions of hardware and software are not completely separated ): Support multiple keys ? Long press 、 double-click ?
2.3 object-oriented —— For example, write a that supports multiple versions read_key() function ?
2.3.1 Introduction of function pointer
(1) Macro switch , Specify which code to use in the code
- shortcoming :
- Only one version is supported
- Every time you add a code, you have to rewrite the function , Most of them are reusable
#define HARDWARE_VER 1 // Code version information
// key.c
// Return value : 0 Indicates being pressed , 1 Indicates that it is loosened
int read_key(void)
{
GPIO_PinState key;
#if (HARDWARE_VER == 1) //C Preprocessing instruction
key = GPIO_ReadPin(GPIOX, GPIO_PIN_X);
#else
key = GPIO_ReadPin(GPIOX, GPIO_PIN_X);
#endif
if (key == GPIO_PIN_RESET)
return 0;
else
return 1;
}
(2) Read the hardware version and select the corresponding code
Design specific circuits ( Such as dial switch ) Transmit information to the master chip , Select a specific version
- shortcoming : Every time you use it if Judge , Low efficiency
// key.c
// Return value : 0 Indicates being pressed , 1 Indicates that it is loosened
int read_key(void)
{
GPIO_PinState key;
int ver = read_hardware_ver();
if (ver == 1)
key = GPIO_ReadPin(GPIOX, GPIO_PIN_X);
else (ver == 2)
key = GPIO_ReadPin(GPIOX, GPIO_PIN_X);
if (key == GPIO_PIN_RESET)
return 0;
else
return 1;
}
(3) Use function pointers
- Change the last method's if The judgment is modified to return the pointer from the function , Increase of efficiency
- The pointer returned from the function can refer to :https://www.runoob.com/cprogramming/c-return-pointer-from-functions.html
int (*read_key)(void);
// Return value : 0 Indicates being pressed , 1 Indicates that it is loosened
int read_key_ver1(void)
{
GPIO_PinState key;
key = GPIO_ReadPin(GPIOX, GPIO_PIN_X);
if (key == GPIO_PIN_RESET)
return 0;
else
return 1;
}
// Return value : 0 Indicates being pressed , 1 Indicates that it is loosened
int read_key_ver2(void)
{
GPIO_PinState key;
key = HAL_GPIO_ReadPin(GPIOF, GPIO_PIN_6);
if (key == GPIO_PIN_RESET)
return 0;
else
return 1;
}
void key_init()
{
int ver = read_hardware_ver();
if (ver == 1)
read_key = read_key_ver1;
else
read_key = read_key_ver2;
}
// main.c
void main(void)
{
int key;
key_init();
while (1)
{
key = read_key();
if (key == UP)
led_on();
else
led_off();
}
}
2.3.2 Handle multiple keys
A key detects a low level , A key detects the high level
// key.c
// Return value : 0 Indicates being pressed , 1 Indicates that it is loosened
int read_key(int which)
{
GPIO_PinState key;
switch (which)
{
case 0:
key = GPIO_ReadPin(GPIOX, GPIO_PIN_X);
if (key == GPIO_PIN_RESET)
return 0;
else
return 1;
break;
case 1:
key = GPIO_ReadPin(GPIOX, GPIO_PIN_X);
if (key == GPIO_PIN_RESET)
return 1;
else
return 0;
break;
}
}
2.3.3 Introduction of structure ( Start the show operation )
Define a key Structure :
typedef struct key {
char *name; // Key name , distinguish K1,K2...
void (*init)(struct key *k); // Corresponding key initialization
int (*read)(struct key *k); // Check whether the key is pressed
}key, *p_key;
Each button implements a key Structure :
// key1.c
key k1 = {
"k1", k1_Init, read_key1};
// key2.c
key k2 = {
"k2", NULL, read_key2};
// key_net.c
key k_net = {
"net", NULL, read_key_net}; // A network interface can also be abstracted as a key
2.3.4 management layer / Introduction of interface layer
- Add a management layer , Easy to manage : All hardware related operations are performed on the driver layer , Register the data obtained from the driver layer to the middle layer , The application layer operates on the data of the middle layer , Thus, the hardware operation is completely separated from the application operation .

// main.c
void main(void)
{
key *k;
key_init();
/* Use a key */
k = get_key("k1");
if (k == NULL)
return;
while (1)
{
if (k->read(k) == 0)
led_on();
else
led_off();
}
}
// key_manager.c
int key_cnt = 0;
key *keys[32]; // At most 32 Key types
void register_key(key *k)
{
keys[key_cnt] = k;
key_cnt++;
}
void key_init(void)
{
k1_init();
k2_init();
}
key *get_key(char *name)
{
int i = 0;
for (i = 0; i < key_cnt; i++)
if (strcmp(name, keys[i]->name) == 0)
return keys[i];
return NULL;
}
// key_manager.h
typedef struct key {
char *name;
void (*init)(struct key *k);
int (*read)(struct key *k);
}key, *p_key;
void key_init(void);
key *get_key(char *name);
// k1.c
// Return value : 0 Indicates being pressed , 1 Indicates that it is loosened
static int read_key1(void)
{
GPIO_PinState key;
key = GPIO_ReadPin(GPIOX, GPIO_PIN_X);
if (key == GPIO_PIN_RESET)
return 0;
else
return 1;
}
static key k1 = {
"k1", NULL, read_key1};
void k1_init(void)
{
register_key(&k1);
}
2.4 Overall transformation
2.4.1 System partition
- It is divided into key system 、LED System 、 Business system :

2.4.2 Abstract structure
- The overall structure :

// led_manager.h
typedef struct led {
char *name;
void (*init)(struct led *l);// initialization
int (*control)(struct led *l, int color); /* 0x00rrggbb */
}led, *p_led;
void led_init(void);
led *get_led(char *name);
// led_manager.c
int led_cnt = 0;
led *leds[32];
void register_led(led *k)
{
leds[led_cnt] = k;
led_cnt++;
}
void led_init(void)
{
led1_init();
}
led *get_led(char *name)
{
int i = 0;
for (i = 0; i < led_cnt; i++)
if (strcmp(name, leds[i]->name) == 0)
return leds[i];
return NULL;
}
// led.c
static int led1_ctl(struct led *l, int color) /* 0x00rrggbb */
{
if (color)
{
/* Lighten up */
WritePin(GPIOX, GPIO_PIN_X, GPIO_PIN_RESET);
}
else
{
/* Extinguish */
WritePin(GPIOX, GPIO_PIN_X, GPIO_PIN_SET);
}
}
static led led1 = {
"led", NULL, led1_ctl};
void led1_init(void)
{
register_led(&led1);
}
边栏推荐
- 将本地电脑文件复制到虚拟机系统中详细方法
- 免实名域名是什么意思?
- [datawhale team learning] task02: mathematical operation, string and text, list
- Stm32g0 and FreeRTOS learning summary
- 我今年毕业,但我不知道我要做什么
- The maximum expression in Oracle database message list is 1000 error
- Network security - single arm routing, DHCP relay and ICMP Protocol
- Resolved: initialize specified but the data directory has files in it Aborting
- [introduction to Expo application] v Expert recommendation letter template
- Binary tree traversal
猜你喜欢

Class template case - encapsulation of array classes

神经网络计算量及参数量

vs2019和sql

编写并运行第一个Go语言程序

Win10踩坑-开机0xc0000225

Google Earth engine (GEE) - Murray global tidal wetland change V1 (1999-2019) data set

Network security - routing principle

Starting MySQL ERROR! Couldn‘t find MySQL server (/usr/local/mysql/bin/mysqld_safe)

The maximum expression in Oracle database message list is 1000 error

年轻人搞副业有多疯狂:月薪3000,副业收入3W
随机推荐
Introduction to go project directory structure
Stm32g0 and FreeRTOS learning summary
app quits unexpectedly
Traverse map
Stm32g0 porting FreeRTOS
Class template case - encapsulation of array classes
Egret engine P2 physics engine (2) - Funny physical phenomenon of small balls hitting the ground
[daily question] 535 Encryption and decryption of tinyurl
Error reporting record
Win10 step pit - power on 0xc0000225
[introduction to Expo application] v Expert recommendation letter template
QT wmic command obtains some hardware information
JS widget wave JS implementation of wave progress bar animation style
Class templates and friends
Realization of dissolve effect in unity and its principle analysis
Starting MySQL ERROR! Couldn‘t find MySQL server (/usr/local/mysql/bin/mysqld_safe)
6、 Shopping ⻋ and orders
SQL Server2005中SUM函数内嵌套IF语句
Double click the idea to solve the problem of downloading again
failed to create symbolic link ‘/usr/bin/mysql’: File exists