一、关键字

1.1 interrupt&using

sdcc中,中断程序使用的关键字和keil一样:

1
2
3
4
void timer_isr (void) __interrupt (1) __using (1)
{

...
}

interrupt指定中断号,using指定register bank。

中断程序可以写在任意一个源文件里,但在包含main程序的源文件里,必须要有一份中断程序的声明。

如果使用register bank 0,那么系统会将当前程序用到的寄存器全都保存进堆栈。如果用到其他register bank,那么只会保存类似dptr这样的特殊寄存器。

1.2 critical

critical用于表示一个程序不能被中断打算,sdcc会在运行__critical修饰的程序前保存当前中断使能状态,并关闭所有中断,运行完了之后再打开。

1
2
3
4
5
int foo () __critical
{
...
...
}

同样对单独的语句也可以使用

1
__critical{ i++; }

二、使用中断时的常见bug

2.1 变量没有被定义为volatile

这是个常见的错误,没有声明为volatele的变量,会使编译器对变量的读取采取优化。

2.2 非原子指令

有些c语句并非对应一句汇编指令,比如在c51下16位变量读取,可能需要2到3条指令来执行。如果在执行第一条指令时发生了中断,很有可能会产生意想不到的后果,而且这种bug很难reproduce。

2.3 堆栈溢出

中断程序的返回地址和保留的寄存器值全都存在堆栈里。如果在调用中断程序时,程序正好调用了多层的子程序里最深的一层,很有可能会没有足够的堆栈给中断使用。

2.4 使用了不可重入的函数

如果中断程序里对16位/32位的变量进行了乘除、取余等操作,其实是额外调用了一些子函数,要使用—stack-auto将这些都编译为可重入函数。

另外,如果在中断程序中调用了其他函数(不推荐这么做),那么要使用#pragma nooverlay来避免子程序使用可覆盖的变量。

一、mem文件和map文件

sdcc提供mem文件和map文件来帮助我们分析一个项目编译完成后,它对各种存储空间的占用情况。

1.1 mem文件

mem文件主要组成是这样的:
——内部ram使用表
——外部ram和rom使用统计表

打开在前一个实验里生成的test.mem查看的结果如下

Internal RAM layout:
0 1 2 3 4 5 6 7 8 9 A B C D E F
0x00:|0|0|0|0|0|0|0|0|a|I|S|S|S|S|S|S|
0x10:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x20:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x30:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x40:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x50:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x60:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x70:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x80:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x90:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0xa0:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0xb0:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0xc0:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0xd0:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0xe0:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0xf0:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|

0-3:Reg Banks, T:Bit regs, a-z:Data, B:Bits, Q:Overlay, I:iData, S:Stack, A:Absolute

Stack starts at: 0x0a (sp set to 0x09) with 246 bytes available.

可以看到它有一个内部ram的map图,每个字节的指派都很清晰,对于外部ram和rom,也提供了一张总体统计表。

Other memory:

Name Start End Size Max
PAGED EXT. RAM 0x0000 0x0000 1 256
EXTERNAL RAM 0x0001 0x0001 1 65536
ROM/EPROM/FLASH 0x0000 0x0079 122 65536

1.2 map文件

mem文件提供的是ram和rom的总体使用统计,而map文件,则是ram和rom的详细内存使用表。

map文件的前两段是由链接器创建的符号表,然后再是ram的详细分段。

map文件的主要组成是这样的:
——符号表
——ram map
———ram segment REG_BANK_0
———ram segment DSEG
———ram segment …..
——rom map
———-start up
———-code (代码区)
———-const(常量区)
———-lib&rel列表

在ram map中,除了分段的大小,map文件还会列出所有申明在这个区域的变量名以及该变量实际是在哪个源文件里申明的,比如DSEG段:

Area Addr Size Decimal Bytes (Attributes)
DSEG 00000000 00000080 128 bytes (REL,CON)

地址表

Value Global Global Defined In Module
00000008 _data_v test

变量表

段表的顺序是REG_BANK_0(R0-R7),DSEG(data),ISEG(idata),SSEG(stack),PSEG(pdata),XSEG(xdata),都是之前有提到的存储空间。

