打印

放弃现有固件库,建立自己的库

[复制链接]
3713|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
01dxwlm|  楼主 | 2009-9-30 12:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1.
为什么?


由于在使用ST的固件库发现1是不能看到最底层的固件库代码,在开发的过程中不管怎么管控和严格测试也不能消除软件的所有bug,所以在ST提供的固件库中也可能存在未知的bug;2是使用库函数的时候效率低下,占用FLASH 较多,

虽然STM32现在有FLASH 512K的了,可毕竟ARM 的资源还是有限,就象上次我公司为DELL开发的一款产品使用的芯片(freescale的)FLASH为256K,到最后完成所有功能时只剩下不到1K的FLASH了,可以想像这个产品如果升级的话将会面临巨大的挑战。
所以,鉴于这两个问题有必要舍弃STM32的现有固件库,虽然做这个工作需要大量的精力和时间,我想如果是大的公司或者想做高质量的产品的公司为自己的产品从新设计一个高效的库文件是很有必要的。
2.
库文件的实现


现以GPIO部分为例来从新建立固件库。



1.
为什么?

由于在使用ST的固件库发现1是不能看到最底层的固件库代码,在开发的过程中不管怎么管控和严格测试也不能消除软件的所有bug,所以在ST提供的固件库中也可能存在未知的bug;2是使用库函数的时候效率低下,占用FLASH 较多,
虽然STM32现在有FLASH 512K的了,可毕竟ARM 的资源还是有限,就象上次我公司为DELL开发的一款产品使用的芯片(freescale的)FLASH为256K,到最后完成所有功能时只剩下不到1K的FLASH了,可以想像这个产品如果升级的话将会面临巨大的挑战。
所以,鉴于这两个问题有必要舍弃STM32的现有固件库,虽然做这个工作需要大量的精力和时间,我想如果是大的公司或者想做高质量的产品的公司为自己的产品从新设计一个高效的库文件是很有必要的。
2.
库文件的实现

现以GPIO部分为例来从新建立固件库。
//****帖子限制字数,见2贴




然后把各个GPIO的map对应到具体的芯片地址,比如GPIOA就是:
#define
GPIOA
(*(volatile struct GPIO
*)GPIOA_BASE)
/* GPIOA
Address*/

其中:GPIOA_BASE 是(APB2PERIPH_BASE + 0x0800)
3.
如何使用自己的库
在使用自己的库时可以直接使用数据结构的数据,比如在使用GPIOA的PA0
时:

GPIOA.CRL.BIT.MODE0 = 0x01;

//
输出模式,最大速度10MHz

GPIOA.CRL.BIT.CNF0 = 0x00;

//
通用推挽输出模式
GPIOA.BSRR.DWOED = 0x01;

也可以在再义一个io文件 比如GPIOA PA0时输出控制LED的则:
#define mTurnOnLed()
GPIOA.BSRR.BIT.BR0

=1

#define mTurnOffLed()
GPIOA.BSRR.BIT.BS0
=1

1.
总结:
通过这样编写的自己库文件很法方便使用并不比ST提供的库文件难,相反很多地方操作更简单,特别在一个口里面既有输出又有输入,各个IO配置各不相同的情况下优势比ST的固件库更简单了。
比如 :GPIOAA.CRL.DWORD =((MODE_OUTPUT_2M| CNF_Out_OD<<2)<<3*4)
|((MODE_INPUT|CNF_IN_FLOATING<<2)<<1*4)|((MODE_OUTPUT_2M| CNF_Out_OD<<2)) // PA3和PA0设置为推挽输出,PA1设置为输入
由于我也还只接触STM32才只有2天,所以我对STM32的基本知识还理解的不够清楚,写出来的东西错误在所难免,我只是把我的想法写出来而已,欢迎大家批评指点。谢谢

MyLib.rar

279.86 KB

