2022年1月1日 星期六

A pattern for command table


我們常常會需要比對字串/指令後, 執行對應的function, 常見的就是用for loop把command table比對過一次, 但是如果command table大, 效率就不好, 可以用qsort()+bsearch()做binary search以提升效率.

#include <stdio.h> #include <string.h> typedef void (*cmd_fp)(char *cmd);
/* * command function */ void hello(char *cmd) { printf("%s(#%d)\n", __FUNCTION__, __LINE__); }
/* * command function */ void world(char *cmd) { printf("%s(#%d)\n", __FUNCTION__, __LINE__); } /* The structure for command entry */ struct cmd_ent { char const * cmd; cmd_fp fp; } /* Command table - a command array */ cmd_tab[] = { {"hello", hello}, {"world", world}, }; #define AR_SZ(a) (sizeof(a)/sizeof(a[0])) int main(int argc, char *argv[]) { char cmd[64]; int i; while(fgets(cmd, sizeof(cmd) - 1, stdin)) { cmd[strlen(cmd) - 1] = 0; for (i = 0; i < AR_SZ(cmd_tab); i++) { if (strcmp(cmd, cmd_tab[i].cmd) == 0) { cmd_tab[i].fp(cmd); break; } } if (i == AR_SZ(cmd_tab)) { printf("cmd not found\n"); } } }


qsort() + bsearch() version
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef void (*cmd_fp)(char *cmd);

/* * command function */ void hello(char *cmd) { printf("%s(#%d)\n", __FUNCTION__, __LINE__); }
/* * command function */ static void world(char *cmd) { printf("%s(#%d)\n", __FUNCTION__, __LINE__); }
/* The structure for command entry */ struct cmd_ent { char const * cmd; cmd_fp fp; };
/* Command table that is qsort() + bsearch() version */ static struct cmd_tab { int sz; // total htab size int count; // how many comand entry stored in htab. struct cmd_ent *htab; } cmd_tab; /* * increas htab. it will be invoked once htab is full. */ static struct cmd_ent * realloc_htab_and_copy(int new_sz, struct cmd_ent *otab, int num) { struct cmd_ent *ntab; ntab = (struct cmd_ent *) malloc(sizeof(struct cmd_ent) * new_sz); memset(ntab, 0, sizeof(struct cmd_ent) * new_sz); if (num) { memcpy(ntab, otab, sizeof(struct cmd_ent) * num); free(otab); } return ntab; } /* compare function is used for qsort()/sorting or bsearch()/searching */ static int compmi(const void *v1, const void *v2) { struct cmd_ent* e1 = (struct cmd_ent*) v1; struct cmd_ent* e2 = (struct cmd_ent*) v2; return strcmp(e1->cmd, e2->cmd); } /* used for registering a new "cmd"/"fp" into comand table */ static void reg_cmd(char *cmd, cmd_fp fp) { if (cmd_tab.sz == cmd_tab.count) { cmd_tab.sz = (cmd_tab.sz + 16) * 2; cmd_tab.htab = realloc_htab_and_copy(cmd_tab.sz, cmd_tab.htab, cmd_tab.count); } cmd_tab.htab[cmd_tab.count].cmd = cmd; cmd_tab.htab[cmd_tab.count].fp = fp; cmd_tab.count++; qsort(cmd_tab.htab, cmd_tab.count, sizeof(struct cmd_ent), compmi); } /* an example to register two commands into command table */ static void reg_cmds(void) { reg_cmd("hello", hello); reg_cmd("world", world); } int main(int argc, char *argv[]) { char cmd[64]; struct cmd_ent key, *res; int i; reg_cmds(); while(fgets(cmd, sizeof(cmd) - 1, stdin)) { /* main body for command searching */ cmd[strlen(cmd) - 1] = 0; key.cmd = cmd; res = bsearch(&key, cmd_tab.htab, cmd_tab.count, sizeof(struct cmd_ent), compmi); if (res == NULL) { printf("cmd not found\n"); } else { res->fp(cmd); } } }




2021年1月10日 星期日

Linux Kernel(21)- Pulse-Width Modulation


Duty cycle,所謂的Duty Cycle指的是一段時間內on的百分比(The term duty cycle describes the proportion of 'on' time to the regular interval or 'period' of time),如下圖


Polarity,這裡的Polarity指的是high active或是low active,
 * @PWM_POLARITY_NORMAL: a high signal for the duration of the duty-
 * cycle, followed by a low signal for the remainder of the pulse
 * period
 * @PWM_POLARITY_INVERSED: a low signal for the duration of the duty-
 * cycle, followed by a high signal for the remainder of the pulse
 * period

PWM常被當成是信號調變(modulation)的一種形式,在一端進行編碼並在另一端進行解碼。通常我們會拿來控制LED或馬達等裝置。
          _      _      _      _      _      _      _      _     
         | |    | |    | |    | |    | |    | |    | |    | |    
Clock    | |    | |    | |    | |    | |    | |    | |    | |    
       __| |____| |____| |____| |____| |____| |____| |____| |____

                 _      __     ____          ____   _
PWM signal      | |    |  |   |    |        |    | | |
                | |    |  |   |    |        |    | | |
       _________| |____|  |___|    |________|    |_| |___________

Data       0     1       2      4      0      4     1      0
The inclusion of a clock signal is not necessary, as the leading edge of the data signal can be used as the clock if a small offset is added to each data value in order to avoid a data value with a zero length pulse.

                _      __     ___    _____   _      _____   __     _   
               | |    |  |   |   |  |     | | |    |     | |  |   | | 
PWM signal     | |    |  |   |   |  |     | | |    |     | |  |   | |  
             __| |____|  |___|   |__|     |_| |____|     |_|  |___| |_____

Data            0       1      2       4     0        4      1     0





2020年11月28日 星期六

LTE-U and LAA


LTE-Unliceded(LTE-U/3GPP Rel-10/11/12)最早是由Qualcomm提出的LTE標準,旨在允許Operator透過ISM(Industrial Scientific Medical Band/5GHz)頻帶取得更大的頻寬。control channel需要走LTE,而data走5GHz 頻段,所以要搭配CA(Carrier Aggregation)以及SDL(Supplemental Downlink)完成該功能,該5G頻段為LTE Band 46。

LAA(Licensed Assisted Access)是LTE-U的進化版,並提入3GPP Rel-13,隨後還有3GPP Rel-14的eLAA(enhanced-LAA)以及3GPP Rel-14的feLAA(Further Enhanced LAA)。

LTE-U 與 LAA 主要的差異在於採用不同的避免干擾機制(contention protocol),LTE-U 主要採取CSAT(Carrier Sense Adaptation Transmission)而LAA採用LBT through CCA((Listen Before Talk through clear channel assessment) ,兩種模式皆是為了與既有 Wi-Fi 服務於免執照頻段中共享與共存。





熱門文章