在rom map里,一开始是一段汇编函数的地址图,关于sdcc如何初始化单片机及c语言运行环境,之后再做分析。

进入代码区,我写了一个小的实验项目,它的代码区memory map是这样的:

Area Addr Size Decimal Bytes (Attributes)
CSEG 0000006E 00000282 642. bytes (REL,CON,CODE)

code区总表

Value Global Global Defined In Module
C: 0000006E _init_timer0 debug
C: 00000075 _count_runtime_start debug
C: 00000078 _count_runtime_over debug
C: 0000008D _init_uart debug
C: 0000009F _uart_send_char debug
C: 000000AD _delay10ms debug
C: 000000AE _delay100cyc delay
C: 000000B8 _delay10000cyc delay
C: 000000CA _HC595_Send_Data display
C: 000000F5 _HC595_Set_Row display
C: 0000012C _Led_Show_Word display
C: 0000018B _Delay10ms key
C: 000001A3 _Scan_key key
C: 00000239 _Check_Password key
C: 0000027C _board_init main
C: 0000028C _Beer main
C: 000002B3 _main main
C: 000002EC __sdcc_external_startup _startup

函数表

然后是常量区的大小和常量表(略),形式同上述data分段。

mem文件会分别列出每个函数在rom中的起始地址以及他们从哪里链接而来。也会给出所有链接的rel和lib

Files Linked [ module(s) ]

build/debug.rel [ ]
build/delay.rel [ ]
build/display.rel [ ]
build/key.rel [ ]
build/main.rel [ ]

Libraries Linked [ object file ]

/usr/bin/../share/sdcc/lib/small/mcs51.lib
[ crtclear.rel ]
/usr/bin/../share/sdcc/lib/small/mcs51.lib
[ crtxinit.rel ]
/usr/bin/../share/sdcc/lib/small/mcs51.lib
[ crtxclear.rel ]
/usr/bin/../share/sdcc/lib/small/mcs51.lib
[ crtpagesfr.rel ]
/usr/bin/../share/sdcc/lib/small/mcs51.lib
[ crtstart.rel ]
/usr/bin/../share/sdcc/lib/small/libsdcc.lib
[ _startup.rel ]

二、指定分段地址

sdcc可以用一些链接选项来修改默认的ram/rom段的起始地址。

2.1 —xram-loc

默认值为0,指定外部内存使用的起始地址,链接选项可以用16进制或者10进制,e.g

1
--xram-loc 0x8000 or --xram-loc 32768

2.2 —code-loc

修改code段在rom中的起始地址,默认为0

2.3 —stack-loc

修改堆栈指针,如果要使用这个选项,要一并使用—no-pack-iram来关闭用寄存器优化变量的访问。

2.4 —xstack-loc

默认值为pdata区域之后

2.5 —idata-loc

默认值为0x80

一、存储类型关键字

1.1 sdcc中特殊关键字的使用

sdcc提供和keil一样的特殊关键字来指定变量的存储类型,和keil不同的是,sdcc在使用c51专用的特殊关键字时,要用两个下划线作为前缀,比如申明一个idata存储类型的变量时语句如下。

1
__idata unsigned char i;

1.2 __data类型

该类型是small存储模式下默认使用的存储类型,对应直接寻址方式。

1.3 __pdata类型

该类型是medium存储模式下默认使用的存储类型,对应8bit的寄存器间接寻址。

1.4 __xdata类型

该类型是large存储模式下默认使用的储存类型,对应16bit的寄存器间接寻址。

1.5 __idata类型

用间接寻址的方式,用这种方式可以访问片内ram的高128bit,当然也可以同时访问低128bit,只是效率会降低。之所以有这个关键字存在,应该是由于许多51单片机将最初的128bit的内部ram扩展到了256bit。它和pdata在间接寻址上的区别是无需用寄存暂存要赋值的数值。

1.6 __code类型

将数据存在rom中,只能存储常量。

1.7 __bit类型

用来定义bit变量,51的位寻址区在内置ram的0x20-0x2f区域,共128个bit位。

1.8 __sfr类型

用来定义特殊功能寄存器

定义P0口

1
__sfr __at (0x80) P0;