沙发
01dxwlm|  楼主 | 2009-9-30 12:23 | 只看该作者
struct GPIO     /* GPIO struct */
{
        union
        {
                unsigned long int DWOED;
                struct
                {
                        unsigned long int MODE0:2;  /*  IO 0 */
                        unsigned long int CNF0: 2;
                        unsigned long int MODE1:2;  /*  IO 1 */
                        unsigned long int CNF1: 2;
                        unsigned long int MODE2:2;  /*  IO 2 */
                        unsigned long int CNF2: 2;
                        unsigned long int MODE3:2;  /*  IO 3 */
                        unsigned long int CNF3: 2;
                        unsigned long int MODE4:2;  /*  IO 4 */
                        unsigned long int CNF4: 2;
                        unsigned long int MODE5:2;  /*  IO 5 */
                        unsigned long int CNF5: 2;
                        unsigned long int MODE6:2;  /*  IO 6 */
                        unsigned long int CNF6: 2;
                        unsigned long int MODE7:2;  /*  IO 7 */
                        unsigned long int CNF7: 2;
                }BIT;
        }CRL;             /* 端口配置低寄存器  */
       
        union
        {
                unsigned long int DWOED;
                struct
                {
                        unsigned long int MODE8:2;  /*  IO 8 */
                        unsigned long int CNF8: 2;
                        unsigned long int MODE9:2;  /*  IO 9 */
                        unsigned long int CNF9: 2;
                        unsigned long int MODE10:2;  /*  IO 10 */
                        unsigned long int CNF10: 2;
                        unsigned long int MODE11:2;  /*  IO 11 */
                        unsigned long int CNF11: 2;
                        unsigned long int MODE12:2;  /*  IO 12 */
                        unsigned long int CNF12: 2;
                        unsigned long int MODE13:2;  /*  IO 13 */
                        unsigned long int CNF13: 2;
                        unsigned long int MODE14:2;  /*  IO 14 */
                        unsigned long int CNF14: 2;
                        unsigned long int MODE15:2;  /*  IO 15 */
                        unsigned long int CNF15: 2;
                }BIT;
        }CRH;             /* 端口配置高寄存器 */
       
        union
        {
                unsigned long int DWOED;
                struct
                {
                        unsigned long int IDR0 :1;   /* IDR0 */
                        unsigned long int IDR1 :1;   /* IDR1 */
                        unsigned long int IDR2 :1;   /* IDR2 */
                        unsigned long int IDR3 :1;   /* IDR3 */
                        unsigned long int IDR4 :1;   /* IDR4 */
                        unsigned long int IDR5 :1;   /* IDR5 */
                        unsigned long int IDR6 :1;   /* IDR6 */
                        unsigned long int IDR7 :1;   /* IDR7 */
                        unsigned long int IDR8 :1;   /* IDR8 */
                        unsigned long int IDR9 :1;   /* IDR9 */
                        unsigned long int IDR10 :1;   /* IDR10 */
                        unsigned long int IDR11 :1;   /* IDR11 */
                        unsigned long int IDR12 :1;   /* IDR12 */
                        unsigned long int IDR13 :1;   /* IDR13 */
                        unsigned long int IDR14 :1;   /* IDR14 */
                        unsigned long int IDR15 :1;   /* IDR15 */
                        unsigned long int RSV :15;   /* IDR16~31 */
                }BIT;
        }IDR;             /* 端口输入数据寄存 */
       
        union
        {
                unsigned long int DWOED;
                struct
                {
                        unsigned long int ODR0 :1;   /* ODR0 */
                        unsigned long int ODR1 :1;   /* ODR1 */
                        unsigned long int ODR2 :1;   /* ODR2 */
                        unsigned long int ODR3 :1;   /* ODR3 */
                        unsigned long int ODR4 :1;   /* ODR4 */
                        unsigned long int ODR5 :1;   /* ODR5 */
                        unsigned long int ODR6 :1;   /* ODR6 */
                        unsigned long int ODR7 :1;   /* ODR7 */
                        unsigned long int ODR8 :1;   /* ODR8 */
                        unsigned long int ODR9 :1;   /* ODR9 */
                        unsigned long int ODR10 :1;   /* ODR10 */
                        unsigned long int ODR11 :1;   /* ODR11 */
                        unsigned long int ODR12 :1;   /* ODR12 */
                        unsigned long int ODR13 :1;   /* ODR13 */
                        unsigned long int ODR14 :1;   /* ODR14 */
                        unsigned long int ODR15 :1;   /* ODR15 */
                        unsigned long int RSV :16;   /* ODR16~31 */
                }BIT;
        }ODR;              /* 端口输出数据寄存器 */
       
