基于SDCC的工程化实践

本文讲述了作者在MacBook Pro上使用SDCC编译器开发嵌入式项目时遇到的中文支持难题,转向Windows PC和KeilC,以及解决多文件编译链接问题的过程。涉及到了struct数组初始化和汉字字模处理的技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、上位机环境

MacBook Pro
系统:macOS Big Sur
编译器:SDCC
烧录器:stcgal

二、总结

先说结论:由于sdcc对中文的支持不好,我尝试了各种办法均无解,不想浪费太多时间在趟坑上面,所以暂时放弃了探索。转而使用Windows的PC机作为开发机,重点是使用Keil C编译器。
(为什么需要用到中文?因为要向屏幕上输出中文…… 有些液晶屏驱动还不带中文字库,需要自己维护字库,就需要维护charcode和代码对应关系,如果都是用unicode编码来替代,我尝试了一下,可以是可以,但可读性也太差了,实在是得不偿失)

三、多文件编译

在真实工程中,由于代码量更大更复杂,都写在一个 main.c 的文件中肯定是不现实的。根据经验肯定是编写相应的头文件 xxxx.h 和其实现代码 xxxx.c ,然后在 main.c 中引用头文件。

在SDCC中编译时,如果直接编译 main.c 会报错:

sdcc ../src/main.c           

?ASlink-Warning-Undefined Global '_LcdSt7565_WriteCmd' referenced by module 'main'

?ASlink-Warning-Undefined Global '_Lcd12864_ClearScreen' referenced by module 'main'

?ASlink-Warning-Undefined Global '_Lcd12864_Init' referenced by module 'main'

?ASlink-Warning-Undefined Global '_LcdSt7565_WriteData' referenced by module 'main'

在多处查找答案无果,只能狠下心来啃用户手册,没想到很快就找到了答案。

3.2.3 Projects with Multiple Source Files
SDCC can compile only ONE file at a time. Let us for example assume that you have a project containing the following files:
foo1.c (contains some functions)
foo2.c (contains some more functions)
foomain.c (contains more functions and the function main)
The first two files will need to be compiled separately with the commands:
sdcc -c foo1.c
sdcc -c foo2.c
Then compile the source file containing the main() function and link the files together with the following command:
sdcc foomain.c foo1.rel foo2.rel

对应到上面的12864显示例子中,就是:

sdcc -c ../src/st7565.c 
sdcc ../src/main.c st7565.rel
stcgal -P stc89 -p /dev/tty.wchusbserial14610 main.ihx

因为目前文件还不是很多,暂时可以满足工程化需求了。如果后续文件增多,可能要考虑使用更专业的构建工具进行管理了(如Make或者CMake等)。

四、struct array

示例程序:

struct Cn16CharTypeDef                  // 汉字字模数据结构 
{
	unsigned char index[2];            // 汉字内码索引,一个汉字占两个字节	
	unsigned char msk[32];             // 点阵码数据(16*16有32个数据) 
};

/* 示例, 前两个字节为汉字“普”的unicode编码,后面为16*16点阵信息 */
/* 这种写法使用gcc或者keil c都可以编译成功,但是sdcc会报错 */
__code struct Cn16CharTypeDef CN16CHAR[] =
{0x66,0x6e,0x00,0x40,0x44,0x54,0x64,0x45,0x7E,0x44,0x44,0x44,0x7E,0x45,0x64,0x54,0x44,0x40,
0x00,0x00,0x00,0x00,0xFF,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0xFF,0x00,0x00,0x00
};

编译报错如下:

sdcc -c test.c

...
test.c:9: error 69: struct/union/array 'CN16CHAR': initialization needs curly braces

经查阅SDCC的使用手册,找到如下内容:
在这里插入图片描述

于是,将代码改成如下形式即可解决报错。

// ------------------  汉字字模的数据结构定义 ------------------------ //
struct Cn16CharTypeDef                  // 汉字字模数据结构 
{
	unsigned char index[2];            // 汉字内码索引,一个汉字占两个字节	
	unsigned char msk[32];             // 点阵码数据(16*16有32个数据) 
};

/* 正确示例, 每个字段都用括号引起来 */
__code struct Cn16CharTypeDef CN16CHAR[] =
{{0x66,0x6e},{0x00,0x40,0x44,0x54,0x64,0x45,0x7E,0x44,0x44,0x44,0x7E,0x45,0x64,0x54,0x44,0x40,
0x00,0x00,0x00,0x00,0xFF,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0xFF,0x00,0x00,0x00}
};

五、中文支持问题

SDCC对中文支持不好的问题,开头总结中已经描述了,不赘述。
如果后续SDCC改善了对unicode编码的支持,或者我发现了更优解,也会更新此文档做记录。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值