一般情况下sdcc提供的头文件里已经将51的特殊功能寄存器全都定义好了,所以这个关键字很少使用。

1.9 不同存储空间的指针

sdcc允许指针指向不同类型的存储空间,这样的指针有三个字节,第一个字节表示指向的区域。下面拷贝一段man上的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* pointer physically in internal ram pointing to object in external
ram */

__xdata unsigned char * __data p;
/* pointer physically in external ram pointing to object in internal
ram */

__data unsigned char * __xdata p;
/* pointer physically in code rom pointing to data in xdata space
*/

__xdata unsigned char * __code p;
/* pointer physically in code space pointing to data in code space
*/

__code unsigned char * __code p;
/* generic pointer physically located in xdata space */
unsigned char * __xdata p;
/* generic pointer physically located in default memory space */
unsigned char * p;
/* the following is a function pointer physically located in data
space */


char (* __data fp)(void);

1.10 at关键字

at关键字可以指定变量的存储地址,这可以减少指针的使用,以及直接地址访问这样的语句。

1
2
3
4
__xdata __at (0x7ffe) unsigned int chksum;
__code __at (0x7ff0) char Id[5] = ”SDCC”;
volatile __xdata __at (0x8000) unsigned char PORTA_8255;
__bit __at (0x02) bvar;

使用时需要注意指定的地址是否在overlay区。

1.11 小结

  • small模式下默认使用data存储变量,medium模式下用xdata,large模式下用pdata
  • data和idata用于变量存在片内ram,xdata和pdata用于指定变量存在外部ram
  • data用于片内ram的低128bit, idata用于片内的高128bit
  • xdata用于片外ram的低256bit,pdata用于片外ram的64K
  • bit用于位寻址,sfr用于特殊功能寄存器,code用于rom

二、实验

针对sdcc的储存类型关键字,下面做一个实验来做进一步的学习。

首先写这样一个程序,然后编译。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$vim test.c

__data unsigned char data_v;
__idata unsigned char idata_v;
__pdata unsigned char pdata_v;
__xdata unsigned char xdata_v;

__code unsigned char code_v = 0xff;

void main()
{

unsigned char i;

data_v = 1;
idata_v = 1;
pdata_v = 1;
xdata_v = 1;

i = code_v;
}

先看看他们被分配的区域

data_v被分配在内部ram的前8个字节后:

1
;--------------------------------------------------------
; overlayable register banks
;--------------------------------------------------------
        .area REG_BANK_0        (REL,OVR,DATA)
        .ds 8
;--------------------------------------------------------
; internal ram data
;--------------------------------------------------------
        .area DSEG    (DATA)
_data_v::
        .ds 1

idata_v被分配data之后,它之后区域就是栈区了:

1
;--------------------------------------------------------
; indirectly addressable internal ram data
;--------------------------------------------------------
        .area ISEG    (DATA)
_idata_v::
        .ds 1

pdata和xdata都被分配在外存:

1
;--------------------------------------------------------
; paged external ram data
;--------------------------------------------------------
        .area PSEG    (PAG,XDATA)
_pdata_v::
        .ds 1
;--------------------------------------------------------
; external ram data
;--------------------------------------------------------
        .area XSEG    (XDATA)
_xdata_v::
        .ds 1

接着看对他们的处理方式

1
;       test.c:14: data_v =  1;
        mov     _data_v,#0x01
;       test.c:15: idata_v = 1;
        mov     r0,#_idata_v
        mov     @r0,#0x01
;       test.c:16: pdata_v = 1;
        mov     r0,#_pdata_v
        mov     a,#0x01
        movx    @r0,a
;       test.c:17: xdata_v = 1;
        mov     dptr,#_xdata_v
        mov     a,#0x01
        movx    @dptr,a

很明显,data使用了立即寻址,而pdata和xdata都使用了movx指令来访问外存。

一、C51专用编译选项

1.1 C标准

sdcc提供c89 c99 c11的三种标准,编译选项分别是

1
2
3
4
--std-c89
--std-c99
--std-c11
--std-sdcc99

