打开 VS2010,在上方菜单栏中选择“文件 --> 新建 --> 项目”:
会弹出下面的对话框:
选择“Win32控制台应用程序”,填写好项目名称,选择好存储路径,点击“确定”按钮即可。
会弹出应用程序向导,下一步即可
点击“下一步”按钮,弹出新的对话框:
先取消“预编译头”,再勾选“空项目”,然后点击“完成”按钮就创建了一个新的项目。
在“源文件”处右击鼠标,在弹出菜单中选择“添加 -> 新建项”,如下图所示:
可以根据需要选择新建或已有的文件导入,新建了main.c文件
编写如下代码,这段代码主要是解析终端用户的命令输入,在命令列表中匹配具体命令并且调用相应的命令处理函数来调度执行。代码示例如下:
#include <stdio.h>
#include "main.h"
static cmd_entry_t shell_vtable[100]; /* forward declare */
extern cmd_entry_t chut_vtable[100]; /* extern declare */
int main() {
const char *cmdline = "rspi 0x00 0x00 0x01;";
int ret_value;
ret_value = shell_entry(cmdline);
printf("main: error is %d\n", ret_value);
getchar();
return 0;
}
int shell_entry(const char *cmdline)
{
char cmd[20];
char arg1[100];
char arg2[100];
char arg3[100];
int error;
const char *p;
error = 1;
printf("shell_entry: error is %d\n", error);
for (
p = parse_cmdline(cmdline, cmd, arg1, arg2, arg3);
*p;
p = parse_cmdline(p+1, cmd, arg1, arg2, arg3)
) {
printf("shell_entry: error is %d\n", error);
/* no command */
if (!strlen(cmd))
continue;
printf("shell_entry: error is %d\n", error);
printf("shell_entry: arg1 is %s\n", arg1);
printf("shell_entry: arg2 is %s\n", arg2);
printf("shell_entry: arg3 is %s\n", arg3);
error = dispatch_sh_command(cmd, arg1, arg2, arg3);
if (error){
error = dispatch_cut_command(cmd, arg1, arg2, arg3);
}
printf("\r\n");
}
return error;
}
/*命令行参数解析函数。它通过调用宏 FETCH_PATTERN 来逐个解析命令行参数,并将结果存储到相应的目标数组中。最后返回剩余未解析的命令行字符串的起始位置。*/
const char *parse_cmdline(
const char *cmdline,
char *cmd,
char *arg1,
char *arg2, char *arg3
)
{
const char *pf;
char *pt;
pf = cmdline;
printf("parse_cmdline: pf is %s\n", pf);
TRIM_LEFT(pf);
printf("parse_cmdline: here\n");
/* fetch command */
pt = cmd;
printf("parse_cmdline: pf is %s\n", pf);
printf("parse_cmdline: pt is %s\n", pf);
FETCH_PATTERN(pf, pt);
printf("parse_cmdline: pf is %s\n", pf);
printf("parse_cmdline: pt is %s\n", pf);
/* fetch arg1 */
pt = arg1;
FETCH_PATTERN(pf, pt);
printf("parse_cmdline: pf is %s\n", pf);
printf("parse_cmdline: pt is %s\n", pf);
/* fetch arg2 */
pt = arg2;
FETCH_PATTERN(pf, pt);
printf("parse_cmdline: pf is %s\n", pf);
printf("parse_cmdline: pt is %s\n", pf);
/* fetch arg3 */
pt = arg3;
FETCH_PATTERN(pf, pt);
printf("parse_cmdline: pf is %s\n", pf);
printf("parse_cmdline: pt is %s\n", pf);
printf("parse_cmdline: before return\n");
printf("parse_cmdline: pf is %s\n", pf);
return pf;
}
/*实现了通过匹配命令和调用相应的命令处理函数来调度执行 shell 命令的功能*/
static int dispatch_sh_command(char *cmd, char *arg1, char *arg2, char *arg3)
{
cmd_entry_t *pe;
cmd_proc proc;
char cname[20];
for (pe = shell_vtable; pe->names; ++pe) {
proc = (cmd_proc)pe->proc;
if (find_strpat(pe->names, cmd, ':')) {
get_1st_strpat(cname, pe->names, ':');
(proc)(cname, arg1, arg2, arg3);
break;
}
}
return (pe->names == NULL);
}
static int dispatch_cut_command(char *cmd, char *arg1, char *arg2, char *arg3)
{
cmd_entry_t *pe;
cmd_proc proc;
char cname[20];
for (pe = chut_vtable; pe->names; ++pe) {
proc = (cmd_proc)pe->proc;
if (find_strpat(pe->names, cmd, ':')) {
get_1st_strpat(cname, pe->names, ':');
printf("%s", cname);
(proc)(cname, arg1, arg2, arg3);
break;
}
}
return (pe->names == NULL);
//if (pe->names == NULL) {
//printf("Unknown command!\r\n");
//return 1;
//}
//else {
// return 0;
//}
}
/*实现了在给定字符串中按照指定模式和分隔符进行匹配搜索的功能,它在字符串中逐一检查部分子串,直到找到与模式字符串相匹配的子串为止,然后返回该子串的起始位置。
如果没有找到匹配的子串,则返回 NULL。*/
const char *find_strpat(const char *str, const char *pat, const char delim)
{
const char *p;
const char *q;
u8 pat_len;
pat_len = strlen(pat);
p = str;
q = strchr(p, delim);
while (p && q) {
if (!strncmp(pat, p, pat_len))
break;
p = q+1;
q = strchr(p, delim);
}
if (p && !q && strcmp(pat, p))
return NULL;
return p;
}
/*从给定源字符串中按照指定分隔符获取第一个匹配到的子串的功能*/
void get_1st_strpat(char *dst, const char *src, const char delim)
{
const char *p;
u8 len;
p = strchr(src, ':');
if (p) {
len = p - src;
strncpy(dst, src, len);
dst[len] = '\0';
}
else {
strcpy(dst, src);
}
}
CHUT_INSTALL_BEGIN(JEM5396)
CHUT_ENTRY3("pins" , pins_map , "--Pin Map")
CHUT_ENTRY3("rspi" , read_spi_cmd , "--Read Register:rspi page addr bytenum")
CHUT_ENTRY3("wspi" , write_spi_cmd , "--Write Register:wspi page addr MSB:LSB")
CHUT_ENTRY3("rpphy" , read_pphy_cmd , "--Read Pesudo-PHY Register:rpphy page addr bytenum")
CHUT_ENTRY3("wpphy" , write_pphy_cmd , "--Write Pesudo-PHY Register:wpphy page addr MSB:LSB")
CHUT_ENTRY3("rphy" , read_phy_cmd , "--Read PHY Register:rphy phyid phyreg")
CHUT_ENTRY3("wphy" , write_phy_cmd , "--Write PHY Register:wphy phyid phyreg MSB:LSB")
CHUT_ENTRY3("en_imp" , en_imp , "--enable in-band management port!")
CHUT_ENTRY3("tx_imp" , tx_imp , "--send multiport frame")
CHUT_ENTRY3("rx_imp" , rx_imp , "--display the received imp packet")
CHUT_ENTRY3("tst_gpio" , test_gpio_cmd , "--reset GPIO pin8 for n cycles")
CHUT_INSTALL_END
void pins_map(char *cmd, char *arg1, char *arg2, char *arg3){
char str[] = "pins_map!";
printf("String: %s\n", str);
}
void read_spi_cmd(char *cmd, char *arg1, char *arg2, char *arg3){
char str[] = "read_spi_cmd!";
printf("String: %s\n", str);
}
void write_spi_cmd(char *cmd, char *arg1, char *arg2, char *arg3){
char str[] = "write_spi_cmd!";
printf("String: %s\n", str);
}
void read_pphy_cmd(char *cmd, char *arg1, char *arg2, char *arg3){
char str[] = "read_pphy_cmd!";
printf("String: %s\n", str);
}
void write_pphy_cmd(char *cmd, char *arg1, char *arg2, char *arg3){
char str[] = "write_pphy_cmd!";
printf("String: %s\n", str);
}
void read_phy_cmd(char *cmd, char *arg1, char *arg2, char *arg3){
char str[] = "read_phy_cmd!";
printf("String: %s\n", str);
}
void write_phy_cmd(char *cmd, char *arg1, char *arg2, char *arg3){
char str[] = "write_phy_cmd!";
printf("String: %s\n", str);
}
void en_imp(char *cmd, char *arg1, char *arg2, char *arg3){
char str[] = "en_imp!";
printf("String: %s\n", str);
}
void tx_imp(char *cmd, char *arg1, char *arg2, char *arg3){
char str[] = "tx_imp!";
printf("String: %s\n", str);
}
void rx_imp(char *cmd, char *arg1, char *arg2, char *arg3){
char str[] = "rx_imp!";
printf("String: %s\n", str);
}
void test_gpio_cmd(char *cmd, char *arg1, char *arg2, char *arg3){
char str[] = "test_gpio_cmd!";
printf("String: %s\n", str);
}
添加相应的头文件main.h
main.h 代码如下:
#include <ctype.h>
#include <string.h>
#include <wtypes.h>
#include "types.h"
//#include "chut.h"
#define IS_EOC(p) ((*(p) == NULL) || (*(p) == ';'))
#define SKIP_SPACE(p) do { \
while (!IS_EOC(p) && isspace(*(p))) (p)++; \
} while (0)
#define TRIM_LEFT(p) SKIP_SPACE((p))
#define FETCH_PATTERN(f,t) do { \
while (!IS_EOC(f) && !isspace(*(f))) { \
*(t)++ = *(f)++; \
} \
*(t) = '\0'; \
SKIP_SPACE((f)); \
} while (0)
typedef int (*cmd_proc)(char *cmd, char *arg1, char *arg2, char *arg3);
typedef struct _cmd_entry_t {
char *names; /**< all valid command name string separated with space */
void *proc; /**< cmd_proc */
char *help_str; /**< help string of commands */
} cmd_entry_t;
#ifndef _LINUX_TYPES_H /* Linux has its own types.h file. Skip me */
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef float fp32; /**< single-precision float 32-bit */
typedef double fp64; /**< double-precision float 64-bit */
#endif
#define CHUT_INSTALL_BEGIN(pn) char *PROJECT=#pn; cmd_entry_t chut_vtable[] = {
#define CHUT_ENTRY(f) { #f, (f), #f },
#define CHUT_ENTRY2(n,f) { n, (f), #f },
#define CHUT_ENTRY3(n,f,h) { n, (f), (h) },
#define CHUT_INSTALL_END { NULL, NULL, NULL } };
int shell_entry(const char *cmdline);
const char *parse_cmdline(const char *cmdline, char *cmd, char *arg1, char *arg2, char *arg3);
const char *find_strpat(const char *str, const char *pat, const char delim);
void get_1st_strpat(char *dst, const char *src, const char delim);
static int dispatch_sh_command(char *cmd, char *arg1, char *arg2, char *arg3);
static int dispatch_cut_command(char *cmd, char *arg1, char *arg2, char *arg3);
void pins_map(char *cmd, char *arg1, char *arg2, char *arg3);
void read_spi_cmd(char *cmd, char *arg1, char *arg2, char *arg3);
void write_spi_cmd(char *cmd, char *arg1, char *arg2, char *arg3);
void read_pphy_cmd(char *cmd, char *arg1, char *arg2, char *arg3);
void write_pphy_cmd(char *cmd, char *arg1, char *arg2, char *arg3);
void read_phy_cmd(char *cmd, char *arg1, char *arg2, char *arg3);
void write_phy_cmd(char *cmd, char *arg1, char *arg2, char *arg3);
void en_imp(char *cmd, char *arg1, char *arg2, char *arg3);
void tx_imp(char *cmd, char *arg1, char *arg2, char *arg3);
void rx_imp(char *cmd, char *arg1, char *arg2, char *arg3);
void test_gpio_cmd(char *cmd, char *arg1, char *arg2, char *arg3);
在上方菜单栏中点击“生成”按钮,会弹出一个子菜单,再点击“编译”按钮,就完成了 main.c 源文件的编译工作。
点击编译,可以查看到编译后的结果
在菜单栏中选择“项目 --> 仅用于项目 --> 仅链接 firstdemo”,就完成了 firstdemo.obj 的链接工作,如下图所示:
点击菜单栏中的“运行”按钮,或者按下F5键,可以一键完成编译、链接、运行三个动作。看到输出结果了,如下图所示:
以上就完成了第一个vs项目了,又是新的一天开始加油吧!