        union
        {
                unsigned long int DWOED;
                struct
                {
                        unsigned long int BS0:1;     /* BS0 */
                        unsigned long int BS1:1;     /* BS0 */
                        unsigned long int BS2:1;     /* BS0 */
                        unsigned long int BS3:1;     /* BS0 */
                        unsigned long int BS4:1;     /* BS0 */
                        unsigned long int BS5:1;     /* BS0 */
                        unsigned long int BS6:1;     /* BS0 */
                        unsigned long int BS7:1;     /* BS0 */
                        unsigned long int BS8:1;     /* BS0 */
                        unsigned long int BS9:1;     /* BS0 */
                        unsigned long int BS10:1;     /* BS0 */
                        unsigned long int BS11:1;     /* BS0 */
                        unsigned long int BS12:1;     /* BS0 */
                        unsigned long int BS13:1;     /* BS0 */
                        unsigned long int BS14:1;     /* BS0 */
                        unsigned long int BS15:1;     /* BS0 */
                        unsigned long int BR0:1;     /* BR0 */
                        unsigned long int BR1:1;     /* BR1 */
                        unsigned long int BR2:1;     /* BR2 */
                        unsigned long int BR3:1;     /* BR3 */
                        unsigned long int BR4:1;     /* BR4 */
                        unsigned long int BR5:1;     /* BR5 */
                        unsigned long int BR6:1;     /* BR6 */
                        unsigned long int BR7:1;     /* BR7 */
                        unsigned long int BR8:1;     /* BR8 */
                        unsigned long int BR9:1;     /* BR9 */
                        unsigned long int BR10:1;     /* BR10 */
                        unsigned long int BR11:1;     /* BR11 */
                        unsigned long int BR12:1;     /* BR12 */
                        unsigned long int BR13:1;     /* BR13 */
                        unsigned long int BR14:1;     /* BR14 */
                        unsigned long int BR15:1;     /* BR15 */
                }BIT;
        }BSRR;              /* 端口位设置/复位寄存器 */
       
        union
        {
                unsigned long int DWOED;
                struct
                {
                        unsigned long int BR0:1;     /* BR0 */
                        unsigned long int BR1:1;     /* BR1 */
                        unsigned long int BR2:1;     /* BR2 */
                        unsigned long int BR3:1;     /* BR3 */
                        unsigned long int BR4:1;     /* BR4 */
                        unsigned long int BR5:1;     /* BR5 */
                        unsigned long int BR6:1;     /* BR6 */
                        unsigned long int BR7:1;     /* BR7 */
                        unsigned long int BR8:1;     /* BR8 */
                        unsigned long int BR9:1;     /* BR9 */
                        unsigned long int BR10:1;     /* BR10 */
                        unsigned long int BR11:1;     /* BR11 */
                        unsigned long int BR12:1;     /* BR12 */
                        unsigned long int BR13:1;     /* BR13 */
                        unsigned long int BR14:1;     /* BR14 */
                        unsigned long int BR15:1;     /* BR15 */
                        unsigned long int RSV:16;      /* BR16~31 */
                }BIT;
        }BRR;            /* 端口位复位寄存 */
       
        union
        {
                unsigned long int DWOED;
                struct
                {
                        unsigned long int LCK0:1;     /* LCK 0 */
                        unsigned long int LCK1:1;     /* LCK 1 */
                        unsigned long int LCK2:1;     /* LCK 2 */
                        unsigned long int LCK3:1;     /* LCK 3 */
                        unsigned long int LCK4:1;     /* LCK 4 */
                        unsigned long int LCK5:1;     /* LCK 5 */
                        unsigned long int LCK6:1;     /* LCK 6 */
                        unsigned long int LCK7:1;     /* LCK 7 */
                        unsigned long int LCK8:1;     /* LCK 8 */
                        unsigned long int LCK9:1;     /* LCK 9 */
                        unsigned long int LCK10:1;     /* LCK 10 */
                        unsigned long int LCK11:1;     /* LCK 11 */
                        unsigned long int LCK12:1;     /* LCK 12 */
                        unsigned long int LCK13:1;     /* LCK 13 */
                        unsigned long int LCK14:1;     /* LCK 14 */
                        unsigned long int LCK15:1;     /* LCK 14 */
                        unsigned long int LCKK:1;     /* LCK K */
                        unsigned long int RSV:15;      /* BR17~31 */
                }BIT;
        }LCKR;          /* 端口配置锁定寄存器 */
};
然后把各个GPIO的map对应到具体的芯片地址,比如GPIOA就是:
#define        GPIOA        (*(volatile struct GPIO  *)GPIOA_BASE)        /* GPIOA  Address*/
其中:GPIOA_BASE 是(APB2PERIPH_BASE + 0x0800)