据说用c99,如果函数没有形参编译就不能通过,不能默认为void。在写for函数的时候,不能在第一分句里申明变量,必须提前申明。—std-sdcc99是默认的编译选项,在使用c99规范的时候,兼容c89规范,真方便。

anyway,我觉得很少有人会使用这个编译选项。

1.2 芯片系列

sdcc提供很多种芯片系列的选择,粗略看了一下有pic16bit,飞思卡尔,z80等等。如果是51系列的话,编译选项是-mmcs51

1
-mmcs51

1.3 存储模式

ssdc提供的memory model选项有这么几个

1
2
3
4
--model-small
--model-medium
--model-large
--model-huge

small模式,对应keil的SMALL模式,变量默认存在internal ram中,该模式需要变量总占用的空间小于256bit。

medium模式,对应keil的COMPACT模式,变量默认存在external ram中。需要注意的是,有些51单片机本身就有内部的扩展ram,为了与旧单片机相兼容,这些内部扩展ram在名义上也算是一种外部ram。

large和huge模式是一样的,变量也存在external ram中,不同的是,它可以切换bank。由于c51的最大寻址范围也就是FFFFH,即64K。所以如果要扩展64K以上的ram只能用bank切换的办法。bank切换办法是用一个特殊寄存器来切换bank,将LSB存在r0,MSB存在r1,bank号存在r2。然后用 __sdcc_banked_call来调用位于其他bank的函数,再用__sdcc_banked_ret返回当前函数。

1.4 堆栈

1
--xstack

可以用xstack选项指定external ram的一段空间作为栈区(通常是前256个字节),这样所有的可重入函数的变量和参数传递都会用堆栈来实现。通常默认的栈空间是在internal ram的后区。

1.5 size检查

sdcc提供一些size选项来检查存储控件的使用情况

1
2
3
4
--iram-size <Value>
--xram-size <Value>
--code-size <Value>
--stack-size <Value>

iram-size 用来检查片内ram的使用情况
xram-size 用来检查外部ram的使用情况
code-size 用来检查rom的使用情况
stack-size 用来检查堆栈的使用情况

1.6 寄存器优化开关

1
2
--pack-iram
--no-pack-iram

—pack-iram是默认选项,意思是将多余的寄存器用来存放变量,以加快运行速度。因为这是一种通俗的做法,所以—no-pack-iram选项几乎很少使用,编译器的作者说下一版将移除这个选项。如果想不让编译器优化某个变量的访问,直接使用volatile关键字就可以了。假如担心一个全局变量会被中断程序或者其他线程修改,那么声明它为volatile就可以了,编译器会让该变量在每次访问时都重新从内存读取。

1.7 汇编优化

1
--acall-ajmp

—acall-ajmp选项用来将3字节的汇编指令lcall/ljpm替换成2字节的指令acall-ajmp,这就要求代码总占用空间限制在2K以内。

我很好奇这个选项的使用场景,于是在github上搜索了一下,发现它通常用于一些微型的bootloader。

1
--no-ret-without-call

—no-ret-without-call 用于xc800系列的单片机,用于保持堆栈平衡。

总结

  • sdcc用-mmcs51来指定单片机为51系列
  • sdcc有与keil相同的memory model
  • 可以用编译选项告诉编译器程序使用外部ram里的堆栈
  • 可以用编译选项检查各存储空间的占用情况

一、基础编译选项

1.1 单源文件的编译

假设目前有一个源文件led.c,可以用如下命令进行编译。

1
$sdcc led.c

编译完之后发现目录下好多生成的编译文件。其中led.rel是类似gcc中的led.o这样用于链接的对象文件,有所不同的是,led.rel中并不包含链接用的汇编代码,它包含在led.lst中。而led.ihx是用来烧写的hex文件,它的格式是intel hex规范。实际用于烧写的文件格式要根据烧写工具来定制,这一点之后再研究。

1.2 多源文件的编译

在另外一个项目中,共有4个源文件。key.c用来控制矩阵键盘,display.c用来操作点阵屏,uart.c用来实现串行通信,而main.c用来统一调用其他源文件里的函数。

这几个源文件编译的方法是先将源文件编译成库,然后再统一链接。使用编译选项 -c 表示complier only,只编译不链接。

