driver.c
2026/7/19大约 2 分钟附录源码附录
driver.c
路径: drivers\driver.c
/**
***********************************************************************************************************************
* Copyright (c) 2020, China Mobile Communications Group Co.,Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* @file driver.c
*
* @brief this file implements timer related definitions and declarations
*
* @details
*
* @revision
* Date Author Notes
* 2020-02-20 OneOS Team First Version
***********************************************************************************************************************
*/
#include <string.h>
#include <stdlib.h>
#include <driver.h>
#include <os_clock.h>
void *interrupt_stack_addr = OS_NULL;
uint32_t interrupt_stack_size = 0;
#ifdef OS_USING_SMP
static OS_DEFINE_SPINLOCK(gs_uart_lock);
#endif
uint32_t uart_calc_byte_timeout_us(uint32_t baud)
{
/* start + data + stop = 10 bits */
return 10 * 1000000 / baud;
}
void calc_mult_shift(uint32_t *mult, uint32_t *shift, uint32_t from, uint32_t to, uint32_t max_from)
{
uint64_t tmp;
uint32_t sft, sftacc = 32;
tmp = ((uint64_t)max_from * from) >> 32;
while (tmp)
{
tmp >>= 1;
sftacc--;
}
for (sft = 32; sft > 0; sft--)
{
tmp = (uint64_t)to << sft;
tmp += from / 2;
tmp /= from;
if ((tmp >> sftacc) == 0)
break;
}
*mult = tmp;
*shift = sft;
}
/* clang-format off */
static const unsigned short crc_ta[16] =
{
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
};
/* clang-format on */
unsigned short crc16(unsigned short init_crc, void *buff, int len)
{
unsigned short crc = init_crc;
unsigned char *ptr = buff;
unsigned char da;
while (len-- > 0)
{
da = crc >> 12;
crc <<= 4;
crc ^= crc_ta[da ^ (*ptr >> 4)];
da = crc >> 12;
crc <<= 4;
crc ^= crc_ta[da ^ (*ptr & 0x0f)];
ptr++;
}
return crc;
}
void hex_dump(unsigned char *buff, int count)
{
int i;
for (i = 0; i < count; i++)
{
if (i % 16 == 0)
os_kprintf("%08x: ", i);
os_kprintf("%02x ", buff[i]);
if (i % 8 == 7)
os_kprintf(" ");
if (i % 16 == 15)
os_kprintf("\r\n");
}
os_kprintf("\r\n");
}
OS_WEAK void os_hw_cpu_reset(void)
{
}
#ifdef OS_USING_SHELL
#include <shell.h>
static void reboot(int argc, char *argv[])
{
os_hw_cpu_reset();
}
SH_CMD_EXPORT(reboot, reboot, "reboot");
static void md(int argc, char *argv[])
{
if (argc != 2 && argc != 3)
{
os_kprintf("usage: md <address> [count]\r\n");
os_kprintf(" md 0x20000000 (default 1)\r\n");
os_kprintf(" md 0x20000000 16\r\n");
return;
}
unsigned char *buff = (unsigned char *)strtol(argv[1], OS_NULL, 0);
unsigned int count = 4;
if (argc == 3)
{
count = strtol(argv[2], OS_NULL, 0);
}
hex_dump(buff, count);
}
SH_CMD_EXPORT(md, md, "memory display");
static void mm(int argc, char *argv[])
{
if (argc != 3)
{
os_kprintf("usage: mm <address> <value>\r\n");
os_kprintf(" mm 0x20000000 0x12345678\r\n");
return;
}
unsigned char *buff = (unsigned char *)strtol(argv[1], OS_NULL, 0);
unsigned int value = strtol(argv[2], OS_NULL, 0);
*buff = value;
}
SH_CMD_EXPORT(mm, mm, "memory modify");
#endif
/* kernel start */
void os_kernel_init(void);
void os_kernel_start(void);
#if defined(__CC_ARM) || defined(__CLANG_ARM)
void $Sub$$main(void)
{
os_kernel_init();
os_kernel_start();
}
#elif defined(__ICCARM__) || defined(__GNUC__)
void entry(void)
{
os_kernel_init();
os_kernel_start();
}
#endif
void app_entry(void)
{
#if defined(__CC_ARM) || defined(__CLANG_ARM)
extern int $Super$$main(void);
$Super$$main();
#elif defined(__ICCARM__) || defined(__GNUC__)
extern int main(void);
main();
#endif
}