使用特权

评论回复
板凳
void_c| | 2009-9-30 12:39 | 只看该作者
看不出,楼主这么写有啥优势。

寄存器太多,一个一个这么写,苦力活,这看不找有啥优势。
自己写也不能保证正确。

STM的外设固件库有源代码。

使用特权

评论回复
地板
userchen| | 2009-9-30 16:05 | 只看该作者
初步感觉,没啥意义。。。
自己写的,也不一定保证bug。。。
如果有时间,可以考虑。呵呵。

使用特权

评论回复
5
McuPlayer| | 2009-9-30 19:21 | 只看该作者
楼主做的很好,确实ST自家的库效率低,ST的工程师过多的考虑可读性而不是效率。
相对而言,老外比较在意人力成本。

使用特权

评论回复
6
Simon21ic| | 2009-9-30 23:29 | 只看该作者
关键部分不用库(性能关键、编译效率关键),其他就用库吧。。。。。。

使用特权

评论回复
7
kk2614755| | 2009-10-1 12:06 | 只看该作者
USB挂起
USB复位
USB挂起
USB挂起
USB复位
USB控制端点输出中断
读端点: 0
读取数据长度为: 16
缓冲区:
0x80 0x06 0x00 0x01 0x00 0x00 0x40 0x00
bmRequestType: 0x80
bRequest:      0x06
wValue:        0x0100
wIndex:        0x0000
wLength:       0x0040
标准输入请求: --获取设备描述符
写端点: 0
写数据长度为: 16
缓冲区:
0x12 0x01 0x10 0x01 0x00 0x00 0x00 0x10
0x88 0x88 0x01 0x00 0x00 0x01 0x00 0x00
USB控制端点输入中断
写端点: 0
写数据长度为: 2
缓冲区:
0x00 0x01 USB复位
USB控制端点输出中断
读端点: 0
读取数据长度为: 16
缓冲区:
0x00 0x05 0x01 0x00 0x00 0x00 0x00 0x00
bmRequestType: 0x00
bRequest:      0x05
wValue:        0x0001
wIndex:        0x0000
wLength:       0x0000
标准输出类请求: --设置地址
地址为: 0x01
写端点: 0
写数据长度为: 0
缓冲区:
USB控制端点输入中断
USB控制端点输出中断
读端点: 0
读取数据长度为: 16
缓冲区:
0x80 0x06 0x00 0x01 0x00 0x00 0x12 0x00
bmRequestType: 0x80
bRequest:      0x06
wValue:        0x0100
wIndex:        0x0000
wLength:       0x0012
标准输入请求: --获取设备描述符
写端点: 0
写数据长度为: 16
缓冲区:
0x12 0x01 0x10 0x01 0x00 0x00 0x00 0x10
0x88 0x88 0x01 0x00 0x00 0x01 0x00 0x00
USB控制端点输入中断
写端点: 0
写数据长度为: 2
缓冲区:
0x00 0x01 USB控制端点输入中断
USB控制端点输出中断
读端点: 0
读取数据长度为: 16
缓冲区:
0x80 0x06 0x00 0x02 0x00 0x00 0x09 0x00
bmRequestType: 0x80
bRequest:      0x06
wValue:        0x0200
wIndex:        0x0000
wLength:       0x0009
标准输入请求: --获取配置描述符
写端点: 0
写数据长度为: 9
缓冲区:
0x09 0x02 0x22 0x00 0x01 0x88 0x00 0x80
0x32 USB控制端点输入中断
USB控制端点输出中断
读端点: 0
读取数据长度为: 16
缓冲区:
0x80 0x06 0x00 0x02 0x00 0x00 0xFF 0x00
bmRequestType: 0x80
bRequest:      0x06
wValue:        0x0200
wIndex:        0x0000
wLength:       0x00FF
标准输入请求: --获取配置描述符
写端点: 0
写数据长度为: 16
缓冲区:
0x09 0x02 0x22 0x00 0x01 0x88 0x00 0x80
0x32 0x09 0x04 0x00 0x00 0x01 0x03 0x01
USB控制端点输入中断
写端点: 0
写数据长度为: 16
缓冲区:
0x02 0x00 0x09 0x21 0x10 0x01 0x21 0x01
0x22 0x00 0x00 0x07 0x05 0x81 0x03 0x10
USB控制端点输入中断
写端点: 0
写数据长度为: 2
缓冲区:
0x00 0x0A USB控制端点输入中断
USB控制端点输出中断
读端点: 0
读取数据长度为: 16
缓冲区:
0x80 0x06 0x00 0x01 0x00 0x00 0x12 0x00
bmRequestType: 0x80
bRequest:      0x06
wValue:        0x0100
wIndex:        0x0000
wLength:       0x0012
标准输入请求: --获取设备描述符
写端点: 0
写数据长度为: 16
缓冲区:
0x12 0x01 0x10 0x01 0x00 0x00 0x00 0x10
0x88 0x88 0x01 0x00 0x00 0x01 0x00 0x00
USB控制端点输入中断
写端点: 0
写数据长度为: 2
缓冲区:
0x00 0x01 USB控制端点输入中断
USB控制端点输出中断
读端点: 0
读取数据长度为: 16
缓冲区:
0x80 0x06 0x00 0x02 0x00 0x00 0x09 0x00
bmRequestType: 0x80
bRequest:      0x06
wValue:        0x0200
wIndex:        0x0000
wLength:       0x0009
标准输入请求: --获取配置描述符
写端点: 0
写数据长度为: 9
缓冲区:
0x09 0x02 0x22 0x00 0x01 0x88 0x00 0x80
0x32 USB控制端点输入中断
USB控制端点输出中断
读端点: 0
读取数据长度为: 16
缓冲区:
0x80 0x06 0x00 0x02 0x00 0x00 0x22 0x00
bmRequestType: 0x80
bRequest:      0x06
wValue:        0x0200
wIndex:        0x0000
wLength:       0x0022
标准输入请求: --获取配置描述符
写端点: 0
写数据长度为: 16
缓冲区:
0x09 0x02 0x22 0x00 0x01 0x88 0x00 0x80
0x32 0x09 0x04 0x00 0x00 0x01 0x03 0x01
USB控制端点输入中断
写端点: 0
写数据长度为: 16
缓冲区:
0x02 0x00 0x09 0x21 0x10 0x01 0x21 0x01
0x22 0x00 0x00 0x07 0x05 0x81 0x03 0x10
USB控制端点输入中断
写端点: 0
写数据长度为: 2
缓冲区:
0x00 0x0A USB控制端点输入中断
USB控制端点输出中断
读端点: 0
读取数据长度为: 16
缓冲区:
0x00 0x09 0x88 0x00 0x00 0x00 0x00 0x00
bmRequestType: 0x00
bRequest:      0x09
wValue:        0x0088
wIndex:        0x0000
wLength:       0x0000
标准输出类请求: --设置配置
配置值为: 0x88
写端点: 0
写数据长度为: 0
缓冲区:
USB控制端点输入中断
USB控制端点输出中断
读端点: 0
读取数据长度为: 16
缓冲区:
0x21 0x0A 0x00 0x00 0x00 0x00 0x00 0x00
bmRequestType: 0x21
bRequest:      0x0A
wValue:        0x0000
wIndex:        0x0000
wLength:       0x0000
特殊类输出请求: --设置空闲
写端点: 0
写数据长度为: 0
缓冲区:
USB控制端点输入中断
USB挂起

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

121

主题

592

帖子

2

粉丝