1
2
3
4
$sdcc -c key.c
$sdcc -c display.c
$sdcc -c uart.c
$sdcc main.c key.rel display.rel uart.rel

当然也可以将最后一条命令这样做,统一将源码先全部编译成链接库,这样在写makefile时会更方便。

1
2
$sdcc -c main.c
$sdcc main.rel key.rel display.rel uart.rel

1.3 库文件的链接

在上述的项目里,uart.c的其中一个函数用到了crc校验,它的函数原型在另外的crc.lib库文件中,编译的时候要额外链接该库文件。

1
$sdcc -c uart.c crc.lib

如果库文件不在当前目录要用 -L 选项制定目录

1
$sdcc -c uart.c -L /usr/crc.lib

使用sdcclib命令,可以将对象文件链接成lib文件。

用sdcclib -s和 sdcclib -m可以查看lib文件的符号表和函数表。

1
2
3
4
5
$sdcclib led.lib led.rel
$sdcclib project.lib led.rel display.rel key.rel

$sdcclib -s led.lib
$sdcclib -m projext.lib

二、output file

使用sdcc led.c后发现目录下一大堆编译生成的文件,来看看这些文件都是用来做什么的。

1
2
$ls
led.asm led.lst led.rst led.sym led.rel led.map led.mem

2.1 asm文件

由complier创建,是c源码文件编译成汇编后的结果。在分析一些具体问题的时候,可能会需要去查看编译出来的汇编指令。

2.2 lst文件

由assembler创建,我对比了同一个源文件生成的lst文件和asm文件,两者差不多。不同的是lst在行首有每一行的相对地址,而asm则没有,但asm有用标示符来标示一些用于跳转的地址,方便我们查看。

2.3 rst文件

由linker创建,它和lst的文件的区别是,lst行首的相对地址变更成了链接时使用的地址,将一些栈区与堆区的地址加入了文件,使原文件的指令地址发生了偏移。

2.4 sym文件

由assembler创建,该文件包含的是当前源文件的符号表。

2.5 rel文件

由assembler创建,该文件被用于链接。

2.6 map文件

由linker创建,该文件包含有最终生成的目标文件的地址图,标明了所有函数在最终目标文件里的位置,以及是从哪个模块链接过来的。

2.7 mem文件

该文件里显示目标文件运行时RAM和堆栈的使用情况。

总结

  • 单源文件的工程可以使用sdcc source.c来编译。
  • 多元文件的工程可以将源码编译成rel文件,再统一链接。
  • sdcc编译成功后会生成许多文件。
  • lst rst rel sym文件用于编译过程,如果编译没有出现问题,可以不用去看这些文件。
  • asm用于显示源文件的汇编代码,在解决一些优化及疑难问题时要去查看该文件。
  • map和mem文件可以帮助我们分析该项目对单片机存储资源的占用情况。

一、前言

最近打算写一些单片机程序,因此买了一块51开发板,打算写几个有趣的程序。

出于将学习和娱乐分开的目的,我把编程工作放在linux下来进行。

在linux下进行单片机的软件开发,要先安装专用的交叉编译器sdcc。接下来我会阅读sdcc的man文档,再结合一些简单的实验,来了解一下这款编译器。其目的有三,一是复习一些单片机的知识,为编程做点准备。二是理清sdcc的编译选项,好用来写makefile。三是弄明白sdcc和keil编译器的不同,这样可以把keil c的代码移植过来直接使用。

二、sdcc的安装

1.1 在ubuntun下安装sdcc

由于我的系统是ubuntun,因此可以直接使用apt-get命令来进行安装

1
$sudo apt-get install sdcc

1.2 用其他方式安装sdcc

非ubuntun环境下,可以下载sdcc源码并编译生成sdcc,这样可以得到目前的最高版本。

sdcc源码的下载地址是 http://sdcc.sourceforge.net/snap.php

1
2
3
4
5
6
$tar -xvjf sdcc-src-yyyymmdd-rrrr.tar.bz2

$cd sdcc
$./configure
$make
$make install

sdcc man文件下载地址 http://sdcc.sourceforge.net/doc/sdccman.pdf

三、sdcc包含的内容

安装完sdcc后可以分析一下sdcc一共包含哪些组成部分。

2.1 头文件和库文件

sdcc的头文件和库文件在 installdir/share/sdcc目录下,除此之外的所有bin文件包含在/bin目录下。

installdir/share/sdcc/include
installdir/share/sdcc/lib

installdir/bin

installdir默认的值为/usr。

2.2 编译程序sdcc

编译程序sdcc,最常用到的命令,它所做的其实就是轮流调用预处理器、汇编器、连接器来完成编译工作。

2.3 预处理程序sdccp

这个预编译程序sdccp是直接用gcc的预编译程序的源码修改而来的,它被用来在编译前处理#include #define 这些预编译指令。

2.4 汇编程序和链接程序sdas, sdld

sdas用来将C源码编译成汇编指令,sdld用来链接各目标文件的符号表。顺带一提man文档上说这两个程序都是基于Alan Baldwin的开源代码修改的,现在用的是它的2.0版本。Alan Baldwin已经将它的5.0版本开源,该老兄一直致力于编译器的研发工作。

2.5 仿真器

sdcc集成的仿真器包含s51, sz80 shc08 and sstm8系统,由Daniel Drotos开发,在他的网站上有详细的说明:

http://mazsola.iit.uni-miskolc.hu/~drdani/embedded/s51

2.6 debug工具 sdcdb

sdcc用Daniel Drotos的仿真器进行debug,由于我有开发板,可以直接把程序烧上去。而且该款单片机没有j-tag接口,所以等有时间再来研究这个debug工具吧。

总结

  • 在linux下进行单片机开发可以使用交叉编译器sdcc
  • sdcc包含有一个编译程序、预处理程序、汇编程序和链接程序。
  • sdcc还包含有一个集成的仿真器和debug工具。

一、建立hexo站点

1.1安装node.js

由于hexo基于node.js环境,所以在建立hexo站点前必须先安装node.js环境。

我的系统是从unbuntu官网下载的unbuntu14.04 32bit。如果是windows用户,可以安装node.js的windows版本,官网上也提供win版本的下载链接。

http://nodejs.org/ 上下载node.js的最新源码,然后使用make install 进行编译,即可在系统里生成node.js的环境。编译了半小时才完成,居然没有报任何错误,so lucky!

1
2
$ ./configure
$ make install

1.2安装hexo

装完了node.js就可以安装hexo了,使用npm命令直接安装hexo及它的命令行工具。

1
$ npm install hexo-cli -g

1.3建立站点

使用 http://hexo.io 上的例子可以快速创建一个hexo站点

1
2
3
$ hexo init blog
$ cd blog
$ npm install

完成了这个步骤之后,可以看到站点的相关文件都已经在blog目录下建立完毕。

1
$ hexo server

之后使用hexo server可以在本地浏览该站点,默认的地址是 http://localhost:4000

二、修改hexo站点

2.1修改主题

本站用的是 http://hexo.io 上theme页的jacman主题,先从git上下载下来,然后修改hexo目录下_config.yml的文件即可设置新主题。如果想要定制化hexo,除了看_config.yml里的注释,还可以把官网上的doc看一篇。

1
2
$vim _config.yml
theme: jacman

2.2新建文章

用hexo new命令可以创建一篇新的文章,然后用编辑器编辑即可,支持Markdown语法。

1
2
hexo new hexo
vim source/_posts/hexo.md

2.3与github同步

hexo可以实现一键同步,它提供很多种提交方式,git是最常用的一种。要用git进行提交,先要设置好git用ssh访问,安装hexo的git工具,然后修改_config.yml的设置。

1
2
3
4
5
6
7
8
9
$ npm install hexo-deployer-git --save

vim _config.yml

deploy:
type: git
repo: <repository url>
branch: [branch]
message: [message]

总结

  • hexo依赖于node.js,在安装前必须先架设node.js环境。
  • hexo内置与github服务器同步的命令,前提是安装好git,并在配置文件下设置git的相关配置。
  • 使用hexo server命令可以在本地查看站点,再用hexo d命令与github进行一键同步。
  • 用hexo new命令创建文章,并用Markdown语法直接编辑文件。